Date: 2022-03-04T17:39:21+00:00

Actual source code: snesut.c

      2: #include <petsc/private/snesimpl.h>
      3: #include <petscdm.h>
      4: #include <petscsection.h>
      5: #include <petscblaslapack.h>

      7: /*@C
      8:    SNESMonitorSolution - Monitors progress of the SNES solvers by calling
      9:    VecView() for the approximate solution at each iteration.

     11:    Collective on SNES

     13:    Input Parameters:
     14: +  snes - the SNES context
     15: .  its - iteration number
     16: .  fgnorm - 2-norm of residual
     17: -  dummy -  a viewer

     19:    Options Database Keys:
     20: .  -snes_monitor_solution [ascii binary draw][:filename][:viewer format] - plots solution at each iteration

     22:    Level: intermediate

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

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

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

     45:    Collective on SNES

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

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

     56:    Level: intermediate

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

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

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

     79:    Collective on SNES

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

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

     90:    Level: intermediate

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

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

    109: #include <petscdraw.h>

    111: /*@C
    112:   KSPMonitorSNESResidual - Prints the SNES residual norm, as well as the linear residual norm, at each iteration of an iterative solver.

    114:   Collective on ksp

    116:   Input Parameters:
    117: + ksp   - iterative context
    118: . n     - iteration number
    119: . rnorm - 2-norm (preconditioned) residual value (may be estimated).
    120: - vf    - The viewer context

    122:   Options Database Key:
    123: . -snes_monitor_ksp - Activates KSPMonitorSNESResidual()

    125:   Level: intermediate

    127: .seealso: KSPMonitorSet(), KSPMonitorResidual(),KSPMonitorTrueResidualMaxNorm()
    128: @*/
    129: PetscErrorCode KSPMonitorSNESResidual(KSP ksp, PetscInt n, PetscReal rnorm, PetscViewerAndFormat *vf)
    130: {
    131:   PetscViewer       viewer = vf->viewer;
    132:   PetscViewerFormat format = vf->format;
    133:   SNES              snes   = (SNES) vf->data;
    134:   Vec               snes_solution, work1, work2;
    135:   PetscReal         snorm;
    136:   PetscInt          tablevel;
    137:   const char       *prefix;
    138:   PetscErrorCode    ierr;

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

    152:   PetscObjectGetTabLevel((PetscObject) ksp, &tablevel);
    153:   PetscObjectGetOptionsPrefix((PetscObject) ksp, &prefix);
    154:   PetscViewerPushFormat(viewer, format);
    155:   PetscViewerASCIIAddTab(viewer, tablevel);
    156:   if (n == 0 && prefix) {PetscViewerASCIIPrintf(viewer, "  Residual norms for %s solve.\n", prefix);}
    157:   PetscViewerASCIIPrintf(viewer, "%3D SNES Residual norm %5.3e KSP Residual norm %5.3e \n", n, (double) snorm, (double) rnorm);
    158:   PetscViewerASCIISubtractTab(viewer, tablevel);
    159:   PetscViewerPopFormat(viewer);
    160:   return(0);
    161: }

    163: /*@C
    164:   KSPMonitorSNESResidualDrawLG - Plots the linear SNES residual norm at each iteration of an iterative solver.

    166:   Collective on ksp

    168:   Input Parameters:
    169: + ksp   - iterative context
    170: . n     - iteration number
    171: . rnorm - 2-norm (preconditioned) residual value (may be estimated).
    172: - vf    - The viewer context

    174:   Options Database Key:
    175: . -snes_monitor_ksp draw::draw_lg - Activates KSPMonitorSNESResidualDrawLG()

    177:   Level: intermediate

    179: .seealso: KSPMonitorSet(), KSPMonitorTrueResidual()
    180: @*/
    181: PetscErrorCode KSPMonitorSNESResidualDrawLG(KSP ksp, PetscInt n, PetscReal rnorm, PetscViewerAndFormat *vf)
    182: {
    183:   PetscViewer        viewer = vf->viewer;
    184:   PetscViewerFormat  format = vf->format;
    185:   PetscDrawLG        lg     = vf->lg;
    186:   SNES               snes   = (SNES) vf->data;
    187:   Vec                snes_solution, work1, work2;
    188:   PetscReal          snorm;
    189:   KSPConvergedReason reason;
    190:   PetscReal          x[2], y[2];
    191:   PetscErrorCode     ierr;

    196:   SNESGetSolution(snes, &snes_solution);
    197:   VecDuplicate(snes_solution, &work1);
    198:   VecDuplicate(snes_solution, &work2);
    199:   KSPBuildSolution(ksp, work1, NULL);
    200:   VecAYPX(work1, -1.0, snes_solution);
    201:   SNESComputeFunction(snes, work1, work2);
    202:   VecNorm(work2, NORM_2, &snorm);
    203:   VecDestroy(&work1);
    204:   VecDestroy(&work2);

    206:   PetscViewerPushFormat(viewer, format);
    207:   if (!n) {PetscDrawLGReset(lg);}
    208:   x[0] = (PetscReal) n;
    209:   if (rnorm > 0.0) y[0] = PetscLog10Real(rnorm);
    210:   else y[0] = -15.0;
    211:   x[1] = (PetscReal) n;
    212:   if (snorm > 0.0) y[1] = PetscLog10Real(snorm);
    213:   else y[1] = -15.0;
    214:   PetscDrawLGAddPoint(lg, x, y);
    215:   KSPGetConvergedReason(ksp, &reason);
    216:   if (n <= 20 || !(n % 5) || reason) {
    217:     PetscDrawLGDraw(lg);
    218:     PetscDrawLGSave(lg);
    219:   }
    220:   PetscViewerPopFormat(viewer);
    221:   return(0);
    222: }

    224: /*@C
    225:   KSPMonitorSNESResidualDrawLGCreate - Creates the plotter for the linear SNES residual.

    227:   Collective on ksp

    229:   Input Parameters:
    230: + viewer - The PetscViewer
    231: . format - The viewer format
    232: - ctx    - An optional user context

    234:   Output Parameter:
    235: . vf    - The viewer context

    237:   Level: intermediate

    239: .seealso: KSPMonitorSet(), KSPMonitorTrueResidual()
    240: @*/
    241: PetscErrorCode KSPMonitorSNESResidualDrawLGCreate(PetscViewer viewer, PetscViewerFormat format, void *ctx, PetscViewerAndFormat **vf)
    242: {
    243:   const char    *names[] = {"linear", "nonlinear"};

    247:   PetscViewerAndFormatCreate(viewer, format, vf);
    248:   (*vf)->data = ctx;
    249:   KSPMonitorLGCreate(PetscObjectComm((PetscObject) viewer), NULL, NULL, "Log Residual Norm", 2, names, PETSC_DECIDE, PETSC_DECIDE, 400, 300, &(*vf)->lg);
    250:   return(0);
    251: }

    253: PetscErrorCode SNESMonitorDefaultSetUp(SNES snes, PetscViewerAndFormat *vf)
    254: {

    258:   if (vf->format == PETSC_VIEWER_DRAW_LG) {
    259:     KSPMonitorLGCreate(PetscObjectComm((PetscObject) vf->viewer), NULL, NULL, "Log Residual Norm", 1, NULL, PETSC_DECIDE, PETSC_DECIDE, 400, 300, &vf->lg);
    260:   }
    261:   return(0);
    262: }

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

    267:    Collective on SNES

    269:    Input Parameters:
    270: +  snes - the SNES context
    271: .  its - iteration number
    272: .  fgnorm - 2-norm of residual
    273: -  vf - viewer and format structure

    275:    Notes:
    276:    This routine prints the residual norm at each iteration.

    278:    Level: intermediate

    280: .seealso: SNESMonitorSet(), SNESMonitorSolution()
    281: @*/
    282: PetscErrorCode  SNESMonitorDefault(SNES snes,PetscInt its,PetscReal fgnorm,PetscViewerAndFormat *vf)
    283: {
    284:   PetscViewer       viewer = vf->viewer;
    285:   PetscViewerFormat format = vf->format;
    286:   PetscBool         isascii, isdraw;
    287:   PetscErrorCode    ierr;

    291:   PetscObjectTypeCompare((PetscObject) viewer, PETSCVIEWERASCII, &isascii);
    292:   PetscObjectTypeCompare((PetscObject) viewer, PETSCVIEWERDRAW,  &isdraw);
    293:   PetscViewerPushFormat(viewer,format);
    294:   if (isascii) {
    295:     PetscViewerASCIIAddTab(viewer,((PetscObject)snes)->tablevel);
    296:     PetscViewerASCIIPrintf(viewer,"%3D SNES Function norm %14.12e \n",its,(double)fgnorm);
    297:     PetscViewerASCIISubtractTab(viewer,((PetscObject)snes)->tablevel);
    298:   } else if (isdraw) {
    299:     if (format == PETSC_VIEWER_DRAW_LG) {
    300:       PetscDrawLG lg = (PetscDrawLG) vf->lg;
    301:       PetscReal   x, y;

    304:       if (!its) {PetscDrawLGReset(lg);}
    305:       x = (PetscReal) its;
    306:       if (fgnorm > 0.0) y = PetscLog10Real(fgnorm);
    307:       else y = -15.0;
    308:       PetscDrawLGAddPoint(lg,&x,&y);
    309:       if (its <= 20 || !(its % 5) || snes->reason) {
    310:         PetscDrawLGDraw(lg);
    311:         PetscDrawLGSave(lg);
    312:       }
    313:     }
    314:   }
    315:   PetscViewerPopFormat(viewer);
    316:   return(0);
    317: }

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

    322:    Collective on SNES

    324:    Input Parameters:
    325: +  snes - the SNES context
    326: .  its - iteration number
    327: .  fgnorm - 2-norm of residual
    328: -  vf - viewer and format structure

    330:    Notes:
    331:    This routine prints the largest value in each row of the Jacobian

    333:    Level: intermediate

    335: .seealso: SNESMonitorSet(), SNESMonitorSolution()
    336: @*/
    337: PetscErrorCode  SNESMonitorScaling(SNES snes,PetscInt its,PetscReal fgnorm,PetscViewerAndFormat *vf)
    338: {
    340:   PetscViewer    viewer = vf->viewer;
    341:   KSP            ksp;
    342:   Mat            J;
    343:   Vec            v;

    347:   SNESGetKSP(snes,&ksp);
    348:   KSPGetOperators(ksp,&J,NULL);
    349:   MatCreateVecs(J,&v,NULL);
    350:   MatGetRowMaxAbs(J,v,NULL);
    351:   PetscViewerPushFormat(viewer,vf->format);
    352:   PetscViewerASCIIAddTab(viewer,((PetscObject)snes)->tablevel);
    353:   PetscViewerASCIIPrintf(viewer,"%3D SNES Jacobian maximum row entries \n");
    354:   VecView(v,viewer);
    355:   PetscViewerASCIISubtractTab(viewer,((PetscObject)snes)->tablevel);
    356:   PetscViewerPopFormat(viewer);
    357:   VecDestroy(&v);
    358:   return(0);
    359: }

    361: PetscErrorCode SNESMonitorJacUpdateSpectrum(SNES snes,PetscInt it,PetscReal fnorm,PetscViewerAndFormat *vf)
    362: {
    363:   Vec            X;
    364:   Mat            J,dJ,dJdense;
    366:   PetscErrorCode (*func)(SNES,Vec,Mat,Mat,void*);
    367:   PetscInt       n;
    368:   PetscBLASInt   nb = 0,lwork;
    369:   PetscReal      *eigr,*eigi;
    370:   PetscScalar    *work;
    371:   PetscScalar    *a;

    374:   if (it == 0) return(0);
    375:   /* create the difference between the current update and the current jacobian */
    376:   SNESGetSolution(snes,&X);
    377:   SNESGetJacobian(snes,NULL,&J,&func,NULL);
    378:   MatDuplicate(J,MAT_COPY_VALUES,&dJ);
    379:   SNESComputeJacobian(snes,X,dJ,dJ);
    380:   MatAXPY(dJ,-1.0,J,SAME_NONZERO_PATTERN);

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

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

    418: PetscErrorCode  SNESMonitorRange_Private(SNES snes,PetscInt it,PetscReal *per)
    419: {
    421:   Vec            resid;
    422:   PetscReal      rmax,pwork;
    423:   PetscInt       i,n,N;
    424:   PetscScalar    *r;

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

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

    445:    Collective on SNES

    447:    Input Parameters:
    448: +  snes   - iterative context
    449: .  it    - iteration number
    450: .  rnorm - 2-norm (preconditioned) residual value (may be estimated).
    451: -  dummy - unused monitor context

    453:    Options Database Key:
    454: .  -snes_monitor_range - Activates SNESMonitorRange()

    456:    Level: intermediate

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

    470:   if (!it) prev = rnorm;
    471:   SNESMonitorRange_Private(snes,it,&perc);

    473:   rel  = (prev - rnorm)/prev;
    474:   prev = rnorm;
    475:   PetscViewerPushFormat(viewer,vf->format);
    476:   PetscViewerASCIIAddTab(viewer,((PetscObject)snes)->tablevel);
    477:   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));
    478:   PetscViewerASCIISubtractTab(viewer,((PetscObject)snes)->tablevel);
    479:   PetscViewerPopFormat(viewer);
    480:   return(0);
    481: }

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

    487:    Collective on SNES

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

    495:    Level: intermediate

    497:    Notes:
    498:     Insure that SNESMonitorRatio() is called when you set this monitor
    499: .seealso: SNESMonitorSet(), SNESMonitorSolution(), SNESMonitorRatio()
    500: @*/
    501: PetscErrorCode  SNESMonitorRatio(SNES snes,PetscInt its,PetscReal fgnorm,PetscViewerAndFormat *vf)
    502: {
    503:   PetscErrorCode          ierr;
    504:   PetscInt                len;
    505:   PetscReal               *history;
    506:   PetscViewer             viewer = vf->viewer;

    509:   SNESGetConvergenceHistory(snes,&history,NULL,&len);
    510:   PetscViewerPushFormat(viewer,vf->format);
    511:   PetscViewerASCIIAddTab(viewer,((PetscObject)snes)->tablevel);
    512:   if (!its || !history || its > len) {
    513:     PetscViewerASCIIPrintf(viewer,"%3D SNES Function norm %14.12e \n",its,(double)fgnorm);
    514:   } else {
    515:     PetscReal ratio = fgnorm/history[its-1];
    516:     PetscViewerASCIIPrintf(viewer,"%3D SNES Function norm %14.12e %14.12e \n",its,(double)fgnorm,(double)ratio);
    517:   }
    518:   PetscViewerASCIISubtractTab(viewer,((PetscObject)snes)->tablevel);
    519:   PetscViewerPopFormat(viewer);
    520:   return(0);
    521: }

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

    526:    Collective on SNES

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

    532:    Level: intermediate

    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.

    557:   Deprecated: Intentionally has no manual page
    558: */
    559: PetscErrorCode  SNESMonitorDefaultShort(SNES snes,PetscInt its,PetscReal fgnorm,PetscViewerAndFormat *vf)
    560: {
    562:   PetscViewer    viewer = vf->viewer;

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

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

    583:   Collective on SNES

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

    591:   Notes:
    592:   This routine uses the DM attached to the residual vector

    594:   Level: intermediate

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

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

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

    641:    Collective on SNES

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

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

    661:    where
    662: +    maxf - maximum number of function evaluations,  set with SNESSetTolerances()
    663: .    nfct - number of function evaluations,
    664: .    abstol - absolute function norm tolerance, set with SNESSetTolerances()
    665: .    rtol - relative function norm tolerance, set with SNESSetTolerances()
    666: .    divtol - divergence tolerance, set with SNESSetDivergenceTolerance()
    667: -    fnorm0 - 2-norm of the function at the initial solution (initial guess; zeroth iteration)

    669:   Options Database Keys:
    670: +  -snes_stol - convergence tolerance in terms of the norm  of the change in the solution between steps
    671: .  -snes_atol <abstol> - absolute tolerance of residual norm
    672: .  -snes_rtol <rtol> - relative decrease in tolerance norm from the initial 2-norm of the solution
    673: .  -snes_divergence_tolerance <divtol> - if the residual goes above divtol*rnorm0, exit with divergence
    674: .  -snes_max_funcs <max_funcs> - maximum number of function evaluations
    675: .  -snes_max_fail <max_fail> - maximum number of line search failures allowed before stopping, default is none
    676: -  -snes_max_linear_solve_fail - number of linear solver failures before SNESSolve() stops

    678:    Level: intermediate

    680: .seealso: SNESSetConvergenceTest(), SNESConvergedSkip(), SNESSetTolerances(), SNESSetDivergenceTolerance()
    681: @*/
    682: PetscErrorCode  SNESConvergedDefault(SNES snes,PetscInt it,PetscReal xnorm,PetscReal snorm,PetscReal fnorm,SNESConvergedReason *reason,void *dummy)
    683: {

    690:   *reason = SNES_CONVERGED_ITERATING;

    692:   if (!it) {
    693:     /* set parameter for default relative tolerance convergence test */
    694:     snes->ttol   = fnorm*snes->rtol;
    695:     snes->rnorm0 = fnorm;
    696:   }
    697:   if (PetscIsInfOrNanReal(fnorm)) {
    698:     PetscInfo(snes,"Failed to converged, function norm is NaN\n");
    699:     *reason = SNES_DIVERGED_FNORM_NAN;
    700:   } else if (fnorm < snes->abstol && (it || !snes->forceiteration)) {
    701:     PetscInfo2(snes,"Converged due to function norm %14.12e < %14.12e\n",(double)fnorm,(double)snes->abstol);
    702:     *reason = SNES_CONVERGED_FNORM_ABS;
    703:   } else if (snes->nfuncs >= snes->max_funcs && snes->max_funcs >= 0) {
    704:     PetscInfo2(snes,"Exceeded maximum number of function evaluations: %D > %D\n",snes->nfuncs,snes->max_funcs);
    705:     *reason = SNES_DIVERGED_FUNCTION_COUNT;
    706:   }

    708:   if (it && !*reason) {
    709:     if (fnorm <= snes->ttol) {
    710:       PetscInfo2(snes,"Converged due to function norm %14.12e < %14.12e (relative tolerance)\n",(double)fnorm,(double)snes->ttol);
    711:       *reason = SNES_CONVERGED_FNORM_RELATIVE;
    712:     } else if (snorm < snes->stol*xnorm) {
    713:       PetscInfo3(snes,"Converged due to small update length: %14.12e < %14.12e * %14.12e\n",(double)snorm,(double)snes->stol,(double)xnorm);
    714:       *reason = SNES_CONVERGED_SNORM_RELATIVE;
    715:     } else if (snes->divtol > 0 && (fnorm > snes->divtol*snes->rnorm0)) {
    716:       PetscInfo3(snes,"Diverged due to increase in function norm: %14.12e > %14.12e * %14.12e\n",(double)fnorm,(double)snes->divtol,(double)snes->rnorm0);
    717:       *reason = SNES_DIVERGED_DTOL;
    718:     }

    720:   }
    721:   return(0);
    722: }

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

    728:    Logically Collective on SNES

    730:    Input Parameters:
    731: +  snes - the SNES context
    732: .  it - the iteration (0 indicates before any Newton steps)
    733: .  xnorm - 2-norm of current iterate
    734: .  snorm - 2-norm of current step
    735: .  fnorm - 2-norm of function at current iterate
    736: -  dummy - unused context

    738:    Output Parameter:
    739: .   reason  - SNES_CONVERGED_ITERATING, SNES_CONVERGED_ITS, or SNES_DIVERGED_FNORM_NAN

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

    744:    Level: advanced

    746: .seealso: SNESConvergedDefault(), SNESSetConvergenceTest()
    747: @*/
    748: PetscErrorCode  SNESConvergedSkip(SNES snes,PetscInt it,PetscReal xnorm,PetscReal snorm,PetscReal fnorm,SNESConvergedReason *reason,void *dummy)
    749: {

    756:   *reason = SNES_CONVERGED_ITERATING;

    758:   if (fnorm != fnorm) {
    759:     PetscInfo(snes,"Failed to converged, function norm is NaN\n");
    760:     *reason = SNES_DIVERGED_FNORM_NAN;
    761:   } else if (it == snes->max_its) {
    762:     *reason = SNES_CONVERGED_ITS;
    763:   }
    764:   return(0);
    765: }

    767: /*@C
    768:   SNESSetWorkVecs - Gets a number of work vectors.

    770:   Input Parameters:
    771: + snes  - the SNES context
    772: - nw - number of work vectors to allocate

    774:   Level: developer

    776: @*/
    777: PetscErrorCode SNESSetWorkVecs(SNES snes,PetscInt nw)
    778: {
    779:   DM             dm;
    780:   Vec            v;

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

    787:   SNESGetDM(snes, &dm);
    788:   DMGetGlobalVector(dm, &v);
    789:   VecDuplicateVecs(v,snes->nwork,&snes->work);
    790:   DMRestoreGlobalVector(dm, &v);
    791:   PetscLogObjectParents(snes,nw,snes->work);
    792:   return(0);
    793: }