Actual source code: snesut.c

petsc-master 2019-07-15
Report Typos and Errors

  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: .seealso: SNESMonitorSet(), SNESMonitorDefault(), VecView()
 24: @*/
 25: PetscErrorCode  SNESMonitorSolution(SNES snes,PetscInt its,PetscReal fgnorm,PetscViewerAndFormat *vf)
 26: {
 28:   Vec            x;
 29:   PetscViewer    viewer = vf->viewer;

 33:   SNESGetSolution(snes,&x);
 34:   PetscViewerPushFormat(viewer,vf->format);
 35:   VecView(x,viewer);
 36:   PetscViewerPopFormat(viewer);
 37:   return(0);
 38: }

 40: /*@C
 41:    SNESMonitorResidual - Monitors progress of the SNES solvers by calling
 42:    VecView() for the residual at each iteration.

 44:    Collective on SNES

 46:    Input Parameters:
 47: +  snes - the SNES context
 48: .  its - iteration number
 49: .  fgnorm - 2-norm of residual
 50: -  dummy -  a viewer

 52:    Options Database Keys:
 53: .  -snes_monitor_residual [ascii binary draw][:filename][:viewer format] - plots residual (not its norm) at each iteration

 55:    Level: intermediate

 57: .seealso: SNESMonitorSet(), SNESMonitorDefault(), VecView()
 58: @*/
 59: PetscErrorCode  SNESMonitorResidual(SNES snes,PetscInt its,PetscReal fgnorm,PetscViewerAndFormat *vf)
 60: {
 62:   Vec            x;
 63:   PetscViewer    viewer = vf->viewer;

 67:   SNESGetFunction(snes,&x,0,0);
 68:   PetscViewerPushFormat(viewer,vf->format);
 69:   VecView(x,viewer);
 70:   PetscViewerPopFormat(viewer);
 71:   return(0);
 72: }

 74: /*@C
 75:    SNESMonitorSolutionUpdate - Monitors progress of the SNES solvers by calling
 76:    VecView() for the UPDATE to the solution at each iteration.

 78:    Collective on SNES

 80:    Input Parameters:
 81: +  snes - the SNES context
 82: .  its - iteration number
 83: .  fgnorm - 2-norm of residual
 84: -  dummy - a viewer

 86:    Options Database Keys:
 87: .  -snes_monitor_solution_update [ascii binary draw][:filename][:viewer format] - plots update to solution at each iteration

 89:    Level: intermediate

 91: .seealso: SNESMonitorSet(), SNESMonitorDefault(), VecView()
 92: @*/
 93: PetscErrorCode  SNESMonitorSolutionUpdate(SNES snes,PetscInt its,PetscReal fgnorm,PetscViewerAndFormat *vf)
 94: {
 96:   Vec            x;
 97:   PetscViewer    viewer = vf->viewer;

101:   SNESGetSolutionUpdate(snes,&x);
102:   PetscViewerPushFormat(viewer,vf->format);
103:   VecView(x,viewer);
104:   PetscViewerPopFormat(viewer);
105:   return(0);
106: }

