Actual source code: snesut.c
1: #define PETSCSNES_DLL
3: #include include/private/snesimpl.h
7: /*@C
8: SNESMonitorSolution - Monitors progress of the SNES solvers by calling
9: VecView() for the approximate solution at each iteration.
11: Collective on SNES
13: Input Parameters:
14: + snes - the SNES context
15: . its - iteration number
16: . fgnorm - 2-norm of residual
17: - dummy - either a viewer or PETSC_NULL
19: Level: intermediate
21: .keywords: SNES, nonlinear, vector, monitor, view
23: .seealso: SNESMonitorSet(), SNESMonitorDefault(), VecView()
24: @*/
25: PetscErrorCode SNESMonitorSolution(SNES snes,PetscInt its,PetscReal fgnorm,void *dummy)
26: {
28: Vec x;
29: PetscViewer viewer = (PetscViewer) dummy;
32: SNESGetSolution(snes,&x);
33: if (!viewer) {
34: MPI_Comm comm;
35: PetscObjectGetComm((PetscObject)snes,&comm);
36: viewer = PETSC_VIEWER_DRAW_(comm);
37: }
38: VecView(x,viewer);
40: return(0);
41: }
45: /*@C
46: SNESMonitorResidual - Monitors progress of the SNES solvers by calling
47: VecView() for the residual at each iteration.
49: Collective on SNES
51: Input Parameters:
52: + snes - the SNES context
53: . its - iteration number
54: . fgnorm - 2-norm of residual
55: - dummy - either a viewer or PETSC_NULL
57: Level: intermediate
59: .keywords: SNES, nonlinear, vector, monitor, view
61: .seealso: SNESMonitorSet(), SNESMonitorDefault(), VecView()
62: @*/
63: PetscErrorCode SNESMonitorResidual(SNES snes,PetscInt its,PetscReal fgnorm,void *dummy)
64: {
66: Vec x;
67: PetscViewer viewer = (PetscViewer) dummy;
70: SNESGetFunction(snes,&x,0,0);
71: if (!viewer) {
72: MPI_Comm comm;
73: PetscObjectGetComm((PetscObject)snes,&comm);
74: viewer = PETSC_VIEWER_DRAW_(comm);
75: }
76: VecView(x,viewer);
78: return(0);
79: }
83: /*@C
84: SNESMonitorSolutionUpdate - Monitors progress of the SNES solvers by calling
85: VecView() for the UPDATE to the solution at each iteration.
87: Collective on SNES
89: Input Parameters:
90: + snes - the SNES context
91: . its - iteration number
92: . fgnorm - 2-norm of residual
93: - dummy - either a viewer or PETSC_NULL
95: Level: intermediate
97: .keywords: SNES, nonlinear, vector, monitor, view
99: .seealso: SNESMonitorSet(), SNESMonitorDefault(), VecView()
100: @*/
101: PetscErrorCode SNESMonitorSolutionUpdate(SNES snes,PetscInt its,PetscReal fgnorm,void *dummy)
102: {
104: Vec x;
105: PetscViewer viewer = (PetscViewer) dummy;
108: SNESGetSolutionUpdate(snes,&x);
109: if (!viewer) {
110: MPI_Comm comm;
111: PetscObjectGetComm((PetscObject)snes,&comm);
112: viewer = PETSC_VIEWER_DRAW_(comm);
113: }
114: VecView(x,viewer);
116: return(0);
117: }
121: /*@C
122: SNESMonitorDefault - Monitors progress of the SNES solvers (default).
124: Collective on SNES
126: Input Parameters:
127: + snes - the SNES context
128: . its - iteration number
129: . fgnorm - 2-norm of residual
130: - dummy - unused context
132: Notes:
133: This routine prints the residual norm at each iteration.
135: Level: intermediate
137: .keywords: SNES, nonlinear, default, monitor, norm
139: .seealso: SNESMonitorSet(), SNESMonitorSolution()
140: @*/
141: PetscErrorCode SNESMonitorDefault(SNES snes,PetscInt its,PetscReal fgnorm,void *dummy)
142: {
143: PetscErrorCode ierr;
144: PetscViewerASCIIMonitor viewer = (PetscViewerASCIIMonitor) dummy;
147: if (!dummy) {
148: PetscViewerASCIIMonitorCreate(snes->comm,"stdout",0,&viewer);
149: }
150: PetscViewerASCIIMonitorPrintf(viewer,"%3D SNES Function norm %14.12e \n",its,fgnorm);
151: if (!dummy) {
152: PetscViewerASCIIMonitorDestroy(viewer);
153: }
154: return(0);
155: }
157: typedef struct {
158: PetscViewerASCIIMonitor viewer;
159: PetscReal *history;
160: } SNESMonitorRatioContext;
164: /*@C
165: SNESMonitorRatio - Monitors progress of the SNES solvers by printing the ratio
166: of residual norm at each iteration to the previous.
168: Collective on SNES
170: Input Parameters:
171: + snes - the SNES context
172: . its - iteration number
173: . fgnorm - 2-norm of residual (or gradient)
174: - dummy - context of monitor
176: Level: intermediate
178: .keywords: SNES, nonlinear, monitor, norm
180: .seealso: SNESMonitorSet(), SNESMonitorSolution()
181: @*/
182: PetscErrorCode SNESMonitorRatio(SNES snes,PetscInt its,PetscReal fgnorm,void *dummy)
183: {
184: PetscErrorCode ierr;
185: PetscInt len;
186: PetscReal *history;
187: SNESMonitorRatioContext *ctx = (SNESMonitorRatioContext*)dummy;
190: SNESGetConvergenceHistory(snes,&history,PETSC_NULL,&len);
191: if (!its || !history || its > len) {
192: PetscViewerASCIIMonitorPrintf(ctx->viewer,"%3D SNES Function norm %14.12e \n",its,fgnorm);
193: } else {
194: PetscReal ratio = fgnorm/history[its-1];
195: PetscViewerASCIIMonitorPrintf(ctx->viewer,"%3D SNES Function norm %14.12e %G \n",its,fgnorm,ratio);
196: }
197: return(0);
198: }
200: /*
201: If the we set the history monitor space then we must destroy it
202: */
205: PetscErrorCode SNESMonitorRatioDestroy(void *ct)
206: {
207: PetscErrorCode ierr;
208: SNESMonitorRatioContext *ctx = (SNESMonitorRatioContext*)ct;
211: PetscFree(ctx->history);
212: PetscViewerASCIIMonitorDestroy(ctx->viewer);
213: PetscFree(ctx);
214: return(0);
215: }
219: /*@C
220: SNESMonitorSetRatio - Sets SNES to use a monitor that prints the
221: ratio of the function norm at each iteration.
223: Collective on SNES
225: Input Parameters:
226: + snes - the SNES context
227: - viewer - ASCII viewer to print output
229: Level: intermediate
231: .keywords: SNES, nonlinear, monitor, norm
233: .seealso: SNESMonitorSet(), SNESMonitorSolution(), SNESMonitorDefault()
234: @*/
235: PetscErrorCode SNESMonitorSetRatio(SNES snes,PetscViewerASCIIMonitor viewer)
236: {
237: PetscErrorCode ierr;
238: SNESMonitorRatioContext *ctx;
239: PetscReal *history;
242: if (!viewer) {
243: PetscViewerASCIIMonitorCreate(snes->comm,"stdout",0,&viewer);
244: PetscObjectReference((PetscObject)viewer);
245: }
246: PetscNew(SNESMonitorRatioContext,&ctx);
247: SNESGetConvergenceHistory(snes,&history,PETSC_NULL,PETSC_NULL);
248: if (!history) {
249: PetscMalloc(100*sizeof(PetscReal),&ctx->history);
250: SNESSetConvergenceHistory(snes,ctx->history,0,100,PETSC_TRUE);
251: }
252: ctx->viewer = viewer;
253: SNESMonitorSet(snes,SNESMonitorRatio,ctx,SNESMonitorRatioDestroy);
254: return(0);
255: }
257: /* ---------------------------------------------------------------- */
260: /*
261: Default (short) SNES Monitor, same as SNESMonitorDefault() except
262: it prints fewer digits of the residual as the residual gets smaller.
263: This is because the later digits are meaningless and are often
264: different on different machines; by using this routine different
265: machines will usually generate the same output.
266: */
267: PetscErrorCode SNESMonitorDefaultShort(SNES snes,PetscInt its,PetscReal fgnorm,void *dummy)
268: {
269: PetscErrorCode ierr;
270: PetscViewerASCIIMonitor viewer = (PetscViewerASCIIMonitor) dummy;
273: if (!dummy) {
274: PetscViewerASCIIMonitorCreate(snes->comm,"stdout",0,&viewer);
275: }
276: if (fgnorm > 1.e-9) {
277: PetscViewerASCIIMonitorPrintf(viewer,"%3D SNES Function norm %G \n",its,fgnorm);
278: } else if (fgnorm > 1.e-11){
279: PetscViewerASCIIMonitorPrintf(viewer,"%3D SNES Function norm %5.3e \n",its,fgnorm);
280: } else {
281: PetscViewerASCIIMonitorPrintf(viewer,"%3D SNES Function norm < 1.e-11\n",its);
282: }
283: if (!dummy) {
284: PetscViewerASCIIMonitorDestroy(viewer);
285: }
286: return(0);
287: }
288: /* ---------------------------------------------------------------- */
291: /*@C
292: SNESDefaultConverged - Convergence test of the solvers for
293: systems of nonlinear equations (default).
295: Collective on SNES
297: Input Parameters:
298: + snes - the SNES context
299: . it - the iteration (0 indicates before any Newton steps)
300: . xnorm - 2-norm of current iterate
301: . pnorm - 2-norm of current step
302: . fnorm - 2-norm of function at current iterate
303: - dummy - unused context
305: Output Parameter:
306: . reason - one of
307: $ SNES_CONVERGED_FNORM_ABS - (fnorm < abstol),
308: $ SNES_CONVERGED_PNORM_RELATIVE - (pnorm < xtol*xnorm),
309: $ SNES_CONVERGED_FNORM_RELATIVE - (fnorm < rtol*fnorm0),
310: $ SNES_DIVERGED_FUNCTION_COUNT - (nfct > maxf),
311: $ SNES_DIVERGED_FNORM_NAN - (fnorm == NaN),
312: $ SNES_CONVERGED_ITERATING - (otherwise),
314: where
315: + maxf - maximum number of function evaluations,
316: set with SNESSetTolerances()
317: . nfct - number of function evaluations,
318: . abstol - absolute function norm tolerance,
319: set with SNESSetTolerances()
320: - rtol - relative function norm tolerance, set with SNESSetTolerances()
322: Level: intermediate
324: .keywords: SNES, nonlinear, default, converged, convergence
326: .seealso: SNESSetConvergenceTest()
327: @*/
328: PetscErrorCode SNESDefaultConverged(SNES snes,PetscInt it,PetscReal xnorm,PetscReal pnorm,PetscReal fnorm,SNESConvergedReason *reason,void *dummy)
329: {
335:
336: *reason = SNES_CONVERGED_ITERATING;
338: if (!it) {
339: /* set parameter for default relative tolerance convergence test */
340: snes->ttol = fnorm*snes->rtol;
341: }
342: if (fnorm != fnorm) {
343: PetscInfo(snes,"Failed to converged, function norm is NaN\n");
344: *reason = SNES_DIVERGED_FNORM_NAN;
345: } else if (fnorm < snes->abstol) {
346: PetscInfo2(snes,"Converged due to function norm %G < %G\n",fnorm,snes->abstol);
347: *reason = SNES_CONVERGED_FNORM_ABS;
348: } else if (snes->nfuncs >= snes->max_funcs) {
349: PetscInfo2(snes,"Exceeded maximum number of function evaluations: %D > %D\n",snes->nfuncs,snes->max_funcs);
350: *reason = SNES_DIVERGED_FUNCTION_COUNT;
351: }
353: if (it && !*reason) {
354: if (fnorm <= snes->ttol) {
355: PetscInfo2(snes,"Converged due to function norm %G < %G (relative tolerance)\n",fnorm,snes->ttol);
356: *reason = SNES_CONVERGED_FNORM_RELATIVE;
357: } else if (pnorm < snes->xtol*xnorm) {
358: PetscInfo3(snes,"Converged due to small update length: %G < %G * %G\n",pnorm,snes->xtol,xnorm);
359: *reason = SNES_CONVERGED_PNORM_RELATIVE;
360: }
361: }
362: return(0);
363: }
367: /*@C
368: SNESSkipConverged - Convergence test for SNES that NEVER returns as
369: converged, UNLESS the maximum number of iteration have been reached.
371: Collective on SNES
373: Input Parameters:
374: + snes - the SNES context
375: . it - the iteration (0 indicates before any Newton steps)
376: . xnorm - 2-norm of current iterate
377: . pnorm - 2-norm of current step
378: . fnorm - 2-norm of function at current iterate
379: - dummy - unused context
381: Output Parameter:
382: . reason - SNES_CONVERGED_ITERATING or SNES_DIVERGED_FNORM_NAN
384: Notes:
385: Convergence is then declared after a fixed number of iterations have been used.
386:
387: Level: advanced
389: .keywords: SNES, nonlinear, skip, converged, convergence
391: .seealso: SNESSetConvergenceTest()
392: @*/
393: PetscErrorCode SNESSkipConverged(SNES snes,PetscInt it,PetscReal xnorm,PetscReal pnorm,PetscReal fnorm,SNESConvergedReason *reason,void *dummy)
394: {
401: *reason = SNES_CONVERGED_ITERATING;
403: if (fnorm != fnorm) {
404: PetscInfo(snes,"Failed to converged, function norm is NaN\n");
405: *reason = SNES_DIVERGED_FNORM_NAN;
406: } else if(it == snes->max_its) {
407: *reason = SNES_CONVERGED_ITS;
408: }
409: return(0);
410: }