Actual source code: snesut.c

petsc-3.8.4 2018-03-24
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: .keywords: SNES, nonlinear, vector, monitor, view

 25: .seealso: SNESMonitorSet(), SNESMonitorDefault(), VecView()
 26: @*/
 27: PetscErrorCode  SNESMonitorSolution(SNES snes,PetscInt its,PetscReal fgnorm,PetscViewerAndFormat *vf)
 28: {
 30:   Vec            x;
 31:   PetscViewer    viewer = vf->viewer;

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

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

 46:    Collective on SNES

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

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

 57:    Level: intermediate

 59: .keywords: SNES, nonlinear, vector, monitor, view

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

 71:   SNESGetFunction(snes,&x,0,0);
 72:   PetscViewerPushFormat(viewer,vf->format);
 73:   VecView(x,viewer);
 74:   PetscViewerPopFormat(viewer);
 75:   return(0);
 76: }

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

 82:    Collective on SNES

 84:    Input Parameters:
 85: +  snes - the SNES context
 86: .  its - iteration number
 87: .  fgnorm - 2-norm of residual
 88: -  dummy - a viewer

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

 93:    Level: intermediate

 95: .keywords: SNES, nonlinear, vector, monitor, view

 97: .seealso: SNESMonitorSet(), SNESMonitorDefault(), VecView()
 98: @*/
 99: PetscErrorCode  SNESMonitorSolutionUpdate(SNES snes,PetscInt its,PetscReal fgnorm,PetscViewerAndFormat *vf)
100: {
102:   Vec            x;
103:   PetscViewer    viewer = vf->viewer;

107:   SNESGetSolutionUpdate(snes,&x);
108:   PetscViewerPushFormat(viewer,vf->format);
109:   VecView(x,viewer);
110:   PetscViewerPopFormat(viewer);
111:   return(0);
112: }

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

117:    Collective on KSP

119:    Input Parameters:
120: +  ksp   - iterative context
121: .  n     - iteration number
122: .  rnorm - 2-norm (preconditioned) residual value (may be estimated).
123: -  dummy - unused monitor context

125:    Level: intermediate

127: .keywords: KSP, default, monitor, residual

129: .seealso: KSPMonitorSet(), KSPMonitorTrueResidualNorm(), KSPMonitorLGResidualNormCreate()
130: @*/
131: PetscErrorCode  KSPMonitorSNES(KSP ksp,PetscInt n,PetscReal rnorm,void *dummy)
132: {
134:   PetscViewer    viewer;
135:   SNES           snes = (SNES) dummy;
136:   Vec            snes_solution,work1,work2;
137:   PetscReal      snorm;

140:   SNESGetSolution(snes,&snes_solution);
141:   VecDuplicate(snes_solution,&work1);
142:   VecDuplicate(snes_solution,&work2);
143:   KSPBuildSolution(ksp,work1,NULL);
144:   VecAYPX(work1,-1.0,snes_solution);
145:   SNESComputeFunction(snes,work1,work2);
146:   VecNorm(work2,NORM_2,&snorm);
147:   VecDestroy(&work1);
148:   VecDestroy(&work2);

150:   PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)ksp),&viewer);
151:   PetscViewerASCIIAddTab(viewer,((PetscObject)ksp)->tablevel);
152:   if (n == 0 && ((PetscObject)ksp)->prefix) {
153:     PetscViewerASCIIPrintf(viewer,"  Residual norms for %s solve.\n",((PetscObject)ksp)->prefix);
154:   }
155:   PetscViewerASCIIPrintf(viewer,"%3D SNES Residual norm %5.3e KSP Residual norm %5.3e \n",n,(double)snorm,(double)rnorm);
156:   PetscViewerASCIISubtractTab(viewer,((PetscObject)ksp)->tablevel);
157:   return(0);
158: }

160:  #include <petscdraw.h>

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

166:    Collective on KSP

168:    Input Parameters:
169: +  comm - communicator context
170: .  host - the X display to open, or null for the local machine
171: .  label - the title to put in the title bar
172: .  x, y - the screen coordinates of the upper left coordinate of
173:           the window
174: -  m, n - the screen width and height in pixels