108: /*@C
109:    KSPMonitorSNES - Print the residual norm of the nonlinear function at each iteration of the linear iterative solver.

111:    Collective on KSP

113:    Input Parameters:
114: +  ksp   - iterative context
115: .  n     - iteration number
116: .  rnorm - 2-norm (preconditioned) residual value (may be estimated).
117: -  dummy - unused monitor context

119:    Level: intermediate

121: .seealso: KSPMonitorSet(), KSPMonitorTrueResidualNorm(), KSPMonitorLGResidualNormCreate()
122: @*/
123: PetscErrorCode  KSPMonitorSNES(KSP ksp,PetscInt n,PetscReal rnorm,void *dummy)
124: {
126:   PetscViewer    viewer;
127:   SNES           snes = (SNES) dummy;
128:   Vec            snes_solution,work1,work2;
129:   PetscReal      snorm;

132:   SNESGetSolution(snes,&snes_solution);
133:   VecDuplicate(snes_solution,&work1);
134:   VecDuplicate(snes_solution,&work2);
135:   KSPBuildSolution(ksp,work1,NULL);
136:   VecAYPX(work1,-1.0,snes_solution);
137:   SNESComputeFunction(snes,work1,work2);
138:   VecNorm(work2,NORM_2,&snorm);
139:   VecDestroy(&work1);
140:   VecDestroy(&work2);

142:   PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)ksp),&viewer);
143:   PetscViewerASCIIAddTab(viewer,((PetscObject)ksp)->tablevel);
144:   if (n == 0 && ((PetscObject)ksp)->prefix) {
145:     PetscViewerASCIIPrintf(viewer,"  Residual norms for %s solve.\n",((PetscObject)ksp)->prefix);
146:   }
147:   PetscViewerASCIIPrintf(viewer,"%3D SNES Residual norm %5.3e KSP Residual norm %5.3e \n",n,(double)snorm,(double)rnorm);
148:   PetscViewerASCIISubtractTab(viewer,((PetscObject)ksp)->tablevel);
149:   return(0);
150: }

152:  #include <petscdraw.h>

154: /*@C
155:    KSPMonitorSNESLGResidualNormCreate - Creates a line graph context for use with
156:    KSP to monitor convergence of preconditioned residual norms.

158:    Collective on KSP

160:    Input Parameters:
161: +  comm - communicator context
162: .  host - the X display to open, or null for the local machine
163: .  label - the title to put in the title bar
164: .  x, y - the screen coordinates of the upper left coordinate of
165:           the window
166: -  m, n - the screen width and height in pixels

168:    Output Parameter:
169: .  draw - the drawing context

171:    Options Database Key:
172: .  -ksp_monitor_lg_residualnorm - Sets line graph monitor

174:    Notes:
175:    Use KSPMonitorSNESLGResidualNormDestroy() to destroy this line graph; do not use PetscDrawLGDestroy().

177:    Level: intermediate

179: .seealso: KSPMonitorSNESLGResidualNormDestroy(), KSPMonitorSet(), KSPMonitorSNESLGTrueResidualCreate()
180: @*/
181: PetscErrorCode  KSPMonitorSNESLGResidualNormCreate(MPI_Comm comm,const char host[],const char label[],int x,int y,int m,int n,PetscObject **objs)
182: {
183:   PetscDraw      draw;
185:   PetscDrawAxis  axis;
186:   PetscDrawLG    lg;
187:   const char     *names[] = {"Linear residual","Nonlinear residual"};

190:   PetscDrawCreate(comm,host,label,x,y,m,n,&draw);
191:   PetscDrawSetFromOptions(draw);
192:   PetscDrawLGCreate(draw,2,&lg);
193:   PetscDrawLGSetLegend(lg,names);
194:   PetscDrawLGSetFromOptions(lg);
195:   PetscDrawLGGetAxis(lg,&axis);
196:   PetscDrawAxisSetLabels(axis,"Convergence of Residual Norm","Iteration","Residual Norm");
197:   PetscDrawDestroy(&draw);

199:   PetscMalloc1(2,objs);
200:   (*objs)[1] = (PetscObject)lg;
201:   return(0);
202: }

204: PetscErrorCode  KSPMonitorSNESLGResidualNorm(KSP ksp,PetscInt n,PetscReal rnorm,PetscObject *objs)
205: {
206:   SNES           snes = (SNES) objs[0];
207:   PetscDrawLG    lg   = (PetscDrawLG) objs[1];
209:   PetscReal      y[2];
210:   Vec            snes_solution,work1,work2;

213:   if (rnorm > 0.0) y[0] = PetscLog10Real(rnorm);
214:   else y[0] = -15.0;

216:   SNESGetSolution(snes,&snes_solution);
217:   VecDuplicate(snes_solution,&work1);
218:   VecDuplicate(snes_solution,&work2);
219:   KSPBuildSolution(ksp,work1,NULL);
220:   VecAYPX(work1,-1.0,snes_solution);
221:   SNESComputeFunction(snes,work1,work2);
222:   VecNorm(work2,NORM_2,y+1);
223:   if (y[1] > 0.0) y[1] = PetscLog10Real(y[1]);
224:   else y[1] = -15.0;
225:   VecDestroy(&work1);
226:   VecDestroy(&work2);

228:   PetscDrawLGAddPoint(lg,NULL,y);
229:   if (n < 20 || !(n % 5) || snes->reason) {
230:     PetscDrawLGDraw(lg);
231:     PetscDrawLGSave(lg);
232:   }
233:   return(0);
234: }

