Actual source code: snesut.c
petsc-3.9.4 2018-09-11
2: #include <petsc/private/snesimpl.h>
3: #include <petscdm.h>
4: #include <petscblaslapack.h>
6: /*@C
7: SNESMonitorSolution - Monitors progress of the SNES solvers by calling
8: VecView() for the approximate solution at each iteration.
10: Collective on SNES
12: Input Parameters:
13: + snes - the SNES context
14: . its - iteration number
15: . fgnorm - 2-norm of residual
16: - dummy - a viewer
18: Options Database Keys:
19: . -snes_monitor_solution [ascii binary draw][:filename][:viewer format] - plots solution at each iteration
21: Level: intermediate
23: .keywords: SNES, nonlinear, vector, monitor, view
25: .seealso: SNESMonitorSet(), SNESMonitorDefault(), VecView()
26: @*/
27: PetscErrorCode SNESMonitorSolution(SNES snes,PetscInt its,PetscReal fgnorm,PetscViewerAndFormat *vf)
28: {
30: Vec x;
31: PetscViewer viewer = vf->viewer;
35: SNESGetSolution(snes,&x);
36: PetscViewerPushFormat(viewer,vf->format);
37: VecView(x,viewer);
38: PetscViewerPopFormat(viewer);
39: return(0);
40: }
42: /*@C
43: SNESMonitorResidual - Monitors progress of the SNES solvers by calling
44: VecView() for the residual at each iteration.
46: Collective on SNES
48: Input Parameters:
49: + snes - the SNES context
50: . its - iteration number
51: . fgnorm - 2-norm of residual
52: - dummy - a viewer
54: Options Database Keys:
55: . -snes_monitor_residual [ascii binary draw][:filename][:viewer format] - plots residual (not its norm) at each iteration
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,PetscViewerAndFormat *vf)
64: {
66: Vec x;
67: PetscViewer viewer = vf->viewer;
71: SNESGetFunction(snes,&x,0,0);
72: PetscViewerPushFormat(viewer,vf->format);
73: VecView(x,viewer);
74: PetscViewerPopFormat(viewer);
75: return(0);
76: }
78: /*@C
79: SNESMonitorSolutionUpdate - Monitors progress of the SNES solvers by calling
80: VecView() for the UPDATE to the solution at each iteration.
82: Collective on SNES
84: Input Parameters:
85: + snes - the SNES context
86: . its - iteration number
87: . fgnorm - 2-norm of residual
88: - dummy - a viewer
90: Options Database Keys:
91: . -snes_monitor_solution_update [ascii binary draw][:filename][:viewer format] - plots update to solution at each iteration
93: Level: intermediate
95: .keywords: SNES, nonlinear, vector, monitor, view
97: .seealso: SNESMonitorSet(), SNESMonitorDefault(), VecView()
98: @*/
99: PetscErrorCode SNESMonitorSolutionUpdate(SNES snes,PetscInt its,PetscReal fgnorm,PetscViewerAndFormat *vf)
100: {
102: Vec x;
103: PetscViewer viewer = vf->viewer;
107: SNESGetSolutionUpdate(snes,&x);
108: PetscViewerPushFormat(viewer,vf->format);
109: VecView(x,viewer);
110: PetscViewerPopFormat(viewer);
111: return(0);
112: }
114: /*@C
115: KSPMonitorSNES - Print the residual norm of the nonlinear function at each iteration of the linear iterative solver.
117: Collective on KSP
119: Input Parameters:
120: + ksp - iterative context
121: . n - iteration number
122: . rnorm - 2-norm (preconditioned) residual value (may be estimated).
123: - dummy - unused monitor context
125: Level: intermediate
127: .keywords: KSP, default, monitor, residual
129: .seealso: KSPMonitorSet(), KSPMonitorTrueResidualNorm(), KSPMonitorLGResidualNormCreate()
130: @*/
131: PetscErrorCode KSPMonitorSNES(KSP ksp,PetscInt n,PetscReal rnorm,void *dummy)
132: {
134: PetscViewer viewer;
135: SNES snes = (SNES) dummy;
136: Vec snes_solution,work1,work2;
137: PetscReal snorm;
140: SNESGetSolution(snes,&snes_solution);
141: VecDuplicate(snes_solution,&work1);
142: VecDuplicate(snes_solution,&work2);
143: KSPBuildSolution(ksp,work1,NULL);
144: VecAYPX(work1,-1.0,snes_solution);
145: SNESComputeFunction(snes,work1,work2);
146: VecNorm(work2,NORM_2,&snorm);
147: VecDestroy(&work1);
148: VecDestroy(&work2);
150: PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)ksp),&viewer);
151: PetscViewerASCIIAddTab(viewer,((PetscObject)ksp)->tablevel);
152: if (n == 0 && ((PetscObject)ksp)->prefix) {
153: PetscViewerASCIIPrintf(viewer," Residual norms for %s solve.\n",((PetscObject)ksp)->prefix);
154: }
155: PetscViewerASCIIPrintf(viewer,"%3D SNES Residual norm %5.3e KSP Residual norm %5.3e \n",n,(double)snorm,(double)rnorm);
156: PetscViewerASCIISubtractTab(viewer,((PetscObject)ksp)->tablevel);
157: return(0);
158: }
160: #include <petscdraw.h>
162: /*@C
163: KSPMonitorSNESLGResidualNormCreate - Creates a line graph context for use with
164: KSP to monitor convergence of preconditioned residual norms.
166: Collective on KSP
168: Input Parameters:
169: + comm - communicator context
170: . host - the X display to open, or null for the local machine
171: . label - the title to put in the title bar
172: . x, y - the screen coordinates of the upper left coordinate of
173: the window
174: - m, n - the screen width and height in pixels
176: Output Parameter:
177: . draw - the drawing context
179: Options Database Key:
180: . -ksp_monitor_lg_residualnorm - Sets line graph monitor
182: Notes:
183: Use KSPMonitorSNESLGResidualNormDestroy() to destroy this line graph; do not use PetscDrawLGDestroy().
185: Level: intermediate
187: .keywords: KSP, monitor, line graph, residual, create
189: .seealso: KSPMonitorSNESLGResidualNormDestroy(), KSPMonitorSet(), KSPMonitorSNESLGTrueResidualCreate()
190: @*/
191: PetscErrorCode KSPMonitorSNESLGResidualNormCreate(MPI_Comm comm,const char host[],const char label[],int x,int y,int m,int n,PetscObject **objs)
192: {
193: PetscDraw draw;
195: PetscDrawAxis axis;
196: PetscDrawLG lg;
197: const char *names[] = {"Linear residual","Nonlinear residual"};
200: PetscDrawCreate(comm,host,label,x,y,m,n,&draw);
201: PetscDrawSetFromOptions(draw);
202: PetscDrawLGCreate(draw,2,&lg);
203: PetscDrawLGSetLegend(lg,names);
204: PetscDrawLGSetFromOptions(lg);
205: PetscDrawLGGetAxis(lg,&axis);
206: PetscDrawAxisSetLabels(axis,"Convergence of Residual Norm","Iteration","Residual Norm");
207: PetscDrawDestroy(&draw);
209: PetscMalloc1(2,objs);
210: (*objs)[1] = (PetscObject)lg;
211: return(0);
212: }
214: PetscErrorCode KSPMonitorSNESLGResidualNorm(KSP ksp,PetscInt n,PetscReal rnorm,PetscObject *objs)
215: {
216: SNES snes = (SNES) objs[0];
217: PetscDrawLG lg = (PetscDrawLG) objs[1];
219: PetscReal y[2];
220: Vec snes_solution,work1,work2;
223: if (rnorm > 0.0) y[0] = PetscLog10Real(rnorm);
224: else y[0] = -15.0;
226: SNESGetSolution(snes,&snes_solution);
227: VecDuplicate(snes_solution,&work1);
228: VecDuplicate(snes_solution,&work2);
229: KSPBuildSolution(ksp,work1,NULL);
230: VecAYPX(work1,-1.0,snes_solution);
231: SNESComputeFunction(snes,work1,work2);
232: VecNorm(work2,NORM_2,y+1);
233: if (y[1] > 0.0) y[1] = PetscLog10Real(y[1]);
234: else y[1] = -15.0;
235: VecDestroy(&work1);
236: VecDestroy(&work2);
238: PetscDrawLGAddPoint(lg,NULL,y);
239: if (n < 20 || !(n % 5) || snes->reason) {
240: PetscDrawLGDraw(lg);
241: PetscDrawLGSave(lg);
242: }
243: return(0);
244: }
246: /*@
247: KSPMonitorSNESLGResidualNormDestroy - Destroys a line graph context that was created
248: with KSPMonitorSNESLGResidualNormCreate().
250: Collective on KSP
252: Input Parameter:
253: . draw - the drawing context
255: Level: intermediate
257: .keywords: KSP, monitor, line graph, destroy
259: .seealso: KSPMonitorSNESLGResidualNormCreate(), KSPMonitorSNESLGTrueResidualDestroy(), KSPMonitorSet()
260: @*/
261: PetscErrorCode KSPMonitorSNESLGResidualNormDestroy(PetscObject **objs)
262: {
264: PetscDrawLG lg = (PetscDrawLG) (*objs)[1];
267: PetscDrawLGDestroy(&lg);
268: PetscFree(*objs);
269: return(0);
270: }
272: /*@C
273: SNESMonitorDefault - Monitors progress of the SNES solvers (default).
275: Collective on SNES
277: Input Parameters:
278: + snes - the SNES context
279: . its - iteration number
280: . fgnorm - 2-norm of residual
281: - vf - viewer and format structure
283: Notes:
284: This routine prints the residual norm at each iteration.
286: Level: intermediate
288: .keywords: SNES, nonlinear, default, monitor, norm
290: .seealso: SNESMonitorSet(), SNESMonitorSolution()
291: @*/
292: PetscErrorCode SNESMonitorDefault(SNES snes,PetscInt its,PetscReal fgnorm,PetscViewerAndFormat *vf)
293: {
295: PetscViewer viewer = vf->viewer;
299: PetscViewerPushFormat(viewer,vf->format);
300: PetscViewerASCIIAddTab(viewer,((PetscObject)snes)->tablevel);
301: PetscViewerASCIIPrintf(viewer,"%3D SNES Function norm %14.12e \n",its,(double)fgnorm);
302: PetscViewerASCIISubtractTab(viewer,((PetscObject)snes)->tablevel);
303: PetscViewerPopFormat(viewer);CHKERRQ(ierr) ;
304: return(0);
305: }
307: /*@C
308: SNESMonitorScaling - Monitors the largest value in each row of the Jacobian.
310: Collective on SNES
312: Input Parameters:
313: + snes - the SNES context
314: . its - iteration number
315: . fgnorm - 2-norm of residual
316: - vf - viewer and format structure
318: Notes:
319: This routine prints the largest value in each row of the Jacobian
321: Level: intermediate
323: .keywords: SNES, nonlinear, default, monitor, norm
325: .seealso: SNESMonitorSet(), SNESMonitorSolution()
326: @*/
327: PetscErrorCode SNESMonitorScaling(SNES snes,PetscInt its,PetscReal fgnorm,PetscViewerAndFormat *vf)
328: {
330: PetscViewer viewer = vf->viewer;
331: KSP ksp;
332: Mat J;
333: Vec v;
337: SNESGetKSP(snes,&ksp);
338: KSPGetOperators(ksp,&J,NULL);
339: MatCreateVecs(J,&v,NULL);
340: MatGetRowMaxAbs(J,v,NULL);
341: PetscViewerPushFormat(viewer,vf->format);
342: PetscViewerASCIIAddTab(viewer,((PetscObject)snes)->tablevel);
343: PetscViewerASCIIPrintf(viewer,"%3D SNES Jacobian maximum row entries \n");
344: VecView(v,viewer);
345: PetscViewerASCIISubtractTab(viewer,((PetscObject)snes)->tablevel);
346: PetscViewerPopFormat(viewer);CHKERRQ(ierr) ;
347: VecDestroy(&v);
348: return(0);
349: }
351: PetscErrorCode SNESMonitorJacUpdateSpectrum(SNES snes,PetscInt it,PetscReal fnorm,PetscViewerAndFormat *vf)
352: {
353: #if defined(PETSC_MISSING_LAPACK_GEEV)
354: SETERRQ(PetscObjectComm((PetscObject)snes),PETSC_ERR_SUP,"GEEV - Lapack routine is unavailable\nNot able to provide eigen values.");
355: #elif defined(PETSC_HAVE_ESSL)
356: SETERRQ(PetscObjectComm((PetscObject)snes),PETSC_ERR_SUP,"GEEV - No support for ESSL Lapack Routines");
357: #else
358: Vec X;
359: Mat J,dJ,dJdense;
361: PetscErrorCode (*func)(SNES,Vec,Mat,Mat,void*);
362: PetscInt n,i;
363: PetscBLASInt nb,lwork;
364: PetscReal *eigr,*eigi;
365: PetscScalar *work;
366: PetscScalar *a;
369: if (it == 0) return(0);
370: /* create the difference between the current update and the current jacobian */
371: SNESGetSolution(snes,&X);
372: SNESGetJacobian(snes,NULL,&J,&func,NULL);
373: MatDuplicate(J,MAT_COPY_VALUES,&dJ);
374: SNESComputeJacobian(snes,X,dJ,dJ);
375: MatAXPY(dJ,-1.0,J,SAME_NONZERO_PATTERN);
377: /* compute the spectrum directly */
378: MatConvert(dJ,MATSEQDENSE,MAT_INITIAL_MATRIX,&dJdense);
379: MatGetSize(dJ,&n,NULL);
380: PetscBLASIntCast(n,&nb);
381: lwork = 3*nb;
382: PetscMalloc1(n,&eigr);
383: PetscMalloc1(n,&eigi);
384: PetscMalloc1(lwork,&work);
385: MatDenseGetArray(dJdense,&a);
386: #if !defined(PETSC_USE_COMPLEX)
387: {
388: PetscBLASInt lierr;
389: PetscFPTrapPush(PETSC_FP_TRAP_OFF);
390: PetscStackCallBLAS("LAPACKgeev",LAPACKgeev_("N","N",&nb,a,&nb,eigr,eigi,NULL,&nb,NULL,&nb,work,&lwork,&lierr));
391: if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"geev() error %d",lierr);
392: PetscFPTrapPop();
393: }
394: #else
395: SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not coded for complex");
396: #endif
397: PetscPrintf(PetscObjectComm((PetscObject)snes),"Eigenvalues of J_%d - J_%d:\n",it,it-1);
398: for (i=0;i<n;i++) {
399: PetscPrintf(PetscObjectComm((PetscObject)snes),"%5d: %20.5g + %20.5gi\n",i,(double)eigr[i],(double)eigi[i]);
400: }
401: MatDenseRestoreArray(dJdense,&a);
402: MatDestroy(&dJ);
403: MatDestroy(&dJdense);
404: PetscFree(eigr);
405: PetscFree(eigi);
406: PetscFree(work);
407: return(0);
408: #endif
409: }
411: PETSC_INTERN PetscErrorCode SNESMonitorRange_Private(SNES,PetscInt,PetscReal*);
413: PetscErrorCode SNESMonitorRange_Private(SNES snes,PetscInt it,PetscReal *per)
414: {
416: Vec resid;
417: PetscReal rmax,pwork;
418: PetscInt i,n,N;
419: PetscScalar *r;
422: SNESGetFunction(snes,&resid,0,0);
423: VecNorm(resid,NORM_INFINITY,&rmax);
424: VecGetLocalSize(resid,&n);
425: VecGetSize(resid,&N);
426: VecGetArray(resid,&r);
427: pwork = 0.0;
428: for (i=0; i<n; i++) {
429: pwork += (PetscAbsScalar(r[i]) > .20*rmax);
430: }
431: MPIU_Allreduce(&pwork,per,1,MPIU_REAL,MPIU_SUM,PetscObjectComm((PetscObject)snes));
432: VecRestoreArray(resid,&r);
433: *per = *per/N;
434: return(0);
435: }
437: /*@C
438: SNESMonitorRange - Prints the percentage of residual elements that are more then 10 percent of the maximum value.
440: Collective on SNES
442: Input Parameters:
443: + snes - iterative context
444: . it - iteration number
445: . rnorm - 2-norm (preconditioned) residual value (may be estimated).
446: - dummy - unused monitor context
448: Options Database Key:
449: . -snes_monitor_range - Activates SNESMonitorRange()
451: Level: intermediate
453: .keywords: SNES, default, monitor, residual
455: .seealso: SNESMonitorSet(), SNESMonitorDefault(), SNESMonitorLGCreate()
456: @*/
457: PetscErrorCode SNESMonitorRange(SNES snes,PetscInt it,PetscReal rnorm,PetscViewerAndFormat *vf)
458: {
460: PetscReal perc,rel;
461: PetscViewer viewer = vf->viewer;
462: /* should be in a MonitorRangeContext */
463: static PetscReal prev;
467: if (!it) prev = rnorm;
468: SNESMonitorRange_Private(snes,it,&perc);
470: rel = (prev - rnorm)/prev;
471: prev = rnorm;
472: PetscViewerPushFormat(viewer,vf->format);
473: PetscViewerASCIIAddTab(viewer,((PetscObject)snes)->tablevel);
474: PetscViewerASCIIPrintf(viewer,"%3D SNES preconditioned resid norm %14.12e Percent values above 20 percent of maximum %5.2f relative decrease %5.2e ratio %5.2e \n",it,(double)rnorm,(double)(100.0*perc),(double)rel,(double)(rel/perc));
475: PetscViewerASCIISubtractTab(viewer,((PetscObject)snes)->tablevel);
476: PetscViewerPopFormat(viewer);
477: return(0);
478: }
480: /*@C
481: SNESMonitorRatio - Monitors progress of the SNES solvers by printing the ratio
482: of residual norm at each iteration to the previous.
484: Collective on SNES
486: Input Parameters:
487: + snes - the SNES context
488: . its - iteration number
489: . fgnorm - 2-norm of residual (or gradient)
490: - dummy - context of monitor
492: Level: intermediate
494: Notes: Insure that SNESMonitorRatio() is called when you set this monitor
495: .keywords: SNES, nonlinear, monitor, norm
497: .seealso: SNESMonitorSet(), SNESMonitorSolution(), SNESMonitorRatio()
498: @*/
499: PetscErrorCode SNESMonitorRatio(SNES snes,PetscInt its,PetscReal fgnorm,PetscViewerAndFormat *vf)
500: {
501: PetscErrorCode ierr;
502: PetscInt len;
503: PetscReal *history;
504: PetscViewer viewer = vf->viewer;
505:
507: SNESGetConvergenceHistory(snes,&history,NULL,&len);
508: PetscViewerPushFormat(viewer,vf->format);
509: PetscViewerASCIIAddTab(viewer,((PetscObject)snes)->tablevel);
510: if (!its || !history || its > len) {
511: PetscViewerASCIIPrintf(viewer,"%3D SNES Function norm %14.12e \n",its,(double)fgnorm);
512: } else {
513: PetscReal ratio = fgnorm/history[its-1];
514: PetscViewerASCIIPrintf(viewer,"%3D SNES Function norm %14.12e %14.12e \n",its,(double)fgnorm,(double)ratio);
515: }
516: PetscViewerASCIISubtractTab(viewer,((PetscObject)snes)->tablevel);
517: PetscViewerPopFormat(viewer);
518: return(0);
519: }
521: /*@C
522: SNESMonitorRatioSetUp - Insures the SNES object is saving its history since this monitor needs access to it
524: Collective on SNES
526: Input Parameters:
527: + snes - the SNES context
528: - viewer - the PetscViewer object (ignored)
530: Level: intermediate
532: .keywords: SNES, nonlinear, monitor, norm
534: .seealso: SNESMonitorSet(), SNESMonitorSolution(), SNESMonitorDefault(), SNESMonitorRatio()
535: @*/
536: PetscErrorCode SNESMonitorRatioSetUp(SNES snes,PetscViewerAndFormat *vf)
537: {
538: PetscErrorCode ierr;
539: PetscReal *history;
542: SNESGetConvergenceHistory(snes,&history,NULL,NULL);
543: if (!history) {
544: SNESSetConvergenceHistory(snes,NULL,NULL,100,PETSC_TRUE);
545: }
546: return(0);
547: }
549: /* ---------------------------------------------------------------- */
550: /*
551: Default (short) SNES Monitor, same as SNESMonitorDefault() except
552: it prints fewer digits of the residual as the residual gets smaller.
553: This is because the later digits are meaningless and are often
554: different on different machines; by using this routine different
555: machines will usually generate the same output.
556: */
557: PetscErrorCode SNESMonitorDefaultShort(SNES snes,PetscInt its,PetscReal fgnorm,PetscViewerAndFormat *vf)
558: {
560: PetscViewer viewer = vf->viewer;
564: PetscViewerPushFormat(viewer,vf->format);
565: PetscViewerASCIIAddTab(viewer,((PetscObject)snes)->tablevel);
566: if (fgnorm > 1.e-9) {
567: PetscViewerASCIIPrintf(viewer,"%3D SNES Function norm %g \n",its,(double)fgnorm);
568: } else if (fgnorm > 1.e-11) {
569: PetscViewerASCIIPrintf(viewer,"%3D SNES Function norm %5.3e \n",its,(double)fgnorm);
570: } else {
571: PetscViewerASCIIPrintf(viewer,"%3D SNES Function norm < 1.e-11\n",its);
572: }
573: PetscViewerASCIISubtractTab(viewer,((PetscObject)snes)->tablevel);
574: PetscViewerPopFormat(viewer);
575: return(0);
576: }
578: /*@C
579: SNESMonitorDefaultField - Monitors progress of the SNES solvers, separated into fields.
581: Collective on SNES
583: Input Parameters:
584: + snes - the SNES context
585: . its - iteration number
586: . fgnorm - 2-norm of residual
587: - ctx - the PetscViewer
589: Notes:
590: This routine uses the DM attached to the residual vector
592: Level: intermediate
594: .keywords: SNES, nonlinear, field, monitor, norm
595: .seealso: SNESMonitorSet(), SNESMonitorSolution(), SNESMonitorDefault(), SNESMonitorDefaultShort()
596: @*/
597: PetscErrorCode SNESMonitorDefaultField(SNES snes, PetscInt its, PetscReal fgnorm, PetscViewerAndFormat *vf)
598: {
599: PetscViewer viewer = vf->viewer;
600: Vec r;
601: DM dm;
602: PetscReal res[256];
603: PetscInt tablevel;
608: SNESGetFunction(snes, &r, NULL, NULL);
609: VecGetDM(r, &dm);
610: if (!dm) {SNESMonitorDefault(snes, its, fgnorm, vf);}
611: else {
612: PetscSection s, gs;
613: PetscInt Nf, f;
615: DMGetDefaultSection(dm, &s);
616: DMGetDefaultGlobalSection(dm, &gs);
617: if (!s || !gs) {SNESMonitorDefault(snes, its, fgnorm, vf);}
618: PetscSectionGetNumFields(s, &Nf);
619: if (Nf > 256) SETERRQ1(PetscObjectComm((PetscObject) snes), PETSC_ERR_SUP, "Do not support %d fields > 256", Nf);
620: PetscSectionVecNorm(s, gs, r, NORM_2, res);
621: PetscObjectGetTabLevel((PetscObject) snes, &tablevel);
622: PetscViewerPushFormat(viewer,vf->format);
623: PetscViewerASCIIAddTab(viewer, tablevel);
624: PetscViewerASCIIPrintf(viewer, "%3D SNES Function norm %14.12e [", its, (double) fgnorm);
625: for (f = 0; f < Nf; ++f) {
626: if (f) {PetscViewerASCIIPrintf(viewer, ", ");}
627: PetscViewerASCIIPrintf(viewer, "%14.12e", res[f]);
628: }
629: PetscViewerASCIIPrintf(viewer, "] \n");
630: PetscViewerASCIISubtractTab(viewer, tablevel);
631: PetscViewerPopFormat(viewer);
632: }
633: return(0);
634: }
635: /* ---------------------------------------------------------------- */
636: /*@C
637: SNESConvergedDefault - Convergence test of the solvers for
638: systems of nonlinear equations (default).
640: Collective on SNES
642: Input Parameters:
643: + snes - the SNES context
644: . it - the iteration (0 indicates before any Newton steps)
645: . xnorm - 2-norm of current iterate
646: . snorm - 2-norm of current step
647: . fnorm - 2-norm of function at current iterate
648: - dummy - unused context
650: Output Parameter:
651: . reason - one of
652: $ SNES_CONVERGED_FNORM_ABS - (fnorm < abstol),
653: $ SNES_CONVERGED_SNORM_RELATIVE - (snorm < stol*xnorm),
654: $ SNES_CONVERGED_FNORM_RELATIVE - (fnorm < rtol*fnorm0),
655: $ SNES_DIVERGED_FUNCTION_COUNT - (nfct > maxf),
656: $ SNES_DIVERGED_FNORM_NAN - (fnorm == NaN),
657: $ SNES_CONVERGED_ITERATING - (otherwise),
659: where
660: + maxf - maximum number of function evaluations,
661: set with SNESSetTolerances()
662: . nfct - number of function evaluations,
663: . abstol - absolute function norm tolerance,
664: set with SNESSetTolerances()
665: - rtol - relative function norm tolerance, set with SNESSetTolerances()
667: Level: intermediate
669: .keywords: SNES, nonlinear, default, converged, convergence
671: .seealso: SNESSetConvergenceTest()
672: @*/
673: PetscErrorCode SNESConvergedDefault(SNES snes,PetscInt it,PetscReal xnorm,PetscReal snorm,PetscReal fnorm,SNESConvergedReason *reason,void *dummy)
674: {
681: *reason = SNES_CONVERGED_ITERATING;
683: if (!it) {
684: /* set parameter for default relative tolerance convergence test */
685: snes->ttol = fnorm*snes->rtol;
686: snes->rnorm0 = fnorm;
687: }
688: if (PetscIsInfOrNanReal(fnorm)) {
689: PetscInfo(snes,"Failed to converged, function norm is NaN\n");
690: *reason = SNES_DIVERGED_FNORM_NAN;
691: } else if (fnorm < snes->abstol && (it || !snes->forceiteration)) {
692: PetscInfo2(snes,"Converged due to function norm %14.12e < %14.12e\n",(double)fnorm,(double)snes->abstol);
693: *reason = SNES_CONVERGED_FNORM_ABS;
694: } else if (snes->nfuncs >= snes->max_funcs) {
695: PetscInfo2(snes,"Exceeded maximum number of function evaluations: %D > %D\n",snes->nfuncs,snes->max_funcs);
696: *reason = SNES_DIVERGED_FUNCTION_COUNT;
697: }
699: if (it && !*reason) {
700: if (fnorm <= snes->ttol) {
701: PetscInfo2(snes,"Converged due to function norm %14.12e < %14.12e (relative tolerance)\n",(double)fnorm,(double)snes->ttol);
702: *reason = SNES_CONVERGED_FNORM_RELATIVE;
703: } else if (snorm < snes->stol*xnorm) {
704: PetscInfo3(snes,"Converged due to small update length: %14.12e < %14.12e * %14.12e\n",(double)snorm,(double)snes->stol,(double)xnorm);
705: *reason = SNES_CONVERGED_SNORM_RELATIVE;
706: } else if (snes->divtol > 0 && (fnorm > snes->divtol*snes->rnorm0)) {
707: PetscInfo3(snes,"Diverged due to increase in function norm: %14.12e > %14.12e * %14.12e\n",(double)fnorm,(double)snes->divtol,(double)snes->rnorm0);
708: *reason = SNES_DIVERGED_DTOL;
709: }
710:
711: }
712: return(0);
713: }
715: /*@C
716: SNESConvergedSkip - Convergence test for SNES that NEVER returns as
717: converged, UNLESS the maximum number of iteration have been reached.
719: Logically Collective on SNES
721: Input Parameters:
722: + snes - the SNES context
723: . it - the iteration (0 indicates before any Newton steps)
724: . xnorm - 2-norm of current iterate
725: . snorm - 2-norm of current step
726: . fnorm - 2-norm of function at current iterate
727: - dummy - unused context
729: Output Parameter:
730: . reason - SNES_CONVERGED_ITERATING, SNES_CONVERGED_ITS, or SNES_DIVERGED_FNORM_NAN
732: Notes:
733: Convergence is then declared after a fixed number of iterations have been used.
735: Level: advanced
737: .keywords: SNES, nonlinear, skip, converged, convergence
739: .seealso: SNESSetConvergenceTest()
740: @*/
741: PetscErrorCode SNESConvergedSkip(SNES snes,PetscInt it,PetscReal xnorm,PetscReal snorm,PetscReal fnorm,SNESConvergedReason *reason,void *dummy)
742: {
749: *reason = SNES_CONVERGED_ITERATING;
751: if (fnorm != fnorm) {
752: PetscInfo(snes,"Failed to converged, function norm is NaN\n");
753: *reason = SNES_DIVERGED_FNORM_NAN;
754: } else if (it == snes->max_its) {
755: *reason = SNES_CONVERGED_ITS;
756: }
757: return(0);
758: }
760: /*@C
761: SNESSetWorkVecs - Gets a number of work vectors.
763: Input Parameters:
764: . snes - the SNES context
765: . nw - number of work vectors to allocate
767: Level: developer
769: Developers Note: This is PETSC_EXTERN because it may be used by user written plugin SNES implementations
771: @*/
772: PetscErrorCode SNESSetWorkVecs(SNES snes,PetscInt nw)
773: {
774: DM dm;
775: Vec v;
779: if (snes->work) {VecDestroyVecs(snes->nwork,&snes->work);}
780: snes->nwork = nw;
782: SNESGetDM(snes, &dm);
783: DMGetGlobalVector(dm, &v);
784: VecDuplicateVecs(v,snes->nwork,&snes->work);
785: DMRestoreGlobalVector(dm, &v);
786: PetscLogObjectParents(snes,nw,snes->work);
787: return(0);
788: }