176:    Output Parameter:
177: .  draw - the drawing context

179:    Options Database Key:
180: .  -ksp_monitor_lg_residualnorm - Sets line graph monitor

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

185:    Level: intermediate

187: .keywords: KSP, monitor, line graph, residual, create

189: .seealso: KSPMonitorSNESLGResidualNormDestroy(), KSPMonitorSet(), KSPMonitorSNESLGTrueResidualCreate()
190: @*/
191: PetscErrorCode  KSPMonitorSNESLGResidualNormCreate(MPI_Comm comm,const char host[],const char label[],int x,int y,int m,int n,PetscObject **objs)
192: {
193:   PetscDraw      draw;
195:   PetscDrawAxis  axis;
196:   PetscDrawLG    lg;
197:   const char     *names[] = {"Linear residual","Nonlinear residual"};

200:   PetscDrawCreate(comm,host,label,x,y,m,n,&draw);
201:   PetscDrawSetFromOptions(draw);
202:   PetscDrawLGCreate(draw,2,&lg);
203:   PetscDrawLGSetLegend(lg,names);
204:   PetscDrawLGSetFromOptions(lg);
205:   PetscDrawLGGetAxis(lg,&axis);
206:   PetscDrawAxisSetLabels(axis,"Convergence of Residual Norm","Iteration","Residual Norm");
207:   PetscDrawDestroy(&draw);

209:   PetscMalloc1(2,objs);
210:   (*objs)[1] = (PetscObject)lg;
211:   return(0);
212: }

214: PetscErrorCode  KSPMonitorSNESLGResidualNorm(KSP ksp,PetscInt n,PetscReal rnorm,PetscObject *objs)
215: {
216:   SNES           snes = (SNES) objs[0];
217:   PetscDrawLG    lg   = (PetscDrawLG) objs[1];
219:   PetscReal      y[2];
220:   Vec            snes_solution,work1,work2;

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

226:   SNESGetSolution(snes,&snes_solution);
227:   VecDuplicate(snes_solution,&work1);
228:   VecDuplicate(snes_solution,&work2);
229:   KSPBuildSolution(ksp,work1,NULL);
230:   VecAYPX(work1,-1.0,snes_solution);
231:   SNESComputeFunction(snes,work1,work2);
232:   VecNorm(work2,NORM_2,y+1);
233:   if (y[1] > 0.0) y[1] = PetscLog10Real(y[1]);
234:   else y[1] = -15.0;
235:   VecDestroy(&work1);
236:   VecDestroy(&work2);

238:   PetscDrawLGAddPoint(lg,NULL,y);
239:   if (n < 20 || !(n % 5) || snes->reason) {
240:     PetscDrawLGDraw(lg);
241:     PetscDrawLGSave(lg);
242:   }
243:   return(0);
244: }

246: /*@
247:    KSPMonitorSNESLGResidualNormDestroy - Destroys a line graph context that was created
248:    with KSPMonitorSNESLGResidualNormCreate().

250:    Collective on KSP

252:    Input Parameter:
253: .  draw - the drawing context

255:    Level: intermediate

257: .keywords: KSP, monitor, line graph, destroy

259: .seealso: KSPMonitorSNESLGResidualNormCreate(), KSPMonitorSNESLGTrueResidualDestroy(), KSPMonitorSet()
260: @*/
261: PetscErrorCode  KSPMonitorSNESLGResidualNormDestroy(PetscObject **objs)
262: {
264:   PetscDrawLG    lg = (PetscDrawLG) (*objs)[1];

267:   PetscDrawLGDestroy(&lg);
268:   PetscFree(*objs);
269:   return(0);
270: }

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

275:    Collective on SNES

277:    Input Parameters:
278: +  snes - the SNES context
279: .  its - iteration number
280: .  fgnorm - 2-norm of residual
281: -  vf - viewer and format structure

283:    Notes:
284:    This routine prints the residual norm at each iteration.

286:    Level: intermediate

288: .keywords: SNES, nonlinear, default, monitor, norm