236: /*@
237:    KSPMonitorSNESLGResidualNormDestroy - Destroys a line graph context that was created
238:    with KSPMonitorSNESLGResidualNormCreate().

240:    Collective on KSP

242:    Input Parameter:
243: .  draw - the drawing context

245:    Level: intermediate

247: .seealso: KSPMonitorSNESLGResidualNormCreate(), KSPMonitorSNESLGTrueResidualDestroy(), KSPMonitorSet()
248: @*/
249: PetscErrorCode  KSPMonitorSNESLGResidualNormDestroy(PetscObject **objs)
250: {
252:   PetscDrawLG    lg = (PetscDrawLG) (*objs)[1];

255:   PetscDrawLGDestroy(&lg);
256:   PetscFree(*objs);
257:   return(0);
258: }

260: /*@C
261:    SNESMonitorDefault - Monitors progress of the SNES solvers (default).

263:    Collective on SNES

265:    Input Parameters:
266: +  snes - the SNES context
267: .  its - iteration number
268: .  fgnorm - 2-norm of residual
269: -  vf - viewer and format structure

271:    Notes:
272:    This routine prints the residual norm at each iteration.

274:    Level: intermediate

276: .seealso: SNESMonitorSet(), SNESMonitorSolution()
277: @*/
278: PetscErrorCode  SNESMonitorDefault(SNES snes,PetscInt its,PetscReal fgnorm,PetscViewerAndFormat *vf)
279: {
281:   PetscViewer    viewer = vf->viewer;

285:   PetscViewerPushFormat(viewer,vf->format);
286:   PetscViewerASCIIAddTab(viewer,((PetscObject)snes)->tablevel);
287:   PetscViewerASCIIPrintf(viewer,"%3D SNES Function norm %14.12e \n",its,(double)fgnorm);
288:   PetscViewerASCIISubtractTab(viewer,((PetscObject)snes)->tablevel);
289:   PetscViewerPopFormat(viewer);CHKERRQ(ierr) ;
290:   return(0);
291: }

293: /*@C
294:    SNESMonitorScaling - Monitors the largest value in each row of the Jacobian.

296:    Collective on SNES

298:    Input Parameters:
299: +  snes - the SNES context
300: .  its - iteration number
301: .  fgnorm - 2-norm of residual
302: -  vf - viewer and format structure

304:    Notes:
305:    This routine prints the largest value in each row of the Jacobian 

307:    Level: intermediate

309: .seealso: SNESMonitorSet(), SNESMonitorSolution()
310: @*/
311: PetscErrorCode  SNESMonitorScaling(SNES snes,PetscInt its,PetscReal fgnorm,PetscViewerAndFormat *vf)
312: {
314:   PetscViewer    viewer = vf->viewer;
315:   KSP            ksp;
316:   Mat            J;
317:   Vec            v;

321:   SNESGetKSP(snes,&ksp);
322:   KSPGetOperators(ksp,&J,NULL);
323:   MatCreateVecs(J,&v,NULL);
324:   MatGetRowMaxAbs(J,v,NULL);
325:   PetscViewerPushFormat(viewer,vf->format);
326:   PetscViewerASCIIAddTab(viewer,((PetscObject)snes)->tablevel);
327:   PetscViewerASCIIPrintf(viewer,"%3D SNES Jacobian maximum row entries \n");
328:   VecView(v,viewer);
329:   PetscViewerASCIISubtractTab(viewer,((PetscObject)snes)->tablevel);
330:   PetscViewerPopFormat(viewer);CHKERRQ(ierr) ;
331:   VecDestroy(&v);
332:   return(0);
333: }

