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