290: .seealso: SNESMonitorSet(), SNESMonitorSolution()
291: @*/
292: PetscErrorCode  SNESMonitorDefault(SNES snes,PetscInt its,PetscReal fgnorm,PetscViewerAndFormat *vf)
293: {
295:   PetscViewer    viewer = vf->viewer;

299:   PetscViewerPushFormat(viewer,vf->format);
300:   PetscViewerASCIIAddTab(viewer,((PetscObject)snes)->tablevel);
301:   PetscViewerASCIIPrintf(viewer,"%3D SNES Function norm %14.12e \n",its,(double)fgnorm);
302:   PetscViewerASCIISubtractTab(viewer,((PetscObject)snes)->tablevel);
303:   PetscViewerPopFormat(viewer);CHKERRQ(ierr) ;
304:   return(0);
305: }

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

310:    Collective on SNES

312:    Input Parameters:
313: +  snes - the SNES context
314: .  its - iteration number
315: .  fgnorm - 2-norm of residual
316: -  vf - viewer and format structure

318:    Notes:
319:    This routine prints the largest value in each row of the Jacobian 

321:    Level: intermediate

323: .keywords: SNES, nonlinear, default, monitor, norm

325: .seealso: SNESMonitorSet(), SNESMonitorSolution()
326: @*/
327: PetscErrorCode  SNESMonitorScaling(SNES snes,PetscInt its,PetscReal fgnorm,PetscViewerAndFormat *vf)
328: {
330:   PetscViewer    viewer = vf->viewer;
331:   KSP            ksp;
332:   Mat            J;
333:   Vec            v;

337:   SNESGetKSP(snes,&ksp);
338:   KSPGetOperators(ksp,&J,NULL);
339:   MatCreateVecs(J,&v,NULL);
340:   MatGetRowMaxAbs(J,v,NULL);
341:   PetscViewerPushFormat(viewer,vf->format);
342:   PetscViewerASCIIAddTab(viewer,((PetscObject)snes)->tablevel);
343:   PetscViewerASCIIPrintf(viewer,"%3D SNES Jacobian maximum row entries \n");
344:   VecView(v,viewer);
345:   PetscViewerASCIISubtractTab(viewer,((PetscObject)snes)->tablevel);
346:   PetscViewerPopFormat(viewer);CHKERRQ(ierr) ;
347:   VecDestroy(&v);
348:   return(0);
349: }

351: PetscErrorCode SNESMonitorJacUpdateSpectrum(SNES snes,PetscInt it,PetscReal fnorm,PetscViewerAndFormat *vf)
352: {
353: #if defined(PETSC_MISSING_LAPACK_GEEV)
354:   SETERRQ(PetscObjectComm((PetscObject)snes),PETSC_ERR_SUP,"GEEV - Lapack routine is unavailable\nNot able to provide eigen values.");
355: #elif defined(PETSC_HAVE_ESSL)
356:   SETERRQ(PetscObjectComm((PetscObject)snes),PETSC_ERR_SUP,"GEEV - No support for ESSL Lapack Routines");
357: #else
358:   Vec            X;
359:   Mat            J,dJ,dJdense;
361:   PetscErrorCode (*func)(SNES,Vec,Mat,Mat,void*);
362:   PetscInt       n,i;
363:   PetscBLASInt   nb,lwork;
364:   PetscReal      *eigr,*eigi;
365:   PetscScalar    *work;
366:   PetscScalar    *a;

369:   if (it == 0) return(0);
370:   /* create the difference between the current update and the current jacobian */
371:   SNESGetSolution(snes,&X);
372:   SNESGetJacobian(snes,NULL,&J,&func,NULL);
373:   MatDuplicate(J,MAT_COPY_VALUES,&dJ);
374:   SNESComputeJacobian(snes,X,dJ,dJ);
375:   MatAXPY(dJ,-1.0,J,SAME_NONZERO_PATTERN);

377:   /* compute the spectrum directly */
378:   MatConvert(dJ,MATSEQDENSE,MAT_INITIAL_MATRIX,&dJdense);
379:   MatGetSize(dJ,&n,NULL);
380:   PetscBLASIntCast(n,&nb);
381:   lwork = 3*nb;
382:   PetscMalloc1(n,&eigr);
383:   PetscMalloc1(n,&eigi);
384:   PetscMalloc1(lwork,&work);
385:   MatDenseGetArray(dJdense,&a);
386: #if !defined(PETSC_USE_COMPLEX)
387:   {
388:     PetscBLASInt lierr;
389:     PetscFPTrapPush(PETSC_FP_TRAP_OFF);
390:     PetscStackCallBLAS("LAPACKgeev",LAPACKgeev_("N","N",&nb,a,&nb,eigr,eigi,NULL,&nb,NULL,&nb,work,&lwork,&lierr));
391:     if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"geev() error %d",lierr);
392:     PetscFPTrapPop();
393:   }
394: #else
395:   SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not coded for complex");
396: #endif
397:   PetscPrintf(PetscObjectComm((PetscObject)snes),"Eigenvalues of J_%d - J_%d:\n",it,it-1);
398:   for (i=0;i<n;i++) {
399:     PetscPrintf(PetscObjectComm((PetscObject)snes),"%5d: %20.5g + %20.5gi\n",i,(double)eigr[i],(double)eigi[i]);
400:   }
401:   MatDenseRestoreArray(dJdense,&a);
402:   MatDestroy(&dJ);
403:   MatDestroy(&dJdense);
404:   PetscFree(eigr);
405:   PetscFree(eigi);
406:   PetscFree(work);
407:   return(0);
408: #endif
409: }

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