335: PetscErrorCode SNESMonitorJacUpdateSpectrum(SNES snes,PetscInt it,PetscReal fnorm,PetscViewerAndFormat *vf)
336: {
337: #if defined(PETSC_MISSING_LAPACK_GEEV)
338:   SETERRQ(PetscObjectComm((PetscObject)snes),PETSC_ERR_SUP,"GEEV - Lapack routine is unavailable\nNot able to provide eigen values.");
339: #elif defined(PETSC_HAVE_ESSL)
340:   SETERRQ(PetscObjectComm((PetscObject)snes),PETSC_ERR_SUP,"GEEV - No support for ESSL Lapack Routines");
341: #else
342:   Vec            X;
343:   Mat            J,dJ,dJdense;
345:   PetscErrorCode (*func)(SNES,Vec,Mat,Mat,void*);
346:   PetscInt       n,i;
347:   PetscBLASInt   nb,lwork;
348:   PetscReal      *eigr,*eigi;
349:   PetscScalar    *work;
350:   PetscScalar    *a;

353:   if (it == 0) return(0);
354:   /* create the difference between the current update and the current jacobian */
355:   SNESGetSolution(snes,&X);
356:   SNESGetJacobian(snes,NULL,&J,&func,NULL);
357:   MatDuplicate(J,MAT_COPY_VALUES,&dJ);
358:   SNESComputeJacobian(snes,X,dJ,dJ);
359:   MatAXPY(dJ,-1.0,J,SAME_NONZERO_PATTERN);

361:   /* compute the spectrum directly */
362:   MatConvert(dJ,MATSEQDENSE,MAT_INITIAL_MATRIX,&dJdense);
363:   MatGetSize(dJ,&n,NULL);
364:   PetscBLASIntCast(n,&nb);
365:   lwork = 3*nb;
366:   PetscMalloc1(n,&eigr);
367:   PetscMalloc1(n,&eigi);
368:   PetscMalloc1(lwork,&work);
369:   MatDenseGetArray(dJdense,&a);
370: #if !defined(PETSC_USE_COMPLEX)
371:   {
372:     PetscBLASInt lierr;
373:     PetscFPTrapPush(PETSC_FP_TRAP_OFF);
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:     PetscFPTrapPop();
377:   }
378: #else
379:   SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not coded for complex");
380: #endif
381:   PetscPrintf(PetscObjectComm((PetscObject)snes),"Eigenvalues of J_%d - J_%d:\n",it,it-1);
382:   for (i=0;i<n;i++) {
383:     PetscPrintf(PetscObjectComm((PetscObject)snes),"%5d: %20.5g + %20.5gi\n",i,(double)eigr[i],(double)eigi[i]);
384:   }
385:   MatDenseRestoreArray(dJdense,&a);
386:   MatDestroy(&dJ);
387:   MatDestroy(&dJdense);
388:   PetscFree(eigr);
389:   PetscFree(eigi);
390:   PetscFree(work);
391:   return(0);
392: #endif
393: }

395: PETSC_INTERN PetscErrorCode  SNESMonitorRange_Private(SNES,PetscInt,PetscReal*);

397: PetscErrorCode  SNESMonitorRange_Private(SNES snes,PetscInt it,PetscReal *per)
398: {
400:   Vec            resid;
401:   PetscReal      rmax,pwork;
402:   PetscInt       i,n,N;
403:   PetscScalar    *r;

406:   SNESGetFunction(snes,&resid,0,0);
407:   VecNorm(resid,NORM_INFINITY,&rmax);
408:   VecGetLocalSize(resid,&n);
409:   VecGetSize(resid,&N);
410:   VecGetArray(resid,&r);
411:   pwork = 0.0;
412:   for (i=0; i<n; i++) {
413:     pwork += (PetscAbsScalar(r[i]) > .20*rmax);
414:   }
415:   MPIU_Allreduce(&pwork,per,1,MPIU_REAL,MPIU_SUM,PetscObjectComm((PetscObject)snes));
416:   VecRestoreArray(resid,&r);
417:   *per = *per/N;
418:   return(0);
419: }

