xref: /petsc/src/snes/interface/snesut.c (revision f996e368d2756f6a7e2df466d998849f46aaf50f)
1 
2 #include <petsc/private/snesimpl.h>       /*I   "petsc/private/snesimpl.h"   I*/
3 #include <petscdm.h>
4 #include <petscsection.h>
5 #include <petscblaslapack.h>
6 
7 /*@C
8    SNESMonitorSolution - Monitors progress of the SNES solvers by calling
9    VecView() for the approximate solution at each iteration.
10 
11    Collective on SNES
12 
13    Input Parameters:
14 +  snes - the SNES context
15 .  its - iteration number
16 .  fgnorm - 2-norm of residual
17 -  dummy -  a viewer
18 
19    Options Database Keys:
20 .  -snes_monitor_solution [ascii binary draw][:filename][:viewer format] - plots solution at each iteration
21 
22    Level: intermediate
23 
24 .seealso: SNESMonitorSet(), SNESMonitorDefault(), VecView()
25 @*/
26 PetscErrorCode  SNESMonitorSolution(SNES snes,PetscInt its,PetscReal fgnorm,PetscViewerAndFormat *vf)
27 {
28   PetscErrorCode ierr;
29   Vec            x;
30   PetscViewer    viewer = vf->viewer;
31 
32   PetscFunctionBegin;
33   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,4);
34   ierr = SNESGetSolution(snes,&x);CHKERRQ(ierr);
35   ierr = PetscViewerPushFormat(viewer,vf->format);CHKERRQ(ierr);
36   ierr = VecView(x,viewer);CHKERRQ(ierr);
37   ierr = PetscViewerPopFormat(viewer);CHKERRQ(ierr);
38   PetscFunctionReturn(0);
39 }
40 
41 /*@C
42    SNESMonitorResidual - Monitors progress of the SNES solvers by calling
43    VecView() for the residual at each iteration.
44 
45    Collective on SNES
46 
47    Input Parameters:
48 +  snes - the SNES context
49 .  its - iteration number
50 .  fgnorm - 2-norm of residual
51 -  dummy -  a viewer
52 
53    Options Database Keys:
54 .  -snes_monitor_residual [ascii binary draw][:filename][:viewer format] - plots residual (not its norm) at each iteration
55 
56    Level: intermediate
57 
58 .seealso: SNESMonitorSet(), SNESMonitorDefault(), VecView()
59 @*/
60 PetscErrorCode  SNESMonitorResidual(SNES snes,PetscInt its,PetscReal fgnorm,PetscViewerAndFormat *vf)
61 {
62   PetscErrorCode ierr;
63   Vec            x;
64   PetscViewer    viewer = vf->viewer;
65 
66   PetscFunctionBegin;
67   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,4);
68   ierr = SNESGetFunction(snes,&x,NULL,NULL);CHKERRQ(ierr);
69   ierr = PetscViewerPushFormat(viewer,vf->format);CHKERRQ(ierr);
70   ierr = VecView(x,viewer);CHKERRQ(ierr);
71   ierr = PetscViewerPopFormat(viewer);CHKERRQ(ierr);
72   PetscFunctionReturn(0);
73 }
74 
75 /*@C
76    SNESMonitorSolutionUpdate - Monitors progress of the SNES solvers by calling
77    VecView() for the UPDATE to the solution at each iteration.
78 
79    Collective on SNES
80 
81    Input Parameters:
82 +  snes - the SNES context
83 .  its - iteration number
84 .  fgnorm - 2-norm of residual
85 -  dummy - a viewer
86 
87    Options Database Keys:
88 .  -snes_monitor_solution_update [ascii binary draw][:filename][:viewer format] - plots update to solution at each iteration
89 
90    Level: intermediate
91 
92 .seealso: SNESMonitorSet(), SNESMonitorDefault(), VecView()
93 @*/
94 PetscErrorCode  SNESMonitorSolutionUpdate(SNES snes,PetscInt its,PetscReal fgnorm,PetscViewerAndFormat *vf)
95 {
96   PetscErrorCode ierr;
97   Vec            x;
98   PetscViewer    viewer = vf->viewer;
99 
100   PetscFunctionBegin;
101   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,4);
102   ierr = SNESGetSolutionUpdate(snes,&x);CHKERRQ(ierr);
103   ierr = PetscViewerPushFormat(viewer,vf->format);CHKERRQ(ierr);
104   ierr = VecView(x,viewer);CHKERRQ(ierr);
105   ierr = PetscViewerPopFormat(viewer);CHKERRQ(ierr);
106   PetscFunctionReturn(0);
107 }
108 
109 #include <petscdraw.h>
110 
111 /*@C
112   KSPMonitorSNESResidual - Prints the SNES residual norm, as well as the linear residual norm, at each iteration of an iterative solver.
113 
114   Collective on ksp
115 
116   Input Parameters:
117 + ksp   - iterative context
118 . n     - iteration number
119 . rnorm - 2-norm (preconditioned) residual value (may be estimated).
120 - vf    - The viewer context
121 
122   Options Database Key:
123 . -snes_monitor_ksp - Activates KSPMonitorSNESResidual()
124 
125   Level: intermediate
126 
127 .seealso: KSPMonitorSet(), KSPMonitorResidual(),KSPMonitorTrueResidualMaxNorm()
128 @*/
129 PetscErrorCode KSPMonitorSNESResidual(KSP ksp, PetscInt n, PetscReal rnorm, PetscViewerAndFormat *vf)
130 {
131   PetscViewer       viewer = vf->viewer;
132   PetscViewerFormat format = vf->format;
133   SNES              snes   = (SNES) vf->data;
134   Vec               snes_solution, work1, work2;
135   PetscReal         snorm;
136   PetscInt          tablevel;
137   const char       *prefix;
138   PetscErrorCode    ierr;
139 
140   PetscFunctionBegin;
141   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 4);
142   ierr = SNESGetSolution(snes, &snes_solution);CHKERRQ(ierr);
143   ierr = VecDuplicate(snes_solution, &work1);CHKERRQ(ierr);
144   ierr = VecDuplicate(snes_solution, &work2);CHKERRQ(ierr);
145   ierr = KSPBuildSolution(ksp, work1, NULL);CHKERRQ(ierr);
146   ierr = VecAYPX(work1, -1.0, snes_solution);CHKERRQ(ierr);
147   ierr = SNESComputeFunction(snes, work1, work2);CHKERRQ(ierr);
148   ierr = VecNorm(work2, NORM_2, &snorm);CHKERRQ(ierr);
149   ierr = VecDestroy(&work1);CHKERRQ(ierr);
150   ierr = VecDestroy(&work2);CHKERRQ(ierr);
151 
152   ierr = PetscObjectGetTabLevel((PetscObject) ksp, &tablevel);CHKERRQ(ierr);
153   ierr = PetscObjectGetOptionsPrefix((PetscObject) ksp, &prefix);CHKERRQ(ierr);
154   ierr = PetscViewerPushFormat(viewer, format);CHKERRQ(ierr);
155   ierr = PetscViewerASCIIAddTab(viewer, tablevel);CHKERRQ(ierr);
156   if (n == 0 && prefix) {ierr = PetscViewerASCIIPrintf(viewer, "  Residual norms for %s solve.\n", prefix);CHKERRQ(ierr);}
157   ierr = PetscViewerASCIIPrintf(viewer, "%3D SNES Residual norm %5.3e KSP Residual norm %5.3e \n", n, (double) snorm, (double) rnorm);CHKERRQ(ierr);
158   ierr = PetscViewerASCIISubtractTab(viewer, tablevel);CHKERRQ(ierr);
159   ierr = PetscViewerPopFormat(viewer);CHKERRQ(ierr);
160   PetscFunctionReturn(0);
161 }
162 
163 /*@C
164   KSPMonitorSNESResidualDrawLG - Plots the linear SNES residual norm at each iteration of an iterative solver.
165 
166   Collective on ksp
167 
168   Input Parameters:
169 + ksp   - iterative context
170 . n     - iteration number
171 . rnorm - 2-norm (preconditioned) residual value (may be estimated).
172 - vf    - The viewer context
173 
174   Options Database Key:
175 . -snes_monitor_ksp draw::draw_lg - Activates KSPMonitorSNESResidualDrawLG()
176 
177   Level: intermediate
178 
179 .seealso: KSPMonitorSet(), KSPMonitorTrueResidual()
180 @*/
181 PetscErrorCode KSPMonitorSNESResidualDrawLG(KSP ksp, PetscInt n, PetscReal rnorm, PetscViewerAndFormat *vf)
182 {
183   PetscViewer        viewer = vf->viewer;
184   PetscViewerFormat  format = vf->format;
185   PetscDrawLG        lg     = vf->lg;
186   SNES               snes   = (SNES) vf->data;
187   Vec                snes_solution, work1, work2;
188   PetscReal          snorm;
189   KSPConvergedReason reason;
190   PetscReal          x[2], y[2];
191   PetscErrorCode     ierr;
192 
193   PetscFunctionBegin;
194   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 4);
195   PetscValidHeaderSpecific(lg, PETSC_DRAWLG_CLASSID, 5);
196   ierr = SNESGetSolution(snes, &snes_solution);CHKERRQ(ierr);
197   ierr = VecDuplicate(snes_solution, &work1);CHKERRQ(ierr);
198   ierr = VecDuplicate(snes_solution, &work2);CHKERRQ(ierr);
199   ierr = KSPBuildSolution(ksp, work1, NULL);CHKERRQ(ierr);
200   ierr = VecAYPX(work1, -1.0, snes_solution);CHKERRQ(ierr);
201   ierr = SNESComputeFunction(snes, work1, work2);CHKERRQ(ierr);
202   ierr = VecNorm(work2, NORM_2, &snorm);CHKERRQ(ierr);
203   ierr = VecDestroy(&work1);CHKERRQ(ierr);
204   ierr = VecDestroy(&work2);CHKERRQ(ierr);
205 
206   ierr = PetscViewerPushFormat(viewer, format);CHKERRQ(ierr);
207   if (!n) {ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);}
208   x[0] = (PetscReal) n;
209   if (rnorm > 0.0) y[0] = PetscLog10Real(rnorm);
210   else y[0] = -15.0;
211   x[1] = (PetscReal) n;
212   if (snorm > 0.0) y[1] = PetscLog10Real(snorm);
213   else y[1] = -15.0;
214   ierr = PetscDrawLGAddPoint(lg, x, y);CHKERRQ(ierr);
215   ierr = KSPGetConvergedReason(ksp, &reason);CHKERRQ(ierr);
216   if (n <= 20 || !(n % 5) || reason) {
217     ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr);
218     ierr = PetscDrawLGSave(lg);CHKERRQ(ierr);
219   }
220   ierr = PetscViewerPopFormat(viewer);CHKERRQ(ierr);
221   PetscFunctionReturn(0);
222 }
223 
224 /*@C
225   KSPMonitorSNESResidualDrawLGCreate - Creates the plotter for the linear SNES residual.
226 
227   Collective on ksp
228 
229   Input Parameters:
230 + viewer - The PetscViewer
231 . format - The viewer format
232 - ctx    - An optional user context
233 
234   Output Parameter:
235 . vf    - The viewer context
236 
237   Level: intermediate
238 
239 .seealso: KSPMonitorSet(), KSPMonitorTrueResidual()
240 @*/
241 PetscErrorCode KSPMonitorSNESResidualDrawLGCreate(PetscViewer viewer, PetscViewerFormat format, void *ctx, PetscViewerAndFormat **vf)
242 {
243   const char    *names[] = {"linear", "nonlinear"};
244   PetscErrorCode ierr;
245 
246   PetscFunctionBegin;
247   ierr = PetscViewerAndFormatCreate(viewer, format, vf);CHKERRQ(ierr);
248   (*vf)->data = ctx;
249   ierr = KSPMonitorLGCreate(PetscObjectComm((PetscObject) viewer), NULL, NULL, "Log Residual Norm", 2, names, PETSC_DECIDE, PETSC_DECIDE, 400, 300, &(*vf)->lg);CHKERRQ(ierr);
250   PetscFunctionReturn(0);
251 }
252 
253 /*@C
254    SNESMonitorDefault - Monitors progress of the SNES solvers (default).
255 
256    Collective on SNES
257 
258    Input Parameters:
259 +  snes - the SNES context
260 .  its - iteration number
261 .  fgnorm - 2-norm of residual
262 -  vf - viewer and format structure
263 
264    Notes:
265    This routine prints the residual norm at each iteration.
266 
267    Level: intermediate
268 
269 .seealso: SNESMonitorSet(), SNESMonitorSolution()
270 @*/
271 PetscErrorCode  SNESMonitorDefault(SNES snes,PetscInt its,PetscReal fgnorm,PetscViewerAndFormat *vf)
272 {
273   PetscViewer       viewer = vf->viewer;
274   PetscViewerFormat format = vf->format;
275   PetscBool         isascii, isdraw;
276   PetscErrorCode    ierr;
277 
278   PetscFunctionBegin;
279   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,4);
280   ierr = PetscObjectTypeCompare((PetscObject) viewer, PETSCVIEWERASCII, &isascii);CHKERRQ(ierr);
281   ierr = PetscObjectTypeCompare((PetscObject) viewer, PETSCVIEWERDRAW,  &isdraw);CHKERRQ(ierr);
282   ierr = PetscViewerPushFormat(viewer,format);CHKERRQ(ierr);
283   if (isascii) {
284     ierr = PetscViewerASCIIAddTab(viewer,((PetscObject)snes)->tablevel);CHKERRQ(ierr);
285     ierr = PetscViewerASCIIPrintf(viewer,"%3D SNES Function norm %14.12e \n",its,(double)fgnorm);CHKERRQ(ierr);
286     ierr = PetscViewerASCIISubtractTab(viewer,((PetscObject)snes)->tablevel);CHKERRQ(ierr);
287   } else if (isdraw) {
288     if (format == PETSC_VIEWER_DRAW_LG) {
289       PetscDrawLG lg = (PetscDrawLG) vf->lg;
290       PetscReal   x, y;
291 
292       PetscValidHeaderSpecific(lg,PETSC_DRAWLG_CLASSID,4);
293       if (!its) {ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);}
294       x = (PetscReal) its;
295       if (fgnorm > 0.0) y = PetscLog10Real(fgnorm);
296       else y = -15.0;
297       ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr);
298       if (its <= 20 || !(its % 5) || snes->reason) {
299         ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr);
300         ierr = PetscDrawLGSave(lg);CHKERRQ(ierr);
301       }
302     }
303   }
304   ierr = PetscViewerPopFormat(viewer);CHKERRQ(ierr);
305   PetscFunctionReturn(0);
306 
307   PetscFunctionReturn(0);
308 }
309 
310 /*@C
311    SNESMonitorScaling - Monitors the largest value in each row of the Jacobian.
312 
313    Collective on SNES
314 
315    Input Parameters:
316 +  snes - the SNES context
317 .  its - iteration number
318 .  fgnorm - 2-norm of residual
319 -  vf - viewer and format structure
320 
321    Notes:
322    This routine prints the largest value in each row of the Jacobian
323 
324    Level: intermediate
325 
326 .seealso: SNESMonitorSet(), SNESMonitorSolution()
327 @*/
328 PetscErrorCode  SNESMonitorScaling(SNES snes,PetscInt its,PetscReal fgnorm,PetscViewerAndFormat *vf)
329 {
330   PetscErrorCode ierr;
331   PetscViewer    viewer = vf->viewer;
332   KSP            ksp;
333   Mat            J;
334   Vec            v;
335 
336   PetscFunctionBegin;
337   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,4);
338   ierr = SNESGetKSP(snes,&ksp);CHKERRQ(ierr);
339   ierr = KSPGetOperators(ksp,&J,NULL);CHKERRQ(ierr);
340   ierr = MatCreateVecs(J,&v,NULL);CHKERRQ(ierr);
341   ierr = MatGetRowMaxAbs(J,v,NULL);CHKERRQ(ierr);
342   ierr = PetscViewerPushFormat(viewer,vf->format);CHKERRQ(ierr);
343   ierr = PetscViewerASCIIAddTab(viewer,((PetscObject)snes)->tablevel);CHKERRQ(ierr);
344   ierr = PetscViewerASCIIPrintf(viewer,"%3D SNES Jacobian maximum row entries \n");CHKERRQ(ierr);
345   ierr = VecView(v,viewer);CHKERRQ(ierr);
346   ierr = PetscViewerASCIISubtractTab(viewer,((PetscObject)snes)->tablevel);CHKERRQ(ierr);
347   ierr = PetscViewerPopFormat(viewer);CHKERRQ(ierr);
348   ierr = VecDestroy(&v);CHKERRQ(ierr);
349   PetscFunctionReturn(0);
350 }
351 
352 PetscErrorCode SNESMonitorJacUpdateSpectrum(SNES snes,PetscInt it,PetscReal fnorm,PetscViewerAndFormat *vf)
353 {
354 #if defined(PETSC_HAVE_ESSL)
355   SETERRQ(PetscObjectComm((PetscObject)snes),PETSC_ERR_SUP,"GEEV - No support for ESSL Lapack Routines");
356 #else
357   Vec            X;
358   Mat            J,dJ,dJdense;
359   PetscErrorCode ierr;
360   PetscErrorCode (*func)(SNES,Vec,Mat,Mat,void*);
361   PetscInt       n;
362   PetscBLASInt   nb = 0,lwork;
363   PetscReal      *eigr,*eigi;
364   PetscScalar    *work;
365   PetscScalar    *a;
366 
367   PetscFunctionBegin;
368   if (it == 0) PetscFunctionReturn(0);
369   /* create the difference between the current update and the current jacobian */
370   ierr = SNESGetSolution(snes,&X);CHKERRQ(ierr);
371   ierr = SNESGetJacobian(snes,NULL,&J,&func,NULL);CHKERRQ(ierr);
372   ierr = MatDuplicate(J,MAT_COPY_VALUES,&dJ);CHKERRQ(ierr);
373   ierr = SNESComputeJacobian(snes,X,dJ,dJ);CHKERRQ(ierr);
374   ierr = MatAXPY(dJ,-1.0,J,SAME_NONZERO_PATTERN);CHKERRQ(ierr);
375 
376   /* compute the spectrum directly */
377   ierr  = MatConvert(dJ,MATSEQDENSE,MAT_INITIAL_MATRIX,&dJdense);CHKERRQ(ierr);
378   ierr  = MatGetSize(dJ,&n,NULL);CHKERRQ(ierr);
379   ierr  = PetscBLASIntCast(n,&nb);CHKERRQ(ierr);
380   lwork = 3*nb;
381   ierr  = PetscMalloc1(n,&eigr);CHKERRQ(ierr);
382   ierr  = PetscMalloc1(n,&eigi);CHKERRQ(ierr);
383   ierr  = PetscMalloc1(lwork,&work);CHKERRQ(ierr);
384   ierr  = MatDenseGetArray(dJdense,&a);CHKERRQ(ierr);
385 #if !defined(PETSC_USE_COMPLEX)
386   {
387     PetscBLASInt lierr;
388     PetscInt     i;
389     ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
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     ierr = PetscFPTrapPop();CHKERRQ(ierr);
393     ierr = PetscPrintf(PetscObjectComm((PetscObject)snes),"Eigenvalues of J_%d - J_%d:\n",it,it-1);CHKERRQ(ierr);
394     for (i=0;i<n;i++) {
395       ierr = PetscPrintf(PetscObjectComm((PetscObject)snes),"%5d: %20.5g + %20.5gi\n",i,(double)eigr[i],(double)eigi[i]);CHKERRQ(ierr);
396     }
397   }
398   ierr = MatDenseRestoreArray(dJdense,&a);CHKERRQ(ierr);
399   ierr = MatDestroy(&dJ);CHKERRQ(ierr);
400   ierr = MatDestroy(&dJdense);CHKERRQ(ierr);
401   ierr = PetscFree(eigr);CHKERRQ(ierr);
402   ierr = PetscFree(eigi);CHKERRQ(ierr);
403   ierr = PetscFree(work);CHKERRQ(ierr);
404   PetscFunctionReturn(0);
405 #else
406   SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not coded for complex");
407 #endif
408 #endif
409 }
410 
411 PETSC_INTERN PetscErrorCode  SNESMonitorRange_Private(SNES,PetscInt,PetscReal*);
412 
413 PetscErrorCode  SNESMonitorRange_Private(SNES snes,PetscInt it,PetscReal *per)
414 {
415   PetscErrorCode ierr;
416   Vec            resid;
417   PetscReal      rmax,pwork;
418   PetscInt       i,n,N;
419   PetscScalar    *r;
420 
421   PetscFunctionBegin;
422   ierr  = SNESGetFunction(snes,&resid,NULL,NULL);CHKERRQ(ierr);
423   ierr  = VecNorm(resid,NORM_INFINITY,&rmax);CHKERRQ(ierr);
424   ierr  = VecGetLocalSize(resid,&n);CHKERRQ(ierr);
425   ierr  = VecGetSize(resid,&N);CHKERRQ(ierr);
426   ierr  = VecGetArray(resid,&r);CHKERRQ(ierr);
427   pwork = 0.0;
428   for (i=0; i<n; i++) {
429     pwork += (PetscAbsScalar(r[i]) > .20*rmax);
430   }
431   ierr = MPIU_Allreduce(&pwork,per,1,MPIU_REAL,MPIU_SUM,PetscObjectComm((PetscObject)snes));CHKERRQ(ierr);
432   ierr = VecRestoreArray(resid,&r);CHKERRQ(ierr);
433   *per = *per/N;
434   PetscFunctionReturn(0);
435 }
436 
437 /*@C
438    SNESMonitorRange - Prints the percentage of residual elements that are more then 10 percent of the maximum value.
439 
440    Collective on SNES
441 
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
447 
448    Options Database Key:
449 .  -snes_monitor_range - Activates SNESMonitorRange()
450 
451    Level: intermediate
452 
453 .seealso: SNESMonitorSet(), SNESMonitorDefault(), SNESMonitorLGCreate()
454 @*/
455 PetscErrorCode  SNESMonitorRange(SNES snes,PetscInt it,PetscReal rnorm,PetscViewerAndFormat *vf)
456 {
457   PetscErrorCode ierr;
458   PetscReal      perc,rel;
459   PetscViewer    viewer = vf->viewer;
460   /* should be in a MonitorRangeContext */
461   static PetscReal prev;
462 
463   PetscFunctionBegin;
464   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,4);
465   if (!it) prev = rnorm;
466   ierr = SNESMonitorRange_Private(snes,it,&perc);CHKERRQ(ierr);
467 
468   rel  = (prev - rnorm)/prev;
469   prev = rnorm;
470   ierr = PetscViewerPushFormat(viewer,vf->format);CHKERRQ(ierr);
471   ierr = PetscViewerASCIIAddTab(viewer,((PetscObject)snes)->tablevel);CHKERRQ(ierr);
472   ierr = 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));CHKERRQ(ierr);
473   ierr = PetscViewerASCIISubtractTab(viewer,((PetscObject)snes)->tablevel);CHKERRQ(ierr);
474   ierr = PetscViewerPopFormat(viewer);CHKERRQ(ierr);
475   PetscFunctionReturn(0);
476 }
477 
478 /*@C
479    SNESMonitorRatio - Monitors progress of the SNES solvers by printing the ratio
480    of residual norm at each iteration to the previous.
481 
482    Collective on SNES
483 
484    Input Parameters:
485 +  snes - the SNES context
486 .  its - iteration number
487 .  fgnorm - 2-norm of residual (or gradient)
488 -  dummy -  context of monitor
489 
490    Level: intermediate
491 
492    Notes:
493     Insure that SNESMonitorRatio() is called when you set this monitor
494 .seealso: SNESMonitorSet(), SNESMonitorSolution(), SNESMonitorRatio()
495 @*/
496 PetscErrorCode  SNESMonitorRatio(SNES snes,PetscInt its,PetscReal fgnorm,PetscViewerAndFormat *vf)
497 {
498   PetscErrorCode          ierr;
499   PetscInt                len;
500   PetscReal               *history;
501   PetscViewer             viewer = vf->viewer;
502 
503   PetscFunctionBegin;
504   ierr = SNESGetConvergenceHistory(snes,&history,NULL,&len);CHKERRQ(ierr);
505   ierr = PetscViewerPushFormat(viewer,vf->format);CHKERRQ(ierr);
506   ierr = PetscViewerASCIIAddTab(viewer,((PetscObject)snes)->tablevel);CHKERRQ(ierr);
507   if (!its || !history || its > len) {
508     ierr = PetscViewerASCIIPrintf(viewer,"%3D SNES Function norm %14.12e \n",its,(double)fgnorm);CHKERRQ(ierr);
509   } else {
510     PetscReal ratio = fgnorm/history[its-1];
511     ierr = PetscViewerASCIIPrintf(viewer,"%3D SNES Function norm %14.12e %14.12e \n",its,(double)fgnorm,(double)ratio);CHKERRQ(ierr);
512   }
513   ierr = PetscViewerASCIISubtractTab(viewer,((PetscObject)snes)->tablevel);CHKERRQ(ierr);
514   ierr = PetscViewerPopFormat(viewer);CHKERRQ(ierr);
515   PetscFunctionReturn(0);
516 }
517 
518 /*@C
519    SNESMonitorRatioSetUp - Insures the SNES object is saving its history since this monitor needs access to it
520 
521    Collective on SNES
522 
523    Input Parameters:
524 +   snes - the SNES context
525 -   viewer - the PetscViewer object (ignored)
526 
527    Level: intermediate
528 
529 .seealso: SNESMonitorSet(), SNESMonitorSolution(), SNESMonitorDefault(), SNESMonitorRatio()
530 @*/
531 PetscErrorCode  SNESMonitorRatioSetUp(SNES snes,PetscViewerAndFormat *vf)
532 {
533   PetscErrorCode          ierr;
534   PetscReal               *history;
535 
536   PetscFunctionBegin;
537   ierr = SNESGetConvergenceHistory(snes,&history,NULL,NULL);CHKERRQ(ierr);
538   if (!history) {
539     ierr = SNESSetConvergenceHistory(snes,NULL,NULL,100,PETSC_TRUE);CHKERRQ(ierr);
540   }
541   PetscFunctionReturn(0);
542 }
543 
544 /* ---------------------------------------------------------------- */
545 /*
546      Default (short) SNES Monitor, same as SNESMonitorDefault() except
547   it prints fewer digits of the residual as the residual gets smaller.
548   This is because the later digits are meaningless and are often
549   different on different machines; by using this routine different
550   machines will usually generate the same output.
551 
552   Deprecated: Intentionally has no manual page
553 */
554 PetscErrorCode  SNESMonitorDefaultShort(SNES snes,PetscInt its,PetscReal fgnorm,PetscViewerAndFormat *vf)
555 {
556   PetscErrorCode ierr;
557   PetscViewer    viewer = vf->viewer;
558 
559   PetscFunctionBegin;
560   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,4);
561   ierr = PetscViewerPushFormat(viewer,vf->format);CHKERRQ(ierr);
562   ierr = PetscViewerASCIIAddTab(viewer,((PetscObject)snes)->tablevel);CHKERRQ(ierr);
563   if (fgnorm > 1.e-9) {
564     ierr = PetscViewerASCIIPrintf(viewer,"%3D SNES Function norm %g \n",its,(double)fgnorm);CHKERRQ(ierr);
565   } else if (fgnorm > 1.e-11) {
566     ierr = PetscViewerASCIIPrintf(viewer,"%3D SNES Function norm %5.3e \n",its,(double)fgnorm);CHKERRQ(ierr);
567   } else {
568     ierr = PetscViewerASCIIPrintf(viewer,"%3D SNES Function norm < 1.e-11\n",its);CHKERRQ(ierr);
569   }
570   ierr = PetscViewerASCIISubtractTab(viewer,((PetscObject)snes)->tablevel);CHKERRQ(ierr);
571   ierr = PetscViewerPopFormat(viewer);CHKERRQ(ierr);
572   PetscFunctionReturn(0);
573 }
574 
575 /*@C
576   SNESMonitorDefaultField - Monitors progress of the SNES solvers, separated into fields.
577 
578   Collective on SNES
579 
580   Input Parameters:
581 + snes   - the SNES context
582 . its    - iteration number
583 . fgnorm - 2-norm of residual
584 - ctx    - the PetscViewer
585 
586   Notes:
587   This routine uses the DM attached to the residual vector
588 
589   Level: intermediate
590 
591 .seealso: SNESMonitorSet(), SNESMonitorSolution(), SNESMonitorDefault()
592 @*/
593 PetscErrorCode SNESMonitorDefaultField(SNES snes, PetscInt its, PetscReal fgnorm, PetscViewerAndFormat *vf)
594 {
595   PetscViewer    viewer = vf->viewer;
596   Vec            r;
597   DM             dm;
598   PetscReal      res[256];
599   PetscInt       tablevel;
600   PetscErrorCode ierr;
601 
602   PetscFunctionBegin;
603   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,4);
604   ierr = SNESGetFunction(snes, &r, NULL, NULL);CHKERRQ(ierr);
605   ierr = VecGetDM(r, &dm);CHKERRQ(ierr);
606   if (!dm) {ierr = SNESMonitorDefault(snes, its, fgnorm, vf);CHKERRQ(ierr);}
607   else {
608     PetscSection s, gs;
609     PetscInt     Nf, f;
610 
611     ierr = DMGetLocalSection(dm, &s);CHKERRQ(ierr);
612     ierr = DMGetGlobalSection(dm, &gs);CHKERRQ(ierr);
613     if (!s || !gs) {ierr = SNESMonitorDefault(snes, its, fgnorm, vf);CHKERRQ(ierr);}
614     ierr = PetscSectionGetNumFields(s, &Nf);CHKERRQ(ierr);
615     if (Nf > 256) SETERRQ1(PetscObjectComm((PetscObject) snes), PETSC_ERR_SUP, "Do not support %d fields > 256", Nf);
616     ierr = PetscSectionVecNorm(s, gs, r, NORM_2, res);CHKERRQ(ierr);
617     ierr = PetscObjectGetTabLevel((PetscObject) snes, &tablevel);CHKERRQ(ierr);
618     ierr = PetscViewerPushFormat(viewer,vf->format);CHKERRQ(ierr);
619     ierr = PetscViewerASCIIAddTab(viewer, tablevel);CHKERRQ(ierr);
620     ierr = PetscViewerASCIIPrintf(viewer, "%3D SNES Function norm %14.12e [", its, (double) fgnorm);CHKERRQ(ierr);
621     for (f = 0; f < Nf; ++f) {
622       if (f) {ierr = PetscViewerASCIIPrintf(viewer, ", ");CHKERRQ(ierr);}
623       ierr = PetscViewerASCIIPrintf(viewer, "%14.12e", res[f]);CHKERRQ(ierr);
624     }
625     ierr = PetscViewerASCIIPrintf(viewer, "] \n");CHKERRQ(ierr);
626     ierr = PetscViewerASCIISubtractTab(viewer, tablevel);CHKERRQ(ierr);
627     ierr = PetscViewerPopFormat(viewer);CHKERRQ(ierr);
628   }
629   PetscFunctionReturn(0);
630 }
631 /* ---------------------------------------------------------------- */
632 /*@C
633    SNESConvergedDefault - Default onvergence test of the solvers for
634    systems of nonlinear equations.
635 
636    Collective on SNES
637 
638    Input Parameters:
639 +  snes - the SNES context
640 .  it - the iteration (0 indicates before any Newton steps)
641 .  xnorm - 2-norm of current iterate
642 .  snorm - 2-norm of current step
643 .  fnorm - 2-norm of function at current iterate
644 -  dummy - unused context
645 
646    Output Parameter:
647 .   reason  - one of
648 $  SNES_CONVERGED_FNORM_ABS       - (fnorm < abstol),
649 $  SNES_CONVERGED_SNORM_RELATIVE  - (snorm < stol*xnorm),
650 $  SNES_CONVERGED_FNORM_RELATIVE  - (fnorm < rtol*fnorm0),
651 $  SNES_DIVERGED_FUNCTION_COUNT   - (nfct > maxf),
652 $  SNES_DIVERGED_FNORM_NAN        - (fnorm == NaN),
653 $  SNES_CONVERGED_ITERATING       - (otherwise),
654 $  SNES_DIVERGED_DTOL             - (fnorm > divtol*snes->fnorm0)
655 
656    where
657 +    maxf - maximum number of function evaluations,  set with SNESSetTolerances()
658 .    nfct - number of function evaluations,
659 .    abstol - absolute function norm tolerance, set with SNESSetTolerances()
660 .    rtol - relative function norm tolerance, set with SNESSetTolerances()
661 .    divtol - divergence tolerance, set with SNESSetDivergenceTolerance()
662 -    fnorm0 - 2-norm of the function at the initial solution (initial guess; zeroth iteration)
663 
664   Options Database Keys:
665 +  -snes_stol - convergence tolerance in terms of the norm  of the change in the solution between steps
666 .  -snes_atol <abstol> - absolute tolerance of residual norm
667 .  -snes_rtol <rtol> - relative decrease in tolerance norm from the initial 2-norm of the solution
668 .  -snes_divergence_tolerance <divtol> - if the residual goes above divtol*rnorm0, exit with divergence
669 .  -snes_max_funcs <max_funcs> - maximum number of function evaluations
670 .  -snes_max_fail <max_fail> - maximum number of line search failures allowed before stopping, default is none
671 -  -snes_max_linear_solve_fail - number of linear solver failures before SNESSolve() stops
672 
673    Level: intermediate
674 
675 .seealso: SNESSetConvergenceTest(), SNESConvergedSkip(), SNESSetTolerances(), SNESSetDivergenceTolerance()
676 @*/
677 PetscErrorCode  SNESConvergedDefault(SNES snes,PetscInt it,PetscReal xnorm,PetscReal snorm,PetscReal fnorm,SNESConvergedReason *reason,void *dummy)
678 {
679   PetscErrorCode ierr;
680 
681   PetscFunctionBegin;
682   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
683   PetscValidPointer(reason,6);
684 
685   *reason = SNES_CONVERGED_ITERATING;
686 
687   if (!it) {
688     /* set parameter for default relative tolerance convergence test */
689     snes->ttol   = fnorm*snes->rtol;
690     snes->rnorm0 = fnorm;
691   }
692   if (PetscIsInfOrNanReal(fnorm)) {
693     ierr    = PetscInfo(snes,"Failed to converged, function norm is NaN\n");CHKERRQ(ierr);
694     *reason = SNES_DIVERGED_FNORM_NAN;
695   } else if (fnorm < snes->abstol && (it || !snes->forceiteration)) {
696     ierr    = PetscInfo2(snes,"Converged due to function norm %14.12e < %14.12e\n",(double)fnorm,(double)snes->abstol);CHKERRQ(ierr);
697     *reason = SNES_CONVERGED_FNORM_ABS;
698   } else if (snes->nfuncs >= snes->max_funcs && snes->max_funcs >= 0) {
699     ierr    = PetscInfo2(snes,"Exceeded maximum number of function evaluations: %D > %D\n",snes->nfuncs,snes->max_funcs);CHKERRQ(ierr);
700     *reason = SNES_DIVERGED_FUNCTION_COUNT;
701   }
702 
703   if (it && !*reason) {
704     if (fnorm <= snes->ttol) {
705       ierr    = PetscInfo2(snes,"Converged due to function norm %14.12e < %14.12e (relative tolerance)\n",(double)fnorm,(double)snes->ttol);CHKERRQ(ierr);
706       *reason = SNES_CONVERGED_FNORM_RELATIVE;
707     } else if (snorm < snes->stol*xnorm) {
708       ierr    = PetscInfo3(snes,"Converged due to small update length: %14.12e < %14.12e * %14.12e\n",(double)snorm,(double)snes->stol,(double)xnorm);CHKERRQ(ierr);
709       *reason = SNES_CONVERGED_SNORM_RELATIVE;
710     } else if (snes->divtol > 0 && (fnorm > snes->divtol*snes->rnorm0)) {
711       ierr    = PetscInfo3(snes,"Diverged due to increase in function norm: %14.12e > %14.12e * %14.12e\n",(double)fnorm,(double)snes->divtol,(double)snes->rnorm0);CHKERRQ(ierr);
712       *reason = SNES_DIVERGED_DTOL;
713     }
714 
715   }
716   PetscFunctionReturn(0);
717 }
718 
719 /*@C
720    SNESConvergedSkip - Convergence test for SNES that NEVER returns as
721    converged, UNLESS the maximum number of iteration have been reached.
722 
723    Logically Collective on SNES
724 
725    Input Parameters:
726 +  snes - the SNES context
727 .  it - the iteration (0 indicates before any Newton steps)
728 .  xnorm - 2-norm of current iterate
729 .  snorm - 2-norm of current step
730 .  fnorm - 2-norm of function at current iterate
731 -  dummy - unused context
732 
733    Output Parameter:
734 .   reason  - SNES_CONVERGED_ITERATING, SNES_CONVERGED_ITS, or SNES_DIVERGED_FNORM_NAN
735 
736    Notes:
737    Convergence is then declared after a fixed number of iterations have been used.
738 
739    Level: advanced
740 
741 .seealso: SNESConvergedDefault(), SNESSetConvergenceTest()
742 @*/
743 PetscErrorCode  SNESConvergedSkip(SNES snes,PetscInt it,PetscReal xnorm,PetscReal snorm,PetscReal fnorm,SNESConvergedReason *reason,void *dummy)
744 {
745   PetscErrorCode ierr;
746 
747   PetscFunctionBegin;
748   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
749   PetscValidPointer(reason,6);
750 
751   *reason = SNES_CONVERGED_ITERATING;
752 
753   if (fnorm != fnorm) {
754     ierr    = PetscInfo(snes,"Failed to converged, function norm is NaN\n");CHKERRQ(ierr);
755     *reason = SNES_DIVERGED_FNORM_NAN;
756   } else if (it == snes->max_its) {
757     *reason = SNES_CONVERGED_ITS;
758   }
759   PetscFunctionReturn(0);
760 }
761 
762 /*@C
763   SNESSetWorkVecs - Gets a number of work vectors.
764 
765   Input Parameters:
766 + snes  - the SNES context
767 - nw - number of work vectors to allocate
768 
769   Level: developer
770 
771 @*/
772 PetscErrorCode SNESSetWorkVecs(SNES snes,PetscInt nw)
773 {
774   DM             dm;
775   Vec            v;
776   PetscErrorCode ierr;
777 
778   PetscFunctionBegin;
779   if (snes->work) {ierr = VecDestroyVecs(snes->nwork,&snes->work);CHKERRQ(ierr);}
780   snes->nwork = nw;
781 
782   ierr = SNESGetDM(snes, &dm);CHKERRQ(ierr);
783   ierr = DMGetGlobalVector(dm, &v);CHKERRQ(ierr);
784   ierr = VecDuplicateVecs(v,snes->nwork,&snes->work);CHKERRQ(ierr);
785   ierr = DMRestoreGlobalVector(dm, &v);CHKERRQ(ierr);
786   ierr = PetscLogObjectParents(snes,nw,snes->work);CHKERRQ(ierr);
787   PetscFunctionReturn(0);
788 }
789