413: PetscErrorCode  SNESMonitorRange_Private(SNES snes,PetscInt it,PetscReal *per)
414: {
416:   Vec            resid;
417:   PetscReal      rmax,pwork;
418:   PetscInt       i,n,N;
419:   PetscScalar    *r;

422:   SNESGetFunction(snes,&resid,0,0);
423:   VecNorm(resid,NORM_INFINITY,&rmax);
424:   VecGetLocalSize(resid,&n);
425:   VecGetSize(resid,&N);
426:   VecGetArray(resid,&r);
427:   pwork = 0.0;
428:   for (i=0; i<n; i++) {
429:     pwork += (PetscAbsScalar(r[i]) > .20*rmax);
430:   }
431:   MPIU_Allreduce(&pwork,per,1,MPIU_REAL,MPIU_SUM,PetscObjectComm((PetscObject)snes));
432:   VecRestoreArray(resid,&r);
433:   *per = *per/N;
434:   return(0);
435: }

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

440:    Collective on SNES

442:    Input Parameters:
443: +  snes   - iterative context
444: .  it    - iteration number
445: .  rnorm - 2-norm (preconditioned) residual value (may be estimated).
446: -  dummy - unused monitor context

448:    Options Database Key:
449: .  -snes_monitor_range - Activates SNESMonitorRange()

451:    Level: intermediate

453: .keywords: SNES, default, monitor, residual

455: .seealso: SNESMonitorSet(), SNESMonitorDefault(), SNESMonitorLGCreate()
456: @*/
457: PetscErrorCode  SNESMonitorRange(SNES snes,PetscInt it,PetscReal rnorm,PetscViewerAndFormat *vf)
458: {
460:   PetscReal      perc,rel;
461:   PetscViewer    viewer = vf->viewer;
462:   /* should be in a MonitorRangeContext */
463:   static PetscReal prev;

467:   if (!it) prev = rnorm;
468:   SNESMonitorRange_Private(snes,it,&perc);

470:   rel  = (prev - rnorm)/prev;
471:   prev = rnorm;
472:   PetscViewerPushFormat(viewer,vf->format);
473:   PetscViewerASCIIAddTab(viewer,((PetscObject)snes)->tablevel);
474:   PetscViewerASCIIPrintf(viewer,"%3D SNES preconditioned resid norm %14.12e Percent values above 20 percent of maximum %5.2f relative decrease %5.2e ratio %5.2e \n",it,(double)rnorm,(double)(100.0*perc),(double)rel,(double)(rel/perc));
475:   PetscViewerASCIISubtractTab(viewer,((PetscObject)snes)->tablevel);
476:   PetscViewerPopFormat(viewer);
477:   return(0);
478: }

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

484:    Collective on SNES

486:    Input Parameters:
487: +  snes - the SNES context
488: .  its - iteration number
489: .  fgnorm - 2-norm of residual (or gradient)
490: -  dummy -  context of monitor