421: /*@C
422:    SNESMonitorRange - Prints the percentage of residual elements that are more then 10 percent of the maximum value.

424:    Collective on SNES

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

432:    Options Database Key:
433: .  -snes_monitor_range - Activates SNESMonitorRange()

435:    Level: intermediate

437: .seealso: SNESMonitorSet(), SNESMonitorDefault(), SNESMonitorLGCreate()
438: @*/
439: PetscErrorCode  SNESMonitorRange(SNES snes,PetscInt it,PetscReal rnorm,PetscViewerAndFormat *vf)
440: {
442:   PetscReal      perc,rel;
443:   PetscViewer    viewer = vf->viewer;
444:   /* should be in a MonitorRangeContext */
445:   static PetscReal prev;

449:   if (!it) prev = rnorm;
450:   SNESMonitorRange_Private(snes,it,&perc);

452:   rel  = (prev - rnorm)/prev;
453:   prev = rnorm;
454:   PetscViewerPushFormat(viewer,vf->format);
455:   PetscViewerASCIIAddTab(viewer,((PetscObject)snes)->tablevel);
456:   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));
457:   PetscViewerASCIISubtractTab(viewer,((PetscObject)snes)->tablevel);
458:   PetscViewerPopFormat(viewer);
459:   return(0);
460: }

462: /*@C
463:    SNESMonitorRatio - Monitors progress of the SNES solvers by printing the ratio
464:    of residual norm at each iteration to the previous.

466:    Collective on SNES

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

474:    Level: intermediate

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: 
488:   SNESGetConvergenceHistory(snes,&history,NULL,&len);
489:   PetscViewerPushFormat(viewer,vf->format);
490:   PetscViewerASCIIAddTab(viewer,((PetscObject)snes)->tablevel);
491:   if (!its || !history || its > len) {
492:     PetscViewerASCIIPrintf(viewer,"%3D SNES Function norm %14.12e \n",its,(double)fgnorm);
493:   } else {
494:     PetscReal ratio = fgnorm/history[its-1];
495:     PetscViewerASCIIPrintf(viewer,"%3D SNES Function norm %14.12e %14.12e \n",its,(double)fgnorm,(double)ratio);
496:   }
497:   PetscViewerASCIISubtractTab(viewer,((PetscObject)snes)->tablevel);
498:   PetscViewerPopFormat(viewer);
499:   return(0);
500: }

502: /*@C
503:    SNESMonitorRatioSetUp - Insures the SNES object is saving its history since this monitor needs access to it

505:    Collective on SNES

507:    Input Parameters:
508: +   snes - the SNES context
509: -   viewer - the PetscViewer object (ignored)

511:    Level: intermediate

513: .seealso: SNESMonitorSet(), SNESMonitorSolution(), SNESMonitorDefault(), SNESMonitorRatio()
514: @*/
515: PetscErrorCode  SNESMonitorRatioSetUp(SNES snes,PetscViewerAndFormat *vf)
516: {
517:   PetscErrorCode          ierr;
518:   PetscReal               *history;

521:   SNESGetConvergenceHistory(snes,&history,NULL,NULL);
522:   if (!history) {
523:     SNESSetConvergenceHistory(snes,NULL,NULL,100,PETSC_TRUE);
524:   }
525:   return(0);
526: }

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.

