xref: /petsc/src/snes/interface/snesut.c (revision ea10fe75d81f3a54c99f2bcb15f7101c15d054de)
1 
2 #include <petsc-private/snesimpl.h>       /*I   "petscsnes.h"   I*/
3 #include <petscblaslapack.h>
4 
5 #undef __FUNCT__
6 #define __FUNCT__ "SNESMonitorSolution"
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 - either a viewer or PETSC_NULL
18 
19    Level: intermediate
20 
21 .keywords: SNES, nonlinear, vector, monitor, view
22 
23 .seealso: SNESMonitorSet(), SNESMonitorDefault(), VecView()
24 @*/
25 PetscErrorCode  SNESMonitorSolution(SNES snes,PetscInt its,PetscReal fgnorm,void *dummy)
26 {
27   PetscErrorCode ierr;
28   Vec            x;
29   PetscViewer    viewer = (PetscViewer) dummy;
30 
31   PetscFunctionBegin;
32   ierr = SNESGetSolution(snes,&x);CHKERRQ(ierr);
33   if (!viewer) {
34     MPI_Comm comm;
35     ierr   = PetscObjectGetComm((PetscObject)snes,&comm);CHKERRQ(ierr);
36     viewer = PETSC_VIEWER_DRAW_(comm);
37   }
38   ierr = VecView(x,viewer);CHKERRQ(ierr);
39 
40   PetscFunctionReturn(0);
41 }
42 
43 #undef __FUNCT__
44 #define __FUNCT__ "SNESMonitorResidual"
45 /*@C
46    SNESMonitorResidual - Monitors progress of the SNES solvers by calling
47    VecView() for the residual at each iteration.
48 
49    Collective on SNES
50 
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
56 
57    Level: intermediate
58 
59 .keywords: SNES, nonlinear, vector, monitor, view
60 
61 .seealso: SNESMonitorSet(), SNESMonitorDefault(), VecView()
62 @*/
63 PetscErrorCode  SNESMonitorResidual(SNES snes,PetscInt its,PetscReal fgnorm,void *dummy)
64 {
65   PetscErrorCode ierr;
66   Vec            x;
67   PetscViewer    viewer = (PetscViewer) dummy;
68 
69   PetscFunctionBegin;
70   ierr = SNESGetFunction(snes,&x,0,0);CHKERRQ(ierr);
71   if (!viewer) {
72     MPI_Comm comm;
73     ierr   = PetscObjectGetComm((PetscObject)snes,&comm);CHKERRQ(ierr);
74     viewer = PETSC_VIEWER_DRAW_(comm);
75   }
76   ierr = VecView(x,viewer);CHKERRQ(ierr);
77 
78   PetscFunctionReturn(0);
79 }
80 
81 #undef __FUNCT__
82 #define __FUNCT__ "SNESMonitorSolutionUpdate"
83 /*@C
84    SNESMonitorSolutionUpdate - Monitors progress of the SNES solvers by calling
85    VecView() for the UPDATE to the solution at each iteration.
86 
87    Collective on SNES
88 
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
94 
95    Level: intermediate
96 
97 .keywords: SNES, nonlinear, vector, monitor, view
98 
99 .seealso: SNESMonitorSet(), SNESMonitorDefault(), VecView()
100 @*/
101 PetscErrorCode  SNESMonitorSolutionUpdate(SNES snes,PetscInt its,PetscReal fgnorm,void *dummy)
102 {
103   PetscErrorCode ierr;
104   Vec            x;
105   PetscViewer    viewer = (PetscViewer) dummy;
106 
107   PetscFunctionBegin;
108   ierr = SNESGetSolutionUpdate(snes,&x);CHKERRQ(ierr);
109   if (!viewer) {
110     MPI_Comm comm;
111     ierr   = PetscObjectGetComm((PetscObject)snes,&comm);CHKERRQ(ierr);
112     viewer = PETSC_VIEWER_DRAW_(comm);
113   }
114   ierr = VecView(x,viewer);CHKERRQ(ierr);
115 
116   PetscFunctionReturn(0);
117 }
118 
119 #undef __FUNCT__
120 #define __FUNCT__ "SNESMonitorDefault"
121 /*@C
122    SNESMonitorDefault - Monitors progress of the SNES solvers (default).
123 
124    Collective on SNES
125 
126    Input Parameters:
127 +  snes - the SNES context
128 .  its - iteration number
129 .  fgnorm - 2-norm of residual
130 -  dummy - unused context
131 
132    Notes:
133    This routine prints the residual norm at each iteration.
134 
135    Level: intermediate
136 
137 .keywords: SNES, nonlinear, default, monitor, norm
138 
139 .seealso: SNESMonitorSet(), SNESMonitorSolution()
140 @*/
141 PetscErrorCode  SNESMonitorDefault(SNES snes,PetscInt its,PetscReal fgnorm,void *dummy)
142 {
143   PetscErrorCode ierr;
144   PetscViewer    viewer = dummy ? (PetscViewer) dummy : PETSC_VIEWER_STDOUT_(((PetscObject)snes)->comm);
145 
146   PetscFunctionBegin;
147   ierr = PetscViewerASCIIAddTab(viewer,((PetscObject)snes)->tablevel);CHKERRQ(ierr);
148   ierr = PetscViewerASCIIPrintf(viewer,"%3D SNES Function norm %14.12e \n",its,(double)fgnorm);CHKERRQ(ierr);
149   ierr = PetscViewerASCIISubtractTab(viewer,((PetscObject)snes)->tablevel);CHKERRQ(ierr);
150   PetscFunctionReturn(0);
151 }
152 
153 #undef __FUNCT__
154 #define __FUNCT__ "SNESMonitorJacUpdateSpectrum"
155 PetscErrorCode SNESMonitorJacUpdateSpectrum(SNES snes,PetscInt it,PetscReal fnorm,void *ctx)
156 {
157 #if defined(PETSC_MISSING_LAPACK_GEEV)
158   SETERRQ(((PetscObject)snes)->comm,PETSC_ERR_SUP,"GEEV - Lapack routine is unavailable\nNot able to provide eigen values.");
159 #elif defined(PETSC_HAVE_ESSL)
160   SETERRQ(((PetscObject)snes)->comm,PETSC_ERR_SUP,"GEEV - No support for ESSL Lapack Routines");
161 #else
162   Vec            X;
163   Mat            J,dJ,dJdense;
164   PetscErrorCode ierr;
165   PetscErrorCode (*func)(SNES,Vec,Mat*,Mat*,MatStructure*,void*);
166   PetscInt       n,i;
167   PetscBLASInt   nb,lwork;
168   PetscReal      *eigr,*eigi;
169   MatStructure   flg = DIFFERENT_NONZERO_PATTERN;
170   PetscScalar    *work;
171   PetscScalar    *a;
172 
173   PetscFunctionBegin;
174   if (it == 0) PetscFunctionReturn(0);
175   /* create the difference between the current update and the current jacobian */
176   ierr = SNESGetSolution(snes,&X);CHKERRQ(ierr);
177   ierr = SNESGetJacobian(snes,&J,PETSC_NULL,&func,PETSC_NULL);CHKERRQ(ierr);
178   ierr = MatDuplicate(J,MAT_COPY_VALUES,&dJ);CHKERRQ(ierr);
179   ierr = SNESComputeJacobian(snes,X,&dJ,&dJ,&flg);CHKERRQ(ierr);
180   ierr = MatAXPY(dJ,-1.0,J,SAME_NONZERO_PATTERN);CHKERRQ(ierr);
181   /* compute the spectrum directly */
182   ierr = MatConvert(dJ,MATSEQDENSE,MAT_INITIAL_MATRIX,&dJdense);CHKERRQ(ierr);
183   ierr = MatGetSize(dJ,&n,PETSC_NULL);CHKERRQ(ierr);
184   nb    = PetscBLASIntCast(n);
185   lwork = 3*nb;
186   ierr = PetscMalloc(n*sizeof(PetscReal),&eigr);CHKERRQ(ierr);
187   ierr = PetscMalloc(n*sizeof(PetscReal),&eigi);CHKERRQ(ierr);
188   ierr = PetscMalloc(lwork*sizeof(PetscScalar),&work);CHKERRQ(ierr);
189   ierr = MatDenseGetArray(dJdense,&a);CHKERRQ(ierr);
190 #if !defined(PETSC_USE_COMPLEX)
191   {
192     PetscBLASInt lierr;
193     ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
194     LAPACKgeev_("N","N",&nb,a,&nb,eigr,eigi,PETSC_NULL,&nb,PETSC_NULL,&nb,work,&lwork,&lierr);
195     if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"geev() error %d",lierr);
196     ierr = PetscFPTrapPop();CHKERRQ(ierr);
197   }
198 #else
199   SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not coded for complex");
200 #endif
201   PetscPrintf(((PetscObject)snes)->comm,"Eigenvalues of J_%d - J_%d:\n",it,it-1);CHKERRQ(ierr);
202   for (i=0;i<n;i++) {
203     PetscPrintf(((PetscObject)snes)->comm,"%5d: %20.5g + %20.5gi\n",i,eigr[i],eigi[i]);CHKERRQ(ierr);
204   }
205   ierr = MatDenseRestoreArray(dJdense,&a);CHKERRQ(ierr);
206   ierr = MatDestroy(&dJ);CHKERRQ(ierr);
207   ierr = MatDestroy(&dJdense);CHKERRQ(ierr);
208   ierr = PetscFree(eigr);CHKERRQ(ierr);
209   ierr = PetscFree(eigi);CHKERRQ(ierr);
210   ierr = PetscFree(work);CHKERRQ(ierr);
211   PetscFunctionReturn(0);
212 #endif
213 }
214 
215 #undef __FUNCT__
216 #define __FUNCT__ "SNESMonitorRange_Private"
217 PetscErrorCode  SNESMonitorRange_Private(SNES snes,PetscInt it,PetscReal *per)
218 {
219   PetscErrorCode          ierr;
220   Vec                     resid;
221   PetscReal               rmax,pwork;
222   PetscInt                i,n,N;
223   PetscScalar             *r;
224 
225   PetscFunctionBegin;
226   ierr = SNESGetFunction(snes,&resid,0,0);CHKERRQ(ierr);
227   ierr = VecNorm(resid,NORM_INFINITY,&rmax);CHKERRQ(ierr);
228   ierr = VecGetLocalSize(resid,&n);CHKERRQ(ierr);
229   ierr = VecGetSize(resid,&N);CHKERRQ(ierr);
230   ierr = VecGetArray(resid,&r);CHKERRQ(ierr);
231   pwork = 0.0;
232   for (i=0; i<n; i++) {
233     pwork += (PetscAbsScalar(r[i]) > .20*rmax);
234   }
235   ierr = MPI_Allreduce(&pwork,per,1,MPIU_REAL,MPIU_SUM,((PetscObject)snes)->comm);CHKERRQ(ierr);
236   ierr = VecRestoreArray(resid,&r);CHKERRQ(ierr);
237   *per  = *per/N;
238   PetscFunctionReturn(0);
239 }
240 
241 #undef __FUNCT__
242 #define __FUNCT__ "SNESMonitorRange"
243 /*@C
244    SNESMonitorRange - Prints the percentage of residual elements that are more then 10 percent of the maximum value.
245 
246    Collective on SNES
247 
248    Input Parameters:
249 +  snes   - iterative context
250 .  it    - iteration number
251 .  rnorm - 2-norm (preconditioned) residual value (may be estimated).
252 -  dummy - unused monitor context
253 
254    Options Database Key:
255 .  -snes_monitor_range - Activates SNESMonitorRange()
256 
257    Level: intermediate
258 
259 .keywords: SNES, default, monitor, residual
260 
261 .seealso: SNESMonitorSet(), SNESMonitorDefault(), SNESMonitorLGCreate()
262 @*/
263 PetscErrorCode  SNESMonitorRange(SNES snes,PetscInt it,PetscReal rnorm,void *dummy)
264 {
265   PetscErrorCode   ierr;
266   PetscReal        perc,rel;
267   PetscViewer      viewer = dummy ? (PetscViewer) dummy : PETSC_VIEWER_STDOUT_(((PetscObject)snes)->comm);
268   /* should be in a MonitorRangeContext */
269   static PetscReal prev;
270 
271   PetscFunctionBegin;
272   if (!it) prev = rnorm;
273   ierr = SNESMonitorRange_Private(snes,it,&perc);CHKERRQ(ierr);
274 
275   rel  = (prev - rnorm)/prev;
276   prev = rnorm;
277   ierr = PetscViewerASCIIAddTab(viewer,((PetscObject)snes)->tablevel);CHKERRQ(ierr);
278   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);
279   ierr = PetscViewerASCIISubtractTab(viewer,((PetscObject)snes)->tablevel);CHKERRQ(ierr);
280   PetscFunctionReturn(0);
281 }
282 
283 typedef struct {
284   PetscViewer viewer;
285   PetscReal   *history;
286 } SNESMonitorRatioContext;
287 
288 #undef __FUNCT__
289 #define __FUNCT__ "SNESMonitorRatio"
290 /*@C
291    SNESMonitorRatio - Monitors progress of the SNES solvers by printing the ratio
292    of residual norm at each iteration to the previous.
293 
294    Collective on SNES
295 
296    Input Parameters:
297 +  snes - the SNES context
298 .  its - iteration number
299 .  fgnorm - 2-norm of residual (or gradient)
300 -  dummy -  context of monitor
301 
302    Level: intermediate
303 
304 .keywords: SNES, nonlinear, monitor, norm
305 
306 .seealso: SNESMonitorSet(), SNESMonitorSolution()
307 @*/
308 PetscErrorCode  SNESMonitorRatio(SNES snes,PetscInt its,PetscReal fgnorm,void *dummy)
309 {
310   PetscErrorCode          ierr;
311   PetscInt                len;
312   PetscReal               *history;
313   SNESMonitorRatioContext *ctx = (SNESMonitorRatioContext*)dummy;
314 
315   PetscFunctionBegin;
316   ierr = SNESGetConvergenceHistory(snes,&history,PETSC_NULL,&len);CHKERRQ(ierr);
317   ierr = PetscViewerASCIIAddTab(ctx->viewer,((PetscObject)snes)->tablevel);CHKERRQ(ierr);
318   if (!its || !history || its > len) {
319     ierr = PetscViewerASCIIPrintf(ctx->viewer,"%3D SNES Function norm %14.12e \n",its,(double)fgnorm);CHKERRQ(ierr);
320   } else {
321     PetscReal ratio = fgnorm/history[its-1];
322     ierr = PetscViewerASCIIPrintf(ctx->viewer,"%3D SNES Function norm %14.12e %14.12e \n",its,(double)fgnorm,(double)ratio);CHKERRQ(ierr);
323   }
324   ierr = PetscViewerASCIISubtractTab(ctx->viewer,((PetscObject)snes)->tablevel);CHKERRQ(ierr);
325   PetscFunctionReturn(0);
326 }
327 
328 /*
329    If the we set the history monitor space then we must destroy it
330 */
331 #undef __FUNCT__
332 #define __FUNCT__ "SNESMonitorRatioDestroy"
333 PetscErrorCode SNESMonitorRatioDestroy(void **ct)
334 {
335   PetscErrorCode          ierr;
336   SNESMonitorRatioContext *ctx = *(SNESMonitorRatioContext**)ct;
337 
338   PetscFunctionBegin;
339   ierr = PetscFree(ctx->history);CHKERRQ(ierr);
340   ierr = PetscViewerDestroy(&ctx->viewer);CHKERRQ(ierr);
341   ierr = PetscFree(ctx);CHKERRQ(ierr);
342   PetscFunctionReturn(0);
343 }
344 
345 #undef __FUNCT__
346 #define __FUNCT__ "SNESMonitorSetRatio"
347 /*@C
348    SNESMonitorSetRatio - Sets SNES to use a monitor that prints the
349    ratio of the function norm at each iteration.
350 
351    Collective on SNES
352 
353    Input Parameters:
354 +   snes - the SNES context
355 -   viewer - ASCII viewer to print output
356 
357    Level: intermediate
358 
359 .keywords: SNES, nonlinear, monitor, norm
360 
361 .seealso: SNESMonitorSet(), SNESMonitorSolution(), SNESMonitorDefault()
362 @*/
363 PetscErrorCode  SNESMonitorSetRatio(SNES snes,PetscViewer viewer)
364 {
365   PetscErrorCode          ierr;
366   SNESMonitorRatioContext *ctx;
367   PetscReal               *history;
368 
369   PetscFunctionBegin;
370   if (!viewer) {
371     ierr = PetscViewerASCIIOpen(((PetscObject)snes)->comm,"stdout",&viewer);CHKERRQ(ierr);
372     ierr = PetscObjectReference((PetscObject)viewer);CHKERRQ(ierr);
373   }
374   ierr = PetscNewLog(snes,SNESMonitorRatioContext,&ctx);CHKERRQ(ierr);
375   ierr = SNESGetConvergenceHistory(snes,&history,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr);
376   if (!history) {
377     ierr = PetscMalloc(100*sizeof(PetscReal),&ctx->history);CHKERRQ(ierr);
378     ierr = SNESSetConvergenceHistory(snes,ctx->history,0,100,PETSC_TRUE);CHKERRQ(ierr);
379   }
380   ctx->viewer = viewer;
381   ierr = SNESMonitorSet(snes,SNESMonitorRatio,ctx,SNESMonitorRatioDestroy);CHKERRQ(ierr);
382   PetscFunctionReturn(0);
383 }
384 
385 /* ---------------------------------------------------------------- */
386 #undef __FUNCT__
387 #define __FUNCT__ "SNESMonitorDefaultShort"
388 /*
389      Default (short) SNES Monitor, same as SNESMonitorDefault() except
390   it prints fewer digits of the residual as the residual gets smaller.
391   This is because the later digits are meaningless and are often
392   different on different machines; by using this routine different
393   machines will usually generate the same output.
394 */
395 PetscErrorCode  SNESMonitorDefaultShort(SNES snes,PetscInt its,PetscReal fgnorm,void *dummy)
396 {
397   PetscErrorCode ierr;
398   PetscViewer    viewer = dummy ? (PetscViewer) dummy : PETSC_VIEWER_STDOUT_(((PetscObject)snes)->comm);
399 
400   PetscFunctionBegin;
401   ierr = PetscViewerASCIIAddTab(viewer,((PetscObject)snes)->tablevel);CHKERRQ(ierr);
402   if (fgnorm > 1.e-9) {
403     ierr = PetscViewerASCIIPrintf(viewer,"%3D SNES Function norm %G \n",its,fgnorm);CHKERRQ(ierr);
404   } else if (fgnorm > 1.e-11) {
405     ierr = PetscViewerASCIIPrintf(viewer,"%3D SNES Function norm %5.3e \n",its,fgnorm);CHKERRQ(ierr);
406   } else {
407     ierr = PetscViewerASCIIPrintf(viewer,"%3D SNES Function norm < 1.e-11\n",its);CHKERRQ(ierr);
408   }
409   ierr = PetscViewerASCIISubtractTab(viewer,((PetscObject)snes)->tablevel);CHKERRQ(ierr);
410   PetscFunctionReturn(0);
411 }
412 /* ---------------------------------------------------------------- */
413 #undef __FUNCT__
414 #define __FUNCT__ "SNESDefaultConverged"
415 /*@C
416    SNESDefaultConverged - Convergence test of the solvers for
417    systems of nonlinear equations (default).
418 
419    Collective on SNES
420 
421    Input Parameters:
422 +  snes - the SNES context
423 .  it - the iteration (0 indicates before any Newton steps)
424 .  xnorm - 2-norm of current iterate
425 .  snorm - 2-norm of current step
426 .  fnorm - 2-norm of function at current iterate
427 -  dummy - unused context
428 
429    Output Parameter:
430 .   reason  - one of
431 $  SNES_CONVERGED_FNORM_ABS       - (fnorm < abstol),
432 $  SNES_CONVERGED_SNORM_RELATIVE  - (snorm < stol*xnorm),
433 $  SNES_CONVERGED_FNORM_RELATIVE  - (fnorm < rtol*fnorm0),
434 $  SNES_DIVERGED_FUNCTION_COUNT   - (nfct > maxf),
435 $  SNES_DIVERGED_FNORM_NAN        - (fnorm == NaN),
436 $  SNES_CONVERGED_ITERATING       - (otherwise),
437 
438    where
439 +    maxf - maximum number of function evaluations,
440             set with SNESSetTolerances()
441 .    nfct - number of function evaluations,
442 .    abstol - absolute function norm tolerance,
443             set with SNESSetTolerances()
444 -    rtol - relative function norm tolerance, set with SNESSetTolerances()
445 
446    Level: intermediate
447 
448 .keywords: SNES, nonlinear, default, converged, convergence
449 
450 .seealso: SNESSetConvergenceTest()
451 @*/
452 PetscErrorCode  SNESDefaultConverged(SNES snes,PetscInt it,PetscReal xnorm,PetscReal snorm,PetscReal fnorm,SNESConvergedReason *reason,void *dummy)
453 {
454   PetscErrorCode ierr;
455 
456   PetscFunctionBegin;
457   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
458   PetscValidPointer(reason,6);
459 
460   *reason = SNES_CONVERGED_ITERATING;
461 
462   if (!it) {
463     /* set parameter for default relative tolerance convergence test */
464     snes->ttol = fnorm*snes->rtol;
465   }
466   if (PetscIsInfOrNanReal(fnorm)) {
467     ierr = PetscInfo(snes,"Failed to converged, function norm is NaN\n");CHKERRQ(ierr);
468     *reason = SNES_DIVERGED_FNORM_NAN;
469   } else if (fnorm < snes->abstol) {
470     ierr = PetscInfo2(snes,"Converged due to function norm %14.12e < %14.12e\n",(double)fnorm,(double)snes->abstol);CHKERRQ(ierr);
471     *reason = SNES_CONVERGED_FNORM_ABS;
472   } else if (snes->nfuncs >= snes->max_funcs) {
473     ierr = PetscInfo2(snes,"Exceeded maximum number of function evaluations: %D > %D\n",snes->nfuncs,snes->max_funcs);CHKERRQ(ierr);
474     *reason = SNES_DIVERGED_FUNCTION_COUNT;
475   }
476 
477   if (it && !*reason) {
478     if (fnorm <= snes->ttol) {
479       ierr = PetscInfo2(snes,"Converged due to function norm %14.12e < %14.12e (relative tolerance)\n",(double)fnorm,(double)snes->ttol);CHKERRQ(ierr);
480       *reason = SNES_CONVERGED_FNORM_RELATIVE;
481     } else if (snorm < snes->stol*xnorm) {
482       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);
483       *reason = SNES_CONVERGED_SNORM_RELATIVE;
484     }
485   }
486   PetscFunctionReturn(0);
487 }
488 
489 #undef __FUNCT__
490 #define __FUNCT__ "SNESSkipConverged"
491 /*@C
492    SNESSkipConverged - Convergence test for SNES that NEVER returns as
493    converged, UNLESS the maximum number of iteration have been reached.
494 
495    Logically Collective on SNES
496 
497    Input Parameters:
498 +  snes - the SNES context
499 .  it - the iteration (0 indicates before any Newton steps)
500 .  xnorm - 2-norm of current iterate
501 .  snorm - 2-norm of current step
502 .  fnorm - 2-norm of function at current iterate
503 -  dummy - unused context
504 
505    Output Parameter:
506 .   reason  - SNES_CONVERGED_ITERATING, SNES_CONVERGED_ITS, or SNES_DIVERGED_FNORM_NAN
507 
508    Notes:
509    Convergence is then declared after a fixed number of iterations have been used.
510 
511    Level: advanced
512 
513 .keywords: SNES, nonlinear, skip, converged, convergence
514 
515 .seealso: SNESSetConvergenceTest()
516 @*/
517 PetscErrorCode  SNESSkipConverged(SNES snes,PetscInt it,PetscReal xnorm,PetscReal snorm,PetscReal fnorm,SNESConvergedReason *reason,void *dummy)
518 {
519   PetscErrorCode ierr;
520 
521   PetscFunctionBegin;
522   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
523   PetscValidPointer(reason,6);
524 
525   *reason = SNES_CONVERGED_ITERATING;
526 
527   if (fnorm != fnorm) {
528     ierr = PetscInfo(snes,"Failed to converged, function norm is NaN\n");CHKERRQ(ierr);
529     *reason = SNES_DIVERGED_FNORM_NAN;
530   } else if (it == snes->max_its) {
531     *reason = SNES_CONVERGED_ITS;
532   }
533   PetscFunctionReturn(0);
534 }
535 
536 #undef __FUNCT__
537 #define __FUNCT__ "SNESDefaultGetWork"
538 /*@
539   SNESDefaultGetWork - Gets a number of work vectors.
540 
541   Input Parameters:
542 . snes  - the SNES context
543 . nw - number of work vectors to allocate
544 
545    Level: developer
546 
547   Notes:
548   Call this only if no work vectors have been allocated
549 @*/
550 PetscErrorCode SNESDefaultGetWork(SNES snes,PetscInt nw)
551 {
552   PetscErrorCode ierr;
553 
554   PetscFunctionBegin;
555   if (snes->work) {ierr = VecDestroyVecs(snes->nwork,&snes->work);CHKERRQ(ierr);}
556   snes->nwork = nw;
557   ierr = VecDuplicateVecs(snes->vec_sol,snes->nwork,&snes->work);CHKERRQ(ierr);
558   ierr = PetscLogObjectParents(snes,nw,snes->work);CHKERRQ(ierr);
559   PetscFunctionReturn(0);
560 }
561