492:    Level: intermediate

494:    Notes: Insure that SNESMonitorRatio() is called when you set this monitor
495: .keywords: SNES, nonlinear, monitor, norm

497: .seealso: SNESMonitorSet(), SNESMonitorSolution(), SNESMonitorRatio()
498: @*/
499: PetscErrorCode  SNESMonitorRatio(SNES snes,PetscInt its,PetscReal fgnorm,PetscViewerAndFormat *vf)
500: {
501:   PetscErrorCode          ierr;
502:   PetscInt                len;
503:   PetscReal               *history;
504:   PetscViewer             viewer = vf->viewer;
505: 
507:   SNESGetConvergenceHistory(snes,&history,NULL,&len);
508:   PetscViewerPushFormat(viewer,vf->format);
509:   PetscViewerASCIIAddTab(viewer,((PetscObject)snes)->tablevel);
510:   if (!its || !history || its > len) {
511:     PetscViewerASCIIPrintf(viewer,"%3D SNES Function norm %14.12e \n",its,(double)fgnorm);
512:   } else {
513:     PetscReal ratio = fgnorm/history[its-1];
514:     PetscViewerASCIIPrintf(viewer,"%3D SNES Function norm %14.12e %14.12e \n",its,(double)fgnorm,(double)ratio);
515:   }
516:   PetscViewerASCIISubtractTab(viewer,((PetscObject)snes)->tablevel);
517:   PetscViewerPopFormat(viewer);
518:   return(0);
519: }

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

524:    Collective on SNES

526:    Input Parameters:
527: +   snes - the SNES context
528: -   viewer - the PetscViewer object (ignored)

530:    Level: intermediate

532: .keywords: SNES, nonlinear, monitor, norm

534: .seealso: SNESMonitorSet(), SNESMonitorSolution(), SNESMonitorDefault(), SNESMonitorRatio()
535: @*/
536: PetscErrorCode  SNESMonitorRatioSetUp(SNES snes,PetscViewerAndFormat *vf)
537: {
538:   PetscErrorCode          ierr;
539:   PetscReal               *history;

542:   SNESGetConvergenceHistory(snes,&history,NULL,NULL);
543:   if (!history) {
544:     SNESSetConvergenceHistory(snes,NULL,NULL,100,PETSC_TRUE);
545:   }
546:   return(0);
547: }

549: /* ---------------------------------------------------------------- */
550: /*
551:      Default (short) SNES Monitor, same as SNESMonitorDefault() except
552:   it prints fewer digits of the residual as the residual gets smaller.
553:   This is because the later digits are meaningless and are often
554:   different on different machines; by using this routine different
555:   machines will usually generate the same output.
556: */
557: PetscErrorCode  SNESMonitorDefaultShort(SNES snes,PetscInt its,PetscReal fgnorm,PetscViewerAndFormat *vf)
558: {
560:   PetscViewer    viewer = vf->viewer;

564:   PetscViewerPushFormat(viewer,vf->format);
565:   PetscViewerASCIIAddTab(viewer,((PetscObject)snes)->tablevel);
566:   if (fgnorm > 1.e-9) {
567:     PetscViewerASCIIPrintf(viewer,"%3D SNES Function norm %g \n",its,(double)fgnorm);
568:   } else if (fgnorm > 1.e-11) {
569:     PetscViewerASCIIPrintf(viewer,"%3D SNES Function norm %5.3e \n",its,(double)fgnorm);
570:   } else {
571:     PetscViewerASCIIPrintf(viewer,"%3D SNES Function norm < 1.e-11\n",its);
572:   }
573:   PetscViewerASCIISubtractTab(viewer,((PetscObject)snes)->tablevel);
574:   PetscViewerPopFormat(viewer);
575:   return(0);
576: }

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

581:   Collective on SNES

583:   Input Parameters:
584: + snes   - the SNES context
585: . its    - iteration number
586: . fgnorm - 2-norm of residual
587: - ctx    - the PetscViewer

589:   Notes:
590:   This routine uses the DM attached to the residual vector

592:   Level: intermediate

