Actual source code: snes.c
petsc-3.10.5 2019-03-28
Report Typos and Errors

      1:  #include <petsc/private/snesimpl.h>
      2:  #include <petscdmshell.h>
      3:  #include <petscdraw.h>
      4:  #include <petscds.h>
      5:  #include <petscdmadaptor.h>
      6:  #include <petscconvest.h>

      8: PetscBool         SNESRegisterAllCalled = PETSC_FALSE;
      9: PetscFunctionList SNESList              = NULL;

     11: /* Logging support */
     12: PetscClassId  SNES_CLASSID, DMSNES_CLASSID;
     13: PetscLogEvent SNES_Solve, SNES_FunctionEval, SNES_JacobianEval, SNES_NGSEval, SNES_NGSFuncEval, SNES_NPCSolve, SNES_ObjectiveEval;

     15: /*@
     16:    SNESSetErrorIfNotConverged - Causes SNESSolve() to generate an error if the solver has not converged.

     18:    Logically Collective on SNES

     20:    Input Parameters:
     21: +  snes - iterative context obtained from SNESCreate()
     22: -  flg - PETSC_TRUE indicates you want the error generated

     24:    Options database keys:
     25: .  -snes_error_if_not_converged : this takes an optional truth value (0/1/no/yes/true/false)

     27:    Level: intermediate

     29:    Notes:
     30:     Normally PETSc continues if a linear solver fails to converge, you can call SNESGetConvergedReason() after a SNESSolve()
     31:     to determine if it has converged.

     33: .keywords: SNES, set, initial guess, nonzero

     35: .seealso: SNESGetErrorIfNotConverged(), KSPGetErrorIfNotConverged(), KSPSetErrorIFNotConverged()
     36: @*/
     37: PetscErrorCode  SNESSetErrorIfNotConverged(SNES snes,PetscBool flg)
     38: {
     42:   snes->errorifnotconverged = flg;
     43:   return(0);
     44: }

     46: /*@
     47:    SNESGetErrorIfNotConverged - Will SNESSolve() generate an error if the solver does not converge?

     49:    Not Collective

     51:    Input Parameter:
     52: .  snes - iterative context obtained from SNESCreate()

     54:    Output Parameter:
     55: .  flag - PETSC_TRUE if it will generate an error, else PETSC_FALSE

     57:    Level: intermediate

     59: .keywords: SNES, set, initial guess, nonzero

     61: .seealso:  SNESSetErrorIfNotConverged(), KSPGetErrorIfNotConverged(), KSPSetErrorIFNotConverged()
     62: @*/
     63: PetscErrorCode  SNESGetErrorIfNotConverged(SNES snes,PetscBool  *flag)
     64: {
     68:   *flag = snes->errorifnotconverged;
     69:   return(0);
     70: }

     72: /*@
     73:     SNESSetAlwaysComputesFinalResidual - does the SNES always compute the residual at the final solution?

     75:    Logically Collective on SNES

     77:     Input Parameters:
     78: +   snes - the shell SNES
     79: -   flg - is the residual computed?

     81:    Level: advanced

     83: .seealso: SNESGetAlwaysComputesFinalResidual()
     84: @*/
     85: PetscErrorCode  SNESSetAlwaysComputesFinalResidual(SNES snes, PetscBool flg)
     86: {
     89:   snes->alwayscomputesfinalresidual = flg;
     90:   return(0);
     91: }

     93: /*@
     94:     SNESGetAlwaysComputesFinalResidual - does the SNES always compute the residual at the final solution?

     96:    Logically Collective on SNES

     98:     Input Parameter:
     99: .   snes - the shell SNES

    101:     Output Parameter:
    102: .   flg - is the residual computed?

    104:    Level: advanced

    106: .seealso: SNESSetAlwaysComputesFinalResidual()
    107: @*/
    108: PetscErrorCode  SNESGetAlwaysComputesFinalResidual(SNES snes, PetscBool *flg)
    109: {
    112:   *flg = snes->alwayscomputesfinalresidual;
    113:   return(0);
    114: }

    116: /*@
    117:    SNESSetFunctionDomainError - tells SNES that the input vector to your SNESFunction is not
    118:      in the functions domain. For example, negative pressure.

    120:    Logically Collective on SNES

    122:    Input Parameters:
    123: .  snes - the SNES context

    125:    Level: advanced

    127: .keywords: SNES, view

    129: .seealso: SNESCreate(), SNESSetFunction(), SNESFunction
    130: @*/
    131: PetscErrorCode  SNESSetFunctionDomainError(SNES snes)
    132: {
    135:   if (snes->errorifnotconverged) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"User code indicates input vector is not in the function domain");
    136:   snes->domainerror = PETSC_TRUE;
    137:   return(0);
    138: }

    140: /*@
    141:    SNESGetFunctionDomainError - Gets the status of the domain error after a call to SNESComputeFunction;

    143:    Logically Collective on SNES

    145:    Input Parameters:
    146: .  snes - the SNES context

    148:    Output Parameters:
    149: .  domainerror - Set to PETSC_TRUE if there's a domain error; PETSC_FALSE otherwise.

    151:    Level: advanced

    153: .keywords: SNES, view

    155: .seealso: SNESSetFunctionDomainError(), SNESComputeFunction()
    156: @*/
    157: PetscErrorCode  SNESGetFunctionDomainError(SNES snes, PetscBool *domainerror)
    158: {
    162:   *domainerror = snes->domainerror;
    163:   return(0);
    164: }

    166: /*@C
    167:   SNESLoad - Loads a SNES that has been stored in binary  with SNESView().

    169:   Collective on PetscViewer

    171:   Input Parameters:
    172: + newdm - the newly loaded SNES, this needs to have been created with SNESCreate() or
    173:            some related function before a call to SNESLoad().
    174: - viewer - binary file viewer, obtained from PetscViewerBinaryOpen()

    176:    Level: intermediate

    178:   Notes:
    179:    The type is determined by the data in the file, any type set into the SNES before this call is ignored.

    181:   Notes for advanced users:
    182:   Most users should not need to know the details of the binary storage
    183:   format, since SNESLoad() and TSView() completely hide these details.
    184:   But for anyone who's interested, the standard binary matrix storage
    185:   format is
    186: .vb
    187:      has not yet been determined
    188: .ve

    190: .seealso: PetscViewerBinaryOpen(), SNESView(), MatLoad(), VecLoad()
    191: @*/
    192: PetscErrorCode  SNESLoad(SNES snes, PetscViewer viewer)
    193: {
    195:   PetscBool      isbinary;
    196:   PetscInt       classid;
    197:   char           type[256];
    198:   KSP            ksp;
    199:   DM             dm;
    200:   DMSNES         dmsnes;

    205:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&isbinary);
    206:   if (!isbinary) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Invalid viewer; open viewer with PetscViewerBinaryOpen()");

    208:   PetscViewerBinaryRead(viewer,&classid,1,NULL,PETSC_INT);
    209:   if (classid != SNES_FILE_CLASSID) SETERRQ(PetscObjectComm((PetscObject)snes),PETSC_ERR_ARG_WRONG,"Not SNES next in file");
    210:   PetscViewerBinaryRead(viewer,type,256,NULL,PETSC_CHAR);
    211:   SNESSetType(snes, type);
    212:   if (snes->ops->load) {
    213:     (*snes->ops->load)(snes,viewer);
    214:   }
    215:   SNESGetDM(snes,&dm);
    216:   DMGetDMSNES(dm,&dmsnes);
    217:   DMSNESLoad(dmsnes,viewer);
    218:   SNESGetKSP(snes,&ksp);
    219:   KSPLoad(ksp,viewer);
    220:   return(0);
    221: }

    223:  #include <petscdraw.h>
    224: #if defined(PETSC_HAVE_SAWS)
    225:  #include <petscviewersaws.h>
    226: #endif

    228: /*@C
    229:    SNESView - Prints the SNES data structure.

    231:    Collective on SNES

    233:    Input Parameters:
    234: +  SNES - the SNES context
    235: -  viewer - visualization context

    237:    Options Database Key:
    238: .  -snes_view - Calls SNESView() at end of SNESSolve()

    240:    Notes:
    241:    The available visualization contexts include
    242: +     PETSC_VIEWER_STDOUT_SELF - standard output (default)
    243: -     PETSC_VIEWER_STDOUT_WORLD - synchronized standard
    244:          output where only the first processor opens
    245:          the file.  All other processors send their
    246:          data to the first processor to print.

    248:    The user can open an alternative visualization context with
    249:    PetscViewerASCIIOpen() - output to a specified file.

    251:    Level: beginner

    253: .keywords: SNES, view

    255: .seealso: PetscViewerASCIIOpen()
    256: @*/
    257: PetscErrorCode  SNESView(SNES snes,PetscViewer viewer)
    258: {
    259:   SNESKSPEW      *kctx;
    261:   KSP            ksp;
    262:   SNESLineSearch linesearch;
    263:   PetscBool      iascii,isstring,isbinary,isdraw;
    264:   DMSNES         dmsnes;
    265: #if defined(PETSC_HAVE_SAWS)
    266:   PetscBool      issaws;
    267: #endif

    271:   if (!viewer) {
    272:     PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)snes),&viewer);
    273:   }

    277:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
    278:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERSTRING,&isstring);
    279:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&isbinary);
    280:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERDRAW,&isdraw);
    281: #if defined(PETSC_HAVE_SAWS)
    282:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERSAWS,&issaws);
    283: #endif
    284:   if (iascii) {
    285:     SNESNormSchedule normschedule;
    286:     DM               dm;
    287:     PetscErrorCode   (*cJ)(SNES,Vec,Mat,Mat,void*);
    288:     void             *ctx;

    290:     PetscObjectPrintClassNamePrefixType((PetscObject)snes,viewer);
    291:     if (!snes->setupcalled) {
    292:       PetscViewerASCIIPrintf(viewer,"  SNES has not been set up so information may be incomplete\n");
    293:     }
    294:     if (snes->ops->view) {
    295:       PetscViewerASCIIPushTab(viewer);
    296:       (*snes->ops->view)(snes,viewer);
    297:       PetscViewerASCIIPopTab(viewer);
    298:     }
    299:     PetscViewerASCIIPrintf(viewer,"  maximum iterations=%D, maximum function evaluations=%D\n",snes->max_its,snes->max_funcs);
    300:     PetscViewerASCIIPrintf(viewer,"  tolerances: relative=%g, absolute=%g, solution=%g\n",(double)snes->rtol,(double)snes->abstol,(double)snes->stol);
    301:     if (snes->usesksp) {
    302:       PetscViewerASCIIPrintf(viewer,"  total number of linear solver iterations=%D\n",snes->linear_its);
    303:     }
    304:     PetscViewerASCIIPrintf(viewer,"  total number of function evaluations=%D\n",snes->nfuncs);
    305:     SNESGetNormSchedule(snes, &normschedule);
    306:     if (normschedule > 0) {PetscViewerASCIIPrintf(viewer,"  norm schedule %s\n",SNESNormSchedules[normschedule]);}
    307:     if (snes->gridsequence) {
    308:       PetscViewerASCIIPrintf(viewer,"  total number of grid sequence refinements=%D\n",snes->gridsequence);
    309:     }
    310:     if (snes->ksp_ewconv) {
    311:       kctx = (SNESKSPEW*)snes->kspconvctx;
    312:       if (kctx) {
    313:         PetscViewerASCIIPrintf(viewer,"  Eisenstat-Walker computation of KSP relative tolerance (version %D)\n",kctx->version);
    314:         PetscViewerASCIIPrintf(viewer,"    rtol_0=%g, rtol_max=%g, threshold=%g\n",(double)kctx->rtol_0,(double)kctx->rtol_max,(double)kctx->threshold);
    315:         PetscViewerASCIIPrintf(viewer,"    gamma=%g, alpha=%g, alpha2=%g\n",(double)kctx->gamma,(double)kctx->alpha,(double)kctx->alpha2);
    316:       }
    317:     }
    318:     if (snes->lagpreconditioner == -1) {
    319:       PetscViewerASCIIPrintf(viewer,"  Preconditioned is never rebuilt\n");
    320:     } else if (snes->lagpreconditioner > 1) {
    321:       PetscViewerASCIIPrintf(viewer,"  Preconditioned is rebuilt every %D new Jacobians\n",snes->lagpreconditioner);
    322:     }
    323:     if (snes->lagjacobian == -1) {
    324:       PetscViewerASCIIPrintf(viewer,"  Jacobian is never rebuilt\n");
    325:     } else if (snes->lagjacobian > 1) {
    326:       PetscViewerASCIIPrintf(viewer,"  Jacobian is rebuilt every %D SNES iterations\n",snes->lagjacobian);
    327:     }
    328:     SNESGetDM(snes,&dm);
    329:     DMSNESGetJacobian(dm,&cJ,&ctx);
    330:     if (cJ == SNESComputeJacobianDefault) {
    331:       PetscViewerASCIIPrintf(viewer,"  Jacobian is built using finite differences one column at a time\n");
    332:     } else if (cJ == SNESComputeJacobianDefaultColor) {
    333:       PetscViewerASCIIPrintf(viewer,"  Jacobian is built using finite differences with coloring\n");
    334:     }
    335:   } else if (isstring) {
    336:     const char *type;
    337:     SNESGetType(snes,&type);
    338:     PetscViewerStringSPrintf(viewer," %-3.3s",type);
    339:   } else if (isbinary) {
    340:     PetscInt    classid = SNES_FILE_CLASSID;
    341:     MPI_Comm    comm;
    342:     PetscMPIInt rank;
    343:     char        type[256];

    345:     PetscObjectGetComm((PetscObject)snes,&comm);
    346:     MPI_Comm_rank(comm,&rank);
    347:     if (!rank) {
    348:       PetscViewerBinaryWrite(viewer,&classid,1,PETSC_INT,PETSC_FALSE);
    349:       PetscStrncpy(type,((PetscObject)snes)->type_name,sizeof(type));
    350:       PetscViewerBinaryWrite(viewer,type,sizeof(type),PETSC_CHAR,PETSC_FALSE);
    351:     }
    352:     if (snes->ops->view) {
    353:       (*snes->ops->view)(snes,viewer);
    354:     }
    355:   } else if (isdraw) {
    356:     PetscDraw draw;
    357:     char      str[36];
    358:     PetscReal x,y,bottom,h;

    360:     PetscViewerDrawGetDraw(viewer,0,&draw);
    361:     PetscDrawGetCurrentPoint(draw,&x,&y);
    362:     PetscStrncpy(str,"SNES: ",sizeof(str));
    363:     PetscStrlcat(str,((PetscObject)snes)->type_name,sizeof(str));
    364:     PetscDrawStringBoxed(draw,x,y,PETSC_DRAW_BLUE,PETSC_DRAW_BLACK,str,NULL,&h);
    365:     bottom = y - h;
    366:     PetscDrawPushCurrentPoint(draw,x,bottom);
    367:     if (snes->ops->view) {
    368:       (*snes->ops->view)(snes,viewer);
    369:     }
    370: #if defined(PETSC_HAVE_SAWS)
    371:   } else if (issaws) {
    372:     PetscMPIInt rank;
    373:     const char *name;

    375:     PetscObjectGetName((PetscObject)snes,&name);
    376:     MPI_Comm_rank(PETSC_COMM_WORLD,&rank);
    377:     if (!((PetscObject)snes)->amsmem && !rank) {
    378:       char       dir[1024];

    380:       PetscObjectViewSAWs((PetscObject)snes,viewer);
    381:       PetscSNPrintf(dir,1024,"/PETSc/Objects/%s/its",name);
    382:       PetscStackCallSAWs(SAWs_Register,(dir,&snes->iter,1,SAWs_READ,SAWs_INT));
    383:       if (!snes->conv_hist) {
    384:         SNESSetConvergenceHistory(snes,NULL,NULL,PETSC_DECIDE,PETSC_TRUE);
    385:       }
    386:       PetscSNPrintf(dir,1024,"/PETSc/Objects/%s/conv_hist",name);
    387:       PetscStackCallSAWs(SAWs_Register,(dir,snes->conv_hist,10,SAWs_READ,SAWs_DOUBLE));
    388:     }
    389: #endif
    390:   }
    391:   if (snes->linesearch) {
    392:     SNESGetLineSearch(snes, &linesearch);
    393:     PetscViewerASCIIPushTab(viewer);
    394:     SNESLineSearchView(linesearch, viewer);
    395:     PetscViewerASCIIPopTab(viewer);
    396:   }
    397:   if (snes->npc && snes->usesnpc) {
    398:     PetscViewerASCIIPushTab(viewer);
    399:     SNESView(snes->npc, viewer);
    400:     PetscViewerASCIIPopTab(viewer);
    401:   }
    402:   PetscViewerASCIIPushTab(viewer);
    403:   DMGetDMSNES(snes->dm,&dmsnes);
    404:   DMSNESView(dmsnes, viewer);
    405:   PetscViewerASCIIPopTab(viewer);
    406:   if (snes->usesksp) {
    407:     SNESGetKSP(snes,&ksp);
    408:     PetscViewerASCIIPushTab(viewer);
    409:     KSPView(ksp,viewer);
    410:     PetscViewerASCIIPopTab(viewer);
    411:   }
    412:   if (isdraw) {
    413:     PetscDraw draw;
    414:     PetscViewerDrawGetDraw(viewer,0,&draw);
    415:     PetscDrawPopCurrentPoint(draw);
    416:   }
    417:   return(0);
    418: }

    420: /*
    421:   We retain a list of functions that also take SNES command
    422:   line options. These are called at the end SNESSetFromOptions()
    423: */
    424: #define MAXSETFROMOPTIONS 5
    425: static PetscInt numberofsetfromoptions;
    426: static PetscErrorCode (*othersetfromoptions[MAXSETFROMOPTIONS])(SNES);

    428: /*@C
    429:   SNESAddOptionsChecker - Adds an additional function to check for SNES options.

    431:   Not Collective

    433:   Input Parameter:
    434: . snescheck - function that checks for options

    436:   Level: developer

    438: .seealso: SNESSetFromOptions()
    439: @*/
    440: PetscErrorCode  SNESAddOptionsChecker(PetscErrorCode (*snescheck)(SNES))
    441: {
    443:   if (numberofsetfromoptions >= MAXSETFROMOPTIONS) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE, "Too many options checkers, only %D allowed", MAXSETFROMOPTIONS);
    444:   othersetfromoptions[numberofsetfromoptions++] = snescheck;
    445:   return(0);
    446: }

    448: PETSC_INTERN PetscErrorCode SNESDefaultMatrixFreeCreate2(SNES,Vec,Mat*);

    450: static PetscErrorCode SNESSetUpMatrixFree_Private(SNES snes, PetscBool hasOperator, PetscInt version)
    451: {
    452:   Mat            J;
    453:   KSP            ksp;
    454:   PC             pc;
    455:   PetscBool      match;
    457:   MatNullSpace   nullsp;

    462:   if (!snes->vec_func && (snes->jacobian || snes->jacobian_pre)) {
    463:     Mat A = snes->jacobian, B = snes->jacobian_pre;
    464:     MatCreateVecs(A ? A : B, NULL,&snes->vec_func);
    465:   }

    467:   if (version == 1) {
    468:     MatCreateSNESMF(snes,&J);
    469:     MatMFFDSetOptionsPrefix(J,((PetscObject)snes)->prefix);
    470:     MatSetFromOptions(J);
    471:   } else if (version == 2) {
    472:     if (!snes->vec_func) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"SNESSetFunction() must be called first");
    473: #if !defined(PETSC_USE_COMPLEX) && !defined(PETSC_USE_REAL_SINGLE) && !defined(PETSC_USE_REAL___FLOAT128) && !defined(PETSC_USE_REAL___FP16)
    474:     SNESDefaultMatrixFreeCreate2(snes,snes->vec_func,&J);
    475: #else
    476:     SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP, "matrix-free operator rutines (version 2)");
    477: #endif
    478:   } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE, "matrix-free operator rutines, only version 1 and 2");

    480:   /* attach any user provided null space that was on Amat to the newly created matrix free matrix */
    481:   if (snes->jacobian) {
    482:     MatGetNullSpace(snes->jacobian,&nullsp);
    483:     if (nullsp) {
    484:       MatSetNullSpace(J,nullsp);
    485:     }
    486:   }

    488:   PetscInfo1(snes,"Setting default matrix-free operator routines (version %D)\n", version);
    489:   if (hasOperator) {

    491:     /* This version replaces the user provided Jacobian matrix with a
    492:        matrix-free version but still employs the user-provided preconditioner matrix. */
    493:     SNESSetJacobian(snes,J,0,0,0);
    494:   } else {
    495:     /* This version replaces both the user-provided Jacobian and the user-
    496:      provided preconditioner Jacobian with the default matrix free version. */
    497:     if ((snes->npcside== PC_LEFT) && snes->npc) {
    498:       if (!snes->jacobian){SNESSetJacobian(snes,J,0,0,0);}
    499:     } else {
    500:       SNESSetJacobian(snes,J,J,MatMFFDComputeJacobian,0);
    501:     }
    502:     /* Force no preconditioner */
    503:     SNESGetKSP(snes,&ksp);
    504:     KSPGetPC(ksp,&pc);
    505:     PetscObjectTypeCompare((PetscObject)pc,PCSHELL,&match);
    506:     if (!match) {
    507:       PetscInfo(snes,"Setting default matrix-free preconditioner routines\nThat is no preconditioner is being used\n");
    508:       PCSetType(pc,PCNONE);
    509:     }
    510:   }
    511:   MatDestroy(&J);
    512:   return(0);
    513: }

    515: static PetscErrorCode DMRestrictHook_SNESVecSol(DM dmfine,Mat Restrict,Vec Rscale,Mat Inject,DM dmcoarse,void *ctx)
    516: {
    517:   SNES           snes = (SNES)ctx;
    519:   Vec            Xfine,Xfine_named = NULL,Xcoarse;

    522:   if (PetscLogPrintInfo) {
    523:     PetscInt finelevel,coarselevel,fineclevel,coarseclevel;
    524:     DMGetRefineLevel(dmfine,&finelevel);
    525:     DMGetCoarsenLevel(dmfine,&fineclevel);
    526:     DMGetRefineLevel(dmcoarse,&coarselevel);
    527:     DMGetCoarsenLevel(dmcoarse,&coarseclevel);
    528:     PetscInfo4(dmfine,"Restricting SNES solution vector from level %D-%D to level %D-%D\n",finelevel,fineclevel,coarselevel,coarseclevel);
    529:   }
    530:   if (dmfine == snes->dm) Xfine = snes->vec_sol;
    531:   else {
    532:     DMGetNamedGlobalVector(dmfine,"SNESVecSol",&Xfine_named);
    533:     Xfine = Xfine_named;
    534:   }
    535:   DMGetNamedGlobalVector(dmcoarse,"SNESVecSol",&Xcoarse);
    536:   if (Inject) {
    537:     MatRestrict(Inject,Xfine,Xcoarse);
    538:   } else {
    539:     MatRestrict(Restrict,Xfine,Xcoarse);
    540:     VecPointwiseMult(Xcoarse,Xcoarse,Rscale);
    541:   }
    542:   DMRestoreNamedGlobalVector(dmcoarse,"SNESVecSol",&Xcoarse);
    543:   if (Xfine_named) {DMRestoreNamedGlobalVector(dmfine,"SNESVecSol",&Xfine_named);}
    544:   return(0);
    545: }

    547: static PetscErrorCode DMCoarsenHook_SNESVecSol(DM dm,DM dmc,void *ctx)
    548: {

    552:   DMCoarsenHookAdd(dmc,DMCoarsenHook_SNESVecSol,DMRestrictHook_SNESVecSol,ctx);
    553:   return(0);
    554: }

    556: /* This may be called to rediscretize the operator on levels of linear multigrid. The DM shuffle is so the user can
    557:  * safely call SNESGetDM() in their residual evaluation routine. */
    558: static PetscErrorCode KSPComputeOperators_SNES(KSP ksp,Mat A,Mat B,void *ctx)
    559: {
    560:   SNES           snes = (SNES)ctx;
    562:   Mat            Asave = A,Bsave = B;
    563:   Vec            X,Xnamed = NULL;
    564:   DM             dmsave;
    565:   void           *ctxsave;
    566:   PetscErrorCode (*jac)(SNES,Vec,Mat,Mat,void*) = NULL;

    569:   dmsave = snes->dm;
    570:   KSPGetDM(ksp,&snes->dm);
    571:   if (dmsave == snes->dm) X = snes->vec_sol; /* We are on the finest level */
    572:   else {                                     /* We are on a coarser level, this vec was initialized using a DM restrict hook */
    573:     DMGetNamedGlobalVector(snes->dm,"SNESVecSol",&Xnamed);
    574:     X    = Xnamed;
    575:     SNESGetJacobian(snes,NULL,NULL,&jac,&ctxsave);
    576:     /* If the DM's don't match up, the MatFDColoring context needed for the jacobian won't match up either -- fixit. */
    577:     if (jac == SNESComputeJacobianDefaultColor) {
    578:       SNESSetJacobian(snes,NULL,NULL,SNESComputeJacobianDefaultColor,0);
    579:     }
    580:   }
    581:   /* put the previous context back */

    583:   SNESComputeJacobian(snes,X,A,B);
    584:   if (snes->dm != dmsave && jac == SNESComputeJacobianDefaultColor) {
    585:     SNESSetJacobian(snes,NULL,NULL,jac,ctxsave);
    586:   }

    588:   if (A != Asave || B != Bsave) SETERRQ(PetscObjectComm((PetscObject)snes),PETSC_ERR_SUP,"No support for changing matrices at this time");
    589:   if (Xnamed) {
    590:     DMRestoreNamedGlobalVector(snes->dm,"SNESVecSol",&Xnamed);
    591:   }
    592:   snes->dm = dmsave;
    593:   return(0);
    594: }

    596: /*@
    597:    SNESSetUpMatrices - ensures that matrices are available for SNES, to be called by SNESSetUp_XXX()

    599:    Collective

    601:    Input Arguments:
    602: .  snes - snes to configure

    604:    Level: developer

    606: .seealso: SNESSetUp()
    607: @*/
    608: PetscErrorCode SNESSetUpMatrices(SNES snes)
    609: {
    611:   DM             dm;
    612:   DMSNES         sdm;

    615:   SNESGetDM(snes,&dm);
    616:   DMGetDMSNES(dm,&sdm);
    617:   if (!sdm->ops->computejacobian) SETERRQ(PetscObjectComm((PetscObject)snes),PETSC_ERR_PLIB,"DMSNES not properly configured");
    618:   else if (!snes->jacobian && snes->mf) {
    619:     Mat  J;
    620:     void *functx;
    621:     MatCreateSNESMF(snes,&J);
    622:     MatMFFDSetOptionsPrefix(J,((PetscObject)snes)->prefix);
    623:     MatSetFromOptions(J);
    624:     SNESGetFunction(snes,NULL,NULL,&functx);
    625:     SNESSetJacobian(snes,J,J,0,0);
    626:     MatDestroy(&J);
    627:   } else if (snes->mf_operator && !snes->jacobian_pre && !snes->jacobian) {
    628:     Mat J,B;
    629:     MatCreateSNESMF(snes,&J);
    630:     MatMFFDSetOptionsPrefix(J,((PetscObject)snes)->prefix);
    631:     MatSetFromOptions(J);
    632:     DMCreateMatrix(snes->dm,&B);
    633:     /* sdm->computejacobian was already set to reach here */
    634:     SNESSetJacobian(snes,J,B,NULL,NULL);
    635:     MatDestroy(&J);
    636:     MatDestroy(&B);
    637:   } else if (!snes->jacobian_pre) {
    638:     PetscErrorCode (*nspconstr)(DM, PetscInt, MatNullSpace *);
    639:     PetscDS          prob;
    640:     Mat              J, B;
    641:     MatNullSpace     nullspace = NULL;
    642:     PetscBool        hasPrec   = PETSC_FALSE;
    643:     PetscInt         Nf;

    645:     J    = snes->jacobian;
    646:     DMGetDS(dm, &prob);
    647:     if (prob) {PetscDSHasJacobianPreconditioner(prob, &hasPrec);}
    648:     if (J)            {PetscObjectReference((PetscObject) J);}
    649:     else if (hasPrec) {DMCreateMatrix(snes->dm, &J);}
    650:     DMCreateMatrix(snes->dm, &B);
    651:     PetscDSGetNumFields(prob, &Nf);
    652:     DMGetNullSpaceConstructor(snes->dm, Nf, &nspconstr);
    653:     if (nspconstr) (*nspconstr)(snes->dm, -1, &nullspace);
    654:     MatSetNullSpace(B, nullspace);
    655:     MatNullSpaceDestroy(&nullspace);
    656:     SNESSetJacobian(snes, J ? J : B, B, NULL, NULL);
    657:     MatDestroy(&J);
    658:     MatDestroy(&B);
    659:   }
    660:   {
    661:     KSP ksp;
    662:     SNESGetKSP(snes,&ksp);
    663:     KSPSetComputeOperators(ksp,KSPComputeOperators_SNES,snes);
    664:     DMCoarsenHookAdd(snes->dm,DMCoarsenHook_SNESVecSol,DMRestrictHook_SNESVecSol,snes);
    665:   }
    666:   return(0);
    667: }

    669: /*@C
    670:    SNESMonitorSetFromOptions - Sets a monitor function and viewer appropriate for the type indicated by the user

    672:    Collective on SNES

    674:    Input Parameters:
    675: +  snes - SNES object you wish to monitor
    676: .  name - the monitor type one is seeking
    677: .  help - message indicating what monitoring is done
    678: .  manual - manual page for the monitor
    679: .  monitor - the monitor function
    680: -  monitorsetup - a function that is called once ONLY if the user selected this monitor that may set additional features of the SNES or PetscViewer objects

    682:    Level: developer

    684: .seealso: PetscOptionsGetViewer(), PetscOptionsGetReal(), PetscOptionsHasName(), PetscOptionsGetString(),
    685:           PetscOptionsGetIntArray(), PetscOptionsGetRealArray(), PetscOptionsBool()
    686:           PetscOptionsInt(), PetscOptionsString(), PetscOptionsReal(), PetscOptionsBool(),
    687:           PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(),
    688:           PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(),
    689:           PetscOptionsBoolGroupBegin(), PetscOptionsBoolGroup(), PetscOptionsBoolGroupEnd(),
    690:           PetscOptionsFList(), PetscOptionsEList()
    691: @*/
    692: PetscErrorCode  SNESMonitorSetFromOptions(SNES snes,const char name[],const char help[], const char manual[],PetscErrorCode (*monitor)(SNES,PetscInt,PetscReal,PetscViewerAndFormat*),PetscErrorCode (*monitorsetup)(SNES,PetscViewerAndFormat*))
    693: {
    694:   PetscErrorCode    ierr;
    695:   PetscViewer       viewer;
    696:   PetscViewerFormat format;
    697:   PetscBool         flg;

    700:   PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes),((PetscObject)snes)->prefix,name,&viewer,&format,&flg);
    701:   if (flg) {
    702:     PetscViewerAndFormat *vf;
    703:     PetscViewerAndFormatCreate(viewer,format,&vf);
    704:     PetscObjectDereference((PetscObject)viewer);
    705:     if (monitorsetup) {
    706:       (*monitorsetup)(snes,vf);
    707:     }
    708:     SNESMonitorSet(snes,(PetscErrorCode (*)(SNES,PetscInt,PetscReal,void*))monitor,vf,(PetscErrorCode (*)(void**))PetscViewerAndFormatDestroy);
    709:   }
    710:   return(0);
    711: }

    713: /*@
    714:    SNESSetFromOptions - Sets various SNES and KSP parameters from user options.

    716:    Collective on SNES

    718:    Input Parameter:
    719: .  snes - the SNES context

    721:    Options Database Keys:
    722: +  -snes_type <type> - newtonls, newtontr, ngmres, ncg, nrichardson, qn, vi, fas, SNESType for complete list
    723: .  -snes_stol - convergence tolerance in terms of the norm
    724:                 of the change in the solution between steps
    725: .  -snes_atol <abstol> - absolute tolerance of residual norm
    726: .  -snes_rtol <rtol> - relative decrease in tolerance norm from initial
    727: .  -snes_divergence_tolerance <divtol> - if the residual goes above divtol*rnorm0, exit with divergence
    728: .  -snes_force_iteration <force> - force SNESSolve() to take at least one iteration
    729: .  -snes_max_it <max_it> - maximum number of iterations
    730: .  -snes_max_funcs <max_funcs> - maximum number of function evaluations
    731: .  -snes_max_fail <max_fail> - maximum number of line search failures allowed before stopping, default is none
    732: .  -snes_max_linear_solve_fail - number of linear solver failures before SNESSolve() stops
    733: .  -snes_lag_preconditioner <lag> - how often preconditioner is rebuilt (use -1 to never rebuild)
    734: .  -snes_lag_jacobian <lag> - how often Jacobian is rebuilt (use -1 to never rebuild)
    735: .  -snes_trtol <trtol> - trust region tolerance
    736: .  -snes_no_convergence_test - skip convergence test in nonlinear
    737:                                solver; hence iterations will continue until max_it
    738:                                or some other criterion is reached. Saves expense
    739:                                of convergence test
    740: .  -snes_monitor [ascii][:filename][:viewer format] - prints residual norm at each iteration. if no filename given prints to stdout
    741: .  -snes_monitor_solution [ascii binary draw][:filename][:viewer format] - plots solution at each iteration
    742: .  -snes_monitor_residual [ascii binary draw][:filename][:viewer format] - plots residual (not its norm) at each iteration
    743: .  -snes_monitor_solution_update [ascii binary draw][:filename][:viewer format] - plots update to solution at each iteration
    744: .  -snes_monitor_lg_residualnorm - plots residual norm at each iteration
    745: .  -snes_monitor_lg_range - plots residual norm at each iteration
    746: .  -snes_fd - use finite differences to compute Jacobian; very slow, only for testing
    747: .  -snes_fd_color - use finite differences with coloring to compute Jacobian
    748: .  -snes_mf_ksp_monitor - if using matrix-free multiply then print h at each KSP iteration
    749: -  -snes_converged_reason - print the reason for convergence/divergence after each solve

    751:     Options Database for Eisenstat-Walker method:
    752: +  -snes_ksp_ew - use Eisenstat-Walker method for determining linear system convergence
    753: .  -snes_ksp_ew_version ver - version of  Eisenstat-Walker method
    754: .  -snes_ksp_ew_rtol0 <rtol0> - Sets rtol0
    755: .  -snes_ksp_ew_rtolmax <rtolmax> - Sets rtolmax
    756: .  -snes_ksp_ew_gamma <gamma> - Sets gamma
    757: .  -snes_ksp_ew_alpha <alpha> - Sets alpha
    758: .  -snes_ksp_ew_alpha2 <alpha2> - Sets alpha2
    759: -  -snes_ksp_ew_threshold <threshold> - Sets threshold

    761:    Notes:
    762:    To see all options, run your program with the -help option or consult
    763:    Users-Manual: ch_snes

    765:    Level: beginner

    767: .keywords: SNES, nonlinear, set, options, database

    769: .seealso: SNESSetOptionsPrefix(), SNESResetFromOptions()
    770: @*/
    771: PetscErrorCode  SNESSetFromOptions(SNES snes)
    772: {
    773:   PetscBool      flg,pcset,persist,set;
    774:   PetscInt       i,indx,lag,grids;
    775:   const char     *deft        = SNESNEWTONLS;
    776:   const char     *convtests[] = {"default","skip"};
    777:   SNESKSPEW      *kctx        = NULL;
    778:   char           type[256], monfilename[PETSC_MAX_PATH_LEN];
    780:   PCSide         pcside;
    781:   const char     *optionsprefix;

    785:   SNESRegisterAll();
    786:   PetscObjectOptionsBegin((PetscObject)snes);
    787:   if (((PetscObject)snes)->type_name) deft = ((PetscObject)snes)->type_name;
    788:   PetscOptionsFList("-snes_type","Nonlinear solver method","SNESSetType",SNESList,deft,type,256,&flg);
    789:   if (flg) {
    790:     SNESSetType(snes,type);
    791:   } else if (!((PetscObject)snes)->type_name) {
    792:     SNESSetType(snes,deft);
    793:   }
    794:   PetscOptionsReal("-snes_stol","Stop if step length less than","SNESSetTolerances",snes->stol,&snes->stol,NULL);
    795:   PetscOptionsReal("-snes_atol","Stop if function norm less than","SNESSetTolerances",snes->abstol,&snes->abstol,NULL);

    797:   PetscOptionsReal("-snes_rtol","Stop if decrease in function norm less than","SNESSetTolerances",snes->rtol,&snes->rtol,NULL);
    798:   PetscOptionsReal("-snes_divergence_tolerance","Stop if residual norm increases by this factor","SNESSetDivergenceTolerance",snes->divtol,&snes->divtol,NULL);
    799:   PetscOptionsInt("-snes_max_it","Maximum iterations","SNESSetTolerances",snes->max_its,&snes->max_its,NULL);
    800:   PetscOptionsInt("-snes_max_funcs","Maximum function evaluations","SNESSetTolerances",snes->max_funcs,&snes->max_funcs,NULL);
    801:   PetscOptionsInt("-snes_max_fail","Maximum nonlinear step failures","SNESSetMaxNonlinearStepFailures",snes->maxFailures,&snes->maxFailures,NULL);
    802:   PetscOptionsInt("-snes_max_linear_solve_fail","Maximum failures in linear solves allowed","SNESSetMaxLinearSolveFailures",snes->maxLinearSolveFailures,&snes->maxLinearSolveFailures,NULL);
    803:   PetscOptionsBool("-snes_error_if_not_converged","Generate error if solver does not converge","SNESSetErrorIfNotConverged",snes->errorifnotconverged,&snes->errorifnotconverged,NULL);
    804:   PetscOptionsBool("-snes_force_iteration","Force SNESSolve() to take at least one iteration","SNESSetForceIteration",snes->forceiteration,&snes->forceiteration,NULL);

    806:   PetscOptionsInt("-snes_lag_preconditioner","How often to rebuild preconditioner","SNESSetLagPreconditioner",snes->lagpreconditioner,&lag,&flg);
    807:   if (flg) {
    808:     SNESSetLagPreconditioner(snes,lag);
    809:   }
    810:   PetscOptionsBool("-snes_lag_preconditioner_persists","Preconditioner lagging through multiple solves","SNESSetLagPreconditionerPersists",snes->lagjac_persist,&persist,&flg);
    811:   if (flg) {
    812:     SNESSetLagPreconditionerPersists(snes,persist);
    813:   }
    814:   PetscOptionsInt("-snes_lag_jacobian","How often to rebuild Jacobian","SNESSetLagJacobian",snes->lagjacobian,&lag,&flg);
    815:   if (flg) {
    816:     SNESSetLagJacobian(snes,lag);
    817:   }
    818:   PetscOptionsBool("-snes_lag_jacobian_persists","Jacobian lagging through multiple solves","SNESSetLagJacobianPersists",snes->lagjac_persist,&persist,&flg);
    819:   if (flg) {
    820:     SNESSetLagJacobianPersists(snes,persist);
    821:   }

    823:   PetscOptionsInt("-snes_grid_sequence","Use grid sequencing to generate initial guess","SNESSetGridSequence",snes->gridsequence,&grids,&flg);
    824:   if (flg) {
    825:     SNESSetGridSequence(snes,grids);
    826:   }

    828:   PetscOptionsEList("-snes_convergence_test","Convergence test","SNESSetConvergenceTest",convtests,2,"default",&indx,&flg);
    829:   if (flg) {
    830:     switch (indx) {
    831:     case 0: SNESSetConvergenceTest(snes,SNESConvergedDefault,NULL,NULL); break;
    832:     case 1: SNESSetConvergenceTest(snes,SNESConvergedSkip,NULL,NULL);    break;
    833:     }
    834:   }

    836:   PetscOptionsEList("-snes_norm_schedule","SNES Norm schedule","SNESSetNormSchedule",SNESNormSchedules,5,"function",&indx,&flg);
    837:   if (flg) { SNESSetNormSchedule(snes,(SNESNormSchedule)indx); }

    839:   PetscOptionsEList("-snes_function_type","SNES Norm schedule","SNESSetFunctionType",SNESFunctionTypes,2,"unpreconditioned",&indx,&flg);
    840:   if (flg) { SNESSetFunctionType(snes,(SNESFunctionType)indx); }

    842:   kctx = (SNESKSPEW*)snes->kspconvctx;

    844:   PetscOptionsBool("-snes_ksp_ew","Use Eisentat-Walker linear system convergence test","SNESKSPSetUseEW",snes->ksp_ewconv,&snes->ksp_ewconv,NULL);

    846:   PetscOptionsInt("-snes_ksp_ew_version","Version 1, 2 or 3","SNESKSPSetParametersEW",kctx->version,&kctx->version,NULL);
    847:   PetscOptionsReal("-snes_ksp_ew_rtol0","0 <= rtol0 < 1","SNESKSPSetParametersEW",kctx->rtol_0,&kctx->rtol_0,NULL);
    848:   PetscOptionsReal("-snes_ksp_ew_rtolmax","0 <= rtolmax < 1","SNESKSPSetParametersEW",kctx->rtol_max,&kctx->rtol_max,NULL);
    849:   PetscOptionsReal("-snes_ksp_ew_gamma","0 <= gamma <= 1","SNESKSPSetParametersEW",kctx->gamma,&kctx->gamma,NULL);
    850:   PetscOptionsReal("-snes_ksp_ew_alpha","1 < alpha <= 2","SNESKSPSetParametersEW",kctx->alpha,&kctx->alpha,NULL);
    851:   PetscOptionsReal("-snes_ksp_ew_alpha2","alpha2","SNESKSPSetParametersEW",kctx->alpha2,&kctx->alpha2,NULL);
    852:   PetscOptionsReal("-snes_ksp_ew_threshold","0 < threshold < 1","SNESKSPSetParametersEW",kctx->threshold,&kctx->threshold,NULL);

    854:   flg  = PETSC_FALSE;
    855:   PetscOptionsBool("-snes_monitor_cancel","Remove all monitors","SNESMonitorCancel",flg,&flg,&set);
    856:   if (set && flg) {SNESMonitorCancel(snes);}

    858:   SNESMonitorSetFromOptions(snes,"-snes_monitor","Monitor norm of function","SNESMonitorDefault",SNESMonitorDefault,NULL);
    859:   SNESMonitorSetFromOptions(snes,"-snes_monitor_short","Monitor norm of function with fewer digits","SNESMonitorDefaultShort",SNESMonitorDefaultShort,NULL);
    860:   SNESMonitorSetFromOptions(snes,"-snes_monitor_range","Monitor range of elements of function","SNESMonitorRange",SNESMonitorRange,NULL);

    862:   SNESMonitorSetFromOptions(snes,"-snes_monitor_ratio","Monitor ratios of the norm of function for consecutive steps","SNESMonitorRatio",SNESMonitorRatio,SNESMonitorRatioSetUp);
    863:   SNESMonitorSetFromOptions(snes,"-snes_monitor_field","Monitor norm of function (split into fields)","SNESMonitorDefaultField",SNESMonitorDefaultField,NULL);
    864:   SNESMonitorSetFromOptions(snes,"-snes_monitor_solution","View solution at each iteration","SNESMonitorSolution",SNESMonitorSolution,NULL);
    865:   SNESMonitorSetFromOptions(snes,"-snes_monitor_solution_update","View correction at each iteration","SNESMonitorSolutionUpdate",SNESMonitorSolutionUpdate,NULL);
    866:   SNESMonitorSetFromOptions(snes,"-snes_monitor_residual","View residual at each iteration","SNESMonitorResidual",SNESMonitorResidual,NULL);
    867:   SNESMonitorSetFromOptions(snes,"-snes_monitor_jacupdate_spectrum","Print the change in the spectrum of the Jacobian","SNESMonitorJacUpdateSpectrum",SNESMonitorJacUpdateSpectrum,NULL);
    868:   SNESMonitorSetFromOptions(snes,"-snes_monitor_fields","Monitor norm of function per field","SNESMonitorSet",SNESMonitorFields,NULL);

    870:   PetscOptionsString("-snes_monitor_python","Use Python function","SNESMonitorSet",0,monfilename,PETSC_MAX_PATH_LEN,&flg);
    871:   if (flg) {PetscPythonMonitorSet((PetscObject)snes,monfilename);}

    874:   flg  = PETSC_FALSE;
    875:   PetscOptionsBool("-snes_monitor_lg_residualnorm","Plot function norm at each iteration","SNESMonitorLGResidualNorm",flg,&flg,NULL);
    876:   if (flg) {
    877:     PetscDrawLG ctx;

    879:     SNESMonitorLGCreate(PetscObjectComm((PetscObject)snes),NULL,NULL,PETSC_DECIDE,PETSC_DECIDE,400,300,&ctx);
    880:     SNESMonitorSet(snes,SNESMonitorLGResidualNorm,ctx,(PetscErrorCode (*)(void**))PetscDrawLGDestroy);
    881:   }
    882:   flg  = PETSC_FALSE;
    883:   PetscOptionsBool("-snes_monitor_lg_range","Plot function range at each iteration","SNESMonitorLGRange",flg,&flg,NULL);
    884:   if (flg) {
    885:     PetscViewer ctx;

    887:     PetscViewerDrawOpen(PetscObjectComm((PetscObject)snes),NULL,NULL,PETSC_DECIDE,PETSC_DECIDE,400,300,&ctx);
    888:     SNESMonitorSet(snes,SNESMonitorLGRange,ctx,(PetscErrorCode (*)(void**))PetscViewerDestroy);
    889:   }

    893:   flg  = PETSC_FALSE;
    894:   PetscOptionsBool("-snes_fd","Use finite differences (slow) to compute Jacobian","SNESComputeJacobianDefault",flg,&flg,NULL);
    895:   if (flg) {
    896:     void    *functx;
    897:     DM      dm;
    898:     DMSNES  sdm;
    899:     SNESGetDM(snes,&dm);
    900:     DMGetDMSNES(dm,&sdm);
    901:     sdm->jacobianctx = NULL;
    902:     SNESGetFunction(snes,NULL,NULL,&functx);
    903:     SNESSetJacobian(snes,snes->jacobian,snes->jacobian_pre,SNESComputeJacobianDefault,functx);
    904:     PetscInfo(snes,"Setting default finite difference Jacobian matrix\n");
    905:   }

    907:   flg  = PETSC_FALSE;
    908:   PetscOptionsBool("-snes_fd_function","Use finite differences (slow) to compute function from user objective","SNESObjectiveComputeFunctionDefaultFD",flg,&flg,NULL);
    909:   if (flg) {
    910:     SNESSetFunction(snes,NULL,SNESObjectiveComputeFunctionDefaultFD,NULL);
    911:   }

    913:   flg  = PETSC_FALSE;
    914:   PetscOptionsBool("-snes_fd_color","Use finite differences with coloring to compute Jacobian","SNESComputeJacobianDefaultColor",flg,&flg,NULL);
    915:   if (flg) {
    916:     DM             dm;
    917:     DMSNES         sdm;
    918:     SNESGetDM(snes,&dm);
    919:     DMGetDMSNES(dm,&sdm);
    920:     sdm->jacobianctx = NULL;
    921:     SNESSetJacobian(snes,snes->jacobian,snes->jacobian_pre,SNESComputeJacobianDefaultColor,0);
    922:     PetscInfo(snes,"Setting default finite difference coloring Jacobian matrix\n");
    923:   }

    925:   flg  = PETSC_FALSE;
    926:   PetscOptionsBool("-snes_mf_operator","Use a Matrix-Free Jacobian with user-provided preconditioner matrix","SNESSetUseMatrixFree",PETSC_FALSE,&snes->mf_operator,&flg);
    927:   if (flg && snes->mf_operator) {
    928:     snes->mf_operator = PETSC_TRUE;
    929:     snes->mf          = PETSC_TRUE;
    930:   }
    931:   flg  = PETSC_FALSE;
    932:   PetscOptionsBool("-snes_mf","Use a Matrix-Free Jacobian with no preconditioner matrix","SNESSetUseMatrixFree",PETSC_FALSE,&snes->mf,&flg);
    933:   if (!flg && snes->mf_operator) snes->mf = PETSC_TRUE;
    934:   PetscOptionsInt("-snes_mf_version","Matrix-Free routines version 1 or 2","None",snes->mf_version,&snes->mf_version,0);

    936:   flg  = PETSC_FALSE;
    937:   SNESGetNPCSide(snes,&pcside);
    938:   PetscOptionsEnum("-snes_npc_side","SNES nonlinear preconditioner side","SNESSetNPCSide",PCSides,(PetscEnum)pcside,(PetscEnum*)&pcside,&flg);
    939:   if (flg) {SNESSetNPCSide(snes,pcside);}

    941: #if defined(PETSC_HAVE_SAWS)
    942:   /*
    943:     Publish convergence information using SAWs
    944:   */
    945:   flg  = PETSC_FALSE;
    946:   PetscOptionsBool("-snes_monitor_saws","Publish SNES progress using SAWs","SNESMonitorSet",flg,&flg,NULL);
    947:   if (flg) {
    948:     void *ctx;
    949:     SNESMonitorSAWsCreate(snes,&ctx);
    950:     SNESMonitorSet(snes,SNESMonitorSAWs,ctx,SNESMonitorSAWsDestroy);
    951:   }
    952: #endif
    953: #if defined(PETSC_HAVE_SAWS)
    954:   {
    955:   PetscBool set;
    956:   flg  = PETSC_FALSE;
    957:   PetscOptionsBool("-snes_saws_block","Block for SAWs at end of SNESSolve","PetscObjectSAWsBlock",((PetscObject)snes)->amspublishblock,&flg,&set);
    958:   if (set) {
    959:     PetscObjectSAWsSetBlock((PetscObject)snes,flg);
    960:   }
    961:   }
    962: #endif

    964:   for (i = 0; i < numberofsetfromoptions; i++) {
    965:     (*othersetfromoptions[i])(snes);
    966:   }

    968:   if (snes->ops->setfromoptions) {
    969:     (*snes->ops->setfromoptions)(PetscOptionsObject,snes);
    970:   }

    972:   /* process any options handlers added with PetscObjectAddOptionsHandler() */
    973:   PetscObjectProcessOptionsHandlers(PetscOptionsObject,(PetscObject)snes);
    974:   PetscOptionsEnd();

    976:   if (!snes->linesearch) {
    977:     SNESGetLineSearch(snes, &snes->linesearch);
    978:   }
    979:   SNESLineSearchSetFromOptions(snes->linesearch);

    981:   if (!snes->ksp) {SNESGetKSP(snes,&snes->ksp);}
    982:   KSPSetOperators(snes->ksp,snes->jacobian,snes->jacobian_pre);
    983:   KSPSetFromOptions(snes->ksp);

    985:   /* if someone has set the SNES NPC type, create it. */
    986:   SNESGetOptionsPrefix(snes, &optionsprefix);
    987:   PetscOptionsHasName(((PetscObject)snes)->options,optionsprefix, "-npc_snes_type", &pcset);
    988:   if (pcset && (!snes->npc)) {
    989:     SNESGetNPC(snes, &snes->npc);
    990:   }
    991:   snes->setfromoptionscalled++;
    992:   return(0);
    993: }

    995: /*@
    996:    SNESResetFromOptions - Sets various SNES and KSP parameters from user options ONLY if the SNES was previously set from options

    998:    Collective on SNES

    1000:    Input Parameter:
    1001: .  snes - the SNES context

    1003:    Level: beginner

    1005: .keywords: SNES, nonlinear, set, options, database

    1007: .seealso: SNESSetFromOptions(), SNESSetOptionsPrefix()
    1008: @*/
    1009: PetscErrorCode SNESResetFromOptions(SNES snes)
    1010: {

    1014:   if (snes->setfromoptionscalled) {SNESSetFromOptions(snes);}
    1015:   return(0);
    1016: }

    1018: /*@C
    1019:    SNESSetComputeApplicationContext - Sets an optional function to compute a user-defined context for
    1020:    the nonlinear solvers.

    1022:    Logically Collective on SNES

    1024:    Input Parameters:
    1025: +  snes - the SNES context
    1026: .  compute - function to compute the context
    1027: -  destroy - function to destroy the context

    1029:    Level: intermediate

    1031:    Notes:
    1032:    This function is currently not available from Fortran.

    1034: .keywords: SNES, nonlinear, set, application, context

    1036: .seealso: SNESGetApplicationContext(), SNESSetComputeApplicationContext(), SNESGetApplicationContext()
    1037: @*/
    1038: PetscErrorCode  SNESSetComputeApplicationContext(SNES snes,PetscErrorCode (*compute)(SNES,void**),PetscErrorCode (*destroy)(void**))
    1039: {
    1042:   snes->ops->usercompute = compute;
    1043:   snes->ops->userdestroy = destroy;
    1044:   return(0);
    1045: }

    1047: /*@
    1048:    SNESSetApplicationContext - Sets the optional user-defined context for
    1049:    the nonlinear solvers.

    1051:    Logically Collective on SNES

    1053:    Input Parameters:
    1054: +  snes - the SNES context
    1055: -  usrP - optional user context

    1057:    Level: intermediate

    1059:    Fortran Notes:
    1060:     To use this from Fortran you must write a Fortran interface definition for this
    1061:     function that tells Fortran the Fortran derived data type that you are passing in as the ctx argument.

    1063: .keywords: SNES, nonlinear, set, application, context

    1065: .seealso: SNESGetApplicationContext()
    1066: @*/
    1067: PetscErrorCode  SNESSetApplicationContext(SNES snes,void *usrP)
    1068: {
    1070:   KSP            ksp;

    1074:   SNESGetKSP(snes,&ksp);
    1075:   KSPSetApplicationContext(ksp,usrP);
    1076:   snes->user = usrP;
    1077:   return(0);
    1078: }

    1080: /*@
    1081:    SNESGetApplicationContext - Gets the user-defined context for the
    1082:    nonlinear solvers.

    1084:    Not Collective

    1086:    Input Parameter:
    1087: .  snes - SNES context

    1089:    Output Parameter:
    1090: .  usrP - user context

    1092:    Fortran Notes:
    1093:     To use this from Fortran you must write a Fortran interface definition for this
    1094:     function that tells Fortran the Fortran derived data type that you are passing in as the ctx argument.

    1096:    Level: intermediate

    1098: .keywords: SNES, nonlinear, get, application, context

    1100: .seealso: SNESSetApplicationContext()
    1101: @*/
    1102: PetscErrorCode  SNESGetApplicationContext(SNES snes,void *usrP)
    1103: {
    1106:   *(void**)usrP = snes->user;
    1107:   return(0);
    1108: }

    1110: /*@
    1111:    SNESSetUseMatrixFree - indicates that SNES should use matrix free finite difference matrix vector products internally to apply
    1112:                           the Jacobian.

    1114:    Collective on SNES

    1116:    Input Parameters:
    1117: +  snes - SNES context
    1118: .  mf - use matrix-free for both the Amat and Pmat used by SNESSetJacobian(), both the Amat and Pmat set in SNESSetJacobian() will be ignored
    1119: -  mf_operator - use matrix-free only for the Amat used by SNESSetJacobian(), this means the user provided Pmat will continue to be used

    1121:    Options Database:
    1122: + -snes_mf - use matrix free for both the mat and pmat operator
    1123: - -snes_mf_operator - use matrix free only for the mat operator

    1125:    Level: intermediate

    1127: .keywords: SNES, nonlinear, get, iteration, number,

    1129: .seealso:   SNESGetUseMatrixFree(), MatCreateSNESMF()
    1130: @*/
    1131: PetscErrorCode  SNESSetUseMatrixFree(SNES snes,PetscBool mf_operator,PetscBool mf)
    1132: {
    1137:   if (mf && !mf_operator) SETERRQ(PetscObjectComm((PetscObject)snes),PETSC_ERR_ARG_INCOMP,"If using mf must also use mf_operator");
    1138:   snes->mf          = mf;
    1139:   snes->mf_operator = mf_operator;
    1140:   return(0);
    1141: }

    1143: /*@
    1144:    SNESGetUseMatrixFree - indicates if the SNES uses matrix free finite difference matrix vector products to apply
    1145:                           the Jacobian.

    1147:    Collective on SNES

    1149:    Input Parameter:
    1150: .  snes - SNES context

    1152:    Output Parameters:
    1153: +  mf - use matrix-free for both the Amat and Pmat used by SNESSetJacobian(), both the Amat and Pmat set in SNESSetJacobian() will be ignored
    1154: -  mf_operator - use matrix-free only for the Amat used by SNESSetJacobian(), this means the user provided Pmat will continue to be used

    1156:    Options Database:
    1157: + -snes_mf - use matrix free for both the mat and pmat operator
    1158: - -snes_mf_operator - use matrix free only for the mat operator

    1160:    Level: intermediate

    1162: .keywords: SNES, nonlinear, get, iteration, number,

    1164: .seealso:   SNESSetUseMatrixFree(), MatCreateSNESMF()
    1165: @*/
    1166: PetscErrorCode  SNESGetUseMatrixFree(SNES snes,PetscBool *mf_operator,PetscBool *mf)
    1167: {
    1170:   if (mf)          *mf          = snes->mf;
    1171:   if (mf_operator) *mf_operator = snes->mf_operator;
    1172:   return(0);
    1173: }

    1175: /*@
    1176:    SNESGetIterationNumber - Gets the number of nonlinear iterations completed
    1177:    at this time.

    1179:    Not Collective

    1181:    Input Parameter:
    1182: .  snes - SNES context

    1184:    Output Parameter:
    1185: .  iter - iteration number

    1187:    Notes:
    1188:    For example, during the computation of iteration 2 this would return 1.

    1190:    This is useful for using lagged Jacobians (where one does not recompute the
    1191:    Jacobian at each SNES iteration). For example, the code
    1192: .vb
    1193:       SNESGetIterationNumber(snes,&it);
    1194:       if (!(it % 2)) {
    1195:         [compute Jacobian here]
    1196:       }
    1197: .ve
    1198:    can be used in your ComputeJacobian() function to cause the Jacobian to be
    1199:    recomputed every second SNES iteration.

    1201:    After the SNES solve is complete this will return the number of nonlinear iterations used.

    1203:    Level: intermediate

    1205: .keywords: SNES, nonlinear, get, iteration, number,

    1207: .seealso:   SNESGetLinearSolveIterations()
    1208: @*/
    1209: PetscErrorCode  SNESGetIterationNumber(SNES snes,PetscInt *iter)
    1210: {
    1214:   *iter = snes->iter;
    1215:   return(0);
    1216: }

    1218: /*@
    1219:    SNESSetIterationNumber - Sets the current iteration number.

    1221:    Not Collective

    1223:    Input Parameter:
    1224: .  snes - SNES context
    1225: .  iter - iteration number

    1227:    Level: developer

    1229: .keywords: SNES, nonlinear, set, iteration, number,

    1231: .seealso:   SNESGetLinearSolveIterations()
    1232: @*/
    1233: PetscErrorCode  SNESSetIterationNumber(SNES snes,PetscInt iter)
    1234: {

    1239:   PetscObjectSAWsTakeAccess((PetscObject)snes);
    1240:   snes->iter = iter;
    1241:   PetscObjectSAWsGrantAccess((PetscObject)snes);
    1242:   return(0);
    1243: }

    1245: /*@
    1246:    SNESGetNonlinearStepFailures - Gets the number of unsuccessful steps
    1247:    attempted by the nonlinear solver.

    1249:    Not Collective

    1251:    Input Parameter:
    1252: .  snes - SNES context

    1254:    Output Parameter:
    1255: .  nfails - number of unsuccessful steps attempted

    1257:    Notes:
    1258:    This counter is reset to zero for each successive call to SNESSolve().

    1260:    Level: intermediate

    1262: .keywords: SNES, nonlinear, get, number, unsuccessful, steps

    1264: .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), SNESGetLinearSolveFailures(),
    1265:           SNESSetMaxNonlinearStepFailures(), SNESGetMaxNonlinearStepFailures()
    1266: @*/
    1267: PetscErrorCode  SNESGetNonlinearStepFailures(SNES snes,PetscInt *nfails)
    1268: {
    1272:   *nfails = snes->numFailures;
    1273:   return(0);
    1274: }

    1276: /*@
    1277:    SNESSetMaxNonlinearStepFailures - Sets the maximum number of unsuccessful steps
    1278:    attempted by the nonlinear solver before it gives up.

    1280:    Not Collective

    1282:    Input Parameters:
    1283: +  snes     - SNES context
    1284: -  maxFails - maximum of unsuccessful steps

    1286:    Level: intermediate

    1288: .keywords: SNES, nonlinear, set, maximum, unsuccessful, steps

    1290: .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), SNESGetLinearSolveFailures(),
    1291:           SNESGetMaxNonlinearStepFailures(), SNESGetNonlinearStepFailures()
    1292: @*/
    1293: PetscErrorCode  SNESSetMaxNonlinearStepFailures(SNES snes, PetscInt maxFails)
    1294: {
    1297:   snes->maxFailures = maxFails;
    1298:   return(0);
    1299: }

    1301: /*@
    1302:    SNESGetMaxNonlinearStepFailures - Gets the maximum number of unsuccessful steps
    1303:    attempted by the nonlinear solver before it gives up.

    1305:    Not Collective

    1307:    Input Parameter:
    1308: .  snes     - SNES context

    1310:    Output Parameter:
    1311: .  maxFails - maximum of unsuccessful steps

    1313:    Level: intermediate

    1315: .keywords: SNES, nonlinear, get, maximum, unsuccessful, steps

    1317: .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), SNESGetLinearSolveFailures(),
    1318:           SNESSetMaxNonlinearStepFailures(), SNESGetNonlinearStepFailures()

    1320: @*/
    1321: PetscErrorCode  SNESGetMaxNonlinearStepFailures(SNES snes, PetscInt *maxFails)
    1322: {
    1326:   *maxFails = snes->maxFailures;
    1327:   return(0);
    1328: }

    1330: /*@
    1331:    SNESGetNumberFunctionEvals - Gets the number of user provided function evaluations
    1332:      done by SNES.

    1334:    Not Collective

    1336:    Input Parameter:
    1337: .  snes     - SNES context

    1339:    Output Parameter:
    1340: .  nfuncs - number of evaluations

    1342:    Level: intermediate

    1344:    Notes:
    1345:     Reset every time SNESSolve is called unless SNESSetCountersReset() is used.

    1347: .keywords: SNES, nonlinear, get, maximum, unsuccessful, steps

    1349: .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), SNESGetLinearSolveFailures(), SNESSetCountersReset()
    1350: @*/
    1351: PetscErrorCode  SNESGetNumberFunctionEvals(SNES snes, PetscInt *nfuncs)
    1352: {
    1356:   *nfuncs = snes->nfuncs;
    1357:   return(0);
    1358: }

    1360: /*@
    1361:    SNESGetLinearSolveFailures - Gets the number of failed (non-converged)
    1362:    linear solvers.

    1364:    Not Collective

    1366:    Input Parameter:
    1367: .  snes - SNES context

    1369:    Output Parameter:
    1370: .  nfails - number of failed solves

    1372:    Level: intermediate

    1374:    Options Database Keys:
    1375: . -snes_max_linear_solve_fail <num> - The number of failures before the solve is terminated

    1377:    Notes:
    1378:    This counter is reset to zero for each successive call to SNESSolve().

    1380: .keywords: SNES, nonlinear, get, number, unsuccessful, steps

    1382: .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures()
    1383: @*/
    1384: PetscErrorCode  SNESGetLinearSolveFailures(SNES snes,PetscInt *nfails)
    1385: {
    1389:   *nfails = snes->numLinearSolveFailures;
    1390:   return(0);
    1391: }

    1393: /*@
    1394:    SNESSetMaxLinearSolveFailures - the number of failed linear solve attempts
    1395:    allowed before SNES returns with a diverged reason of SNES_DIVERGED_LINEAR_SOLVE

    1397:    Logically Collective on SNES

    1399:    Input Parameters:
    1400: +  snes     - SNES context
    1401: -  maxFails - maximum allowed linear solve failures

    1403:    Level: intermediate

    1405:    Options Database Keys:
    1406: . -snes_max_linear_solve_fail <num> - The number of failures before the solve is terminated

    1408:    Notes:
    1409:     By default this is 0; that is SNES returns on the first failed linear solve

    1411: .keywords: SNES, nonlinear, set, maximum, unsuccessful, steps

    1413: .seealso: SNESGetLinearSolveFailures(), SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations()
    1414: @*/
    1415: PetscErrorCode  SNESSetMaxLinearSolveFailures(SNES snes, PetscInt maxFails)
    1416: {
    1420:   snes->maxLinearSolveFailures = maxFails;
    1421:   return(0);
    1422: }

    1424: /*@
    1425:    SNESGetMaxLinearSolveFailures - gets the maximum number of linear solve failures that
    1426:      are allowed before SNES terminates

    1428:    Not Collective

    1430:    Input Parameter:
    1431: .  snes     - SNES context

    1433:    Output Parameter:
    1434: .  maxFails - maximum of unsuccessful solves allowed

    1436:    Level: intermediate

    1438:    Notes:
    1439:     By default this is 1; that is SNES returns on the first failed linear solve

    1441: .keywords: SNES, nonlinear, get, maximum, unsuccessful, steps

    1443: .seealso: SNESGetLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(),
    1444: @*/
    1445: PetscErrorCode  SNESGetMaxLinearSolveFailures(SNES snes, PetscInt *maxFails)
    1446: {
    1450:   *maxFails = snes->maxLinearSolveFailures;
    1451:   return(0);
    1452: }

    1454: /*@
    1455:    SNESGetLinearSolveIterations - Gets the total number of linear iterations
    1456:    used by the nonlinear solver.

    1458:    Not Collective

    1460:    Input Parameter:
    1461: .  snes - SNES context

    1463:    Output Parameter:
    1464: .  lits - number of linear iterations

    1466:    Notes:
    1467:    This counter is reset to zero for each successive call to SNESSolve() unless SNESSetCountersReset() is used.

    1469:    If the linear solver fails inside the SNESSolve() the iterations for that call to the linear solver are not included. If you wish to count them
    1470:    then call KSPGetIterationNumber() after the failed solve.

    1472:    Level: intermediate

    1474: .keywords: SNES, nonlinear, get, number, linear, iterations

    1476: .seealso:  SNESGetIterationNumber(), SNESGetLinearSolveFailures(), SNESGetMaxLinearSolveFailures(), SNESSetCountersReset()
    1477: @*/
    1478: PetscErrorCode  SNESGetLinearSolveIterations(SNES snes,PetscInt *lits)
    1479: {
    1483:   *lits = snes->linear_its;
    1484:   return(0);
    1485: }

    1487: /*@
    1488:    SNESSetCountersReset - Sets whether or not the counters for linear iterations and function evaluations
    1489:    are reset every time SNESSolve() is called.

    1491:    Logically Collective on SNES

    1493:    Input Parameter:
    1494: +  snes - SNES context
    1495: -  reset - whether to reset the counters or not

    1497:    Notes:
    1498:    This defaults to PETSC_TRUE

    1500:    Level: developer

    1502: .keywords: SNES, nonlinear, set, reset, number, linear, iterations

    1504: .seealso:  SNESGetNumberFunctionEvals(), SNESGetLinearSolveIterations(), SNESGetNPC()
    1505: @*/
    1506: PetscErrorCode  SNESSetCountersReset(SNES snes,PetscBool reset)
    1507: {
    1511:   snes->counters_reset = reset;
    1512:   return(0);
    1513: }

    1516: /*@
    1517:    SNESSetKSP - Sets a KSP context for the SNES object to use

    1519:    Not Collective, but the SNES and KSP objects must live on the same MPI_Comm

    1521:    Input Parameters:
    1522: +  snes - the SNES context
    1523: -  ksp - the KSP context

    1525:    Notes:
    1526:    The SNES object already has its KSP object, you can obtain with SNESGetKSP()
    1527:    so this routine is rarely needed.

    1529:    The KSP object that is already in the SNES object has its reference count
    1530:    decreased by one.

    1532:    Level: developer

    1534: .keywords: SNES, nonlinear, get, KSP, context

    1536: .seealso: KSPGetPC(), SNESCreate(), KSPCreate(), SNESSetKSP()
    1537: @*/
    1538: PetscErrorCode  SNESSetKSP(SNES snes,KSP ksp)
    1539: {

    1546:   PetscObjectReference((PetscObject)ksp);
    1547:   if (snes->ksp) {PetscObjectDereference((PetscObject)snes->ksp);}
    1548:   snes->ksp = ksp;
    1549:   return(0);
    1550: }

    1552: /* -----------------------------------------------------------*/
    1553: /*@
    1554:    SNESCreate - Creates a nonlinear solver context.

    1556:    Collective on MPI_Comm

    1558:    Input Parameters:
    1559: .  comm - MPI communicator

    1561:    Output Parameter:
    1562: .  outsnes - the new SNES context

    1564:    Options Database Keys:
    1565: +   -snes_mf - Activates default matrix-free Jacobian-vector products,
    1566:                and no preconditioning matrix
    1567: .   -snes_mf_operator - Activates default matrix-free Jacobian-vector
    1568:                products, and a user-provided preconditioning matrix
    1569:                as set by SNESSetJacobian()
    1570: -   -snes_fd - Uses (slow!) finite differences to compute Jacobian

    1572:    Level: beginner

    1574:    Developer Notes:
    1575:     SNES always creates a KSP object even though many SNES methods do not use it. This is
    1576:                     unfortunate and should be fixed at some point. The flag snes->usesksp indicates if the
    1577:                     particular method does use KSP and regulates if the information about the KSP is printed
    1578:                     in SNESView(). TSSetFromOptions() does call SNESSetFromOptions() which can lead to users being confused
    1579:                     by help messages about meaningless SNES options.

    1581:                     SNES always creates the snes->kspconvctx even though it is used by only one type. This should
    1582:                     be fixed.

    1584: .keywords: SNES, nonlinear, create, context

    1586: .seealso: SNESSolve(), SNESDestroy(), SNES, SNESSetLagPreconditioner()

    1588: @*/
    1589: PetscErrorCode  SNESCreate(MPI_Comm comm,SNES *outsnes)
    1590: {
    1592:   SNES           snes;
    1593:   SNESKSPEW      *kctx;

    1597:   *outsnes = NULL;
    1598:   SNESInitializePackage();

    1600:   PetscHeaderCreate(snes,SNES_CLASSID,"SNES","Nonlinear solver","SNES",comm,SNESDestroy,SNESView);

    1602:   snes->ops->converged    = SNESConvergedDefault;
    1603:   snes->usesksp           = PETSC_TRUE;
    1604:   snes->tolerancesset     = PETSC_FALSE;
    1605:   snes->max_its           = 50;
    1606:   snes->max_funcs         = 10000;
    1607:   snes->norm              = 0.0;
    1608:   snes->normschedule      = SNES_NORM_ALWAYS;
    1609:   snes->functype          = SNES_FUNCTION_DEFAULT;
    1610: #if defined(PETSC_USE_REAL_SINGLE)
    1611:   snes->rtol              = 1.e-5;
    1612: #else
    1613:   snes->rtol              = 1.e-8;
    1614: #endif
    1615:   snes->ttol              = 0.0;
    1616: #if defined(PETSC_USE_REAL_SINGLE)
    1617:   snes->abstol            = 1.e-25;
    1618: #else
    1619:   snes->abstol            = 1.e-50;
    1620: #endif
    1621: #if defined(PETSC_USE_REAL_SINGLE)
    1622:   snes->stol              = 1.e-5;
    1623: #else
    1624:   snes->stol              = 1.e-8;
    1625: #endif
    1626: #if defined(PETSC_USE_REAL_SINGLE)
    1627:   snes->deltatol          = 1.e-6;
    1628: #else
    1629:   snes->deltatol          = 1.e-12;
    1630: #endif
    1631:   snes->divtol            = 1.e4;
    1632:   snes->rnorm0            = 0;
    1633:   snes->nfuncs            = 0;
    1634:   snes->numFailures       = 0;
    1635:   snes->maxFailures       = 1;
    1636:   snes->linear_its        = 0;
    1637:   snes->lagjacobian       = 1;
    1638:   snes->jac_iter          = 0;
    1639:   snes->lagjac_persist    = PETSC_FALSE;
    1640:   snes->lagpreconditioner = 1;
    1641:   snes->pre_iter          = 0;
    1642:   snes->lagpre_persist    = PETSC_FALSE;
    1643:   snes->numbermonitors    = 0;
    1644:   snes->data              = 0;
    1645:   snes->setupcalled       = PETSC_FALSE;
    1646:   snes->ksp_ewconv        = PETSC_FALSE;
    1647:   snes->nwork             = 0;
    1648:   snes->work              = 0;
    1649:   snes->nvwork            = 0;
    1650:   snes->vwork             = 0;
    1651:   snes->conv_hist_len     = 0;
    1652:   snes->conv_hist_max     = 0;
    1653:   snes->conv_hist         = NULL;
    1654:   snes->conv_hist_its     = NULL;
    1655:   snes->conv_hist_reset   = PETSC_TRUE;
    1656:   snes->counters_reset    = PETSC_TRUE;
    1657:   snes->vec_func_init_set = PETSC_FALSE;
    1658:   snes->reason            = SNES_CONVERGED_ITERATING;
    1659:   snes->npcside           = PC_RIGHT;
    1660:   snes->setfromoptionscalled = 0;

    1662:   snes->mf          = PETSC_FALSE;
    1663:   snes->mf_operator = PETSC_FALSE;
    1664:   snes->mf_version  = 1;

    1666:   snes->numLinearSolveFailures = 0;
    1667:   snes->maxLinearSolveFailures = 1;

    1669:   snes->vizerotolerance = 1.e-8;

    1671:   /* Set this to true if the implementation of SNESSolve_XXX does compute the residual at the final solution. */
    1672:   snes->alwayscomputesfinalresidual = PETSC_FALSE;

    1674:   /* Create context to compute Eisenstat-Walker relative tolerance for KSP */
    1675:   PetscNewLog(snes,&kctx);

    1677:   snes->kspconvctx  = (void*)kctx;
    1678:   kctx->version     = 2;
    1679:   kctx->rtol_0      = .3; /* Eisenstat and Walker suggest rtol_0=.5, but
    1680:                              this was too large for some test cases */
    1681:   kctx->rtol_last   = 0.0;
    1682:   kctx->rtol_max    = .9;
    1683:   kctx->gamma       = 1.0;
    1684:   kctx->alpha       = .5*(1.0 + PetscSqrtReal(5.0));
    1685:   kctx->alpha2      = kctx->alpha;
    1686:   kctx->threshold   = .1;
    1687:   kctx->lresid_last = 0.0;
    1688:   kctx->norm_last   = 0.0;

    1690:   *outsnes = snes;
    1691:   return(0);
    1692: }

    1694: /*MC
    1695:     SNESFunction - Functional form used to convey the nonlinear function to be solved by SNES

    1697:      Synopsis:
    1698:      #include "petscsnes.h"
    1699:      PetscErrorCode SNESFunction(SNES snes,Vec x,Vec f,void *ctx);

    1701:      Input Parameters:
    1702: +     snes - the SNES context
    1703: .     x    - state at which to evaluate residual
    1704: -     ctx     - optional user-defined function context, passed in with SNESSetFunction()

    1706:      Output Parameter:
    1707: .     f  - vector to put residual (function value)

    1709:    Level: intermediate

    1711: .seealso:   SNESSetFunction(), SNESGetFunction()
    1712: M*/

    1714: /*@C
    1715:    SNESSetFunction - Sets the function evaluation routine and function
    1716:    vector for use by the SNES routines in solving systems of nonlinear
    1717:    equations.

    1719:    Logically Collective on SNES

    1721:    Input Parameters:
    1722: +  snes - the SNES context
    1723: .  r - vector to store function value
    1724: .  f - function evaluation routine; see SNESFunction for calling sequence details
    1725: -  ctx - [optional] user-defined context for private data for the
    1726:          function evaluation routine (may be NULL)

    1728:    Notes:
    1729:    The Newton-like methods typically solve linear systems of the form
    1730: $      f'(x) x = -f(x),
    1731:    where f'(x) denotes the Jacobian matrix and f(x) is the function.

    1733:    Level: beginner

    1735: .keywords: SNES, nonlinear, set, function

    1737: .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetPicard(), SNESFunction
    1738: @*/
    1739: PetscErrorCode  SNESSetFunction(SNES snes,Vec r,PetscErrorCode (*f)(SNES,Vec,Vec,void*),void *ctx)
    1740: {
    1742:   DM             dm;

    1746:   if (r) {
    1749:     PetscObjectReference((PetscObject)r);
    1750:     VecDestroy(&snes->vec_func);

    1752:     snes->vec_func = r;
    1753:   }
    1754:   SNESGetDM(snes,&dm);
    1755:   DMSNESSetFunction(dm,f,ctx);
    1756:   return(0);
    1757: }

    1760: /*@C
    1761:    SNESSetInitialFunction - Sets the function vector to be used as the
    1762:    function norm at the initialization of the method.  In some
    1763:    instances, the user has precomputed the function before calling
    1764:    SNESSolve.  This function allows one to avoid a redundant call
    1765:    to SNESComputeFunction in that case.

    1767:    Logically Collective on SNES

    1769:    Input Parameters:
    1770: +  snes - the SNES context
    1771: -  f - vector to store function value

    1773:    Notes:
    1774:    This should not be modified during the solution procedure.

    1776:    This is used extensively in the SNESFAS hierarchy and in nonlinear preconditioning.

    1778:    Level: developer

    1780: .keywords: SNES, nonlinear, set, function

    1782: .seealso: SNESSetFunction(), SNESComputeFunction(), SNESSetInitialFunctionNorm()
    1783: @*/
    1784: PetscErrorCode  SNESSetInitialFunction(SNES snes, Vec f)
    1785: {
    1787:   Vec            vec_func;

    1793:   if (snes->npcside== PC_LEFT && snes->functype == SNES_FUNCTION_PRECONDITIONED) {
    1794:     snes->vec_func_init_set = PETSC_FALSE;
    1795:     return(0);
    1796:   }
    1797:   SNESGetFunction(snes,&vec_func,NULL,NULL);
    1798:   VecCopy(f, vec_func);

    1800:   snes->vec_func_init_set = PETSC_TRUE;
    1801:   return(0);
    1802: }

    1804: /*@
    1805:    SNESSetNormSchedule - Sets the SNESNormSchedule used in covergence and monitoring
    1806:    of the SNES method.

    1808:    Logically Collective on SNES

    1810:    Input Parameters:
    1811: +  snes - the SNES context
    1812: -  normschedule - the frequency of norm computation

    1814:    Options Database Key:
    1815: .  -snes_norm_schedule <none, always, initialonly, finalonly, initalfinalonly>

    1817:    Notes:
    1818:    Only certain SNES methods support certain SNESNormSchedules.  Most require evaluation
    1819:    of the nonlinear function and the taking of its norm at every iteration to
    1820:    even ensure convergence at all.  However, methods such as custom Gauss-Seidel methods
    1821:    (SNESNGS) and the like do not require the norm of the function to be computed, and therfore
    1822:    may either be monitored for convergence or not.  As these are often used as nonlinear
    1823:    preconditioners, monitoring the norm of their error is not a useful enterprise within
    1824:    their solution.

    1826:    Level: developer

    1828: .keywords: SNES, nonlinear, set, function, norm, type

    1830: .seealso: SNESGetNormSchedule(), SNESComputeFunction(), VecNorm(), SNESSetFunction(), SNESSetInitialFunction(), SNESNormSchedule
    1831: @*/
    1832: PetscErrorCode  SNESSetNormSchedule(SNES snes, SNESNormSchedule normschedule)
    1833: {
    1836:   snes->normschedule = normschedule;
    1837:   return(0);
    1838: }

    1841: /*@
    1842:    SNESGetNormSchedule - Gets the SNESNormSchedule used in covergence and monitoring
    1843:    of the SNES method.

    1845:    Logically Collective on SNES

    1847:    Input Parameters:
    1848: +  snes - the SNES context
    1849: -  normschedule - the type of the norm used

    1851:    Level: advanced

    1853: .keywords: SNES, nonlinear, set, function, norm, type

    1855: .seealso: SNESSetNormSchedule(), SNESComputeFunction(), VecNorm(), SNESSetFunction(), SNESSetInitialFunction(), SNESNormSchedule
    1856: @*/
    1857: PetscErrorCode  SNESGetNormSchedule(SNES snes, SNESNormSchedule *normschedule)
    1858: {
    1861:   *normschedule = snes->normschedule;
    1862:   return(0);
    1863: }

    1866: /*@
    1867:   SNESSetFunctionNorm - Sets the last computed residual norm.

    1869:   Logically Collective on SNES

    1871:   Input Parameters:
    1872: + snes - the SNES context

    1874: - normschedule - the frequency of norm computation

    1876:   Level: developer

    1878: .keywords: SNES, nonlinear, set, function, norm, type
    1879: .seealso: SNESGetNormSchedule(), SNESComputeFunction(), VecNorm(), SNESSetFunction(), SNESSetInitialFunction(), SNESNormSchedule
    1880: @*/
    1881: PetscErrorCode SNESSetFunctionNorm(SNES snes, PetscReal norm)
    1882: {
    1885:   snes->norm = norm;
    1886:   return(0);
    1887: }

    1889: /*@
    1890:   SNESGetFunctionNorm - Gets the last computed norm of the residual

    1892:   Not Collective

    1894:   Input Parameter:
    1895: . snes - the SNES context

    1897:   Output Parameter:
    1898: . norm - the last computed residual norm

    1900:   Level: developer

    1902: .keywords: SNES, nonlinear, set, function, norm, type
    1903: .seealso: SNESSetNormSchedule(), SNESComputeFunction(), VecNorm(), SNESSetFunction(), SNESSetInitialFunction(), SNESNormSchedule
    1904: @*/
    1905: PetscErrorCode SNESGetFunctionNorm(SNES snes, PetscReal *norm)
    1906: {
    1910:   *norm = snes->norm;
    1911:   return(0);
    1912: }

    1914: /*@C
    1915:    SNESSetFunctionType - Sets the SNESNormSchedule used in covergence and monitoring
    1916:    of the SNES method.

    1918:    Logically Collective on SNES

    1920:    Input Parameters:
    1921: +  snes - the SNES context
    1922: -  normschedule - the frequency of norm computation

    1924:    Notes:
    1925:    Only certain SNES methods support certain SNESNormSchedules.  Most require evaluation
    1926:    of the nonlinear function and the taking of its norm at every iteration to
    1927:    even ensure convergence at all.  However, methods such as custom Gauss-Seidel methods
    1928:    (SNESNGS) and the like do not require the norm of the function to be computed, and therfore
    1929:    may either be monitored for convergence or not.  As these are often used as nonlinear
    1930:    preconditioners, monitoring the norm of their error is not a useful enterprise within
    1931:    their solution.

    1933:    Level: developer

    1935: .keywords: SNES, nonlinear, set, function, norm, type

    1937: .seealso: SNESGetNormSchedule(), SNESComputeFunction(), VecNorm(), SNESSetFunction(), SNESSetInitialFunction(), SNESNormSchedule
    1938: @*/
    1939: PetscErrorCode  SNESSetFunctionType(SNES snes, SNESFunctionType type)
    1940: {
    1943:   snes->functype = type;
    1944:   return(0);
    1945: }

    1948: /*@C
    1949:    SNESGetFunctionType - Gets the SNESNormSchedule used in covergence and monitoring
    1950:    of the SNES method.

    1952:    Logically Collective on SNES

    1954:    Input Parameters:
    1955: +  snes - the SNES context
    1956: -  normschedule - the type of the norm used

    1958:    Level: advanced

    1960: .keywords: SNES, nonlinear, set, function, norm, type

    1962: .seealso: SNESSetNormSchedule(), SNESComputeFunction(), VecNorm(), SNESSetFunction(), SNESSetInitialFunction(), SNESNormSchedule
    1963: @*/
    1964: PetscErrorCode  SNESGetFunctionType(SNES snes, SNESFunctionType *type)
    1965: {
    1968:   *type = snes->functype;
    1969:   return(0);
    1970: }

    1972: /*MC
    1973:     SNESNGSFunction - function used to convey a Gauss-Seidel sweep on the nonlinear function

    1975:      Synopsis:
    1976:      #include <petscsnes.h>
    1977: $    SNESNGSFunction(SNES snes,Vec x,Vec b,void *ctx);

    1979: +  X   - solution vector
    1980: .  B   - RHS vector
    1981: -  ctx - optional user-defined Gauss-Seidel context

    1983:    Level: intermediate

    1985: .seealso:   SNESSetNGS(), SNESGetNGS()
    1986: M*/

    1988: /*@C
    1989:    SNESSetNGS - Sets the user nonlinear Gauss-Seidel routine for
    1990:    use with composed nonlinear solvers.

    1992:    Input Parameters:
    1993: +  snes   - the SNES context
    1994: .  f - function evaluation routine to apply Gauss-Seidel see SNESNGSFunction
    1995: -  ctx    - [optional] user-defined context for private data for the
    1996:             smoother evaluation routine (may be NULL)

    1998:    Notes:
    1999:    The NGS routines are used by the composed nonlinear solver to generate
    2000:     a problem appropriate update to the solution, particularly FAS.

    2002:    Level: intermediate

    2004: .keywords: SNES, nonlinear, set, Gauss-Seidel

    2006: .seealso: SNESGetFunction(), SNESComputeNGS()
    2007: @*/
    2008: PetscErrorCode SNESSetNGS(SNES snes,PetscErrorCode (*f)(SNES,Vec,Vec,void*),void *ctx)
    2009: {
    2011:   DM             dm;

    2015:   SNESGetDM(snes,&dm);
    2016:   DMSNESSetNGS(dm,f,ctx);
    2017:   return(0);
    2018: }

    2020: PetscErrorCode SNESPicardComputeFunction(SNES snes,Vec x,Vec f,void *ctx)
    2021: {
    2023:   DM             dm;
    2024:   DMSNES         sdm;

    2027:   SNESGetDM(snes,&dm);
    2028:   DMGetDMSNES(dm,&sdm);
    2029:   if (!sdm->ops->computepfunction) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE, "Must call SNESSetPicard() to provide Picard function.");
    2030:   if (!sdm->ops->computepjacobian) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE, "Must call SNESSetPicard() to provide Picard Jacobian.");
    2031:   /*  A(x)*x - b(x) */
    2032:   PetscStackPush("SNES Picard user function");
    2033:   (*sdm->ops->computepfunction)(snes,x,f,sdm->pctx);
    2034:   PetscStackPop;
    2035:   PetscStackPush("SNES Picard user Jacobian");
    2036:   (*sdm->ops->computepjacobian)(snes,x,snes->jacobian,snes->jacobian_pre,sdm->pctx);
    2037:   PetscStackPop;
    2038:   VecScale(f,-1.0);
    2039:   MatMultAdd(snes->jacobian,x,f,f);
    2040:   return(0);
    2041: }

    2043: PetscErrorCode SNESPicardComputeJacobian(SNES snes,Vec x1,Mat J,Mat B,void *ctx)
    2044: {
    2046:   /* the jacobian matrix should be pre-filled in SNESPicardComputeFunction */
    2047:   return(0);
    2048: }

    2050: /*@C
    2051:    SNESSetPicard - Use SNES to solve the semilinear-system A(x) x = b(x) via a Picard type iteration (Picard linearization)

    2053:    Logically Collective on SNES

    2055:    Input Parameters:
    2056: +  snes - the SNES context
    2057: .  r - vector to store function value
    2058: .  b - function evaluation routine
    2059: .  Amat - matrix with which A(x) x - b(x) is to be computed
    2060: .  Pmat - matrix from which preconditioner is computed (usually the same as Amat)
    2061: .  J  - function to compute matrix value, see SNESJacobianFunction for details on its calling sequence
    2062: -  ctx - [optional] user-defined context for private data for the
    2063:          function evaluation routine (may be NULL)

    2065:    Notes:
    2066:     We do not recomemend using this routine. It is far better to provide the nonlinear function F() and some approximation to the Jacobian and use
    2067:     an approximate Newton solver. This interface is provided to allow porting/testing a previous Picard based code in PETSc before converting it to approximate Newton.

    2069:     One can call SNESSetPicard() or SNESSetFunction() (and possibly SNESSetJacobian()) but cannot call both

    2071: $     Solves the equation A(x) x = b(x) via the defect correction algorithm A(x^{n}) (x^{n+1} - x^{n}) = b(x^{n}) - A(x^{n})x^{n}
    2072: $     Note that when an exact solver is used this corresponds to the "classic" Picard A(x^{n}) x^{n+1} = b(x^{n}) iteration.

    2074:      Run with -snes_mf_operator to solve the system with Newton's method using A(x^{n}) to construct the preconditioner.

    2076:    We implement the defect correction form of the Picard iteration because it converges much more generally when inexact linear solvers are used then
    2077:    the direct Picard iteration A(x^n) x^{n+1} = b(x^n)

    2079:    There is some controversity over the definition of a Picard iteration for nonlinear systems but almost everyone agrees that it involves a linear solve and some
    2080:    believe it is the iteration  A(x^{n}) x^{n+1} = b(x^{n}) hence we use the name Picard. If anyone has an authoritative  reference that defines the Picard iteration
    2081:    different please contact us at petsc-dev@mcs.anl.gov and we'll have an entirely new argument :-).

    2083:    Level: intermediate

    2085: .keywords: SNES, nonlinear, set, function

    2087: .seealso: SNESGetFunction(), SNESSetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESGetPicard(), SNESLineSearchPreCheckPicard(), SNESJacobianFunction
    2088: @*/
    2089: PetscErrorCode  SNESSetPicard(SNES snes,Vec r,PetscErrorCode (*b)(SNES,Vec,Vec,void*),Mat Amat, Mat Pmat, PetscErrorCode (*J)(SNES,Vec,Mat,Mat,void*),void *ctx)
    2090: {
    2092:   DM             dm;

    2096:   SNESGetDM(snes, &dm);
    2097:   DMSNESSetPicard(dm,b,J,ctx);
    2098:   SNESSetFunction(snes,r,SNESPicardComputeFunction,ctx);
    2099:   SNESSetJacobian(snes,Amat,Pmat,SNESPicardComputeJacobian,ctx);
    2100:   return(0);
    2101: }

    2103: /*@C
    2104:    SNESGetPicard - Returns the context for the Picard iteration

    2106:    Not Collective, but Vec is parallel if SNES is parallel. Collective if Vec is requested, but has not been created yet.

    2108:    Input Parameter:
    2109: .  snes - the SNES context

    2111:    Output Parameter:
    2112: +  r - the function (or NULL)
    2113: .  f - the function (or NULL); see SNESFunction for calling sequence details
    2114: .  Amat - the matrix used to defined the operation A(x) x - b(x) (or NULL)
    2115: .  Pmat  - the matrix from which the preconditioner will be constructed (or NULL)
    2116: .  J - the function for matrix evaluation (or NULL); see SNESJacobianFunction for calling sequence details
    2117: -  ctx - the function context (or NULL)

    2119:    Level: advanced

    2121: .keywords: SNES, nonlinear, get, function

    2123: .seealso: SNESSetPicard(), SNESGetFunction(), SNESGetJacobian(), SNESGetDM(), SNESFunction, SNESJacobianFunction
    2124: @*/
    2125: PetscErrorCode  SNESGetPicard(SNES snes,Vec *r,PetscErrorCode (**f)(SNES,Vec,Vec,void*),Mat *Amat, Mat *Pmat, PetscErrorCode (**J)(SNES,Vec,Mat,Mat,void*),void **ctx)
    2126: {
    2128:   DM             dm;

    2132:   SNESGetFunction(snes,r,NULL,NULL);
    2133:   SNESGetJacobian(snes,Amat,Pmat,NULL,NULL);
    2134:   SNESGetDM(snes,&dm);
    2135:   DMSNESGetPicard(dm,f,J,ctx);
    2136:   return(0);
    2137: }

    2139: /*@C
    2140:    SNESSetComputeInitialGuess - Sets a routine used to compute an initial guess for the problem

    2142:    Logically Collective on SNES

    2144:    Input Parameters:
    2145: +  snes - the SNES context
    2146: .  func - function evaluation routine
    2147: -  ctx - [optional] user-defined context for private data for the
    2148:          function evaluation routine (may be NULL)

    2150:    Calling sequence of func:
    2151: $    func (SNES snes,Vec x,void *ctx);

    2153: .  f - function vector
    2154: -  ctx - optional user-defined function context

    2156:    Level: intermediate

    2158: .keywords: SNES, nonlinear, set, function

    2160: .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian()
    2161: @*/
    2162: PetscErrorCode  SNESSetComputeInitialGuess(SNES snes,PetscErrorCode (*func)(SNES,Vec,void*),void *ctx)
    2163: {
    2166:   if (func) snes->ops->computeinitialguess = func;
    2167:   if (ctx)  snes->initialguessP            = ctx;
    2168:   return(0);
    2169: }

    2171: /* --------------------------------------------------------------- */
    2172: /*@C
    2173:    SNESGetRhs - Gets the vector for solving F(x) = rhs. If rhs is not set
    2174:    it assumes a zero right hand side.

    2176:    Logically Collective on SNES

    2178:    Input Parameter:
    2179: .  snes - the SNES context

    2181:    Output Parameter:
    2182: .  rhs - the right hand side vector or NULL if the right hand side vector is null

    2184:    Level: intermediate

    2186: .keywords: SNES, nonlinear, get, function, right hand side

    2188: .seealso: SNESGetSolution(), SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction()
    2189: @*/
    2190: PetscErrorCode  SNESGetRhs(SNES snes,Vec *rhs)
    2191: {
    2195:   *rhs = snes->vec_rhs;
    2196:   return(0);
    2197: }

    2199: /*@
    2200:    SNESComputeFunction - Calls the function that has been set with SNESSetFunction().

    2202:    Collective on SNES

    2204:    Input Parameters:
    2205: +  snes - the SNES context
    2206: -  x - input vector

    2208:    Output Parameter:
    2209: .  y - function vector, as set by SNESSetFunction()

    2211:    Notes:
    2212:    SNESComputeFunction() is typically used within nonlinear solvers
    2213:    implementations, so most users would not generally call this routine
    2214:    themselves.

    2216:    Level: developer

    2218: .keywords: SNES, nonlinear, compute, function

    2220: .seealso: SNESSetFunction(), SNESGetFunction()
    2221: @*/
    2222: PetscErrorCode  SNESComputeFunction(SNES snes,Vec x,Vec y)
    2223: {
    2225:   DM             dm;
    2226:   DMSNES         sdm;

    2234:   VecValidValues(x,2,PETSC_TRUE);

    2236:   SNESGetDM(snes,&dm);
    2237:   DMGetDMSNES(dm,&sdm);
    2238:   if (sdm->ops->computefunction) {
    2239:     if (sdm->ops->computefunction != SNESObjectiveComputeFunctionDefaultFD) {
    2240:       PetscLogEventBegin(SNES_FunctionEval,snes,x,y,0);
    2241:     }
    2242:     VecLockPush(x);
    2243:     PetscStackPush("SNES user function");
    2244:     (*sdm->ops->computefunction)(snes,x,y,sdm->functionctx);
    2245:     PetscStackPop;
    2246:     VecLockPop(x);
    2247:     if (sdm->ops->computefunction != SNESObjectiveComputeFunctionDefaultFD) {
    2248:       PetscLogEventEnd(SNES_FunctionEval,snes,x,y,0);
    2249:     }
    2250:   } else if (snes->vec_rhs) {
    2251:     MatMult(snes->jacobian, x, y);
    2252:   } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE, "Must call SNESSetFunction() or SNESSetDM() before SNESComputeFunction(), likely called from SNESSolve().");
    2253:   if (snes->vec_rhs) {
    2254:     VecAXPY(y,-1.0,snes->vec_rhs);
    2255:   }
    2256:   snes->nfuncs++;
    2257:   /*
    2258:      domainerror might not be set on all processes; so we tag vector locally with Inf and the next inner product or norm will
    2259:      propagate the value to all processes
    2260:   */
    2261:   if (snes->domainerror) {
    2262:     VecSetInf(y);
    2263:   }
    2264:   return(0);
    2265: }

    2267: /*@
    2268:    SNESComputeNGS - Calls the Gauss-Seidel function that has been set with  SNESSetNGS().

    2270:    Collective on SNES

    2272:    Input Parameters:
    2273: +  snes - the SNES context
    2274: .  x - input vector
    2275: -  b - rhs vector

    2277:    Output Parameter:
    2278: .  x - new solution vector

    2280:    Notes:
    2281:    SNESComputeNGS() is typically used within composed nonlinear solver
    2282:    implementations, so most users would not generally call this routine
    2283:    themselves.

    2285:    Level: developer

    2287: .keywords: SNES, nonlinear, compute, function

    2289: .seealso: SNESSetNGS(), SNESComputeFunction()
    2290: @*/
    2291: PetscErrorCode  SNESComputeNGS(SNES snes,Vec b,Vec x)
    2292: {
    2294:   DM             dm;
    2295:   DMSNES         sdm;

    2303:   if (b) {VecValidValues(b,2,PETSC_TRUE);}
    2304:   PetscLogEventBegin(SNES_NGSEval,snes,x,b,0);
    2305:   SNESGetDM(snes,&dm);
    2306:   DMGetDMSNES(dm,&sdm);
    2307:   if (sdm->ops->computegs) {
    2308:     if (b) {VecLockPush(b);}
    2309:     PetscStackPush("SNES user NGS");
    2310:     (*sdm->ops->computegs)(snes,x,b,sdm->gsctx);
    2311:     PetscStackPop;
    2312:     if (b) {VecLockPop(b);}
    2313:   } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE, "Must call SNESSetNGS() before SNESComputeNGS(), likely called from SNESSolve().");
    2314:   PetscLogEventEnd(SNES_NGSEval,snes,x,b,0);
    2315:   return(0);
    2316: }

    2318: PetscErrorCode SNESTestJacobian(SNES snes)
    2319: {
    2320:   Mat               A,B,C,D,jacobian;
    2321:   Vec               x = snes->vec_sol,f = snes->vec_func;
    2322:   PetscErrorCode    ierr;
    2323:   PetscReal         nrm,gnorm;
    2324:   PetscReal         threshold = 1.e-5;
    2325:   PetscInt          m,n,M,N;
    2326:   void              *functx;
    2327:   PetscBool         complete_print = PETSC_FALSE,threshold_print = PETSC_FALSE,test = PETSC_FALSE,flg;
    2328:   PetscViewer       viewer,mviewer;
    2329:   MPI_Comm          comm;
    2330:   PetscInt          tabs;
    2331:   static PetscBool  directionsprinted = PETSC_FALSE;
    2332:   PetscViewerFormat format;

    2335:   PetscObjectOptionsBegin((PetscObject)snes);
    2336:   PetscOptionsName("-snes_test_jacobian","Compare hand-coded and finite difference Jacobians","None",&test);
    2337:   PetscOptionsReal("-snes_test_jacobian", "Threshold for element difference between hand-coded and finite difference being meaningful", "None", threshold, &threshold,NULL);
    2338:   PetscOptionsViewer("-snes_test_jacobian_view","View difference between hand-coded and finite difference Jacobians element entries","None",&mviewer,&format,&complete_print);
    2339:   if (!complete_print) {
    2340:     PetscOptionsViewer("-snes_test_jacobian_display","Display difference between hand-coded and finite difference Jacobians","None",&mviewer,&format,&complete_print);
    2341:   }
    2342:   /* for compatibility with PETSc 3.9 and older. */
    2343:   PetscOptionsReal("-snes_test_jacobian_display_threshold", "Display difference between hand-coded and finite difference Jacobians which exceed input threshold", "None", threshold, &threshold, &threshold_print);
    2344:   PetscOptionsEnd();
    2345:   if (!test) return(0);

    2347:   PetscObjectGetComm((PetscObject)snes,&comm);
    2348:   PetscViewerASCIIGetStdout(comm,&viewer);
    2349:   PetscViewerASCIIGetTab(viewer, &tabs);
    2350:   PetscViewerASCIISetTab(viewer, ((PetscObject)snes)->tablevel);
    2351:   PetscViewerASCIIPrintf(viewer,"  ---------- Testing Jacobian -------------\n");
    2352:   if (!complete_print && !directionsprinted) {
    2353:     PetscViewerASCIIPrintf(viewer,"  Run with -snes_test_jacobian_view and optionally -snes_test_jacobian <threshold> to show difference\n");
    2354:     PetscViewerASCIIPrintf(viewer,"    of hand-coded and finite difference Jacobian entries greater than <threshold>.\n");
    2355:   }
    2356:   if (!directionsprinted) {
    2357:     PetscViewerASCIIPrintf(viewer,"  Testing hand-coded Jacobian, if (for double precision runs) ||J - Jfd||_F/||J||_F is\n");
    2358:     PetscViewerASCIIPrintf(viewer,"    O(1.e-8), the hand-coded Jacobian is probably correct.\n");
    2359:     directionsprinted = PETSC_TRUE;
    2360:   }
    2361:   if (complete_print) {
    2362:     PetscViewerPushFormat(mviewer,format);
    2363:   }

    2365:   /* evaluate the function at this point because SNESComputeJacobianDefault() assumes that the function has been evaluated and put into snes->vec_func */
    2366:   SNESComputeFunction(snes,x,f);

    2368:   PetscObjectTypeCompare((PetscObject)snes->jacobian,MATMFFD,&flg);
    2369:   if (!flg) jacobian = snes->jacobian;
    2370:   else jacobian = snes->jacobian_pre;

    2372:   while (jacobian) {
    2373:     PetscObjectTypeCompareAny((PetscObject)jacobian,&flg,MATSEQAIJ,MATMPIAIJ,MATSEQDENSE,MATMPIDENSE,MATSEQBAIJ,MATMPIBAIJ,MATSEQSBAIJ,MATMPIBAIJ,"");
    2374:     if (flg) {
    2375:       A    = jacobian;
    2376:       PetscObjectReference((PetscObject)A);
    2377:     } else {
    2378:       MatComputeExplicitOperator(jacobian,&A);
    2379:     }

    2381:     MatCreate(PetscObjectComm((PetscObject)A),&B);
    2382:     MatGetSize(A,&M,&N);
    2383:     MatGetLocalSize(A,&m,&n);
    2384:     MatSetSizes(B,m,n,M,N);
    2385:     MatSetType(B,((PetscObject)A)->type_name);
    2386:     MatSetUp(B);
    2387:     MatSetOption(B,MAT_NEW_NONZERO_ALLOCATION_ERR,PETSC_FALSE);

    2389:     SNESGetFunction(snes,NULL,NULL,&functx);
    2390:     SNESComputeJacobianDefault(snes,x,B,B,functx);

    2392:     MatDuplicate(B,MAT_COPY_VALUES,&D);
    2393:     MatAYPX(D,-1.0,A,DIFFERENT_NONZERO_PATTERN);
    2394:     MatNorm(D,NORM_FROBENIUS,&nrm);
    2395:     MatNorm(A,NORM_FROBENIUS,&gnorm);
    2396:     MatDestroy(&D);
    2397:     if (!gnorm) gnorm = 1; /* just in case */
    2398:     PetscViewerASCIIPrintf(viewer,"  ||J - Jfd||_F/||J||_F = %g, ||J - Jfd||_F = %g\n",(double)(nrm/gnorm),(double)nrm);

    2400:     if (complete_print) {
    2401:       PetscViewerASCIIPrintf(viewer,"  Hand-coded Jacobian ----------\n");
    2402:       MatView(jacobian,mviewer);
    2403:       PetscViewerASCIIPrintf(viewer,"  Finite difference Jacobian ----------\n");
    2404:       MatView(B,mviewer);
    2405:     }

    2407:     if (threshold_print || complete_print) {
    2408:       PetscInt          Istart, Iend, *ccols, bncols, cncols, j, row;
    2409:       PetscScalar       *cvals;
    2410:       const PetscInt    *bcols;
    2411:       const PetscScalar *bvals;

    2413:       MatAYPX(B,-1.0,A,DIFFERENT_NONZERO_PATTERN);
    2414:       MatCreate(PetscObjectComm((PetscObject)A),&C);
    2415:       MatSetSizes(C,m,n,M,N);
    2416:       MatSetType(C,((PetscObject)A)->type_name);
    2417:       MatSetUp(C);
    2418:       MatSetOption(C,MAT_NEW_NONZERO_ALLOCATION_ERR,PETSC_FALSE);
    2419:       MatGetOwnershipRange(B,&Istart,&Iend);

    2421:       for (row = Istart; row < Iend; row++) {
    2422:         MatGetRow(B,row,&bncols,&bcols,&bvals);
    2423:         PetscMalloc2(bncols,&ccols,bncols,&cvals);
    2424:         for (j = 0, cncols = 0; j < bncols; j++) {
    2425:           if (PetscAbsScalar(bvals[j]) > threshold) {
    2426:             ccols[cncols] = bcols[j];
    2427:             cvals[cncols] = bvals[j];
    2428:             cncols += 1;
    2429:           }
    2430:         }
    2431:         if (cncols) {
    2432:           MatSetValues(C,1,&row,cncols,ccols,cvals,INSERT_VALUES);
    2433:         }
    2434:         MatRestoreRow(B,row,&bncols,&bcols,&bvals);
    2435:         PetscFree2(ccols,cvals);
    2436:       }
    2437:       MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY);
    2438:       MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY);
    2439:       PetscViewerASCIIPrintf(viewer,"  Hand-coded minus finite-difference Jacobian with tolerance %g ----------\n",(double)threshold);
    2440:       MatView(C,complete_print ? mviewer : viewer);
    2441:       MatDestroy(&C);
    2442:     }
    2443:     MatDestroy(&A);
    2444:     MatDestroy(&B);

    2446:     if (jacobian != snes->jacobian_pre) {
    2447:       jacobian = snes->jacobian_pre;
    2448:       PetscViewerASCIIPrintf(viewer,"  ---------- Testing Jacobian for preconditioner -------------\n");
    2449:     }
    2450:     else jacobian = NULL;
    2451:   }
    2452:   if (complete_print) {
    2453:     PetscViewerPopFormat(mviewer);
    2454:   }
    2455:   if (mviewer) { PetscViewerDestroy(&mviewer); }
    2456:   PetscViewerASCIISetTab(viewer,tabs);
    2457:   return(0);
    2458: }

    2460: /*@
    2461:    SNESComputeJacobian - Computes the Jacobian matrix that has been set with SNESSetJacobian().

    2463:    Collective on SNES and Mat

    2465:    Input Parameters:
    2466: +  snes - the SNES context
    2467: -  x - input vector

    2469:    Output Parameters:
    2470: +  A - Jacobian matrix
    2471: -  B - optional preconditioning matrix

    2473:   Options Database Keys:
    2474: +    -snes_lag_preconditioner <lag>
    2475: .    -snes_lag_jacobian <lag>
    2476: .    -snes_test_jacobian - compare the user provided Jacobian with one compute via finite differences to check for errors
    2477: .    -snes_test_jacobian_display - display the user provided Jacobian, the finite difference Jacobian and the difference between them to help users detect the location of errors in the user provided Jacobian
    2478: .    -snes_test_jacobian_display_threshold <numerical value>  - display entries in the difference between the user provided Jacobian and finite difference Jacobian that are greater than a certain value to help users detect errors
    2479: .    -snes_compare_explicit - Compare the computed Jacobian to the finite difference Jacobian and output the differences
    2480: .    -snes_compare_explicit_draw  - Compare the computed Jacobian to the finite difference Jacobian and draw the result
    2481: .    -snes_compare_explicit_contour  - Compare the computed Jacobian to the finite difference Jacobian and draw a contour plot with the result
    2482: .    -snes_compare_operator  - Make the comparison options above use the operator instead of the preconditioning matrix
    2483: .    -snes_compare_coloring - Compute the finite difference Jacobian using coloring and display norms of difference
    2484: .    -snes_compare_coloring_display - Compute the finite differece Jacobian using coloring and display verbose differences
    2485: .    -snes_compare_coloring_threshold - Display only those matrix entries that differ by more than a given threshold
    2486: .    -snes_compare_coloring_threshold_atol - Absolute tolerance for difference in matrix entries to be displayed by -snes_compare_coloring_threshold
    2487: .    -snes_compare_coloring_threshold_rtol - Relative tolerance for difference in matrix entries to be displayed by -snes_compare_coloring_threshold
    2488: .    -snes_compare_coloring_draw - Compute the finite differece Jacobian using coloring and draw differences
    2489: -    -snes_compare_coloring_draw_contour - Compute the finite differece Jacobian using coloring and show contours of matrices and differences

    2492:    Notes:
    2493:    Most users should not need to explicitly call this routine, as it
    2494:    is used internally within the nonlinear solvers.

    2496:    Developer Notes:
    2497:     This has duplicative ways of checking the accuracy of the user provided Jacobian (see the options above). This is for historical reasons, the routine SNESTestJacobian() use to used
    2498:       for with the SNESType of test that has been removed.

    2500:    Level: developer

    2502: .keywords: SNES, compute, Jacobian, matrix

    2504: .seealso:  SNESSetJacobian(), KSPSetOperators(), MatStructure, SNESSetLagPreconditioner(), SNESSetLagJacobian()
    2505: @*/
    2506: PetscErrorCode  SNESComputeJacobian(SNES snes,Vec X,Mat A,Mat B)
    2507: {
    2509:   PetscBool      flag;
    2510:   DM             dm;
    2511:   DMSNES         sdm;
    2512:   KSP            ksp;

    2518:   VecValidValues(X,2,PETSC_TRUE);
    2519:   SNESGetDM(snes,&dm);
    2520:   DMGetDMSNES(dm,&sdm);

    2522:   if (!sdm->ops->computejacobian) SETERRQ(PetscObjectComm((PetscObject)snes),PETSC_ERR_USER,"Must call SNESSetJacobian(), DMSNESSetJacobian(), DMDASNESSetJacobianLocal(), etc");

    2524:   /* make sure that MatAssemblyBegin/End() is called on A matrix if it is matrix free */

    2526:   if (snes->lagjacobian == -2) {
    2527:     snes->lagjacobian = -1;

    2529:     PetscInfo(snes,"Recomputing Jacobian/preconditioner because lag is -2 (means compute Jacobian, but then never again) \n");
    2530:   } else if (snes->lagjacobian == -1) {
    2531:     PetscInfo(snes,"Reusing Jacobian/preconditioner because lag is -1\n");
    2532:     PetscObjectTypeCompare((PetscObject)A,MATMFFD,&flag);
    2533:     if (flag) {
    2534:       MatAssemblyBegin(A,MAT_FINAL_ASSEMBLY);
    2535:       MatAssemblyEnd(A,MAT_FINAL_ASSEMBLY);
    2536:     }
    2537:     return(0);
    2538:   } else if (snes->lagjacobian > 1 && (snes->iter + snes->jac_iter) % snes->lagjacobian) {
    2539:     PetscInfo2(snes,"Reusing Jacobian/preconditioner because lag is %D and SNES iteration is %D\n",snes->lagjacobian,snes->iter);
    2540:     PetscObjectTypeCompare((PetscObject)A,MATMFFD,&flag);
    2541:     if (flag) {
    2542:       MatAssemblyBegin(A,MAT_FINAL_ASSEMBLY);
    2543:       MatAssemblyEnd(A,MAT_FINAL_ASSEMBLY);
    2544:     }
    2545:     return(0);
    2546:   }
    2547:   if (snes->npc && snes->npcside== PC_LEFT) {
    2548:       MatAssemblyBegin(A,MAT_FINAL_ASSEMBLY);
    2549:       MatAssemblyEnd(A,MAT_FINAL_ASSEMBLY);
    2550:       return(0);
    2551:   }

    2553:   PetscLogEventBegin(SNES_JacobianEval,snes,X,A,B);
    2554:   VecLockPush(X);
    2555:   PetscStackPush("SNES user Jacobian function");
    2556:   (*sdm->ops->computejacobian)(snes,X,A,B,sdm->jacobianctx);
    2557:   PetscStackPop;
    2558:   VecLockPop(X);
    2559:   PetscLogEventEnd(SNES_JacobianEval,snes,X,A,B);

    2561:   /* the next line ensures that snes->ksp exists */
    2562:   SNESGetKSP(snes,&ksp);
    2563:   if (snes->lagpreconditioner == -2) {
    2564:     PetscInfo(snes,"Rebuilding preconditioner exactly once since lag is -2\n");
    2565:     KSPSetReusePreconditioner(snes->ksp,PETSC_FALSE);
    2566:     snes->lagpreconditioner = -1;
    2567:   } else if (snes->lagpreconditioner == -1) {
    2568:     PetscInfo(snes,"Reusing preconditioner because lag is -1\n");
    2569:     KSPSetReusePreconditioner(snes->ksp,PETSC_TRUE);
    2570:   } else if (snes->lagpreconditioner > 1 && (snes->iter + snes->pre_iter) % snes->lagpreconditioner) {
    2571:     PetscInfo2(snes,"Reusing preconditioner because lag is %D and SNES iteration is %D\n",snes->lagpreconditioner,snes->iter);
    2572:     KSPSetReusePreconditioner(snes->ksp,PETSC_TRUE);
    2573:   } else {
    2574:     PetscInfo(snes,"Rebuilding preconditioner\n");
    2575:     KSPSetReusePreconditioner(snes->ksp,PETSC_FALSE);
    2576:   }

    2578:   SNESTestJacobian(snes);
    2579:   /* make sure user returned a correct Jacobian and preconditioner */
    2582:   {
    2583:     PetscBool flag = PETSC_FALSE,flag_draw = PETSC_FALSE,flag_contour = PETSC_FALSE,flag_operator = PETSC_FALSE;
    2584:     PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes),((PetscObject)snes)->prefix,"-snes_compare_explicit",NULL,NULL,&flag);
    2585:     PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes),((PetscObject)snes)->prefix,"-snes_compare_explicit_draw",NULL,NULL,&flag_draw);
    2586:     PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes),((PetscObject)snes)->prefix,"-snes_compare_explicit_draw_contour",NULL,NULL,&flag_contour);
    2587:     PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes),((PetscObject)snes)->prefix,"-snes_compare_operator",NULL,NULL,&flag_operator);
    2588:     if (flag || flag_draw || flag_contour) {
    2589:       Mat          Bexp_mine = NULL,Bexp,FDexp;
    2590:       PetscViewer  vdraw,vstdout;
    2591:       PetscBool    flg;
    2592:       if (flag_operator) {
    2593:         MatComputeExplicitOperator(A,&Bexp_mine);
    2594:         Bexp = Bexp_mine;
    2595:       } else {
    2596:         /* See if the preconditioning matrix can be viewed and added directly */
    2597:         PetscObjectTypeCompareAny((PetscObject)B,&flg,MATSEQAIJ,MATMPIAIJ,MATSEQDENSE,MATMPIDENSE,MATSEQBAIJ,MATMPIBAIJ,MATSEQSBAIJ,MATMPIBAIJ,"");
    2598:         if (flg) Bexp = B;
    2599:         else {
    2600:           /* If the "preconditioning" matrix is itself MATSHELL or some other type without direct support */
    2601:           MatComputeExplicitOperator(B,&Bexp_mine);
    2602:           Bexp = Bexp_mine;
    2603:         }
    2604:       }
    2605:       MatConvert(Bexp,MATSAME,MAT_INITIAL_MATRIX,&FDexp);
    2606:       SNESComputeJacobianDefault(snes,X,FDexp,FDexp,NULL);
    2607:       PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)snes),&vstdout);
    2608:       if (flag_draw || flag_contour) {
    2609:         PetscViewerDrawOpen(PetscObjectComm((PetscObject)snes),0,"Explicit Jacobians",PETSC_DECIDE,PETSC_DECIDE,300,300,&vdraw);
    2610:         if (flag_contour) {PetscViewerPushFormat(vdraw,PETSC_VIEWER_DRAW_CONTOUR);}
    2611:       } else vdraw = NULL;
    2612:       PetscViewerASCIIPrintf(vstdout,"Explicit %s\n",flag_operator ? "Jacobian" : "preconditioning Jacobian");
    2613:       if (flag) {MatView(Bexp,vstdout);}
    2614:       if (vdraw) {MatView(Bexp,vdraw);}
    2615:       PetscViewerASCIIPrintf(vstdout,"Finite difference Jacobian\n");
    2616:       if (flag) {MatView(FDexp,vstdout);}
    2617:       if (vdraw) {MatView(FDexp,vdraw);}
    2618:       MatAYPX(FDexp,-1.0,Bexp,SAME_NONZERO_PATTERN);
    2619:       PetscViewerASCIIPrintf(vstdout,"User-provided matrix minus finite difference Jacobian\n");
    2620:       if (flag) {MatView(FDexp,vstdout);}
    2621:       if (vdraw) {              /* Always use contour for the difference */
    2622:         PetscViewerPushFormat(vdraw,PETSC_VIEWER_DRAW_CONTOUR);
    2623:         MatView(FDexp,vdraw);
    2624:         PetscViewerPopFormat(vdraw);
    2625:       }
    2626:       if (flag_contour) {PetscViewerPopFormat(vdraw);}
    2627:       PetscViewerDestroy(&vdraw);
    2628:       MatDestroy(&Bexp_mine);
    2629:       MatDestroy(&FDexp);
    2630:     }
    2631:   }
    2632:   {
    2633:     PetscBool flag = PETSC_FALSE,flag_display = PETSC_FALSE,flag_draw = PETSC_FALSE,flag_contour = PETSC_FALSE,flag_threshold = PETSC_FALSE;
    2634:     PetscReal threshold_atol = PETSC_SQRT_MACHINE_EPSILON,threshold_rtol = 10*PETSC_SQRT_MACHINE_EPSILON;
    2635:     PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes),((PetscObject)snes)->prefix,"-snes_compare_coloring",NULL,NULL,&flag);
    2636:     PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes),((PetscObject)snes)->prefix,"-snes_compare_coloring_display",NULL,NULL,&flag_display);
    2637:     PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes),((PetscObject)snes)->prefix,"-snes_compare_coloring_draw",NULL,NULL,&flag_draw);
    2638:     PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes),((PetscObject)snes)->prefix,"-snes_compare_coloring_draw_contour",NULL,NULL,&flag_contour);
    2639:     PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes),((PetscObject)snes)->prefix,"-snes_compare_coloring_threshold",NULL,NULL,&flag_threshold);
    2640:     if (flag_threshold) {
    2641:       PetscOptionsGetReal(((PetscObject)snes)->options,((PetscObject)snes)->prefix,"-snes_compare_coloring_threshold_rtol",&threshold_rtol,NULL);
    2642:       PetscOptionsGetReal(((PetscObject)snes)->options,((PetscObject)snes)->prefix,"-snes_compare_coloring_threshold_atol",&threshold_atol,NULL);
    2643:     }
    2644:     if (flag || flag_display || flag_draw || flag_contour || flag_threshold) {
    2645:       Mat            Bfd;
    2646:       PetscViewer    vdraw,vstdout;
    2647:       MatColoring    coloring;
    2648:       ISColoring     iscoloring;
    2649:       MatFDColoring  matfdcoloring;
    2650:       PetscErrorCode (*func)(SNES,Vec,Vec,void*);
    2651:       void           *funcctx;
    2652:       PetscReal      norm1,norm2,normmax;

    2654:       MatDuplicate(B,MAT_DO_NOT_COPY_VALUES,&Bfd);
    2655:       MatColoringCreate(Bfd,&coloring);
    2656:       MatColoringSetType(coloring,MATCOLORINGSL);
    2657:       MatColoringSetFromOptions(coloring);
    2658:       MatColoringApply(coloring,&iscoloring);
    2659:       MatColoringDestroy(&coloring);
    2660:       MatFDColoringCreate(Bfd,iscoloring,&matfdcoloring);
    2661:       MatFDColoringSetFromOptions(matfdcoloring);
    2662:       MatFDColoringSetUp(Bfd,iscoloring,matfdcoloring);
    2663:       ISColoringDestroy(&iscoloring);

    2665:       /* This method of getting the function is currently unreliable since it doesn't work for DM local functions. */
    2666:       SNESGetFunction(snes,NULL,&func,&funcctx);
    2667:       MatFDColoringSetFunction(matfdcoloring,(PetscErrorCode (*)(void))func,funcctx);
    2668:       PetscObjectSetOptionsPrefix((PetscObject)matfdcoloring,((PetscObject)snes)->prefix);
    2669:       PetscObjectAppendOptionsPrefix((PetscObject)matfdcoloring,"coloring_");
    2670:       MatFDColoringSetFromOptions(matfdcoloring);
    2671:       MatFDColoringApply(Bfd,matfdcoloring,X,snes);
    2672:       MatFDColoringDestroy(&matfdcoloring);

    2674:       PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)snes),&vstdout);
    2675:       if (flag_draw || flag_contour) {
    2676:         PetscViewerDrawOpen(PetscObjectComm((PetscObject)snes),0,"Colored Jacobians",PETSC_DECIDE,PETSC_DECIDE,300,300,&vdraw);
    2677:         if (flag_contour) {PetscViewerPushFormat(vdraw,PETSC_VIEWER_DRAW_CONTOUR);}
    2678:       } else vdraw = NULL;
    2679:       PetscViewerASCIIPrintf(vstdout,"Explicit preconditioning Jacobian\n");
    2680:       if (flag_display) {MatView(B,vstdout);}
    2681:       if (vdraw) {MatView(B,vdraw);}
    2682:       PetscViewerASCIIPrintf(vstdout,"Colored Finite difference Jacobian\n");
    2683:       if (flag_display) {MatView(Bfd,vstdout);}
    2684:       if (vdraw) {MatView(Bfd,vdraw);}
    2685:       MatAYPX(Bfd,-1.0,B,SAME_NONZERO_PATTERN);
    2686:       MatNorm(Bfd,NORM_1,&norm1);
    2687:       MatNorm(Bfd,NORM_FROBENIUS,&norm2);
    2688:       MatNorm(Bfd,NORM_MAX,&normmax);
    2689:       PetscViewerASCIIPrintf(vstdout,"User-provided matrix minus finite difference Jacobian, norm1=%g normFrob=%g normmax=%g\n",(double)norm1,(double)norm2,(double)normmax);
    2690:       if (flag_display) {MatView(Bfd,vstdout);}
    2691:       if (vdraw) {              /* Always use contour for the difference */
    2692:         PetscViewerPushFormat(vdraw,PETSC_VIEWER_DRAW_CONTOUR);
    2693:         MatView(Bfd,vdraw);
    2694:         PetscViewerPopFormat(vdraw);
    2695:       }
    2696:       if (flag_contour) {PetscViewerPopFormat(vdraw);}

    2698:       if (flag_threshold) {
    2699:         PetscInt bs,rstart,rend,i;
    2700:         MatGetBlockSize(B,&bs);
    2701:         MatGetOwnershipRange(B,&rstart,&rend);
    2702:         for (i=rstart; i<rend; i++) {
    2703:           const PetscScalar *ba,*ca;
    2704:           const PetscInt    *bj,*cj;
    2705:           PetscInt          bn,cn,j,maxentrycol = -1,maxdiffcol = -1,maxrdiffcol = -1;
    2706:           PetscReal         maxentry = 0,maxdiff = 0,maxrdiff = 0;
    2707:           MatGetRow(B,i,&bn,&bj,&ba);
    2708:           MatGetRow(Bfd,i,&cn,&cj,&ca);
    2709:           if (bn != cn) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_PLIB,"Unexpected different nonzero pattern in -snes_compare_coloring_threshold");
    2710:           for (j=0; j<bn; j++) {
    2711:             PetscReal rdiff = PetscAbsScalar(ca[j]) / (threshold_atol + threshold_rtol*PetscAbsScalar(ba[j]));
    2712:             if (PetscAbsScalar(ba[j]) > PetscAbs(maxentry)) {
    2713:               maxentrycol = bj[j];
    2714:               maxentry    = PetscRealPart(ba[j]);
    2715:             }
    2716:             if (PetscAbsScalar(ca[j]) > PetscAbs(maxdiff)) {
    2717:               maxdiffcol = bj[j];
    2718:               maxdiff    = PetscRealPart(ca[j]);
    2719:             }
    2720:             if (rdiff > maxrdiff) {
    2721:               maxrdiffcol = bj[j];
    2722:               maxrdiff    = rdiff;
    2723:             }
    2724:           }
    2725:           if (maxrdiff > 1) {
    2726:             PetscViewerASCIIPrintf(vstdout,"row %D (maxentry=%g at %D, maxdiff=%g at %D, maxrdiff=%g at %D):",i,(double)maxentry,maxentrycol,(double)maxdiff,maxdiffcol,(double)maxrdiff,maxrdiffcol);
    2727:             for (j=0; j<bn; j++) {
    2728:               PetscReal rdiff;
    2729:               rdiff = PetscAbsScalar(ca[j]) / (threshold_atol + threshold_rtol*PetscAbsScalar(ba[j]));
    2730:               if (rdiff > 1) {
    2731:                 PetscViewerASCIIPrintf(vstdout," (%D,%g:%g)",bj[j],(double)PetscRealPart(ba[j]),(double)PetscRealPart(ca[j]));
    2732:               }
    2733:             }
    2734:             PetscViewerASCIIPrintf(vstdout,"\n",i,maxentry,maxdiff,maxrdiff);
    2735:           }
    2736:           MatRestoreRow(B,i,&bn,&bj,&ba);
    2737:           MatRestoreRow(Bfd,i,&cn,&cj,&ca);
    2738:         }
    2739:       }
    2740:       PetscViewerDestroy(&vdraw);
    2741:       MatDestroy(&Bfd);
    2742:     }
    2743:   }
    2744:   return(0);
    2745: }

    2747: /*MC
    2748:     SNESJacobianFunction - Function used to convey the nonlinear Jacobian of the function to be solved by SNES

    2750:      Synopsis:
    2751:      #include "petscsnes.h"
    2752:      PetscErrorCode SNESJacobianFunction(SNES snes,Vec x,Mat Amat,Mat Pmat,void *ctx);

    2754: +  x - input vector
    2755: .  Amat - the matrix that defines the (approximate) Jacobian
    2756: .  Pmat - the matrix to be used in constructing the preconditioner, usually the same as Amat.
    2757: -  ctx - [optional] user-defined Jacobian context

    2759:    Level: intermediate

    2761: .seealso:   SNESSetFunction(), SNESGetFunction(), SNESSetJacobian(), SNESGetJacobian()
    2762: M*/

    2764: /*@C
    2765:    SNESSetJacobian - Sets the function to compute Jacobian as well as the
    2766:    location to store the matrix.

    2768:    Logically Collective on SNES and Mat

    2770:    Input Parameters:
    2771: +  snes - the SNES context
    2772: .  Amat - the matrix that defines the (approximate) Jacobian
    2773: .  Pmat - the matrix to be used in constructing the preconditioner, usually the same as Amat.
    2774: .  J - Jacobian evaluation routine (if NULL then SNES retains any previously set value), see SNESJacobianFunction for details
    2775: -  ctx - [optional] user-defined context for private data for the
    2776:          Jacobian evaluation routine (may be NULL) (if NULL then SNES retains any previously set value)

    2778:    Notes:
    2779:    If the Amat matrix and Pmat matrix are different you must call MatAssemblyBegin/End() on
    2780:    each matrix.

    2782:    If you know the operator Amat has a null space you can use MatSetNullSpace() and MatSetTransposeNullSpace() to supply the null
    2783:    space to Amat and the KSP solvers will automatically use that null space as needed during the solution process.

    2785:    If using SNESComputeJacobianDefaultColor() to assemble a Jacobian, the ctx argument
    2786:    must be a MatFDColoring.

    2788:    Other defect-correction schemes can be used by computing a different matrix in place of the Jacobian.  One common
    2789:    example is to use the "Picard linearization" which only differentiates through the highest order parts of each term.

    2791:    Level: beginner

    2793: .keywords: SNES, nonlinear, set, Jacobian, matrix

    2795: .seealso: KSPSetOperators(), SNESSetFunction(), MatMFFDComputeJacobian(), SNESComputeJacobianDefaultColor(), MatStructure, J,
    2796:           SNESSetPicard(), SNESJacobianFunction
    2797: @*/
    2798: PetscErrorCode  SNESSetJacobian(SNES snes,Mat Amat,Mat Pmat,PetscErrorCode (*J)(SNES,Vec,Mat,Mat,void*),void *ctx)
    2799: {
    2801:   DM             dm;

    2809:   SNESGetDM(snes,&dm);
    2810:   DMSNESSetJacobian(dm,J,ctx);
    2811:   if (Amat) {
    2812:     PetscObjectReference((PetscObject)Amat);
    2813:     MatDestroy(&snes->jacobian);

    2815:     snes->jacobian = Amat;
    2816:   }
    2817:   if (Pmat) {
    2818:     PetscObjectReference((PetscObject)Pmat);
    2819:     MatDestroy(&snes->jacobian_pre);

    2821:     snes->jacobian_pre = Pmat;
    2822:   }
    2823:   return(0);
    2824: }

    2826: /*@C
    2827:    SNESGetJacobian - Returns the Jacobian matrix and optionally the user
    2828:    provided context for evaluating the Jacobian.

    2830:    Not Collective, but Mat object will be parallel if SNES object is

    2832:    Input Parameter:
    2833: .  snes - the nonlinear solver context

    2835:    Output Parameters:
    2836: +  Amat - location to stash (approximate) Jacobian matrix (or NULL)
    2837: .  Pmat - location to stash matrix used to compute the preconditioner (or NULL)
    2838: .  J - location to put Jacobian function (or NULL), see SNESJacobianFunction for details on its calling sequence
    2839: -  ctx - location to stash Jacobian ctx (or NULL)

    2841:    Level: advanced

    2843: .seealso: SNESSetJacobian(), SNESComputeJacobian(), SNESJacobianFunction, SNESGetFunction()
    2844: @*/
    2845: PetscErrorCode SNESGetJacobian(SNES snes,Mat *Amat,Mat *Pmat,PetscErrorCode (**J)(SNES,Vec,Mat,Mat,void*),void **ctx)
    2846: {
    2848:   DM             dm;
    2849:   DMSNES         sdm;

    2853:   if (Amat) *Amat = snes->jacobian;
    2854:   if (Pmat) *Pmat = snes->jacobian_pre;
    2855:   SNESGetDM(snes,&dm);
    2856:   DMGetDMSNES(dm,&sdm);
    2857:   if (J) *J = sdm->ops->computejacobian;
    2858:   if (ctx) *ctx = sdm->jacobianctx;
    2859:   return(0);
    2860: }

    2862: /*@
    2863:    SNESSetUp - Sets up the internal data structures for the later use
    2864:    of a nonlinear solver.

    2866:    Collective on SNES

    2868:    Input Parameters:
    2869: .  snes - the SNES context

    2871:    Notes:
    2872:    For basic use of the SNES solvers the user need not explicitly call
    2873:    SNESSetUp(), since these actions will automatically occur during
    2874:    the call to SNESSolve().  However, if one wishes to control this
    2875:    phase separately, SNESSetUp() should be called after SNESCreate()
    2876:    and optional routines of the form SNESSetXXX(), but before SNESSolve().

    2878:    Level: advanced

    2880: .keywords: SNES, nonlinear, setup

    2882: .seealso: SNESCreate(), SNESSolve(), SNESDestroy()
    2883: @*/
    2884: PetscErrorCode  SNESSetUp(SNES snes)
    2885: {
    2887:   DM             dm;
    2888:   DMSNES         sdm;
    2889:   SNESLineSearch linesearch, pclinesearch;
    2890:   void           *lsprectx,*lspostctx;
    2891:   PetscErrorCode (*precheck)(SNESLineSearch,Vec,Vec,PetscBool*,void*);
    2892:   PetscErrorCode (*postcheck)(SNESLineSearch,Vec,Vec,Vec,PetscBool*,PetscBool*,void*);
    2893:   PetscErrorCode (*func)(SNES,Vec,Vec,void*);
    2894:   Vec            f,fpc;
    2895:   void           *funcctx;
    2896:   PetscErrorCode (*jac)(SNES,Vec,Mat,Mat,void*);
    2897:   void           *jacctx,*appctx;
    2898:   Mat            j,jpre;

    2902:   if (snes->setupcalled) return(0);

    2904:   if (!((PetscObject)snes)->type_name) {
    2905:     SNESSetType(snes,SNESNEWTONLS);
    2906:   }

    2908:   SNESGetFunction(snes,&snes->vec_func,NULL,NULL);

    2910:   SNESGetDM(snes,&dm);
    2911:   DMGetDMSNES(dm,&sdm);
    2912:   if (!sdm->ops->computefunction) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_WRONGSTATE,"Function never provided to SNES object");
    2913:   if (!sdm->ops->computejacobian) {
    2914:     DMSNESSetJacobian(dm,SNESComputeJacobianDefaultColor,NULL);
    2915:   }
    2916:   if (!snes->vec_func) {
    2917:     DMCreateGlobalVector(dm,&snes->vec_func);
    2918:   }

    2920:   if (!snes->ksp) {
    2921:     SNESGetKSP(snes, &snes->ksp);
    2922:   }

    2924:   if (!snes->linesearch) {
    2925:     SNESGetLineSearch(snes, &snes->linesearch);
    2926:   }
    2927:   SNESLineSearchSetFunction(snes->linesearch,SNESComputeFunction);

    2929:   if (snes->npc && (snes->npcside== PC_LEFT)) {
    2930:     snes->mf          = PETSC_TRUE;
    2931:     snes->mf_operator = PETSC_FALSE;
    2932:   }

    2934:   if (snes->npc) {
    2935:     /* copy the DM over */
    2936:     SNESGetDM(snes,&dm);
    2937:     SNESSetDM(snes->npc,dm);

    2939:     SNESGetFunction(snes,&f,&func,&funcctx);
    2940:     VecDuplicate(f,&fpc);
    2941:     SNESSetFunction(snes->npc,fpc,func,funcctx);
    2942:     SNESGetJacobian(snes,&j,&jpre,&jac,&jacctx);
    2943:     SNESSetJacobian(snes->npc,j,jpre,jac,jacctx);
    2944:     SNESGetApplicationContext(snes,&appctx);
    2945:     SNESSetApplicationContext(snes->npc,appctx);
    2946:     VecDestroy(&fpc);

    2948:     /* copy the function pointers over */
    2949:     PetscObjectCopyFortranFunctionPointers((PetscObject)snes,(PetscObject)snes->npc);

    2951:     /* default to 1 iteration */
    2952:     SNESSetTolerances(snes->npc,0.0,0.0,0.0,1,snes->npc->max_funcs);
    2953:     if (snes->npcside==PC_RIGHT) {
    2954:       SNESSetNormSchedule(snes->npc,SNES_NORM_FINAL_ONLY);
    2955:     } else {
    2956:       SNESSetNormSchedule(snes->npc,SNES_NORM_NONE);
    2957:     }
    2958:     SNESSetFromOptions(snes->npc);

    2960:     /* copy the line search context over */
    2961:     SNESGetLineSearch(snes,&linesearch);
    2962:     SNESGetLineSearch(snes->npc,&pclinesearch);
    2963:     SNESLineSearchGetPreCheck(linesearch,&precheck,&lsprectx);
    2964:     SNESLineSearchGetPostCheck(linesearch,&postcheck,&lspostctx);
    2965:     SNESLineSearchSetPreCheck(pclinesearch,precheck,lsprectx);
    2966:     SNESLineSearchSetPostCheck(pclinesearch,postcheck,lspostctx);
    2967:     PetscObjectCopyFortranFunctionPointers((PetscObject)linesearch, (PetscObject)pclinesearch);
    2968:   }
    2969:   if (snes->mf) {
    2970:     SNESSetUpMatrixFree_Private(snes, snes->mf_operator, snes->mf_version);
    2971:   }
    2972:   if (snes->ops->usercompute && !snes->user) {
    2973:     (*snes->ops->usercompute)(snes,(void**)&snes->user);
    2974:   }

    2976:   snes->jac_iter = 0;
    2977:   snes->pre_iter = 0;

    2979:   if (snes->ops->setup) {
    2980:     (*snes->ops->setup)(snes);
    2981:   }

    2983:   if (snes->npc && (snes->npcside== PC_LEFT)) {
    2984:     if (snes->functype == SNES_FUNCTION_PRECONDITIONED) {
    2985:       SNESGetLineSearch(snes,&linesearch);
    2986:       SNESLineSearchSetFunction(linesearch,SNESComputeFunctionDefaultNPC);
    2987:     }
    2988:   }

    2990:   snes->setupcalled = PETSC_TRUE;
    2991:   return(0);
    2992: }

    2994: /*@
    2995:    SNESReset - Resets a SNES context to the snessetupcalled = 0 state and removes any allocated Vecs and Mats

    2997:    Collective on SNES

    2999:    Input Parameter:
    3000: .  snes - iterative context obtained from SNESCreate()

    3002:    Level: intermediate

    3004:    Notes:
    3005:     Also calls the application context destroy routine set with SNESSetComputeApplicationContext()

    3007: .keywords: SNES, destroy

    3009: .seealso: SNESCreate(), SNESSetUp(), SNESSolve()
    3010: @*/
    3011: PetscErrorCode  SNESReset(SNES snes)
    3012: {

    3017:   if (snes->ops->userdestroy && snes->user) {
    3018:     (*snes->ops->userdestroy)((void**)&snes->user);
    3019:     snes->user = NULL;
    3020:   }
    3021:   if (snes->npc) {
    3022:     SNESReset(snes->npc);
    3023:   }

    3025:   if (snes->ops->reset) {
    3026:     (*snes->ops->reset)(snes);
    3027:   }
    3028:   if (snes->ksp) {
    3029:     KSPReset(snes->ksp);
    3030:   }

    3032:   if (snes->linesearch) {
    3033:     SNESLineSearchReset(snes->linesearch);
    3034:   }

    3036:   VecDestroy(&snes->vec_rhs);
    3037:   VecDestroy(&snes->vec_sol);
    3038:   VecDestroy(&snes->vec_sol_update);
    3039:   VecDestroy(&snes->vec_func);
    3040:   MatDestroy(&snes->jacobian);
    3041:   MatDestroy(&snes->jacobian_pre);
    3042:   VecDestroyVecs(snes->nwork,&snes->work);
    3043:   VecDestroyVecs(snes->nvwork,&snes->vwork);

    3045:   snes->alwayscomputesfinalresidual = PETSC_FALSE;

    3047:   snes->nwork       = snes->nvwork = 0;
    3048:   snes->setupcalled = PETSC_FALSE;
    3049:   return(0);
    3050: }

    3052: /*@
    3053:    SNESDestroy - Destroys the nonlinear solver context that was created
    3054:    with SNESCreate().

    3056:    Collective on SNES

    3058:    Input Parameter:
    3059: .  snes - the SNES context

    3061:    Level: beginner

    3063: .keywords: SNES, nonlinear, destroy

    3065: .seealso: SNESCreate(), SNESSolve()
    3066: @*/
    3067: PetscErrorCode  SNESDestroy(SNES *snes)
    3068: {

    3072:   if (!*snes) return(0);
    3074:   if (--((PetscObject)(*snes))->refct > 0) {*snes = 0; return(0);}

    3076:   SNESReset((*snes));
    3077:   SNESDestroy(&(*snes)->npc);

    3079:   /* if memory was published with SAWs then destroy it */
    3080:   PetscObjectSAWsViewOff((PetscObject)*snes);
    3081:   if ((*snes)->ops->destroy) {(*((*snes))->ops->destroy)((*snes));}

    3083:   if ((*snes)->dm) {DMCoarsenHookRemove((*snes)->dm,DMCoarsenHook_SNESVecSol,DMRestrictHook_SNESVecSol,*snes);}
    3084:   DMDestroy(&(*snes)->dm);
    3085:   KSPDestroy(&(*snes)->ksp);
    3086:   SNESLineSearchDestroy(&(*snes)->linesearch);

    3088:   PetscFree((*snes)->kspconvctx);
    3089:   if ((*snes)->ops->convergeddestroy) {
    3090:     (*(*snes)->ops->convergeddestroy)((*snes)->cnvP);
    3091:   }
    3092:   if ((*snes)->conv_malloc) {
    3093:     PetscFree((*snes)->conv_hist);
    3094:     PetscFree((*snes)->conv_hist_its);
    3095:   }
    3096:   SNESMonitorCancel((*snes));
    3097:   PetscHeaderDestroy(snes);
    3098:   return(0);
    3099: }

    3101: /* ----------- Routines to set solver parameters ---------- */

    3103: /*@
    3104:    SNESSetLagPreconditioner - Determines when the preconditioner is rebuilt in the nonlinear solve.

    3106:    Logically Collective on SNES

    3108:    Input Parameters:
    3109: +  snes - the SNES context
    3110: -  lag - -1 indicates NEVER rebuild, 1 means rebuild every time the Jacobian is computed within a single nonlinear solve, 2 means every second time
    3111:          the Jacobian is built etc. -2 indicates rebuild preconditioner at next chance but then never rebuild after that

    3113:    Options Database Keys:
    3114: .    -snes_lag_preconditioner <lag>

    3116:    Notes:
    3117:    The default is 1
    3118:    The preconditioner is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1
    3119:    If  -1 is used before the very first nonlinear solve the preconditioner is still built because there is no previous preconditioner to use

    3121:    Level: intermediate

    3123: .keywords: SNES, nonlinear, set, convergence, tolerances

    3125: .seealso: SNESSetTrustRegionTolerance(), SNESGetLagPreconditioner(), SNESSetLagJacobian(), SNESGetLagJacobian()

    3127: @*/
    3128: PetscErrorCode  SNESSetLagPreconditioner(SNES snes,PetscInt lag)
    3129: {
    3132:   if (lag < -2) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag must be -2, -1, 1 or greater");
    3133:   if (!lag) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag cannot be 0");
    3135:   snes->lagpreconditioner = lag;
    3136:   return(0);
    3137: }

    3139: /*@
    3140:    SNESSetGridSequence - sets the number of steps of grid sequencing that SNES does

    3142:    Logically Collective on SNES

    3144:    Input Parameters:
    3145: +  snes - the SNES context
    3146: -  steps - the number of refinements to do, defaults to 0

    3148:    Options Database Keys:
    3149: .    -snes_grid_sequence <steps>

    3151:    Level: intermediate

    3153:    Notes:
    3154:    Use SNESGetSolution() to extract the fine grid solution after grid sequencing.

    3156: .keywords: SNES, nonlinear, set, convergence, tolerances

    3158: .seealso: SNESSetTrustRegionTolerance(), SNESGetLagPreconditioner(), SNESSetLagJacobian(), SNESGetLagJacobian(), SNESGetGridSequence()

    3160: @*/
    3161: PetscErrorCode  SNESSetGridSequence(SNES snes,PetscInt steps)
    3162: {
    3166:   snes->gridsequence = steps;
    3167:   return(0);
    3168: }

    3170: /*@
    3171:    SNESGetGridSequence - gets the number of steps of grid sequencing that SNES does

    3173:    Logically Collective on SNES

    3175:    Input Parameter:
    3176: .  snes - the SNES context

    3178:    Output Parameter:
    3179: .  steps - the number of refinements to do, defaults to 0

    3181:    Options Database Keys:
    3182: .    -snes_grid_sequence <steps>

    3184:    Level: intermediate

    3186:    Notes:
    3187:    Use SNESGetSolution() to extract the fine grid solution after grid sequencing.

    3189: .keywords: SNES, nonlinear, set, convergence, tolerances

    3191: .seealso: SNESSetTrustRegionTolerance(), SNESGetLagPreconditioner(), SNESSetLagJacobian(), SNESGetLagJacobian(), SNESSetGridSequence()

    3193: @*/
    3194: PetscErrorCode  SNESGetGridSequence(SNES snes,PetscInt *steps)
    3195: {
    3198:   *steps = snes->gridsequence;
    3199:   return(0);
    3200: }

    3202: /*@
    3203:    SNESGetLagPreconditioner - Indicates how often the preconditioner is rebuilt

    3205:    Not Collective

    3207:    Input Parameter:
    3208: .  snes - the SNES context

    3210:    Output Parameter:
    3211: .   lag - -1 indicates NEVER rebuild, 1 means rebuild every time the Jacobian is computed within a single nonlinear solve, 2 means every second time
    3212:          the Jacobian is built etc. -2 indicates rebuild preconditioner at next chance but then never rebuild after that

    3214:    Options Database Keys:
    3215: .    -snes_lag_preconditioner <lag>

    3217:    Notes:
    3218:    The default is 1
    3219:    The preconditioner is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1

    3221:    Level: intermediate

    3223: .keywords: SNES, nonlinear, set, convergence, tolerances

    3225: .seealso: SNESSetTrustRegionTolerance(), SNESSetLagPreconditioner()

    3227: @*/
    3228: PetscErrorCode  SNESGetLagPreconditioner(SNES snes,PetscInt *lag)
    3229: {
    3232:   *lag = snes->lagpreconditioner;
    3233:   return(0);
    3234: }

    3236: /*@
    3237:    SNESSetLagJacobian - Determines when the Jacobian is rebuilt in the nonlinear solve. See SNESSetLagPreconditioner() for determining how
    3238:      often the preconditioner is rebuilt.

    3240:    Logically Collective on SNES

    3242:    Input Parameters:
    3243: +  snes - the SNES context
    3244: -  lag - -1 indicates NEVER rebuild, 1 means rebuild every time the Jacobian is computed within a single nonlinear solve, 2 means every second time
    3245:          the Jacobian is built etc. -2 means rebuild at next chance but then never again

    3247:    Options Database Keys:
    3248: .    -snes_lag_jacobian <lag>

    3250:    Notes:
    3251:    The default is 1
    3252:    The Jacobian is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1
    3253:    If  -1 is used before the very first nonlinear solve the CODE WILL FAIL! because no Jacobian is used, use -2 to indicate you want it recomputed
    3254:    at the next Newton step but never again (unless it is reset to another value)

    3256:    Level: intermediate

    3258: .keywords: SNES, nonlinear, set, convergence, tolerances

    3260: .seealso: SNESSetTrustRegionTolerance(), SNESGetLagPreconditioner(), SNESSetLagPreconditioner(), SNESGetLagJacobian()

    3262: @*/
    3263: PetscErrorCode  SNESSetLagJacobian(SNES snes,PetscInt lag)
    3264: {
    3267:   if (lag < -2) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag must be -2, -1, 1 or greater");
    3268:   if (!lag) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag cannot be 0");
    3270:   snes->lagjacobian = lag;
    3271:   return(0);
    3272: }

    3274: /*@
    3275:    SNESGetLagJacobian - Indicates how often the Jacobian is rebuilt. See SNESGetLagPreconditioner() to determine when the preconditioner is rebuilt

    3277:    Not Collective

    3279:    Input Parameter:
    3280: .  snes - the SNES context

    3282:    Output Parameter:
    3283: .   lag - -1 indicates NEVER rebuild, 1 means rebuild every time the Jacobian is computed within a single nonlinear solve, 2 means every second time
    3284:          the Jacobian is built etc.

    3286:    Options Database Keys:
    3287: .    -snes_lag_jacobian <lag>

    3289:    Notes:
    3290:    The default is 1
    3291:    The jacobian is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1

    3293:    Level: intermediate

    3295: .keywords: SNES, nonlinear, set, convergence, tolerances

    3297: .seealso: SNESSetTrustRegionTolerance(), SNESSetLagJacobian(), SNESSetLagPreconditioner(), SNESGetLagPreconditioner()

    3299: @*/
    3300: PetscErrorCode  SNESGetLagJacobian(SNES snes,PetscInt *lag)
    3301: {
    3304:   *lag = snes->lagjacobian;
    3305:   return(0);
    3306: }

    3308: /*@
    3309:    SNESSetLagJacobianPersists - Set whether or not the Jacobian lagging persists through multiple solves

    3311:    Logically collective on SNES

    3313:    Input Parameter:
    3314: +  snes - the SNES context
    3315: -   flg - jacobian lagging persists if true

    3317:    Options Database Keys:
    3318: .    -snes_lag_jacobian_persists <flg>

    3320:    Notes:
    3321:     This is useful both for nonlinear preconditioning, where it's appropriate to have the Jacobian be stale by
    3322:    several solves, and for implicit time-stepping, where Jacobian lagging in the inner nonlinear solve over several
    3323:    timesteps may present huge efficiency gains.

    3325:    Level: developer

    3327: .keywords: SNES, nonlinear, lag

    3329: .seealso: SNESSetLagPreconditionerPersists(), SNESSetLagJacobian(), SNESGetLagJacobian(), SNESGetNPC()

    3331: @*/
    3332: PetscErrorCode  SNESSetLagJacobianPersists(SNES snes,PetscBool flg)
    3333: {
    3337:   snes->lagjac_persist = flg;
    3338:   return(0);
    3339: }

    3341: /*@
    3342:    SNESSetLagPreconditionerPersists - Set whether or not the preconditioner lagging persists through multiple solves

    3344:    Logically Collective on SNES

    3346:    Input Parameter:
    3347: +  snes - the SNES context
    3348: -   flg - preconditioner lagging persists if true

    3350:    Options Database Keys:
    3351: .    -snes_lag_jacobian_persists <flg>

    3353:    Notes:
    3354:     This is useful both for nonlinear preconditioning, where it's appropriate to have the preconditioner be stale
    3355:    by several solves, and for implicit time-stepping, where preconditioner lagging in the inner nonlinear solve over
    3356:    several timesteps may present huge efficiency gains.

    3358:    Level: developer

    3360: .keywords: SNES, nonlinear, lag

    3362: .seealso: SNESSetLagJacobianPersists(), SNESSetLagJacobian(), SNESGetLagJacobian(), SNESGetNPC()

    3364: @*/
    3365: PetscErrorCode  SNESSetLagPreconditionerPersists(SNES snes,PetscBool flg)
    3366: {
    3370:   snes->lagpre_persist = flg;
    3371:   return(0);
    3372: }

    3374: /*@
    3375:    SNESSetForceIteration - force SNESSolve() to take at least one iteration regardless of the initial residual norm

    3377:    Logically Collective on SNES

    3379:    Input Parameters:
    3380: +  snes - the SNES context
    3381: -  force - PETSC_TRUE require at least one iteration

    3383:    Options Database Keys:
    3384: .    -snes_force_iteration <force> - Sets forcing an iteration

    3386:    Notes:
    3387:    This is used sometimes with TS to prevent TS from detecting a false steady state solution

    3389:    Level: intermediate

    3391: .keywords: SNES, nonlinear, set, convergence, tolerances

    3393: .seealso: SNESSetTrustRegionTolerance(), SNESSetDivergenceTolerance()
    3394: @*/
    3395: PetscErrorCode  SNESSetForceIteration(SNES snes,PetscBool force)
    3396: {
    3399:   snes->forceiteration = force;
    3400:   return(0);
    3401: }

    3403: /*@
    3404:    SNESGetForceIteration - Whether or not to force SNESSolve() take at least one iteration regardless of the initial residual norm

    3406:    Logically Collective on SNES

    3408:    Input Parameters:
    3409: .  snes - the SNES context

    3411:    Output Parameter:
    3412: .  force - PETSC_TRUE requires at least one iteration.

    3414: .keywords: SNES, nonlinear, set, convergence, tolerances

    3416:    Level: intermediate

    3418: .seealso: SNESSetForceIteration(), SNESSetTrustRegionTolerance(), SNESSetDivergenceTolerance()
    3419: @*/
    3420: PetscErrorCode  SNESGetForceIteration(SNES snes,PetscBool *force)
    3421: {
    3424:   *force = snes->forceiteration;
    3425:   return(0);
    3426: }

    3428: /*@
    3429:    SNESSetTolerances - Sets various parameters used in convergence tests.

    3431:    Logically Collective on SNES

    3433:    Input Parameters:
    3434: +  snes - the SNES context
    3435: .  abstol - absolute convergence tolerance
    3436: .  rtol - relative convergence tolerance
    3437: .  stol -  convergence tolerance in terms of the norm of the change in the solution between steps,  || delta x || < stol*|| x ||
    3438: .  maxit - maximum number of iterations
    3439: -  maxf - maximum number of function evaluations (-1 indicates no limit)

    3441:    Options Database Keys:
    3442: +    -snes_atol <abstol> - Sets abstol
    3443: .    -snes_rtol <rtol> - Sets rtol
    3444: .    -snes_stol <stol> - Sets stol
    3445: .    -snes_max_it <maxit> - Sets maxit
    3446: -    -snes_max_funcs <maxf> - Sets maxf

    3448:    Notes:
    3449:    The default maximum number of iterations is 50.
    3450:    The default maximum number of function evaluations is 1000.

    3452:    Level: intermediate

    3454: .keywords: SNES, nonlinear, set, convergence, tolerances

    3456: .seealso: SNESSetTrustRegionTolerance(), SNESSetDivergenceTolerance(), SNESSetForceIteration()
    3457: @*/
    3458: PetscErrorCode  SNESSetTolerances(SNES snes,PetscReal abstol,PetscReal rtol,PetscReal stol,PetscInt maxit,PetscInt maxf)
    3459: {

    3468:   if (abstol != PETSC_DEFAULT) {
    3469:     if (abstol < 0.0) SETERRQ1(PetscObjectComm((PetscObject)snes),PETSC_ERR_ARG_OUTOFRANGE,"Absolute tolerance %g must be non-negative",(double)abstol);
    3470:     snes->abstol = abstol;
    3471:   }
    3472:   if (rtol != PETSC_DEFAULT) {
    3473:     if (rtol < 0.0 || 1.0 <= rtol) SETERRQ1(PetscObjectComm((PetscObject)snes),PETSC_ERR_ARG_OUTOFRANGE,"Relative tolerance %g must be non-negative and less than 1.0",(double)rtol);
    3474:     snes->rtol = rtol;
    3475:   }
    3476:   if (stol != PETSC_DEFAULT) {
    3477:     if (stol < 0.0) SETERRQ1(PetscObjectComm((PetscObject)snes),PETSC_ERR_ARG_OUTOFRANGE,"Step tolerance %g must be non-negative",(double)stol);
    3478:     snes->stol = stol;
    3479:   }
    3480:   if (maxit != PETSC_DEFAULT) {
    3481:     if (maxit < 0) SETERRQ1(PetscObjectComm((PetscObject)snes),PETSC_ERR_ARG_OUTOFRANGE,"Maximum number of iterations %D must be non-negative",maxit);
    3482:     snes->max_its = maxit;
    3483:   }
    3484:   if (maxf != PETSC_DEFAULT) {
    3485:     if (maxf < -1) SETERRQ1(PetscObjectComm((PetscObject)snes),PETSC_ERR_ARG_OUTOFRANGE,"Maximum number of function evaluations %D must be -1 or nonnegative",maxf);
    3486:     snes->max_funcs = maxf;
    3487:   }
    3488:   snes->tolerancesset = PETSC_TRUE;
    3489:   return(0);
    3490: }

    3492: /*@
    3493:    SNESSetDivergenceTolerance - Sets the divergence tolerance used for the SNES divergence test.

    3495:    Logically Collective on SNES

    3497:    Input Parameters:
    3498: +  snes - the SNES context
    3499: -  divtol - the divergence tolerance. Use -1 to deactivate the test.

    3501:    Options Database Keys:
    3502: +    -snes_divergence_tolerance <divtol> - Sets divtol

    3504:    Notes:
    3505:    The default divergence tolerance is 1e4.

    3507:    Level: intermediate

    3509: .keywords: SNES, nonlinear, set, divergence, tolerance

    3511: .seealso: SNESSetTolerances(), SNESGetDivergenceTolerance
    3512: @*/
    3513: PetscErrorCode  SNESSetDivergenceTolerance(SNES snes,PetscReal divtol)
    3514: {

    3519:   if (divtol != PETSC_DEFAULT) {
    3520:     snes->divtol = divtol;
    3521:   }
    3522:   else {
    3523:     snes->divtol = 1.0e4;
    3524:   }
    3525:   return(0);
    3526: }

    3528: /*@
    3529:    SNESGetTolerances - Gets various parameters used in convergence tests.

    3531:    Not Collective

    3533:    Input Parameters:
    3534: +  snes - the SNES context
    3535: .  atol - absolute convergence tolerance
    3536: .  rtol - relative convergence tolerance
    3537: .  stol -  convergence tolerance in terms of the norm
    3538:            of the change in the solution between steps
    3539: .  maxit - maximum number of iterations
    3540: -  maxf - maximum number of function evaluations

    3542:    Notes:
    3543:    The user can specify NULL for any parameter that is not needed.

    3545:    Level: intermediate

    3547: .keywords: SNES, nonlinear, get, convergence, tolerances

    3549: .seealso: SNESSetTolerances()
    3550: @*/
    3551: PetscErrorCode  SNESGetTolerances(SNES snes,PetscReal *atol,PetscReal *rtol,PetscReal *stol,PetscInt *maxit,PetscInt *maxf)
    3552: {
    3555:   if (atol)  *atol  = snes->abstol;
    3556:   if (rtol)  *rtol  = snes->rtol;
    3557:   if (stol)  *stol  = snes->stol;
    3558:   if (maxit) *maxit = snes->max_its;
    3559:   if (maxf)  *maxf  = snes->max_funcs;
    3560:   return(0);
    3561: }

    3563: /*@
    3564:    SNESGetDivergenceTolerance - Gets divergence tolerance used in divergence test.

    3566:    Not Collective

    3568:    Input Parameters:
    3569: +  snes - the SNES context
    3570: -  divtol - divergence tolerance

    3572:    Level: intermediate

    3574: .keywords: SNES, nonlinear, get, divergence, tolerance

    3576: .seealso: SNESSetDivergenceTolerance()
    3577: @*/
    3578: PetscErrorCode  SNESGetDivergenceTolerance(SNES snes,PetscReal *divtol)
    3579: {
    3582:   if (divtol) *divtol = snes->divtol;
    3583:   return(0);
    3584: }

    3586: /*@
    3587:    SNESSetTrustRegionTolerance - Sets the trust region parameter tolerance.

    3589:    Logically Collective on SNES

    3591:    Input Parameters:
    3592: +  snes - the SNES context
    3593: -  tol - tolerance

    3595:    Options Database Key:
    3596: .  -snes_trtol <tol> - Sets tol

    3598:    Level: intermediate

    3600: .keywords: SNES, nonlinear, set, trust region, tolerance

    3602: .seealso: SNESSetTolerances()
    3603: @*/
    3604: PetscErrorCode  SNESSetTrustRegionTolerance(SNES snes,PetscReal tol)
    3605: {
    3609:   snes->deltatol = tol;
    3610:   return(0);
    3611: }

    3613: /*
    3614:    Duplicate the lg monitors for SNES from KSP; for some reason with
    3615:    dynamic libraries things don't work under Sun4 if we just use
    3616:    macros instead of functions
    3617: */
    3618: PetscErrorCode  SNESMonitorLGResidualNorm(SNES snes,PetscInt it,PetscReal norm,void *ctx)
    3619: {

    3624:   KSPMonitorLGResidualNorm((KSP)snes,it,norm,ctx);
    3625:   return(0);
    3626: }

    3628: PetscErrorCode  SNESMonitorLGCreate(MPI_Comm comm,const char host[],const char label[],int x,int y,int m,int n,PetscDrawLG *lgctx)
    3629: {

    3633:   KSPMonitorLGResidualNormCreate(comm,host,label,x,y,m,n,lgctx);
    3634:   return(0);
    3635: }

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

    3639: PetscErrorCode  SNESMonitorLGRange(SNES snes,PetscInt n,PetscReal rnorm,void *monctx)
    3640: {
    3641:   PetscDrawLG      lg;
    3642:   PetscErrorCode   ierr;
    3643:   PetscReal        x,y,per;
    3644:   PetscViewer      v = (PetscViewer)monctx;
    3645:   static PetscReal prev; /* should be in the context */
    3646:   PetscDraw        draw;

    3650:   PetscViewerDrawGetDrawLG(v,0,&lg);
    3651:   if (!n) {PetscDrawLGReset(lg);}
    3652:   PetscDrawLGGetDraw(lg,&draw);
    3653:   PetscDrawSetTitle(draw,"Residual norm");
    3654:   x    = (PetscReal)n;
    3655:   if (rnorm > 0.0) y = PetscLog10Real(rnorm);
    3656:   else y = -15.0;
    3657:   PetscDrawLGAddPoint(lg,&x,&y);
    3658:   if (n < 20 || !(n % 5) || snes->reason) {
    3659:     PetscDrawLGDraw(lg);
    3660:     PetscDrawLGSave(lg);
    3661:   }

    3663:   PetscViewerDrawGetDrawLG(v,1,&lg);
    3664:   if (!n) {PetscDrawLGReset(lg);}
    3665:   PetscDrawLGGetDraw(lg,&draw);
    3666:   PetscDrawSetTitle(draw,"% elemts > .2*max elemt");
    3667:    SNESMonitorRange_Private(snes,n,&per);
    3668:   x    = (PetscReal)n;
    3669:   y    = 100.0*per;
    3670:   PetscDrawLGAddPoint(lg,&x,&y);
    3671:   if (n < 20 || !(n % 5) || snes->reason) {
    3672:     PetscDrawLGDraw(lg);
    3673:     PetscDrawLGSave(lg);
    3674:   }

    3676:   PetscViewerDrawGetDrawLG(v,2,&lg);
    3677:   if (!n) {prev = rnorm;PetscDrawLGReset(lg);}
    3678:   PetscDrawLGGetDraw(lg,&draw);
    3679:   PetscDrawSetTitle(draw,"(norm -oldnorm)/oldnorm");
    3680:   x    = (PetscReal)n;
    3681:   y    = (prev - rnorm)/prev;
    3682:   PetscDrawLGAddPoint(lg,&x,&y);
    3683:   if (n < 20 || !(n % 5) || snes->reason) {
    3684:     PetscDrawLGDraw(lg);
    3685:     PetscDrawLGSave(lg);
    3686:   }

    3688:   PetscViewerDrawGetDrawLG(v,3,&lg);
    3689:   if (!n) {PetscDrawLGReset(lg);}
    3690:   PetscDrawLGGetDraw(lg,&draw);
    3691:   PetscDrawSetTitle(draw,"(norm -oldnorm)/oldnorm*(% > .2 max)");
    3692:   x    = (PetscReal)n;
    3693:   y    = (prev - rnorm)/(prev*per);
    3694:   if (n > 2) { /*skip initial crazy value */
    3695:     PetscDrawLGAddPoint(lg,&x,&y);
    3696:   }
    3697:   if (n < 20 || !(n % 5) || snes->reason) {
    3698:     PetscDrawLGDraw(lg);
    3699:     PetscDrawLGSave(lg);
    3700:   }
    3701:   prev = rnorm;
    3702:   return(0);
    3703: }

    3705: /*@
    3706:    SNESMonitor - runs the user provided monitor routines, if they exist

    3708:    Collective on SNES

    3710:    Input Parameters:
    3711: +  snes - nonlinear solver context obtained from SNESCreate()
    3712: .  iter - iteration number
    3713: -  rnorm - relative norm of the residual

    3715:    Notes:
    3716:    This routine is called by the SNES implementations.
    3717:    It does not typically need to be called by the user.

    3719:    Level: developer

    3721: .seealso: SNESMonitorSet()
    3722: @*/
    3723: PetscErrorCode  SNESMonitor(SNES snes,PetscInt iter,PetscReal rnorm)
    3724: {
    3726:   PetscInt       i,n = snes->numbermonitors;

    3729:   VecLockPush(snes->vec_sol);
    3730:   for (i=0; i<n; i++) {
    3731:     (*snes->monitor[i])(snes,iter,rnorm,snes->monitorcontext[i]);
    3732:   }
    3733:   VecLockPop(snes->vec_sol);
    3734:   return(0);
    3735: }

    3737: /* ------------ Routines to set performance monitoring options ----------- */

    3739: /*MC
    3740:     SNESMonitorFunction - functional form passed to SNESMonitorSet() to monitor convergence of nonlinear solver

    3742:      Synopsis:
    3743:      #include <petscsnes.h>
    3744: $    PetscErrorCode SNESMonitorFunction(SNES snes,PetscInt its, PetscReal norm,void *mctx)

    3746: +    snes - the SNES context
    3747: .    its - iteration number
    3748: .    norm - 2-norm function value (may be estimated)
    3749: -    mctx - [optional] monitoring context

    3751:    Level: advanced

    3753: .seealso:   SNESMonitorSet(), SNESMonitorGet()
    3754: M*/

    3756: /*@C
    3757:    SNESMonitorSet - Sets an ADDITIONAL function that is to be used at every
    3758:    iteration of the nonlinear solver to display the iteration's
    3759:    progress.

    3761:    Logically Collective on SNES

    3763:    Input Parameters:
    3764: +  snes - the SNES context
    3765: .  f - the monitor function, see SNESMonitorFunction for the calling sequence
    3766: .  mctx - [optional] user-defined context for private data for the
    3767:           monitor routine (use NULL if no context is desired)
    3768: -  monitordestroy - [optional] routine that frees monitor context
    3769:           (may be NULL)

    3771:    Options Database Keys:
    3772: +    -snes_monitor        - sets SNESMonitorDefault()
    3773: .    -snes_monitor_lg_residualnorm    - sets line graph monitor,
    3774:                             uses SNESMonitorLGCreate()
    3775: -    -snes_monitor_cancel - cancels all monitors that have
    3776:                             been hardwired into a code by
    3777:                             calls to SNESMonitorSet(), but
    3778:                             does not cancel those set via
    3779:                             the options database.

    3781:    Notes:
    3782:    Several different monitoring routines may be set by calling
    3783:    SNESMonitorSet() multiple times; all will be called in the
    3784:    order in which they were set.

    3786:    Fortran Notes:
    3787:     Only a single monitor function can be set for each SNES object

    3789:    Level: intermediate

    3791: .keywords: SNES, nonlinear, set, monitor

    3793: .seealso: SNESMonitorDefault(), SNESMonitorCancel(), SNESMonitorFunction
    3794: @*/
    3795: PetscErrorCode  SNESMonitorSet(SNES snes,PetscErrorCode (*f)(SNES,PetscInt,PetscReal,void*),void *mctx,PetscErrorCode (*monitordestroy)(void**))
    3796: {
    3797:   PetscInt       i;
    3799:   PetscBool      identical;

    3803:   for (i=0; i<snes->numbermonitors;i++) {
    3804:     PetscMonitorCompare((PetscErrorCode (*)(void))f,mctx,monitordestroy,(PetscErrorCode (*)(void))snes->monitor[i],snes->monitorcontext[i],snes->monitordestroy[i],&identical);
    3805:     if (identical) return(0);
    3806:   }
    3807:   if (snes->numbermonitors >= MAXSNESMONITORS) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Too many monitors set");
    3808:   snes->monitor[snes->numbermonitors]          = f;
    3809:   snes->monitordestroy[snes->numbermonitors]   = monitordestroy;
    3810:   snes->monitorcontext[snes->numbermonitors++] = (void*)mctx;
    3811:   return(0);
    3812: }

    3814: /*@
    3815:    SNESMonitorCancel - Clears all the monitor functions for a SNES object.

    3817:    Logically Collective on SNES

    3819:    Input Parameters:
    3820: .  snes - the SNES context

    3822:    Options Database Key:
    3823: .  -snes_monitor_cancel - cancels all monitors that have been hardwired
    3824:     into a code by calls to SNESMonitorSet(), but does not cancel those
    3825:     set via the options database

    3827:    Notes:
    3828:    There is no way to clear one specific monitor from a SNES object.

    3830:    Level: intermediate

    3832: .keywords: SNES, nonlinear, set, monitor

    3834: .seealso: SNESMonitorDefault(), SNESMonitorSet()
    3835: @*/
    3836: PetscErrorCode  SNESMonitorCancel(SNES snes)
    3837: {
    3839:   PetscInt       i;

    3843:   for (i=0; i<snes->numbermonitors; i++) {
    3844:     if (snes->monitordestroy[i]) {
    3845:       (*snes->monitordestroy[i])(&snes->monitorcontext[i]);
    3846:     }
    3847:   }
    3848:   snes->numbermonitors = 0;
    3849:   return(0);
    3850: }

    3852: /*MC
    3853:     SNESConvergenceTestFunction - functional form used for testing of convergence of nonlinear solver

    3855:      Synopsis:
    3856:      #include <petscsnes.h>
    3857: $     PetscErrorCode SNESConvergenceTest(SNES snes,PetscInt it,PetscReal xnorm,PetscReal gnorm,PetscReal f,SNESConvergedReason *reason,void *cctx)

    3859: +    snes - the SNES context
    3860: .    it - current iteration (0 is the first and is before any Newton step)
    3861: .    cctx - [optional] convergence context
    3862: .    reason - reason for convergence/divergence
    3863: .    xnorm - 2-norm of current iterate
    3864: .    gnorm - 2-norm of current step
    3865: -    f - 2-norm of function

    3867:    Level: intermediate

    3869: .seealso:   SNESSetConvergenceTest(), SNESGetConvergenceTest()
    3870: M*/

    3872: /*@C
    3873:    SNESSetConvergenceTest - Sets the function that is to be used
    3874:    to test for convergence of the nonlinear iterative solution.

    3876:    Logically Collective on SNES

    3878:    Input Parameters:
    3879: +  snes - the SNES context
    3880: .  SNESConvergenceTestFunction - routine to test for convergence
    3881: .  cctx - [optional] context for private data for the convergence routine  (may be NULL)
    3882: -  destroy - [optional] destructor for the context (may be NULL; NULL_FUNCTION in Fortran)

    3884:    Level: advanced

    3886: .keywords: SNES, nonlinear, set, convergence, test

    3888: .seealso: SNESConvergedDefault(), SNESConvergedSkip(), SNESConvergenceTestFunction
    3889: @*/
    3890: PetscErrorCode  SNESSetConvergenceTest(SNES snes,PetscErrorCode (*SNESConvergenceTestFunction)(SNES,PetscInt,PetscReal,PetscReal,PetscReal,SNESConvergedReason*,void*),void *cctx,PetscErrorCode (*destroy)(void*))
    3891: {

    3896:   if (!SNESConvergenceTestFunction) SNESConvergenceTestFunction = SNESConvergedSkip;
    3897:   if (snes->ops->convergeddestroy) {
    3898:     (*snes->ops->convergeddestroy)(snes->cnvP);
    3899:   }
    3900:   snes->ops->converged        = SNESConvergenceTestFunction;
    3901:   snes->ops->convergeddestroy = destroy;
    3902:   snes->cnvP                  = cctx;
    3903:   return(0);
    3904: }

    3906: /*@
    3907:    SNESGetConvergedReason - Gets the reason the SNES iteration was stopped.

    3909:    Not Collective

    3911:    Input Parameter:
    3912: .  snes - the SNES context

    3914:    Output Parameter:
    3915: .  reason - negative value indicates diverged, positive value converged, see SNESConvergedReason or the
    3916:             manual pages for the individual convergence tests for complete lists

    3918:    Options Database:
    3919: .   -snes_converged_reason - prints the reason to standard out

    3921:    Level: intermediate

    3923:    Notes:
    3924:     Should only be called after the call the SNESSolve() is complete, if it is called earlier it returns the value SNES__CONVERGED_ITERATING.

    3926: .keywords: SNES, nonlinear, set, convergence, test

    3928: .seealso: SNESSetConvergenceTest(), SNESSetConvergedReason(), SNESConvergedReason
    3929: @*/
    3930: PetscErrorCode SNESGetConvergedReason(SNES snes,SNESConvergedReason *reason)
    3931: {
    3935:   *reason = snes->reason;
    3936:   return(0);
    3937: }

    3939: /*@
    3940:    SNESSetConvergedReason - Sets the reason the SNES iteration was stopped.

    3942:    Not Collective

    3944:    Input Parameters:
    3945: +  snes - the SNES context
    3946: -  reason - negative value indicates diverged, positive value converged, see SNESConvergedReason or the
    3947:             manual pages for the individual convergence tests for complete lists

    3949:    Level: intermediate

    3951: .keywords: SNES, nonlinear, set, convergence, test
    3952: .seealso: SNESGetConvergedReason(), SNESSetConvergenceTest(), SNESConvergedReason
    3953: @*/
    3954: PetscErrorCode SNESSetConvergedReason(SNES snes,SNESConvergedReason reason)
    3955: {
    3958:   snes->reason = reason;
    3959:   return(0);
    3960: }

    3962: /*@
    3963:    SNESSetConvergenceHistory - Sets the array used to hold the convergence history.

    3965:    Logically Collective on SNES

    3967:    Input Parameters:
    3968: +  snes - iterative context obtained from SNESCreate()
    3969: .  a   - array to hold history, this array will contain the function norms computed at each step
    3970: .  its - integer array holds the number of linear iterations for each solve.
    3971: .  na  - size of a and its
    3972: -  reset - PETSC_TRUE indicates each new nonlinear solve resets the history counter to zero,
    3973:            else it continues storing new values for new nonlinear solves after the old ones

    3975:    Notes:
    3976:    If 'a' and 'its' are NULL then space is allocated for the history. If 'na' PETSC_DECIDE or PETSC_DEFAULT then a
    3977:    default array of length 10000 is allocated.

    3979:    This routine is useful, e.g., when running a code for purposes
    3980:    of accurate performance monitoring, when no I/O should be done
    3981:    during the section of code that is being timed.

    3983:    Level: intermediate

    3985: .keywords: SNES, set, convergence, history

    3987: .seealso: SNESGetConvergenceHistory()

    3989: @*/
    3990: PetscErrorCode  SNESSetConvergenceHistory(SNES snes,PetscReal a[],PetscInt its[],PetscInt na,PetscBool reset)
    3991: {

    3998:   if (!a) {
    3999:     if (na == PETSC_DECIDE || na == PETSC_DEFAULT) na = 1000;
    4000:     PetscCalloc1(na,&a);
    4001:     PetscCalloc1(na,&its);

    4003:     snes->conv_malloc = PETSC_TRUE;
    4004:   }
    4005:   snes->conv_hist       = a;
    4006:   snes->conv_hist_its   = its;
    4007:   snes->conv_hist_max   = na;
    4008:   snes->conv_hist_len   = 0;
    4009:   snes->conv_hist_reset = reset;
    4010:   return(0);
    4011: }

    4013: #if defined(PETSC_HAVE_MATLAB_ENGINE)
    4014: #include <engine.h>   /* MATLAB include file */
    4015: #include <mex.h>      /* MATLAB include file */

    4017: PETSC_EXTERN mxArray *SNESGetConvergenceHistoryMatlab(SNES snes)
    4018: {
    4019:   mxArray   *mat;
    4020:   PetscInt  i;
    4021:   PetscReal *ar;

    4024:   mat = mxCreateDoubleMatrix(snes->conv_hist_len,1,mxREAL);
    4025:   ar  = (PetscReal*) mxGetData(mat);
    4026:   for (i=0; i<snes->conv_hist_len; i++) ar[i] = snes->conv_hist[i];
    4027:   PetscFunctionReturn(mat);
    4028: }
    4029: #endif

    4031: /*@C
    4032:    SNESGetConvergenceHistory - Gets the array used to hold the convergence history.

    4034:    Not Collective

    4036:    Input Parameter:
    4037: .  snes - iterative context obtained from SNESCreate()

    4039:    Output Parameters:
    4040: .  a   - array to hold history
    4041: .  its - integer array holds the number of linear iterations (or
    4042:          negative if not converged) for each solve.
    4043: -  na  - size of a and its

    4045:    Notes:
    4046:     The calling sequence for this routine in Fortran is
    4047: $   call SNESGetConvergenceHistory(SNES snes, integer na, integer ierr)

    4049:    This routine is useful, e.g., when running a code for purposes
    4050:    of accurate performance monitoring, when no I/O should be done
    4051:    during the section of code that is being timed.

    4053:    Level: intermediate

    4055: .keywords: SNES, get, convergence, history

    4057: .seealso: SNESSetConvergencHistory()

    4059: @*/
    4060: PetscErrorCode  SNESGetConvergenceHistory(SNES snes,PetscReal *a[],PetscInt *its[],PetscInt *na)
    4061: {
    4064:   if (a)   *a   = snes->conv_hist;
    4065:   if (its) *its = snes->conv_hist_its;
    4066:   if (na)  *na  = snes->conv_hist_len;
    4067:   return(0);
    4068: }

    4070: /*@C
    4071:   SNESSetUpdate - Sets the general-purpose update function called
    4072:   at the beginning of every iteration of the nonlinear solve. Specifically
    4073:   it is called just before the Jacobian is "evaluated".

    4075:   Logically Collective on SNES

    4077:   Input Parameters:
    4078: . snes - The nonlinear solver context
    4079: . func - The function

    4081:   Calling sequence of func:
    4082: . func (SNES snes, PetscInt step);

    4084: . step - The current step of the iteration

    4086:   Level: advanced

    4088:   Note: This is NOT what one uses to update the ghost points before a function evaluation, that should be done at the beginning of your FormFunction()
    4089:         This is not used by most users.

    4091: .keywords: SNES, update

    4093: .seealso SNESSetJacobian(), SNESSolve()
    4094: @*/
    4095: PetscErrorCode  SNESSetUpdate(SNES snes, PetscErrorCode (*func)(SNES, PetscInt))
    4096: {
    4099:   snes->ops->update = func;
    4100:   return(0);
    4101: }

    4103: /*
    4104:    SNESScaleStep_Private - Scales a step so that its length is less than the
    4105:    positive parameter delta.

    4107:     Input Parameters:
    4108: +   snes - the SNES context
    4109: .   y - approximate solution of linear system
    4110: .   fnorm - 2-norm of current function
    4111: -   delta - trust region size

    4113:     Output Parameters:
    4114: +   gpnorm - predicted function norm at the new point, assuming local
    4115:     linearization.  The value is zero if the step lies within the trust
    4116:     region, and exceeds zero otherwise.
    4117: -   ynorm - 2-norm of the step

    4119:     Note:
    4120:     For non-trust region methods such as SNESNEWTONLS, the parameter delta
    4121:     is set to be the maximum allowable step size.

    4123: .keywords: SNES, nonlinear, scale, step
    4124: */
    4125: PetscErrorCode SNESScaleStep_Private(SNES snes,Vec y,PetscReal *fnorm,PetscReal *delta,PetscReal *gpnorm,PetscReal *ynorm)
    4126: {
    4127:   PetscReal      nrm;
    4128:   PetscScalar    cnorm;

    4136:   VecNorm(y,NORM_2,&nrm);
    4137:   if (nrm > *delta) {
    4138:     nrm     = *delta/nrm;
    4139:     *gpnorm = (1.0 - nrm)*(*fnorm);
    4140:     cnorm   = nrm;
    4141:     VecScale(y,cnorm);
    4142:     *ynorm  = *delta;
    4143:   } else {
    4144:     *gpnorm = 0.0;
    4145:     *ynorm  = nrm;
    4146:   }
    4147:   return(0);
    4148: }

    4150: /*@
    4151:    SNESReasonView - Displays the reason a SNES solve converged or diverged to a viewer

    4153:    Collective on SNES

    4155:    Parameter:
    4156: +  snes - iterative context obtained from SNESCreate()
    4157: -  viewer - the viewer to display the reason

    4160:    Options Database Keys:
    4161: .  -snes_converged_reason - print reason for converged or diverged, also prints number of iterations

    4163:    Level: beginner

    4165: .keywords: SNES, solve, linear system

    4167: .seealso: SNESCreate(), SNESSetUp(), SNESDestroy(), SNESSetTolerances(), SNESConvergedDefault()

    4169: @*/
    4170: PetscErrorCode  SNESReasonView(SNES snes,PetscViewer viewer)
    4171: {
    4172:   PetscViewerFormat format;
    4173:   PetscBool         isAscii;
    4174:   PetscErrorCode    ierr;

    4177:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&isAscii);
    4178:   if (isAscii) {
    4179:     PetscViewerGetFormat(viewer, &format);
    4180:     PetscViewerASCIIAddTab(viewer,((PetscObject)snes)->tablevel);
    4181:     if (format == PETSC_VIEWER_ASCII_INFO_DETAIL) {
    4182:       DM                dm;
    4183:       Vec               u;
    4184:       PetscDS           prob;
    4185:       PetscInt          Nf, f;
    4186:       PetscErrorCode (**exactFuncs)(PetscInt, PetscReal, const PetscReal[], PetscInt, PetscScalar[], void *);
    4187:       PetscReal         error;

    4189:       SNESGetDM(snes, &dm);
    4190:       SNESGetSolution(snes, &u);
    4191:       DMGetDS(dm, &prob);
    4192:       PetscDSGetNumFields(prob, &Nf);
    4193:       PetscMalloc1(Nf, &exactFuncs);
    4194:       for (f = 0; f < Nf; ++f) {PetscDSGetExactSolution(prob, f, &exactFuncs[f]);}
    4195:       DMComputeL2Diff(dm, 0.0, exactFuncs, NULL, u, &error);
    4196:       PetscFree(exactFuncs);
    4197:       if (error < 1.0e-11) {PetscViewerASCIIPrintf(viewer, "L_2 Error: < 1.0e-11\n");}
    4198:       else                 {PetscViewerASCIIPrintf(viewer, "L_2 Error: %g\n", error);}
    4199:     }
    4200:     if (snes->reason > 0) {
    4201:       if (((PetscObject) snes)->prefix) {
    4202:         PetscViewerASCIIPrintf(viewer,"Nonlinear %s solve converged due to %s iterations %D\n",((PetscObject) snes)->prefix,SNESConvergedReasons[snes->reason],snes->iter);
    4203:       } else {
    4204:         PetscViewerASCIIPrintf(viewer,"Nonlinear solve converged due to %s iterations %D\n",SNESConvergedReasons[snes->reason],snes->iter);
    4205:       }
    4206:     } else {
    4207:       if (((PetscObject) snes)->prefix) {
    4208:         PetscViewerASCIIPrintf(viewer,"Nonlinear %s solve did not converge due to %s iterations %D\n",((PetscObject) snes)->prefix,SNESConvergedReasons[snes->reason],snes->iter);
    4209:       } else {
    4210:         PetscViewerASCIIPrintf(viewer,"Nonlinear solve did not converge due to %s iterations %D\n",SNESConvergedReasons[snes->reason],snes->iter);
    4211:       }
    4212:     }
    4213:     PetscViewerASCIISubtractTab(viewer,((PetscObject)snes)->tablevel);
    4214:   }
    4215:   return(0);
    4216: }

    4218: /*@C
    4219:   SNESReasonViewFromOptions - Processes command line options to determine if/how a SNESReason is to be viewed.

    4221:   Collective on SNES

    4223:   Input Parameters:
    4224: . snes   - the SNES object

    4226:   Level: intermediate

    4228: @*/
    4229: PetscErrorCode SNESReasonViewFromOptions(SNES snes)
    4230: {
    4231:   PetscErrorCode    ierr;
    4232:   PetscViewer       viewer;
    4233:   PetscBool         flg;
    4234:   static PetscBool  incall = PETSC_FALSE;
    4235:   PetscViewerFormat format;

    4238:   if (incall) return(0);
    4239:   incall = PETSC_TRUE;
    4240:   PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes),((PetscObject)snes)->prefix,"-snes_converged_reason",&viewer,&format,&flg);
    4241:   if (flg) {
    4242:     PetscViewerPushFormat(viewer,format);
    4243:     SNESReasonView(snes,viewer);
    4244:     PetscViewerPopFormat(viewer);
    4245:     PetscViewerDestroy(&viewer);
    4246:   }
    4247:   incall = PETSC_FALSE;
    4248:   return(0);
    4249: }

    4251: /*@
    4252:    SNESSolve - Solves a nonlinear system F(x) = b.
    4253:    Call SNESSolve() after calling SNESCreate() and optional routines of the form SNESSetXXX().

    4255:    Collective on SNES

    4257:    Input Parameters:
    4258: +  snes - the SNES context
    4259: .  b - the constant part of the equation F(x) = b, or NULL to use zero.
    4260: -  x - the solution vector.

    4262:    Notes:
    4263:    The user should initialize the vector,x, with the initial guess
    4264:    for the nonlinear solve prior to calling SNESSolve.  In particular,
    4265:    to employ an initial guess of zero, the user should explicitly set
    4266:    this vector to zero by calling VecSet().

    4268:    Level: beginner

    4270: .keywords: SNES, nonlinear, solve

    4272: .seealso: SNESCreate(), SNESDestroy(), SNESSetFunction(), SNESSetJacobian(), SNESSetGridSequence(), SNESGetSolution()
    4273: @*/
    4274: PetscErrorCode  SNESSolve(SNES snes,Vec b,Vec x)
    4275: {
    4276:   PetscErrorCode    ierr;
    4277:   PetscBool         flg;
    4278:   PetscInt          grid;
    4279:   Vec               xcreated = NULL;
    4280:   DM                dm;

    4289:   /* High level operations using the nonlinear solver */
    4290:   {
    4291:     PetscViewer       viewer;
    4292:     PetscViewerFormat format;
    4293:     PetscInt          num;
    4294:     PetscBool         flg;
    4295:     static PetscBool  incall = PETSC_FALSE;

    4297:     if (!incall) {
    4298:       /* Estimate the convergence rate of the discretization */
    4299:       PetscOptionsGetViewer(PetscObjectComm((PetscObject) snes), ((PetscObject) snes)->prefix, "-snes_convergence_estimate", &viewer, &format, &flg);
    4300:       if (flg) {
    4301:         PetscConvEst conv;
    4302:         DM           dm;
    4303:         PetscReal   *alpha; /* Convergence rate of the solution error for each field in the L_2 norm */
    4304:         PetscInt     Nf;

    4306:         incall = PETSC_TRUE;
    4307:         SNESGetDM(snes, &dm);
    4308:         DMGetNumFields(dm, &Nf);
    4309:         PetscMalloc1(Nf, &alpha);
    4310:         PetscConvEstCreate(PetscObjectComm((PetscObject) snes), &conv);
    4311:         PetscConvEstSetSolver(conv, snes);
    4312:         PetscConvEstSetFromOptions(conv);
    4313:         PetscConvEstSetUp(conv);
    4314:         PetscConvEstGetConvRate(conv, alpha);
    4315:         PetscViewerPushFormat(viewer, format);
    4316:         PetscConvEstRateView(conv, alpha, viewer);
    4317:         PetscViewerPopFormat(viewer);
    4318:         PetscViewerDestroy(&viewer);
    4319:         PetscConvEstDestroy(&conv);
    4320:         PetscFree(alpha);
    4321:         incall = PETSC_FALSE;
    4322:       }
    4323:       /* Adaptively refine the initial grid */
    4324:       num  = 1;
    4325:       PetscOptionsGetInt(NULL, ((PetscObject) snes)->prefix, "-snes_adapt_initial", &num, &flg);
    4326:       if (flg) {
    4327:         DMAdaptor adaptor;

    4329:         incall = PETSC_TRUE;
    4330:         DMAdaptorCreate(PETSC_COMM_WORLD, &adaptor);
    4331:         DMAdaptorSetSolver(adaptor, snes);
    4332:         DMAdaptorSetSequenceLength(adaptor, num);
    4333:         DMAdaptorSetFromOptions(adaptor);
    4334:         DMAdaptorSetUp(adaptor);
    4335:         DMAdaptorAdapt(adaptor, x, DM_ADAPTATION_INITIAL, &dm, &x);
    4336:         DMAdaptorDestroy(&adaptor);
    4337:         incall = PETSC_FALSE;
    4338:       }
    4339:       /* Use grid sequencing to adapt */
    4340:       num  = 0;
    4341:       PetscOptionsGetInt(NULL, ((PetscObject) snes)->prefix, "-snes_adapt_sequence", &num, NULL);
    4342:       if (num) {
    4343:         DMAdaptor adaptor;

    4345:         incall = PETSC_TRUE;
    4346:         DMAdaptorCreate(PETSC_COMM_WORLD, &adaptor);
    4347:         DMAdaptorSetSolver(adaptor, snes);
    4348:         DMAdaptorSetSequenceLength(adaptor, num);
    4349:         DMAdaptorSetFromOptions(adaptor);
    4350:         DMAdaptorSetUp(adaptor);
    4351:         DMAdaptorAdapt(adaptor, x, DM_ADAPTATION_SEQUENTIAL, &dm, &x);
    4352:         DMAdaptorDestroy(&adaptor);
    4353:         incall = PETSC_FALSE;
    4354:       }
    4355:     }
    4356:   }
    4357:   if (!x) {
    4358:     SNESGetDM(snes,&dm);
    4359:     DMCreateGlobalVector(dm,&xcreated);
    4360:     x    = xcreated;
    4361:   }
    4362:   SNESViewFromOptions(snes,NULL,"-snes_view_pre");

    4364:   for (grid=0; grid<snes->gridsequence; grid++) {PetscViewerASCIIPushTab(PETSC_VIEWER_STDOUT_(PetscObjectComm((PetscObject)snes)));}
    4365:   for (grid=0; grid<snes->gridsequence+1; grid++) {

    4367:     /* set solution vector */
    4368:     if (!grid) {PetscObjectReference((PetscObject)x);}
    4369:     VecDestroy(&snes->vec_sol);
    4370:     snes->vec_sol = x;
    4371:     SNESGetDM(snes,&dm);

    4373:     /* set affine vector if provided */
    4374:     if (b) { PetscObjectReference((PetscObject)b); }
    4375:     VecDestroy(&snes->vec_rhs);
    4376:     snes->vec_rhs = b;

    4378:     if (snes->vec_func == snes->vec_sol) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_IDN,"Solution vector cannot be function vector");
    4379:     if (snes->vec_rhs  == snes->vec_sol) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_IDN,"Solution vector cannot be right hand side vector");
    4380:     if (!snes->vec_sol_update /* && snes->vec_sol */) {
    4381:       VecDuplicate(snes->vec_sol,&snes->vec_sol_update);
    4382:       PetscLogObjectParent((PetscObject)snes,(PetscObject)snes->vec_sol_update);
    4383:     }
    4384:     DMShellSetGlobalVector(dm,snes->vec_sol);
    4385:     SNESSetUp(snes);

    4387:     if (!grid) {
    4388:       if (snes->ops->computeinitialguess) {
    4389:         (*snes->ops->computeinitialguess)(snes,snes->vec_sol,snes->initialguessP);
    4390:       }
    4391:     }

    4393:     if (snes->conv_hist_reset) snes->conv_hist_len = 0;
    4394:     if (snes->counters_reset) {snes->nfuncs = 0; snes->linear_its = 0; snes->numFailures = 0;}

    4396:     PetscLogEventBegin(SNES_Solve,snes,0,0,0);
    4397:     (*snes->ops->solve)(snes);
    4398:     PetscLogEventEnd(SNES_Solve,snes,0,0,0);
    4399:     if (!snes->reason) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Internal error, solver returned without setting converged reason");
    4400:     snes->domainerror = PETSC_FALSE; /* clear the flag if it has been set */

    4402:     if (snes->lagjac_persist) snes->jac_iter += snes->iter;
    4403:     if (snes->lagpre_persist) snes->pre_iter += snes->iter;

    4405:     PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes),((PetscObject)snes)->prefix,"-snes_test_local_min",NULL,NULL,&flg);
    4406:     if (flg && !PetscPreLoadingOn) { SNESTestLocalMin(snes); }
    4407:     SNESReasonViewFromOptions(snes);

    4409:     if (snes->errorifnotconverged && snes->reason < 0) SETERRQ(PetscObjectComm((PetscObject)snes),PETSC_ERR_NOT_CONVERGED,"SNESSolve has not converged");
    4410:     if (snes->reason < 0) break;
    4411:     if (grid <  snes->gridsequence) {
    4412:       DM  fine;
    4413:       Vec xnew;
    4414:       Mat interp;

    4416:       DMRefine(snes->dm,PetscObjectComm((PetscObject)snes),&fine);
    4417:       if (!fine) SETERRQ(PetscObjectComm((PetscObject)snes),PETSC_ERR_ARG_INCOMP,"DMRefine() did not perform any refinement, cannot continue grid sequencing");
    4418:       DMCreateInterpolation(snes->dm,fine,&interp,NULL);
    4419:       DMCreateGlobalVector(fine,&xnew);
    4420:       MatInterpolate(interp,x,xnew);
    4421:       DMInterpolate(snes->dm,interp,fine);
    4422:       MatDestroy(&interp);
    4423:       x    = xnew;

    4425:       SNESReset(snes);
    4426:       SNESSetDM(snes,fine);
    4427:       SNESResetFromOptions(snes);
    4428:       DMDestroy(&fine);
    4429:       PetscViewerASCIIPopTab(PETSC_VIEWER_STDOUT_(PetscObjectComm((PetscObject)snes)));
    4430:     }
    4431:   }
    4432:   SNESViewFromOptions(snes,NULL,"-snes_view");
    4433:   VecViewFromOptions(snes->vec_sol,(PetscObject)snes,"-snes_view_solution");

    4435:   VecDestroy(&xcreated);
    4436:   PetscObjectSAWsBlock((PetscObject)snes);
    4437:   return(0);
    4438: }

    4440: /* --------- Internal routines for SNES Package --------- */

    4442: /*@C
    4443:    SNESSetType - Sets the method for the nonlinear solver.

    4445:    Collective on SNES

    4447:    Input Parameters:
    4448: +  snes - the SNES context
    4449: -  type - a known method

    4451:    Options Database Key:
    4452: .  -snes_type <type> - Sets the method; use -help for a list
    4453:    of available methods (for instance, newtonls or newtontr)

    4455:    Notes:
    4456:    See "petsc/include/petscsnes.h" for available methods (for instance)
    4457: +    SNESNEWTONLS - Newton's method with line search
    4458:      (systems of nonlinear equations)
    4459: .    SNESNEWTONTR - Newton's method with trust region
    4460:      (systems of nonlinear equations)

    4462:   Normally, it is best to use the SNESSetFromOptions() command and then
    4463:   set the SNES solver type from the options database rather than by using
    4464:   this routine.  Using the options database provides the user with
    4465:   maximum flexibility in evaluating the many nonlinear solvers.
    4466:   The SNESSetType() routine is provided for those situations where it
    4467:   is necessary to set the nonlinear solver independently of the command
    4468:   line or options database.  This might be the case, for example, when
    4469:   the choice of solver changes during the execution of the program,
    4470:   and the user's application is taking responsibility for choosing the
    4471:   appropriate method.

    4473:     Developer Notes:
    4474:     SNESRegister() adds a constructor for a new SNESType to SNESList, SNESSetType() locates
    4475:     the constructor in that list and calls it to create the spexific object.

    4477:   Level: intermediate

    4479: .keywords: SNES, set, type

    4481: .seealso: SNESType, SNESCreate(), SNESDestroy(), SNESGetType(), SNESSetFromOptions()

    4483: @*/
    4484: PetscErrorCode  SNESSetType(SNES snes,SNESType type)
    4485: {
    4486:   PetscErrorCode ierr,(*r)(SNES);
    4487:   PetscBool      match;

    4493:   PetscObjectTypeCompare((PetscObject)snes,type,&match);
    4494:   if (match) return(0);

    4496:    PetscFunctionListFind(SNESList,type,&r);
    4497:   if (!r) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_UNKNOWN_TYPE,"Unable to find requested SNES type %s",type);
    4498:   /* Destroy the previous private SNES context */
    4499:   if (snes->ops->destroy) {
    4500:     (*(snes)->ops->destroy)(snes);
    4501:     snes->ops->destroy = NULL;
    4502:   }
    4503:   /* Reinitialize function pointers in SNESOps structure */
    4504:   snes->ops->setup          = 0;
    4505:   snes->ops->solve          = 0;
    4506:   snes->ops->view           = 0;
    4507:   snes->ops->setfromoptions = 0;
    4508:   snes->ops->destroy        = 0;
    4509:   /* Call the SNESCreate_XXX routine for this particular Nonlinear solver */
    4510:   snes->setupcalled = PETSC_FALSE;

    4512:   PetscObjectChangeTypeName((PetscObject)snes,type);
    4513:   (*r)(snes);
    4514:   return(0);
    4515: }

    4517: /*@C
    4518:    SNESGetType - Gets the SNES method type and name (as a string).

    4520:    Not Collective

    4522:    Input Parameter:
    4523: .  snes - nonlinear solver context

    4525:    Output Parameter:
    4526: .  type - SNES method (a character string)

    4528:    Level: intermediate

    4530: .keywords: SNES, nonlinear, get, type, name
    4531: @*/
    4532: PetscErrorCode  SNESGetType(SNES snes,SNESType *type)
    4533: {
    4537:   *type = ((PetscObject)snes)->type_name;
    4538:   return(0);
    4539: }

    4541: /*@
    4542:   SNESSetSolution - Sets the solution vector for use by the SNES routines.

    4544:   Logically Collective on SNES and Vec

    4546:   Input Parameters:
    4547: + snes - the SNES context obtained from SNESCreate()
    4548: - u    - the solution vector

    4550:   Level: beginner

    4552: .keywords: SNES, set, solution
    4553: @*/
    4554: PetscErrorCode SNESSetSolution(SNES snes, Vec u)
    4555: {
    4556:   DM             dm;

    4562:   PetscObjectReference((PetscObject) u);
    4563:   VecDestroy(&snes->vec_sol);

    4565:   snes->vec_sol = u;

    4567:   SNESGetDM(snes, &dm);
    4568:   DMShellSetGlobalVector(dm, u);
    4569:   return(0);
    4570: }

    4572: /*@
    4573:    SNESGetSolution - Returns the vector where the approximate solution is
    4574:    stored. This is the fine grid solution when using SNESSetGridSequence().

    4576:    Not Collective, but Vec is parallel if SNES is parallel

    4578:    Input Parameter:
    4579: .  snes - the SNES context

    4581:    Output Parameter:
    4582: .  x - the solution

    4584:    Level: intermediate

    4586: .keywords: SNES, nonlinear, get, solution

    4588: .seealso:  SNESGetSolutionUpdate(), SNESGetFunction()
    4589: @*/
    4590: PetscErrorCode  SNESGetSolution(SNES snes,Vec *x)
    4591: {
    4595:   *x = snes->vec_sol;
    4596:   return(0);
    4597: }

    4599: /*@
    4600:    SNESGetSolutionUpdate - Returns the vector where the solution update is
    4601:    stored.

    4603:    Not Collective, but Vec is parallel if SNES is parallel

    4605:    Input Parameter:
    4606: .  snes - the SNES context

    4608:    Output Parameter:
    4609: .  x - the solution update

    4611:    Level: advanced

    4613: .keywords: SNES, nonlinear, get, solution, update

    4615: .seealso: SNESGetSolution(), SNESGetFunction()
    4616: @*/
    4617: PetscErrorCode  SNESGetSolutionUpdate(SNES snes,Vec *x)
    4618: {
    4622:   *x = snes->vec_sol_update;
    4623:   return(0);
    4624: }

    4626: /*@C
    4627:    SNESGetFunction - Returns the vector where the function is stored.

    4629:    Not Collective, but Vec is parallel if SNES is parallel. Collective if Vec is requested, but has not been created yet.

    4631:    Input Parameter:
    4632: .  snes - the SNES context

    4634:    Output Parameter:
    4635: +  r - the vector that is used to store residuals (or NULL if you don't want it)
    4636: .  f - the function (or NULL if you don't want it); see SNESFunction for calling sequence details
    4637: -  ctx - the function context (or NULL if you don't want it)

    4639:    Level: advanced

    4641:     Notes: The vector r DOES NOT, in general contain the current value of the SNES nonlinear function

    4643: .keywords: SNES, nonlinear, get, function

    4645: .seealso: SNESSetFunction(), SNESGetSolution(), SNESFunction
    4646: @*/
    4647: PetscErrorCode  SNESGetFunction(SNES snes,Vec *r,PetscErrorCode (**f)(SNES,Vec,Vec,void*),void **ctx)
    4648: {
    4650:   DM             dm;

    4654:   if (r) {
    4655:     if (!snes->vec_func) {
    4656:       if (snes->vec_rhs) {
    4657:         VecDuplicate(snes->vec_rhs,&snes->vec_func);
    4658:       } else if (snes->vec_sol) {
    4659:         VecDuplicate(snes->vec_sol,&snes->vec_func);
    4660:       } else if (snes->dm) {
    4661:         DMCreateGlobalVector(snes->dm,&snes->vec_func);
    4662:       }
    4663:     }
    4664:     *r = snes->vec_func;
    4665:   }
    4666:   SNESGetDM(snes,&dm);
    4667:   DMSNESGetFunction(dm,f,ctx);
    4668:   return(0);
    4669: }

    4671: /*@C
    4672:    SNESGetNGS - Returns the NGS function and context.

    4674:    Input Parameter:
    4675: .  snes - the SNES context

    4677:    Output Parameter:
    4678: +  f - the function (or NULL) see SNESNGSFunction for details
    4679: -  ctx    - the function context (or NULL)

    4681:    Level: advanced

    4683: .keywords: SNES, nonlinear, get, function

    4685: .seealso: SNESSetNGS(), SNESGetFunction()
    4686: @*/

    4688: PetscErrorCode SNESGetNGS (SNES snes, PetscErrorCode (**f)(SNES, Vec, Vec, void*), void ** ctx)
    4689: {
    4691:   DM             dm;

    4695:   SNESGetDM(snes,&dm);
    4696:   DMSNESGetNGS(dm,f,ctx);
    4697:   return(0);
    4698: }

    4700: /*@C
    4701:    SNESSetOptionsPrefix - Sets the prefix used for searching for all
    4702:    SNES options in the database.

    4704:    Logically Collective on SNES

    4706:    Input Parameter:
    4707: +  snes - the SNES context
    4708: -  prefix - the prefix to prepend to all option names

    4710:    Notes:
    4711:    A hyphen (-) must NOT be given at the beginning of the prefix name.
    4712:    The first character of all runtime options is AUTOMATICALLY the hyphen.

    4714:    Level: advanced

    4716: .keywords: SNES, set, options, prefix, database

    4718: .seealso: SNESSetFromOptions()
    4719: @*/
    4720: PetscErrorCode  SNESSetOptionsPrefix(SNES snes,const char prefix[])
    4721: {

    4726:   PetscObjectSetOptionsPrefix((PetscObject)snes,prefix);
    4727:   if (!snes->ksp) {SNESGetKSP(snes,&snes->ksp);}
    4728:   if (snes->linesearch) {
    4729:     SNESGetLineSearch(snes,&snes->linesearch);
    4730:     PetscObjectSetOptionsPrefix((PetscObject)snes->linesearch,prefix);
    4731:   }
    4732:   KSPSetOptionsPrefix(snes->ksp,prefix);
    4733:   return(0);
    4734: }

    4736: /*@C
    4737:    SNESAppendOptionsPrefix - Appends to the prefix used for searching for all
    4738:    SNES options in the database.

    4740:    Logically Collective on SNES

    4742:    Input Parameters:
    4743: +  snes - the SNES context
    4744: -  prefix - the prefix to prepend to all option names

    4746:    Notes:
    4747:    A hyphen (-) must NOT be given at the beginning of the prefix name.
    4748:    The first character of all runtime options is AUTOMATICALLY the hyphen.

    4750:    Level: advanced

    4752: .keywords: SNES, append, options, prefix, database

    4754: .seealso: SNESGetOptionsPrefix()
    4755: @*/
    4756: PetscErrorCode  SNESAppendOptionsPrefix(SNES snes,const char prefix[])
    4757: {

    4762:   PetscObjectAppendOptionsPrefix((PetscObject)snes,prefix);
    4763:   if (!snes->ksp) {SNESGetKSP(snes,&snes->ksp);}
    4764:   if (snes->linesearch) {
    4765:     SNESGetLineSearch(snes,&snes->linesearch);
    4766:     PetscObjectAppendOptionsPrefix((PetscObject)snes->linesearch,prefix);
    4767:   }
    4768:   KSPAppendOptionsPrefix(snes->ksp,prefix);
    4769:   return(0);
    4770: }

    4772: /*@C
    4773:    SNESGetOptionsPrefix - Sets the prefix used for searching for all
    4774:    SNES options in the database.

    4776:    Not Collective

    4778:    Input Parameter:
    4779: .  snes - the SNES context

    4781:    Output Parameter:
    4782: .  prefix - pointer to the prefix string used

    4784:    Notes:
    4785:     On the fortran side, the user should pass in a string 'prefix' of
    4786:    sufficient length to hold the prefix.

    4788:    Level: advanced

    4790: .keywords: SNES, get, options, prefix, database

    4792: .seealso: SNESAppendOptionsPrefix()
    4793: @*/
    4794: PetscErrorCode  SNESGetOptionsPrefix(SNES snes,const char *prefix[])
    4795: {

    4800:   PetscObjectGetOptionsPrefix((PetscObject)snes,prefix);
    4801:   return(0);
    4802: }

    4805: /*@C
    4806:   SNESRegister - Adds a method to the nonlinear solver package.

    4808:    Not collective

    4810:    Input Parameters:
    4811: +  name_solver - name of a new user-defined solver
    4812: -  routine_create - routine to create method context

    4814:    Notes:
    4815:    SNESRegister() may be called multiple times to add several user-defined solvers.

    4817:    Sample usage:
    4818: .vb
    4819:    SNESRegister("my_solver",MySolverCreate);
    4820: .ve

    4822:    Then, your solver can be chosen with the procedural interface via
    4823: $     SNESSetType(snes,"my_solver")
    4824:    or at runtime via the option
    4825: $     -snes_type my_solver

    4827:    Level: advanced

    4829:     Note: If your function is not being put into a shared library then use SNESRegister() instead

    4831: .keywords: SNES, nonlinear, register

    4833: .seealso: SNESRegisterAll(), SNESRegisterDestroy()

    4835:   Level: advanced
    4836: @*/
    4837: PetscErrorCode  SNESRegister(const char sname[],PetscErrorCode (*function)(SNES))
    4838: {

    4842:   SNESInitializePackage();
    4843:   PetscFunctionListAdd(&SNESList,sname,function);
    4844:   return(0);
    4845: }

    4847: PetscErrorCode  SNESTestLocalMin(SNES snes)
    4848: {
    4850:   PetscInt       N,i,j;
    4851:   Vec            u,uh,fh;
    4852:   PetscScalar    value;
    4853:   PetscReal      norm;

    4856:   SNESGetSolution(snes,&u);
    4857:   VecDuplicate(u,&uh);
    4858:   VecDuplicate(u,&fh);

    4860:   /* currently only works for sequential */
    4861:   PetscPrintf(PETSC_COMM_WORLD,"Testing FormFunction() for local min\n");
    4862:   VecGetSize(u,&N);
    4863:   for (i=0; i<N; i++) {
    4864:     VecCopy(u,uh);
    4865:     PetscPrintf(PETSC_COMM_WORLD,"i = %D\n",i);
    4866:     for (j=-10; j<11; j++) {
    4867:       value = PetscSign(j)*PetscExpReal(PetscAbs(j)-10.0);
    4868:       VecSetValue(uh,i,value,ADD_VALUES);
    4869:       SNESComputeFunction(snes,uh,fh);
    4870:       VecNorm(fh,NORM_2,&norm);
    4871:       PetscPrintf(PETSC_COMM_WORLD,"       j norm %D %18.16e\n",j,norm);
    4872:       value = -value;
    4873:       VecSetValue(uh,i,value,ADD_VALUES);
    4874:     }
    4875:   }
    4876:   VecDestroy(&uh);
    4877:   VecDestroy(&fh);
    4878:   return(0);
    4879: }

    4881: /*@
    4882:    SNESKSPSetUseEW - Sets SNES use Eisenstat-Walker method for
    4883:    computing relative tolerance for linear solvers within an inexact
    4884:    Newton method.

    4886:    Logically Collective on SNES

    4888:    Input Parameters:
    4889: +  snes - SNES context
    4890: -  flag - PETSC_TRUE or PETSC_FALSE

    4892:     Options Database:
    4893: +  -snes_ksp_ew - use Eisenstat-Walker method for determining linear system convergence
    4894: .  -snes_ksp_ew_version ver - version of  Eisenstat-Walker method
    4895: .  -snes_ksp_ew_rtol0 <rtol0> - Sets rtol0
    4896: .  -snes_ksp_ew_rtolmax <rtolmax> - Sets rtolmax
    4897: .  -snes_ksp_ew_gamma <gamma> - Sets gamma
    4898: .  -snes_ksp_ew_alpha <alpha> - Sets alpha
    4899: .  -snes_ksp_ew_alpha2 <alpha2> - Sets alpha2
    4900: -  -snes_ksp_ew_threshold <threshold> - Sets threshold

    4902:    Notes:
    4903:    Currently, the default is to use a constant relative tolerance for
    4904:    the inner linear solvers.  Alternatively, one can use the
    4905:    Eisenstat-Walker method, where the relative convergence tolerance
    4906:    is reset at each Newton iteration according progress of the nonlinear
    4907:    solver.

    4909:    Level: advanced

    4911:    Reference:
    4912:    S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an
    4913:    inexact Newton method", SISC 17 (1), pp.16-32, 1996.

    4915: .keywords: SNES, KSP, Eisenstat, Walker, convergence, test, inexact, Newton

    4917: .seealso: SNESKSPGetUseEW(), SNESKSPGetParametersEW(), SNESKSPSetParametersEW()
    4918: @*/
    4919: PetscErrorCode  SNESKSPSetUseEW(SNES snes,PetscBool flag)
    4920: {
    4924:   snes->ksp_ewconv = flag;
    4925:   return(0);
    4926: }

    4928: /*@
    4929:    SNESKSPGetUseEW - Gets if SNES is using Eisenstat-Walker method
    4930:    for computing relative tolerance for linear solvers within an
    4931:    inexact Newton method.

    4933:    Not Collective

    4935:    Input Parameter:
    4936: .  snes - SNES context

    4938:    Output Parameter:
    4939: .  flag - PETSC_TRUE or PETSC_FALSE

    4941:    Notes:
    4942:    Currently, the default is to use a constant relative tolerance for
    4943:    the inner linear solvers.  Alternatively, one can use the
    4944:    Eisenstat-Walker method, where the relative convergence tolerance
    4945:    is reset at each Newton iteration according progress of the nonlinear
    4946:    solver.

    4948:    Level: advanced

    4950:    Reference:
    4951:    S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an
    4952:    inexact Newton method", SISC 17 (1), pp.16-32, 1996.

    4954: .keywords: SNES, KSP, Eisenstat, Walker, convergence, test, inexact, Newton

    4956: .seealso: SNESKSPSetUseEW(), SNESKSPGetParametersEW(), SNESKSPSetParametersEW()
    4957: @*/
    4958: PetscErrorCode  SNESKSPGetUseEW(SNES snes, PetscBool  *flag)
    4959: {
    4963:   *flag = snes->ksp_ewconv;
    4964:   return(0);
    4965: }

    4967: /*@
    4968:    SNESKSPSetParametersEW - Sets parameters for Eisenstat-Walker
    4969:    convergence criteria for the linear solvers within an inexact
    4970:    Newton method.

    4972:    Logically Collective on SNES

    4974:    Input Parameters:
    4975: +    snes - SNES context
    4976: .    version - version 1, 2 (default is 2) or 3
    4977: .    rtol_0 - initial relative tolerance (0 <= rtol_0 < 1)
    4978: .    rtol_max - maximum relative tolerance (0 <= rtol_max < 1)
    4979: .    gamma - multiplicative factor for version 2 rtol computation
    4980:              (0 <= gamma2 <= 1)
    4981: .    alpha - power for version 2 rtol computation (1 < alpha <= 2)
    4982: .    alpha2 - power for safeguard
    4983: -    threshold - threshold for imposing safeguard (0 < threshold < 1)

    4985:    Note:
    4986:    Version 3 was contributed by Luis Chacon, June 2006.

    4988:    Use PETSC_DEFAULT to retain the default for any of the parameters.

    4990:    Level: advanced

    4992:    Reference:
    4993:    S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an
    4994:    inexact Newton method", Utah State University Math. Stat. Dept. Res.
    4995:    Report 6/94/75, June, 1994, to appear in SIAM J. Sci. Comput.

    4997: .keywords: SNES, KSP, Eisenstat, Walker, set, parameters

    4999: .seealso: SNESKSPSetUseEW(), SNESKSPGetUseEW(), SNESKSPGetParametersEW()
    5000: @*/
    5001: PetscErrorCode  SNESKSPSetParametersEW(SNES snes,PetscInt version,PetscReal rtol_0,PetscReal rtol_max,PetscReal gamma,PetscReal alpha,PetscReal alpha2,PetscReal threshold)
    5002: {
    5003:   SNESKSPEW *kctx;

    5007:   kctx = (SNESKSPEW*)snes->kspconvctx;
    5008:   if (!kctx) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context existing");

    5017:   if (version != PETSC_DEFAULT)   kctx->version   = version;
    5018:   if (rtol_0 != PETSC_DEFAULT)    kctx->rtol_0    = rtol_0;
    5019:   if (rtol_max != PETSC_DEFAULT)  kctx->rtol_max  = rtol_max;
    5020:   if (gamma != PETSC_DEFAULT)     kctx->gamma     = gamma;
    5021:   if (alpha != PETSC_DEFAULT)     kctx->alpha     = alpha;
    5022:   if (alpha2 != PETSC_DEFAULT)    kctx->alpha2    = alpha2;
    5023:   if (threshold != PETSC_DEFAULT) kctx->threshold = threshold;

    5025:   if (kctx->version < 1 || kctx->version > 3) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Only versions 1, 2 and 3 are supported: %D",kctx->version);
    5026:   if (kctx->rtol_0 < 0.0 || kctx->rtol_0 >= 1.0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"0.0 <= rtol_0 < 1.0: %g",(double)kctx->rtol_0);
    5027:   if (kctx->rtol_max < 0.0 || kctx->rtol_max >= 1.0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"0.0 <= rtol_max (%g) < 1.0\n",(double)kctx->rtol_max);
    5028:   if (kctx->gamma < 0.0 || kctx->gamma > 1.0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"0.0 <= gamma (%g) <= 1.0\n",(double)kctx->gamma);
    5029:   if (kctx->alpha <= 1.0 || kctx->alpha > 2.0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"1.0 < alpha (%g) <= 2.0\n",(double)kctx->alpha);
    5030:   if (kctx->threshold <= 0.0 || kctx->threshold >= 1.0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"0.0 < threshold (%g) < 1.0\n",(double)kctx->threshold);
    5031:   return(0);
    5032: }

    5034: /*@
    5035:    SNESKSPGetParametersEW - Gets parameters for Eisenstat-Walker
    5036:    convergence criteria for the linear solvers within an inexact
    5037:    Newton method.

    5039:    Not Collective

    5041:    Input Parameters:
    5042:      snes - SNES context

    5044:    Output Parameters:
    5045: +    version - version 1, 2 (default is 2) or 3
    5046: .    rtol_0 - initial relative tolerance (0 <= rtol_0 < 1)
    5047: .    rtol_max - maximum relative tolerance (0 <= rtol_max < 1)
    5048: .    gamma - multiplicative factor for version 2 rtol computation (0 <= gamma2 <= 1)
    5049: .    alpha - power for version 2 rtol computation (1 < alpha <= 2)
    5050: .    alpha2 - power for safeguard
    5051: -    threshold - threshold for imposing safeguard (0 < threshold < 1)

    5053:    Level: advanced

    5055: .keywords: SNES, KSP, Eisenstat, Walker, get, parameters

    5057: .seealso: SNESKSPSetUseEW(), SNESKSPGetUseEW(), SNESKSPSetParametersEW()
    5058: @*/
    5059: PetscErrorCode  SNESKSPGetParametersEW(SNES snes,PetscInt *version,PetscReal *rtol_0,PetscReal *rtol_max,PetscReal *gamma,PetscReal *alpha,PetscReal *alpha2,PetscReal *threshold)
    5060: {
    5061:   SNESKSPEW *kctx;

    5065:   kctx = (SNESKSPEW*)snes->kspconvctx;
    5066:   if (!kctx) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context existing");
    5067:   if (version)   *version   = kctx->version;
    5068:   if (rtol_0)    *rtol_0    = kctx->rtol_0;
    5069:   if (rtol_max)  *rtol_max  = kctx->rtol_max;
    5070:   if (gamma)     *gamma     = kctx->gamma;
    5071:   if (alpha)     *alpha     = kctx->alpha;
    5072:   if (alpha2)    *alpha2    = kctx->alpha2;
    5073:   if (threshold) *threshold = kctx->threshold;
    5074:   return(0);
    5075: }

    5077:  PetscErrorCode KSPPreSolve_SNESEW(KSP ksp, Vec b, Vec x, SNES snes)
    5078: {
    5080:   SNESKSPEW      *kctx = (SNESKSPEW*)snes->kspconvctx;
    5081:   PetscReal      rtol  = PETSC_DEFAULT,stol;

    5084:   if (!snes->ksp_ewconv) return(0);
    5085:   if (!snes->iter) {
    5086:     rtol = kctx->rtol_0; /* first time in, so use the original user rtol */
    5087:     VecNorm(snes->vec_func,NORM_2,&kctx->norm_first);
    5088:   }
    5089:   else {
    5090:     if (kctx->version == 1) {
    5091:       rtol = (snes->norm - kctx->lresid_last)/kctx->norm_last;
    5092:       if (rtol < 0.0) rtol = -rtol;
    5093:       stol = PetscPowReal(kctx->rtol_last,kctx->alpha2);
    5094:       if (stol > kctx->threshold) rtol = PetscMax(rtol,stol);
    5095:     } else if (kctx->version == 2) {
    5096:       rtol = kctx->gamma * PetscPowReal(snes->norm/kctx->norm_last,kctx->alpha);
    5097:       stol = kctx->gamma * PetscPowReal(kctx->rtol_last,kctx->alpha);
    5098:       if (stol > kctx->threshold) rtol = PetscMax(rtol,stol);
    5099:     } else if (kctx->version == 3) { /* contributed by Luis Chacon, June 2006. */
    5100:       rtol = kctx->gamma * PetscPowReal(snes->norm/kctx->norm_last,kctx->alpha);
    5101:       /* safeguard: avoid sharp decrease of rtol */
    5102:       stol = kctx->gamma*PetscPowReal(kctx->rtol_last,kctx->alpha);
    5103:       stol = PetscMax(rtol,stol);
    5104:       rtol = PetscMin(kctx->rtol_0,stol);
    5105:       /* safeguard: avoid oversolving */
    5106:       stol = kctx->gamma*(kctx->norm_first*snes->rtol)/snes->norm;
    5107:       stol = PetscMax(rtol,stol);
    5108:       rtol = PetscMin(kctx->rtol_0,stol);
    5109:     } else SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Only versions 1, 2 or 3 are supported: %D",kctx->version);
    5110:   }
    5111:   /* safeguard: avoid rtol greater than one */
    5112:   rtol = PetscMin(rtol,kctx->rtol_max);
    5113:   KSPSetTolerances(ksp,rtol,PETSC_DEFAULT,PETSC_DEFAULT,PETSC_DEFAULT);
    5114:   PetscInfo3(snes,"iter %D, Eisenstat-Walker (version %D) KSP rtol=%g\n",snes->iter,kctx->version,(double)rtol);
    5115:   return(0);
    5116: }

    5118: PetscErrorCode KSPPostSolve_SNESEW(KSP ksp, Vec b, Vec x, SNES snes)
    5119: {
    5121:   SNESKSPEW      *kctx = (SNESKSPEW*)snes->kspconvctx;
    5122:   PCSide         pcside;
    5123:   Vec            lres;

    5126:   if (!snes->ksp_ewconv) return(0);
    5127:   KSPGetTolerances(ksp,&kctx->rtol_last,0,0,0);
    5128:   kctx->norm_last = snes->norm;
    5129:   if (kctx->version == 1) {
    5130:     PC        pc;
    5131:     PetscBool isNone;

    5133:     KSPGetPC(ksp, &pc);
    5134:     PetscObjectTypeCompare((PetscObject) pc, PCNONE, &isNone);
    5135:     KSPGetPCSide(ksp,&pcside);
    5136:      if (pcside == PC_RIGHT || isNone) { /* XXX Should we also test KSP_UNPRECONDITIONED_NORM ? */
    5137:       /* KSP residual is true linear residual */
    5138:       KSPGetResidualNorm(ksp,&kctx->lresid_last);
    5139:     } else {
    5140:       /* KSP residual is preconditioned residual */
    5141:       /* compute true linear residual norm */
    5142:       VecDuplicate(b,&lres);
    5143:       MatMult(snes->jacobian,x,lres);
    5144:       VecAYPX(lres,-1.0,b);
    5145:       VecNorm(lres,NORM_2,&kctx->lresid_last);
    5146:       VecDestroy(&lres);
    5147:     }
    5148:   }
    5149:   return(0);
    5150: }

    5152: /*@
    5153:    SNESGetKSP - Returns the KSP context for a SNES solver.

    5155:    Not Collective, but if SNES object is parallel, then KSP object is parallel

    5157:    Input Parameter:
    5158: .  snes - the SNES context

    5160:    Output Parameter:
    5161: .  ksp - the KSP context

    5163:    Notes:
    5164:    The user can then directly manipulate the KSP context to set various
    5165:    options, etc.  Likewise, the user can then extract and manipulate the
    5166:    PC contexts as well.

    5168:    Level: beginner

    5170: .keywords: SNES, nonlinear, get, KSP, context

    5172: .seealso: KSPGetPC(), SNESCreate(), KSPCreate(), SNESSetKSP()
    5173: @*/
    5174: PetscErrorCode  SNESGetKSP(SNES snes,KSP *ksp)
    5175: {

    5182:   if (!snes->ksp) {
    5183:     PetscBool monitor = PETSC_FALSE;

    5185:     KSPCreate(PetscObjectComm((PetscObject)snes),&snes->ksp);
    5186:     PetscObjectIncrementTabLevel((PetscObject)snes->ksp,(PetscObject)snes,1);
    5187:     PetscLogObjectParent((PetscObject)snes,(PetscObject)snes->ksp);

    5189:     KSPSetPreSolve(snes->ksp,(PetscErrorCode (*)(KSP,Vec,Vec,void*))KSPPreSolve_SNESEW,snes);
    5190:     KSPSetPostSolve(snes->ksp,(PetscErrorCode (*)(KSP,Vec,Vec,void*))KSPPostSolve_SNESEW,snes);

    5192:     PetscOptionsGetBool(((PetscObject)snes)->options,((PetscObject)snes)->prefix,"-ksp_monitor_snes",&monitor,NULL);
    5193:     if (monitor) {
    5194:       KSPMonitorSet(snes->ksp,KSPMonitorSNES,snes,NULL);
    5195:     }
    5196:     monitor = PETSC_FALSE;
    5197:     PetscOptionsGetBool(((PetscObject)snes)->options,((PetscObject)snes)->prefix,"-ksp_monitor_snes_lg",&monitor,NULL);
    5198:     if (monitor) {
    5199:       PetscObject *objs;
    5200:       KSPMonitorSNESLGResidualNormCreate(PetscObjectComm((PetscObject)snes),NULL,NULL,PETSC_DECIDE,PETSC_DECIDE,600,600,&objs);
    5201:       objs[0] = (PetscObject) snes;
    5202:       KSPMonitorSet(snes->ksp,(PetscErrorCode (*)(KSP,PetscInt,PetscReal,void*))KSPMonitorSNESLGResidualNorm,objs,(PetscErrorCode (*)(void**))KSPMonitorSNESLGResidualNormDestroy);
    5203:     }
    5204:   }
    5205:   *ksp = snes->ksp;
    5206:   return(0);
    5207: }

    5210:  #include <petsc/private/dmimpl.h>
    5211: /*@
    5212:    SNESSetDM - Sets the DM that may be used by some nonlinear solvers or their underlying preconditioners

    5214:    Logically Collective on SNES

    5216:    Input Parameters:
    5217: +  snes - the nonlinear solver context
    5218: -  dm - the dm, cannot be NULL

    5220:    Notes:
    5221:    A DM can only be used for solving one problem at a time because information about the problem is stored on the DM,
    5222:    even when not using interfaces like DMSNESSetFunction().  Use DMClone() to get a distinct DM when solving different
    5223:    problems using the same function space.

    5225:    Level: intermediate

    5227: .seealso: SNESGetDM(), KSPSetDM(), KSPGetDM()
    5228: @*/
    5229: PetscErrorCode  SNESSetDM(SNES snes,DM dm)
    5230: {
    5232:   KSP            ksp;
    5233:   DMSNES         sdm;

    5238:   PetscObjectReference((PetscObject)dm);
    5239:   if (snes->dm) {               /* Move the DMSNES context over to the new DM unless the new DM already has one */
    5240:     if (snes->dm->dmsnes && !dm->dmsnes) {
    5241:       DMCopyDMSNES(snes->dm,dm);
    5242:       DMGetDMSNES(snes->dm,&sdm);
    5243:       if (sdm->originaldm == snes->dm) sdm->originaldm = dm; /* Grant write privileges to the replacement DM */
    5244:     }
    5245:     DMCoarsenHookRemove(snes->dm,DMCoarsenHook_SNESVecSol,DMRestrictHook_SNESVecSol,snes);
    5246:     DMDestroy(&snes->dm);
    5247:   }
    5248:   snes->dm     = dm;
    5249:   snes->dmAuto = PETSC_FALSE;

    5251:   SNESGetKSP(snes,&ksp);
    5252:   KSPSetDM(ksp,dm);
    5253:   KSPSetDMActive(ksp,PETSC_FALSE);
    5254:   if (snes->npc) {
    5255:     SNESSetDM(snes->npc, snes->dm);
    5256:     SNESSetNPCSide(snes,snes->npcside);
    5257:   }
    5258:   return(0);
    5259: }

    5261: /*@
    5262:    SNESGetDM - Gets the DM that may be used by some preconditioners

    5264:    Not Collective but DM obtained is parallel on SNES

    5266:    Input Parameter:
    5267: . snes - the preconditioner context

    5269:    Output Parameter:
    5270: .  dm - the dm

    5272:    Level: intermediate

    5274: .seealso: SNESSetDM(), KSPSetDM(), KSPGetDM()
    5275: @*/
    5276: PetscErrorCode  SNESGetDM(SNES snes,DM *dm)
    5277: {

    5282:   if (!snes->dm) {
    5283:     DMShellCreate(PetscObjectComm((PetscObject)snes),&snes->dm);
    5284:     snes->dmAuto = PETSC_TRUE;
    5285:   }
    5286:   *dm = snes->dm;
    5287:   return(0);
    5288: }

    5290: /*@
    5291:   SNESSetNPC - Sets the nonlinear preconditioner to be used.

    5293:   Collective on SNES

    5295:   Input Parameters:
    5296: + snes - iterative context obtained from SNESCreate()
    5297: - pc   - the preconditioner object

    5299:   Notes:
    5300:   Use SNESGetNPC() to retrieve the preconditioner context (for example,
    5301:   to configure it using the API).

    5303:   Level: developer

    5305: .keywords: SNES, set, precondition
    5306: .seealso: SNESGetNPC(), SNESHasNPC()
    5307: @*/
    5308: PetscErrorCode SNESSetNPC(SNES snes, SNES pc)
    5309: {

    5316:   PetscObjectReference((PetscObject) pc);
    5317:   SNESDestroy(&snes->npc);
    5318:   snes->npc = pc;
    5319:   PetscLogObjectParent((PetscObject)snes, (PetscObject)snes->npc);
    5320:   return(0);
    5321: }

    5323: /*@
    5324:   SNESGetNPC - Creates a nonlinear preconditioning solver (SNES) to be used to precondition the nonlinear solver.

    5326:   Not Collective

    5328:   Input Parameter:
    5329: . snes - iterative context obtained from SNESCreate()

    5331:   Output Parameter:
    5332: . pc - preconditioner context

    5334:   Notes:
    5335:     If a SNES was previously set with SNESSetNPC() then that SNES is returned.

    5337:   Level: developer

    5339: .keywords: SNES, get, preconditioner
    5340: .seealso: SNESSetNPC(), SNESHasNPC()
    5341: @*/
    5342: PetscErrorCode SNESGetNPC(SNES snes, SNES *pc)
    5343: {
    5345:   const char     *optionsprefix;

    5350:   if (!snes->npc) {
    5351:     SNESCreate(PetscObjectComm((PetscObject)snes),&snes->npc);
    5352:     PetscObjectIncrementTabLevel((PetscObject)snes->npc,(PetscObject)snes,1);
    5353:     PetscLogObjectParent((PetscObject)snes,(PetscObject)snes->npc);
    5354:     SNESGetOptionsPrefix(snes,&optionsprefix);
    5355:     SNESSetOptionsPrefix(snes->npc,optionsprefix);
    5356:     SNESAppendOptionsPrefix(snes->npc,"npc_");
    5357:     SNESSetCountersReset(snes->npc,PETSC_FALSE);
    5358:   }
    5359:   *pc = snes->npc;
    5360:   return(0);
    5361: }

    5363: /*@
    5364:   SNESHasNPC - Returns whether a nonlinear preconditioner exists

    5366:   Not Collective

    5368:   Input Parameter:
    5369: . snes - iterative context obtained from SNESCreate()

    5371:   Output Parameter:
    5372: . has_npc - whether the SNES has an NPC or not

    5374:   Level: developer

    5376: .keywords: SNES, has, preconditioner
    5377: .seealso: SNESSetNPC(), SNESGetNPC()
    5378: @*/
    5379: PetscErrorCode SNESHasNPC(SNES snes, PetscBool *has_npc)
    5380: {
    5383:   *has_npc = (PetscBool) (snes->npc ? PETSC_TRUE : PETSC_FALSE);
    5384:   return(0);
    5385: }

    5387: /*@
    5388:     SNESSetNPCSide - Sets the preconditioning side.

    5390:     Logically Collective on SNES

    5392:     Input Parameter:
    5393: .   snes - iterative context obtained from SNESCreate()

    5395:     Output Parameter:
    5396: .   side - the preconditioning side, where side is one of
    5397: .vb
    5398:       PC_LEFT - left preconditioning
    5399:       PC_RIGHT - right preconditioning (default for most nonlinear solvers)
    5400: .ve

    5402:     Options Database Keys:
    5403: .   -snes_pc_side <right,left>

    5405:     Notes:
    5406:     SNESNRICHARDSON and SNESNCG only support left preconditioning.

    5408:     Level: intermediate

    5410: .keywords: SNES, set, right, left, side, preconditioner, flag

    5412: .seealso: SNESGetNPCSide(), KSPSetPCSide()
    5413: @*/
    5414: PetscErrorCode  SNESSetNPCSide(SNES snes,PCSide side)
    5415: {
    5419:   snes->npcside= side;
    5420:   return(0);
    5421: }

    5423: /*@
    5424:     SNESGetNPCSide - Gets the preconditioning side.

    5426:     Not Collective

    5428:     Input Parameter:
    5429: .   snes - iterative context obtained from SNESCreate()

    5431:     Output Parameter:
    5432: .   side - the preconditioning side, where side is one of
    5433: .vb
    5434:       PC_LEFT - left preconditioning
    5435:       PC_RIGHT - right preconditioning (default for most nonlinear solvers)
    5436: .ve

    5438:     Level: intermediate

    5440: .keywords: SNES, get, right, left, side, preconditioner, flag

    5442: .seealso: SNESSetNPCSide(), KSPGetPCSide()
    5443: @*/
    5444: PetscErrorCode  SNESGetNPCSide(SNES snes,PCSide *side)
    5445: {
    5449:   *side = snes->npcside;
    5450:   return(0);
    5451: }

    5453: /*@
    5454:   SNESSetLineSearch - Sets the linesearch on the SNES instance.

    5456:   Collective on SNES

    5458:   Input Parameters:
    5459: + snes - iterative context obtained from SNESCreate()
    5460: - linesearch   - the linesearch object

    5462:   Notes:
    5463:   Use SNESGetLineSearch() to retrieve the preconditioner context (for example,
    5464:   to configure it using the API).

    5466:   Level: developer

    5468: .keywords: SNES, set, linesearch
    5469: .seealso: SNESGetLineSearch()
    5470: @*/
    5471: PetscErrorCode SNESSetLineSearch(SNES snes, SNESLineSearch linesearch)
    5472: {

    5479:   PetscObjectReference((PetscObject) linesearch);
    5480:   SNESLineSearchDestroy(&snes->linesearch);

    5482:   snes->linesearch = linesearch;

    5484:   PetscLogObjectParent((PetscObject)snes, (PetscObject)snes->linesearch);
    5485:   return(0);
    5486: }

    5488: /*@
    5489:   SNESGetLineSearch - Returns a pointer to the line search context set with SNESSetLineSearch()
    5490:   or creates a default line search instance associated with the SNES and returns it.

    5492:   Not Collective

    5494:   Input Parameter:
    5495: . snes - iterative context obtained from SNESCreate()

    5497:   Output Parameter:
    5498: . linesearch - linesearch context

    5500:   Level: beginner

    5502: .keywords: SNES, get, linesearch
    5503: .seealso: SNESSetLineSearch(), SNESLineSearchCreate()
    5504: @*/
    5505: PetscErrorCode SNESGetLineSearch(SNES snes, SNESLineSearch *linesearch)
    5506: {
    5508:   const char     *optionsprefix;

    5513:   if (!snes->linesearch) {
    5514:     SNESGetOptionsPrefix(snes, &optionsprefix);
    5515:     SNESLineSearchCreate(PetscObjectComm((PetscObject)snes), &snes->linesearch);
    5516:     SNESLineSearchSetSNES(snes->linesearch, snes);
    5517:     SNESLineSearchAppendOptionsPrefix(snes->linesearch, optionsprefix);
    5518:     PetscObjectIncrementTabLevel((PetscObject) snes->linesearch, (PetscObject) snes, 1);
    5519:     PetscLogObjectParent((PetscObject)snes, (PetscObject)snes->linesearch);
    5520:   }
    5521:   *linesearch = snes->linesearch;
    5522:   return(0);
    5523: }

    5525: #if defined(PETSC_HAVE_MATLAB_ENGINE)
    5526: #include <mex.h>

    5528: typedef struct {char *funcname; mxArray *ctx;} SNESMatlabContext;

    5530: /*
    5531:    SNESComputeFunction_Matlab - Calls the function that has been set with SNESSetFunctionMatlab().

    5533:    Collective on SNES

    5535:    Input Parameters:
    5536: +  snes - the SNES context
    5537: -  x - input vector

    5539:    Output Parameter:
    5540: .  y - function vector, as set by SNESSetFunction()

    5542:    Notes:
    5543:    SNESComputeFunction() is typically used within nonlinear solvers
    5544:    implementations, so most users would not generally call this routine
    5545:    themselves.

    5547:    Level: developer

    5549: .keywords: SNES, nonlinear, compute, function

    5551: .seealso: SNESSetFunction(), SNESGetFunction()
    5552: */
    5553: PetscErrorCode  SNESComputeFunction_Matlab(SNES snes,Vec x,Vec y, void *ctx)
    5554: {
    5555:   PetscErrorCode    ierr;
    5556:   SNESMatlabContext *sctx = (SNESMatlabContext*)ctx;
    5557:   int               nlhs  = 1,nrhs = 5;
    5558:   mxArray           *plhs[1],*prhs[5];
    5559:   long long int     lx = 0,ly = 0,ls = 0;

    5568:   /* call Matlab function in ctx with arguments x and y */

    5570:   PetscMemcpy(&ls,&snes,sizeof(snes));
    5571:   PetscMemcpy(&lx,&x,sizeof(x));
    5572:   PetscMemcpy(&ly,&y,sizeof(x));
    5573:   prhs[0] = mxCreateDoubleScalar((double)ls);
    5574:   prhs[1] = mxCreateDoubleScalar((double)lx);
    5575:   prhs[2] = mxCreateDoubleScalar((double)ly);
    5576:   prhs[3] = mxCreateString(sctx->funcname);
    5577:   prhs[4] = sctx->ctx;
    5578:   mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscSNESComputeFunctionInternal");
    5579:   mxGetScalar(plhs[0]);
    5580:   mxDestroyArray(prhs[0]);
    5581:   mxDestroyArray(prhs[1]);
    5582:   mxDestroyArray(prhs[2]);
    5583:   mxDestroyArray(prhs[3]);
    5584:   mxDestroyArray(plhs[0]);
    5585:   return(0);
    5586: }

    5588: /*
    5589:    SNESSetFunctionMatlab - Sets the function evaluation routine and function
    5590:    vector for use by the SNES routines in solving systems of nonlinear
    5591:    equations from MATLAB. Here the function is a string containing the name of a MATLAB function

    5593:    Logically Collective on SNES

    5595:    Input Parameters:
    5596: +  snes - the SNES context
    5597: .  r - vector to store function value
    5598: -  f - function evaluation routine

    5600:    Notes:
    5601:    The Newton-like methods typically solve linear systems of the form
    5602: $      f'(x) x = -f(x),
    5603:    where f'(x) denotes the Jacobian matrix and f(x) is the function.

    5605:    Level: beginner

    5607:    Developer Note:  This bleeds the allocated memory SNESMatlabContext *sctx;

    5609: .keywords: SNES, nonlinear, set, function

    5611: .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction()
    5612: */
    5613: PetscErrorCode  SNESSetFunctionMatlab(SNES snes,Vec r,const char *f,mxArray *ctx)
    5614: {
    5615:   PetscErrorCode    ierr;
    5616:   SNESMatlabContext *sctx;

    5619:   /* currently sctx is memory bleed */
    5620:   PetscNew(&sctx);
    5621:   PetscStrallocpy(f,&sctx->funcname);
    5622:   /*
    5623:      This should work, but it doesn't
    5624:   sctx->ctx = ctx;
    5625:   mexMakeArrayPersistent(sctx->ctx);
    5626:   */
    5627:   sctx->ctx = mxDuplicateArray(ctx);
    5628:   SNESSetFunction(snes,r,SNESComputeFunction_Matlab,sctx);
    5629:   return(0);
    5630: }

    5632: /*
    5633:    SNESComputeJacobian_Matlab - Calls the function that has been set with SNESSetJacobianMatlab().

    5635:    Collective on SNES

    5637:    Input Parameters:
    5638: +  snes - the SNES context
    5639: .  x - input vector
    5640: .  A, B - the matrices
    5641: -  ctx - user context

    5643:    Level: developer

    5645: .keywords: SNES, nonlinear, compute, function

    5647: .seealso: SNESSetFunction(), SNESGetFunction()
    5648: @*/
    5649: PetscErrorCode  SNESComputeJacobian_Matlab(SNES snes,Vec x,Mat A,Mat B,void *ctx)
    5650: {
    5651:   PetscErrorCode    ierr;
    5652:   SNESMatlabContext *sctx = (SNESMatlabContext*)ctx;
    5653:   int               nlhs  = 2,nrhs = 6;
    5654:   mxArray           *plhs[2],*prhs[6];
    5655:   long long int     lx = 0,lA = 0,ls = 0, lB = 0;

    5661:   /* call Matlab function in ctx with arguments x and y */

    5663:   PetscMemcpy(&ls,&snes,sizeof(snes));
    5664:   PetscMemcpy(&lx,&x,sizeof(x));
    5665:   PetscMemcpy(&lA,A,sizeof(x));
    5666:   PetscMemcpy(&lB,B,sizeof(x));
    5667:   prhs[0] = mxCreateDoubleScalar((double)ls);
    5668:   prhs[1] = mxCreateDoubleScalar((double)lx);
    5669:   prhs[2] = mxCreateDoubleScalar((double)lA);
    5670:   prhs[3] = mxCreateDoubleScalar((double)lB);
    5671:   prhs[4] = mxCreateString(sctx->funcname);
    5672:   prhs[5] = sctx->ctx;
    5673:   mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscSNESComputeJacobianInternal");
    5674:   mxGetScalar(plhs[0]);
    5675:   mxDestroyArray(prhs[0]);
    5676:   mxDestroyArray(prhs[1]);
    5677:   mxDestroyArray(prhs[2]);
    5678:   mxDestroyArray(prhs[3]);
    5679:   mxDestroyArray(prhs[4]);
    5680:   mxDestroyArray(plhs[0]);
    5681:   mxDestroyArray(plhs[1]);
    5682:   return(0);
    5683: }

    5685: /*
    5686:    SNESSetJacobianMatlab - Sets the Jacobian function evaluation routine and two empty Jacobian matrices
    5687:    vector for use by the SNES routines in solving systems of nonlinear
    5688:    equations from MATLAB. Here the function is a string containing the name of a MATLAB function

    5690:    Logically Collective on SNES

    5692:    Input Parameters:
    5693: +  snes - the SNES context
    5694: .  A,B - Jacobian matrices
    5695: .  J - function evaluation routine
    5696: -  ctx - user context

    5698:    Level: developer

    5700:    Developer Note:  This bleeds the allocated memory SNESMatlabContext *sctx;

    5702: .keywords: SNES, nonlinear, set, function

    5704: .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction(), J
    5705: */
    5706: PetscErrorCode  SNESSetJacobianMatlab(SNES snes,Mat A,Mat B,const char *J,mxArray *ctx)
    5707: {
    5708:   PetscErrorCode    ierr;
    5709:   SNESMatlabContext *sctx;

    5712:   /* currently sctx is memory bleed */
    5713:   PetscNew(&sctx);
    5714:   PetscStrallocpy(J,&sctx->funcname);
    5715:   /*
    5716:      This should work, but it doesn't
    5717:   sctx->ctx = ctx;
    5718:   mexMakeArrayPersistent(sctx->ctx);
    5719:   */
    5720:   sctx->ctx = mxDuplicateArray(ctx);
    5721:   SNESSetJacobian(snes,A,B,SNESComputeJacobian_Matlab,sctx);
    5722:   return(0);
    5723: }

    5725: /*
    5726:    SNESMonitor_Matlab - Calls the function that has been set with SNESMonitorSetMatlab().

    5728:    Collective on SNES

    5730: .seealso: SNESSetFunction(), SNESGetFunction()
    5731: @*/
    5732: PetscErrorCode  SNESMonitor_Matlab(SNES snes,PetscInt it, PetscReal fnorm, void *ctx)
    5733: {
    5734:   PetscErrorCode    ierr;
    5735:   SNESMatlabContext *sctx = (SNESMatlabContext*)ctx;
    5736:   int               nlhs  = 1,nrhs = 6;
    5737:   mxArray           *plhs[1],*prhs[6];
    5738:   long long int     lx = 0,ls = 0;
    5739:   Vec               x  = snes->vec_sol;

    5744:   PetscMemcpy(&ls,&snes,sizeof(snes));
    5745:   PetscMemcpy(&lx,&x,sizeof(x));
    5746:   prhs[0] = mxCreateDoubleScalar((double)ls);
    5747:   prhs[1] = mxCreateDoubleScalar((double)it);
    5748:   prhs[2] = mxCreateDoubleScalar((double)fnorm);
    5749:   prhs[3] = mxCreateDoubleScalar((double)lx);
    5750:   prhs[4] = mxCreateString(sctx->funcname);
    5751:   prhs[5] = sctx->ctx;
    5752:   mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscSNESMonitorInternal");
    5753:   mxGetScalar(plhs[0]);
    5754:   mxDestroyArray(prhs[0]);
    5755:   mxDestroyArray(prhs[1]);
    5756:   mxDestroyArray(prhs[2]);
    5757:   mxDestroyArray(prhs[3]);
    5758:   mxDestroyArray(prhs[4]);
    5759:   mxDestroyArray(plhs[0]);
    5760:   return(0);
    5761: }

    5763: /*
    5764:    SNESMonitorSetMatlab - Sets the monitor function from MATLAB

    5766:    Level: developer

    5768:    Developer Note:  This bleeds the allocated memory SNESMatlabContext *sctx;

    5770: .keywords: SNES, nonlinear, set, function

    5772: .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction()
    5773: */
    5774: PetscErrorCode  SNESMonitorSetMatlab(SNES snes,const char *f,mxArray *ctx)
    5775: {
    5776:   PetscErrorCode    ierr;
    5777:   SNESMatlabContext *sctx;

    5780:   /* currently sctx is memory bleed */
    5781:   PetscNew(&sctx);
    5782:   PetscStrallocpy(f,&sctx->funcname);
    5783:   /*
    5784:      This should work, but it doesn't
    5785:   sctx->ctx = ctx;
    5786:   mexMakeArrayPersistent(sctx->ctx);
    5787:   */
    5788:   sctx->ctx = mxDuplicateArray(ctx);
    5789:   SNESMonitorSet(snes,SNESMonitor_Matlab,sctx,NULL);
    5790:   return(0);
    5791: }

    5793: #endif