536:   Deprecated: Intentionally has no manual page
537: */
538: PetscErrorCode  SNESMonitorDefaultShort(SNES snes,PetscInt its,PetscReal fgnorm,PetscViewerAndFormat *vf)
539: {
541:   PetscViewer    viewer = vf->viewer;

545:   PetscViewerPushFormat(viewer,vf->format);
546:   PetscViewerASCIIAddTab(viewer,((PetscObject)snes)->tablevel);
547:   if (fgnorm > 1.e-9) {
548:     PetscViewerASCIIPrintf(viewer,"%3D SNES Function norm %g \n",its,(double)fgnorm);
549:   } else if (fgnorm > 1.e-11) {
550:     PetscViewerASCIIPrintf(viewer,"%3D SNES Function norm %5.3e \n",its,(double)fgnorm);
551:   } else {
552:     PetscViewerASCIIPrintf(viewer,"%3D SNES Function norm < 1.e-11\n",its);
553:   }
554:   PetscViewerASCIISubtractTab(viewer,((PetscObject)snes)->tablevel);
555:   PetscViewerPopFormat(viewer);
556:   return(0);
557: }

559: /*@C
560:   SNESMonitorDefaultField - Monitors progress of the SNES solvers, separated into fields.

562:   Collective on SNES

564:   Input Parameters:
565: + snes   - the SNES context
566: . its    - iteration number
567: . fgnorm - 2-norm of residual
568: - ctx    - the PetscViewer

570:   Notes:
571:   This routine uses the DM attached to the residual vector

573:   Level: intermediate

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;

588:   SNESGetFunction(snes, &r, NULL, NULL);
589:   VecGetDM(r, &dm);
590:   if (!dm) {SNESMonitorDefault(snes, its, fgnorm, vf);}
591:   else {
592:     PetscSection s, gs;
593:     PetscInt     Nf, f;

595:     DMGetSection(dm, &s);
596:     DMGetGlobalSection(dm, &gs);
597:     if (!s || !gs) {SNESMonitorDefault(snes, its, fgnorm, vf);}
598:     PetscSectionGetNumFields(s, &Nf);
599:     if (Nf > 256) SETERRQ1(PetscObjectComm((PetscObject) snes), PETSC_ERR_SUP, "Do not support %d fields > 256", Nf);
600:     PetscSectionVecNorm(s, gs, r, NORM_2, res);
601:     PetscObjectGetTabLevel((PetscObject) snes, &tablevel);
602:     PetscViewerPushFormat(viewer,vf->format);
603:     PetscViewerASCIIAddTab(viewer, tablevel);
604:     PetscViewerASCIIPrintf(viewer, "%3D SNES Function norm %14.12e [", its, (double) fgnorm);
605:     for (f = 0; f < Nf; ++f) {
606:       if (f) {PetscViewerASCIIPrintf(viewer, ", ");}
607:       PetscViewerASCIIPrintf(viewer, "%14.12e", res[f]);
608:     }
609:     PetscViewerASCIIPrintf(viewer, "] \n");
610:     PetscViewerASCIISubtractTab(viewer, tablevel);
611:     PetscViewerPopFormat(viewer);
612:   }
613:   return(0);
614: }
615: /* ---------------------------------------------------------------- */
616: /*@C
617:    SNESConvergedDefault - Convergence test of the solvers for
618:    systems of nonlinear equations (default).

620:    Collective on SNES

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

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),

639:    where
640: +    maxf - maximum number of function evaluations,
641:             set with SNESSetTolerances()
642: .    nfct - number of function evaluations,
643: .    abstol - absolute function norm tolerance,
644:             set with SNESSetTolerances()
645: -    rtol - relative function norm tolerance, set with SNESSetTolerances()

647:    Level: intermediate

649: .seealso: SNESSetConvergenceTest()
650: @*/
651: PetscErrorCode  SNESConvergedDefault(SNES snes,PetscInt it,PetscReal xnorm,PetscReal snorm,PetscReal fnorm,SNESConvergedReason *reason,void *dummy)
652: {


659:   *reason = SNES_CONVERGED_ITERATING;

661:   if (!it) {
662:     /* set parameter for default relative tolerance convergence test */
663:     snes->ttol   = fnorm*snes->rtol;
664:     snes->rnorm0 = fnorm;
665:   }
666:   if (PetscIsInfOrNanReal(fnorm)) {
667:     PetscInfo(snes,"Failed to converged, function norm is NaN\n");
668:     *reason = SNES_DIVERGED_FNORM_NAN;
669:   } else if (fnorm < snes->abstol && (it || !snes->forceiteration)) {
670:     PetscInfo2(snes,"Converged due to function norm %14.12e < %14.12e\n",(double)fnorm,(double)snes->abstol);
671:     *reason = SNES_CONVERGED_FNORM_ABS;
672:   } else if (snes->nfuncs >= snes->max_funcs && snes->max_funcs >= 0) {
673:     PetscInfo2(snes,"Exceeded maximum number of function evaluations: %D > %D\n",snes->nfuncs,snes->max_funcs);
674:     *reason = SNES_DIVERGED_FUNCTION_COUNT;
675:   }

677:   if (it && !*reason) {
678:     if (fnorm <= snes->ttol) {
679:       PetscInfo2(snes,"Converged due to function norm %14.12e < %14.12e (relative tolerance)\n",(double)fnorm,(double)snes->ttol);
680:       *reason = SNES_CONVERGED_FNORM_RELATIVE;
681:     } else if (snorm < snes->stol*xnorm) {
682:       PetscInfo3(snes,"Converged due to small update length: %14.12e < %14.12e * %14.12e\n",(double)snorm,(double)snes->stol,(double)xnorm);
683:       *reason = SNES_CONVERGED_SNORM_RELATIVE;
684:     } else if (snes->divtol > 0 && (fnorm > snes->divtol*snes->rnorm0)) {
685:       PetscInfo3(snes,"Diverged due to increase in function norm: %14.12e > %14.12e * %14.12e\n",(double)fnorm,(double)snes->divtol,(double)snes->rnorm0);
686:       *reason = SNES_DIVERGED_DTOL;
687:     }
688: 
689:   }
690:   return(0);
691: }