594: .keywords: SNES, nonlinear, field, monitor, norm
595: .seealso: SNESMonitorSet(), SNESMonitorSolution(), SNESMonitorDefault(), SNESMonitorDefaultShort()
596: @*/
597: PetscErrorCode SNESMonitorDefaultField(SNES snes, PetscInt its, PetscReal fgnorm, PetscViewerAndFormat *vf)
598: {
599:   PetscViewer    viewer = vf->viewer;
600:   Vec            r;
601:   DM             dm;
602:   PetscReal      res[256];
603:   PetscInt       tablevel;

608:   SNESGetFunction(snes, &r, NULL, NULL);
609:   VecGetDM(r, &dm);
610:   if (!dm) {SNESMonitorDefault(snes, its, fgnorm, vf);}
611:   else {
612:     PetscSection s, gs;
613:     PetscInt     Nf, f;

615:     DMGetDefaultSection(dm, &s);
616:     DMGetDefaultGlobalSection(dm, &gs);
617:     if (!s || !gs) {SNESMonitorDefault(snes, its, fgnorm, vf);}
618:     PetscSectionGetNumFields(s, &Nf);
619:     if (Nf > 256) SETERRQ1(PetscObjectComm((PetscObject) snes), PETSC_ERR_SUP, "Do not support %d fields > 256", Nf);
620:     PetscSectionVecNorm(s, gs, r, NORM_2, res);
621:     PetscObjectGetTabLevel((PetscObject) snes, &tablevel);
622:     PetscViewerPushFormat(viewer,vf->format);
623:     PetscViewerASCIIAddTab(viewer, tablevel);
624:     PetscViewerASCIIPrintf(viewer, "%3D SNES Function norm %14.12e [", its, (double) fgnorm);
625:     for (f = 0; f < Nf; ++f) {
626:       if (f) {PetscViewerASCIIPrintf(viewer, ", ");}
627:       PetscViewerASCIIPrintf(viewer, "%14.12e", res[f]);
628:     }
629:     PetscViewerASCIIPrintf(viewer, "] \n");
630:     PetscViewerASCIISubtractTab(viewer, tablevel);
631:     PetscViewerPopFormat(viewer);
632:   }
633:   return(0);
634: }
635: /* ---------------------------------------------------------------- */
636: /*@C
637:    SNESConvergedDefault - Convergence test of the solvers for
638:    systems of nonlinear equations (default).

640:    Collective on SNES

642:    Input Parameters:
643: +  snes - the SNES context
644: .  it - the iteration (0 indicates before any Newton steps)
645: .  xnorm - 2-norm of current iterate
646: .  snorm - 2-norm of current step
647: .  fnorm - 2-norm of function at current iterate
648: -  dummy - unused context

650:    Output Parameter:
651: .   reason  - one of
652: $  SNES_CONVERGED_FNORM_ABS       - (fnorm < abstol),
653: $  SNES_CONVERGED_SNORM_RELATIVE  - (snorm < stol*xnorm),
654: $  SNES_CONVERGED_FNORM_RELATIVE  - (fnorm < rtol*fnorm0),
655: $  SNES_DIVERGED_FUNCTION_COUNT   - (nfct > maxf),
656: $  SNES_DIVERGED_FNORM_NAN        - (fnorm == NaN),
657: $  SNES_CONVERGED_ITERATING       - (otherwise),

659:    where
660: +    maxf - maximum number of function evaluations,
661:             set with SNESSetTolerances()
662: .    nfct - number of function evaluations,
663: .    abstol - absolute function norm tolerance,
664:             set with SNESSetTolerances()
665: -    rtol - relative function norm tolerance, set with SNESSetTolerances()

667:    Level: intermediate

669: .keywords: SNES, nonlinear, default, converged, convergence

671: .seealso: SNESSetConvergenceTest()
672: @*/
673: PetscErrorCode  SNESConvergedDefault(SNES snes,PetscInt it,PetscReal xnorm,PetscReal snorm,PetscReal fnorm,SNESConvergedReason *reason,void *dummy)
674: {


681:   *reason = SNES_CONVERGED_ITERATING;

683:   if (!it) {
684:     /* set parameter for default relative tolerance convergence test */
685:     snes->ttol   = fnorm*snes->rtol;
686:     snes->rnorm0 = fnorm;
687:   }
688:   if (PetscIsInfOrNanReal(fnorm)) {
689:     PetscInfo(snes,"Failed to converged, function norm is NaN\n");
690:     *reason = SNES_DIVERGED_FNORM_NAN;
691:   } else if (fnorm < snes->abstol && (it || !snes->forceiteration)) {
692:     PetscInfo2(snes,"Converged due to function norm %14.12e < %14.12e\n",(double)fnorm,(double)snes->abstol);
693:     *reason = SNES_CONVERGED_FNORM_ABS;
694:   } else if (snes->nfuncs >= snes->max_funcs) {
695:     PetscInfo2(snes,"Exceeded maximum number of function evaluations: %D > %D\n",snes->nfuncs,snes->max_funcs);
696:     *reason = SNES_DIVERGED_FUNCTION_COUNT;
697:   }

699:   if (it && !*reason) {
700:     if (fnorm <= snes->ttol) {
701:       PetscInfo2(snes,"Converged due to function norm %14.12e < %14.12e (relative tolerance)\n",(double)fnorm,(double)snes->ttol);
702:       *reason = SNES_CONVERGED_FNORM_RELATIVE;
703:     } else if (snorm < snes->stol*xnorm) {
704:       PetscInfo3(snes,"Converged due to small update length: %14.12e < %14.12e * %14.12e\n",(double)snorm,(double)snes->stol,(double)xnorm);
705:       *reason = SNES_CONVERGED_SNORM_RELATIVE;
706:     } else if (snes->divtol > 0 && (fnorm > snes->divtol*snes->rnorm0)) {
707:       PetscInfo3(snes,"Diverged due to increase in function norm: %14.12e > %14.12e * %14.12e\n",(double)fnorm,(double)snes->divtol,(double)snes->rnorm0);
708:       *reason = SNES_DIVERGED_DTOL;
709:     }
710: 
711:   }
712:   return(0);
713: }

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

719:    Logically Collective on SNES

721:    Input Parameters:
722: +  snes - the SNES context
723: .  it - the iteration (0 indicates before any Newton steps)
724: .  xnorm - 2-norm of current iterate
725: .  snorm - 2-norm of current step
726: .  fnorm - 2-norm of function at current iterate
727: -  dummy - unused context

729:    Output Parameter:
730: .   reason  - SNES_CONVERGED_ITERATING, SNES_CONVERGED_ITS, or SNES_DIVERGED_FNORM_NAN

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

735:    Level: advanced

737: .keywords: SNES, nonlinear, skip, converged, convergence

739: .seealso: SNESSetConvergenceTest()
740: @*/
741: PetscErrorCode  SNESConvergedSkip(SNES snes,PetscInt it,PetscReal xnorm,PetscReal snorm,PetscReal fnorm,SNESConvergedReason *reason,void *dummy)
742: {


749:   *reason = SNES_CONVERGED_ITERATING;

751:   if (fnorm != fnorm) {
752:     PetscInfo(snes,"Failed to converged, function norm is NaN\n");
753:     *reason = SNES_DIVERGED_FNORM_NAN;
754:   } else if (it == snes->max_its) {
755:     *reason = SNES_CONVERGED_ITS;
756:   }
757:   return(0);
758: }

760: /*@C
761:   SNESSetWorkVecs - Gets a number of work vectors.

763:   Input Parameters:
764: . snes  - the SNES context
765: . nw - number of work vectors to allocate

767:    Level: developer

769:    Developers Note: This is PETSC_EXTERN because it may be used by user written plugin SNES implementations

771: @*/
772: PetscErrorCode SNESSetWorkVecs(SNES snes,PetscInt nw)
773: {
774:   DM             dm;
775:   Vec            v;

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

782:   SNESGetDM(snes, &dm);
783:   DMGetGlobalVector(dm, &v);
784:   VecDuplicateVecs(v,snes->nwork,&snes->work);
785:   DMRestoreGlobalVector(dm, &v);
786:   PetscLogObjectParents(snes,nw,snes->work);
787:   return(0);
788: }