693: /*@C
694:    SNESConvergedSkip - Convergence test for SNES that NEVER returns as
695:    converged, UNLESS the maximum number of iteration have been reached.

697:    Logically Collective on SNES

699:    Input Parameters:
700: +  snes - the SNES context
701: .  it - the iteration (0 indicates before any Newton steps)
702: .  xnorm - 2-norm of current iterate
703: .  snorm - 2-norm of current step
704: .  fnorm - 2-norm of function at current iterate
705: -  dummy - unused context

707:    Output Parameter:
708: .   reason  - SNES_CONVERGED_ITERATING, SNES_CONVERGED_ITS, or SNES_DIVERGED_FNORM_NAN

710:    Notes:
711:    Convergence is then declared after a fixed number of iterations have been used.

713:    Level: advanced

715: .seealso: SNESSetConvergenceTest()
716: @*/
717: PetscErrorCode  SNESConvergedSkip(SNES snes,PetscInt it,PetscReal xnorm,PetscReal snorm,PetscReal fnorm,SNESConvergedReason *reason,void *dummy)
718: {


725:   *reason = SNES_CONVERGED_ITERATING;

727:   if (fnorm != fnorm) {
728:     PetscInfo(snes,"Failed to converged, function norm is NaN\n");
729:     *reason = SNES_DIVERGED_FNORM_NAN;
730:   } else if (it == snes->max_its) {
731:     *reason = SNES_CONVERGED_ITS;
732:   }
733:   return(0);
734: }

736: /*@C
737:   SNESSetWorkVecs - Gets a number of work vectors.

739:   Input Parameters:
740: + snes  - the SNES context
741: - nw - number of work vectors to allocate

743:   Level: developer

745: @*/
746: PetscErrorCode SNESSetWorkVecs(SNES snes,PetscInt nw)
747: {
748:   DM             dm;
749:   Vec            v;

753:   if (snes->work) {VecDestroyVecs(snes->nwork,&snes->work);}
754:   snes->nwork = nw;

756:   SNESGetDM(snes, &dm);
757:   DMGetGlobalVector(dm, &v);
758:   VecDuplicateVecs(v,snes->nwork,&snes->work);
759:   DMRestoreGlobalVector(dm, &v);
760:   PetscLogObjectParents(snes,nw,snes->work);
761:   return(0);
762: }