Date: 2013-07-02T14:49:12+00:00

Actual source code: snes.c
petsc-3.4.2 2013-07-02

      2: #include <petsc-private/snesimpl.h>      /*I "petscsnes.h"  I*/
      3: #include <petscdmshell.h>

      5: PetscBool         SNESRegisterAllCalled = PETSC_FALSE;
      6: PetscFunctionList SNESList              = NULL;

      8: /* Logging support */
      9: PetscClassId  SNES_CLASSID, DMSNES_CLASSID;
     10: PetscLogEvent SNES_Solve, SNES_FunctionEval, SNES_JacobianEval, SNES_GSEval, SNES_NPCSolve;

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

     17:    Logically Collective on SNES

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

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

     26:    Level: intermediate

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

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

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

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

     50:    Not Collective

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

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

     58:    Level: intermediate

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

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

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

     79:    Logically Collective on SNES

     81:    Input Parameters:
     82: .  snes - the SNES context

     84:    Level: advanced

     86: .keywords: SNES, view

     88: .seealso: SNESCreate(), SNESSetFunction(), SNESFunction
     89: @*/
     90: PetscErrorCode  SNESSetFunctionDomainError(SNES snes)
     91: {
     94:   snes->domainerror = PETSC_TRUE;
     95:   return(0);
     96: }

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

    103:    Logically Collective on SNES

    105:    Input Parameters:
    106: .  snes - the SNES context

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

    111:    Level: advanced

    113: .keywords: SNES, view

    115: .seealso: SNESSetFunctionDomainError(), SNESComputeFunction()
    116: @*/
    117: PetscErrorCode  SNESGetFunctionDomainError(SNES snes, PetscBool *domainerror)
    118: {
    122:   *domainerror = snes->domainerror;
    123:   return(0);
    124: }

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

    131:   Collective on PetscViewer

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

    138:    Level: intermediate

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

    143:   Notes for advanced users:
    144:   Most users should not need to know the details of the binary storage
    145:   format, since SNESLoad() and TSView() completely hide these details.
    146:   But for anyone who's interested, the standard binary matrix storage
    147:   format is
    148: .vb
    149:      has not yet been determined
    150: .ve

    152: .seealso: PetscViewerBinaryOpen(), SNESView(), MatLoad(), VecLoad()
    153: @*/
    154: PetscErrorCode  SNESLoad(SNES snes, PetscViewer viewer)
    155: {
    157:   PetscBool      isbinary;
    158:   PetscInt       classid;
    159:   char           type[256];
    160:   KSP            ksp;
    161:   DM             dm;
    162:   DMSNES         dmsnes;

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

    170:   PetscViewerBinaryRead(viewer,&classid,1,PETSC_INT);
    171:   if (classid != SNES_FILE_CLASSID) SETERRQ(PetscObjectComm((PetscObject)snes),PETSC_ERR_ARG_WRONG,"Not SNES next in file");
    172:   PetscViewerBinaryRead(viewer,type,256,PETSC_CHAR);
    173:   SNESSetType(snes, type);
    174:   if (snes->ops->load) {
    175:     (*snes->ops->load)(snes,viewer);
    176:   }
    177:   SNESGetDM(snes,&dm);
    178:   DMGetDMSNES(dm,&dmsnes);
    179:   DMSNESLoad(dmsnes,viewer);
    180:   SNESGetKSP(snes,&ksp);
    181:   KSPLoad(ksp,viewer);
    182:   return(0);
    183: }

    185: #include <petscdraw.h>
    186: #if defined(PETSC_HAVE_AMS)
    187: #include <petscviewerams.h>
    188: #endif
    191: /*@C
    192:    SNESView - Prints the SNES data structure.

    194:    Collective on SNES

    196:    Input Parameters:
    197: +  SNES - the SNES context
    198: -  viewer - visualization context

    200:    Options Database Key:
    201: .  -snes_view - Calls SNESView() at end of SNESSolve()

    203:    Notes:
    204:    The available visualization contexts include
    205: +     PETSC_VIEWER_STDOUT_SELF - standard output (default)
    206: -     PETSC_VIEWER_STDOUT_WORLD - synchronized standard
    207:          output where only the first processor opens
    208:          the file.  All other processors send their
    209:          data to the first processor to print.

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

    214:    Level: beginner

    216: .keywords: SNES, view

    218: .seealso: PetscViewerASCIIOpen()
    219: @*/
    220: PetscErrorCode  SNESView(SNES snes,PetscViewer viewer)
    221: {
    222:   SNESKSPEW      *kctx;
    224:   KSP            ksp;
    225:   SNESLineSearch linesearch;
    226:   PetscBool      iascii,isstring,isbinary,isdraw;
    227:   DMSNES         dmsnes;
    228: #if defined(PETSC_HAVE_AMS)
    229:   PetscBool      isams;
    230: #endif

    234:   if (!viewer) {
    235:     PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)snes),&viewer);
    236:   }

    240:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
    241:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERSTRING,&isstring);
    242:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&isbinary);
    243:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERDRAW,&isdraw);
    244: #if defined(PETSC_HAVE_AMS)
    245:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERAMS,&isams);
    246: #endif
    247:   if (iascii) {
    248:     PetscObjectPrintClassNamePrefixType((PetscObject)snes,viewer,"SNES Object");
    249:     if (!snes->setupcalled) {
    250:       PetscViewerASCIIPrintf(viewer,"  SNES has not been set up so information may be incomplete\n");
    251:     }
    252:     if (snes->ops->view) {
    253:       PetscViewerASCIIPushTab(viewer);
    254:       (*snes->ops->view)(snes,viewer);
    255:       PetscViewerASCIIPopTab(viewer);
    256:     }
    257:     PetscViewerASCIIPrintf(viewer,"  maximum iterations=%D, maximum function evaluations=%D\n",snes->max_its,snes->max_funcs);
    258:     PetscViewerASCIIPrintf(viewer,"  tolerances: relative=%G, absolute=%G, solution=%G\n",snes->rtol,snes->abstol,snes->stol);
    259:     PetscViewerASCIIPrintf(viewer,"  total number of linear solver iterations=%D\n",snes->linear_its);
    260:     PetscViewerASCIIPrintf(viewer,"  total number of function evaluations=%D\n",snes->nfuncs);
    261:     if (snes->gridsequence) {
    262:       PetscViewerASCIIPrintf(viewer,"  total number of grid sequence refinements=%D\n",snes->gridsequence);
    263:     }
    264:     if (snes->ksp_ewconv) {
    265:       kctx = (SNESKSPEW*)snes->kspconvctx;
    266:       if (kctx) {
    267:         PetscViewerASCIIPrintf(viewer,"  Eisenstat-Walker computation of KSP relative tolerance (version %D)\n",kctx->version);
    268:         PetscViewerASCIIPrintf(viewer,"    rtol_0=%G, rtol_max=%G, threshold=%G\n",kctx->rtol_0,kctx->rtol_max,kctx->threshold);
    269:         PetscViewerASCIIPrintf(viewer,"    gamma=%G, alpha=%G, alpha2=%G\n",kctx->gamma,kctx->alpha,kctx->alpha2);
    270:       }
    271:     }
    272:     if (snes->lagpreconditioner == -1) {
    273:       PetscViewerASCIIPrintf(viewer,"  Preconditioned is never rebuilt\n");
    274:     } else if (snes->lagpreconditioner > 1) {
    275:       PetscViewerASCIIPrintf(viewer,"  Preconditioned is rebuilt every %D new Jacobians\n",snes->lagpreconditioner);
    276:     }
    277:     if (snes->lagjacobian == -1) {
    278:       PetscViewerASCIIPrintf(viewer,"  Jacobian is never rebuilt\n");
    279:     } else if (snes->lagjacobian > 1) {
    280:       PetscViewerASCIIPrintf(viewer,"  Jacobian is rebuilt every %D SNES iterations\n",snes->lagjacobian);
    281:     }
    282:   } else if (isstring) {
    283:     const char *type;
    284:     SNESGetType(snes,&type);
    285:     PetscViewerStringSPrintf(viewer," %-3.3s",type);
    286:   } else if (isbinary) {
    287:     PetscInt    classid = SNES_FILE_CLASSID;
    288:     MPI_Comm    comm;
    289:     PetscMPIInt rank;
    290:     char        type[256];

    292:     PetscObjectGetComm((PetscObject)snes,&comm);
    293:     MPI_Comm_rank(comm,&rank);
    294:     if (!rank) {
    295:       PetscViewerBinaryWrite(viewer,&classid,1,PETSC_INT,PETSC_FALSE);
    296:       PetscStrncpy(type,((PetscObject)snes)->type_name,256);
    297:       PetscViewerBinaryWrite(viewer,type,256,PETSC_CHAR,PETSC_FALSE);
    298:     }
    299:     if (snes->ops->view) {
    300:       (*snes->ops->view)(snes,viewer);
    301:     }
    302:   } else if (isdraw) {
    303:     PetscDraw draw;
    304:     char      str[36];
    305:     PetscReal x,y,bottom,h;

    307:     PetscViewerDrawGetDraw(viewer,0,&draw);
    308:     PetscDrawGetCurrentPoint(draw,&x,&y);
    309:     PetscStrcpy(str,"SNES: ");
    310:     PetscStrcat(str,((PetscObject)snes)->type_name);
    311:     PetscDrawBoxedString(draw,x,y,PETSC_DRAW_BLUE,PETSC_DRAW_BLACK,str,NULL,&h);
    312:     bottom = y - h;
    313:     PetscDrawPushCurrentPoint(draw,x,bottom);
    314:     if (snes->ops->view) {
    315:       (*snes->ops->view)(snes,viewer);
    316:     }
    317: #if defined(PETSC_HAVE_AMS)
    318:   } else if (isams) {
    319:     if (((PetscObject)snes)->amsmem == -1) {
    320:       PetscObjectViewAMS((PetscObject)snes,viewer);
    321:       PetscStackCallAMS(AMS_Memory_take_access,(((PetscObject)snes)->amsmem));
    322:       PetscStackCallAMS(AMS_Memory_add_field,(((PetscObject)snes)->amsmem,"its",&snes->iter,1,AMS_INT,AMS_READ,AMS_COMMON,AMS_REDUCT_UNDEF));
    323:       if (!snes->conv_hist) {
    324:         SNESSetConvergenceHistory(snes,NULL,NULL,PETSC_DECIDE,PETSC_FALSE);
    325:       }
    326:       PetscStackCallAMS(AMS_Memory_add_field,(((PetscObject)snes)->amsmem,"conv_hist",snes->conv_hist,10,AMS_DOUBLE,AMS_READ,AMS_COMMON,AMS_REDUCT_UNDEF));
    327:       PetscStackCallAMS(AMS_Memory_grant_access,(((PetscObject)snes)->amsmem));
    328:     }
    329: #endif
    330:   }
    331:   if (snes->linesearch) {
    332:     PetscViewerASCIIPushTab(viewer);
    333:     SNESGetLineSearch(snes, &linesearch);
    334:     SNESLineSearchView(linesearch, viewer);
    335:     PetscViewerASCIIPopTab(viewer);
    336:   }
    337:   if (snes->pc && snes->usespc) {
    338:     PetscViewerASCIIPushTab(viewer);
    339:     SNESView(snes->pc, viewer);
    340:     PetscViewerASCIIPopTab(viewer);
    341:   }
    342:   PetscViewerASCIIPushTab(viewer);
    343:   DMGetDMSNES(snes->dm,&dmsnes);
    344:   DMSNESView(dmsnes, viewer);
    345:   PetscViewerASCIIPopTab(viewer);
    346:   if (snes->usesksp) {
    347:     SNESGetKSP(snes,&ksp);
    348:     PetscViewerASCIIPushTab(viewer);
    349:     KSPView(ksp,viewer);
    350:     PetscViewerASCIIPopTab(viewer);
    351:   }
    352:   if (isdraw) {
    353:     PetscDraw draw;
    354:     PetscViewerDrawGetDraw(viewer,0,&draw);
    355:     PetscDrawPopCurrentPoint(draw);
    356:   }
    357:   return(0);
    358: }

    360: /*
    361:   We retain a list of functions that also take SNES command
    362:   line options. These are called at the end SNESSetFromOptions()
    363: */
    364: #define MAXSETFROMOPTIONS 5
    365: static PetscInt numberofsetfromoptions;
    366: static PetscErrorCode (*othersetfromoptions[MAXSETFROMOPTIONS])(SNES);

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

    373:   Not Collective

    375:   Input Parameter:
    376: . snescheck - function that checks for options

    378:   Level: developer

    380: .seealso: SNESSetFromOptions()
    381: @*/
    382: PetscErrorCode  SNESAddOptionsChecker(PetscErrorCode (*snescheck)(SNES))
    383: {
    385:   if (numberofsetfromoptions >= MAXSETFROMOPTIONS) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE, "Too many options checkers, only %D allowed", MAXSETFROMOPTIONS);
    386:   othersetfromoptions[numberofsetfromoptions++] = snescheck;
    387:   return(0);
    388: }

    390: extern PetscErrorCode  SNESDefaultMatrixFreeCreate2(SNES,Vec,Mat*);

    394: static PetscErrorCode SNESSetUpMatrixFree_Private(SNES snes, PetscBool hasOperator, PetscInt version)
    395: {
    396:   Mat            J;
    397:   KSP            ksp;
    398:   PC             pc;
    399:   PetscBool      match;

    405:   if (!snes->vec_func && (snes->jacobian || snes->jacobian_pre)) {
    406:     Mat A = snes->jacobian, B = snes->jacobian_pre;
    407:     MatGetVecs(A ? A : B, NULL,&snes->vec_func);
    408:   }

    410:   if (version == 1) {
    411:     MatCreateSNESMF(snes,&J);
    412:     MatMFFDSetOptionsPrefix(J,((PetscObject)snes)->prefix);
    413:     MatSetFromOptions(J);
    414:   } else if (version == 2) {
    415:     if (!snes->vec_func) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"SNESSetFunction() must be called first");
    416: #if !defined(PETSC_USE_COMPLEX) && !defined(PETSC_USE_REAL_SINGLE) && !defined(PETSC_USE_REAL___FLOAT128)
    417:     SNESDefaultMatrixFreeCreate2(snes,snes->vec_func,&J);
    418: #else
    419:     SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP, "matrix-free operator rutines (version 2)");
    420: #endif
    421:   } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE, "matrix-free operator rutines, only version 1 and 2");

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

    426:     /* This version replaces the user provided Jacobian matrix with a
    427:        matrix-free version but still employs the user-provided preconditioner matrix. */
    428:     SNESSetJacobian(snes,J,0,0,0);
    429:   } else {
    430:     /* This version replaces both the user-provided Jacobian and the user-
    431:      provided preconditioner Jacobian with the default matrix free version. */
    432:     if ((snes->pcside == PC_LEFT) && snes->pc) {
    433:       if (!snes->jacobian){SNESSetJacobian(snes,J,0,0,0);}
    434:     } else {
    435:       SNESSetJacobian(snes,J,J,MatMFFDComputeJacobian,0);
    436:     }
    437:     /* Force no preconditioner */
    438:     SNESGetKSP(snes,&ksp);
    439:     KSPGetPC(ksp,&pc);
    440:     PetscObjectTypeCompare((PetscObject)pc,PCSHELL,&match);
    441:     if (!match) {
    442:       PetscInfo(snes,"Setting default matrix-free preconditioner routines\nThat is no preconditioner is being used\n");
    443:       PCSetType(pc,PCNONE);
    444:     }
    445:   }
    446:   MatDestroy(&J);
    447:   return(0);
    448: }

    452: static PetscErrorCode DMRestrictHook_SNESVecSol(DM dmfine,Mat Restrict,Vec Rscale,Mat Inject,DM dmcoarse,void *ctx)
    453: {
    454:   SNES           snes = (SNES)ctx;
    456:   Vec            Xfine,Xfine_named = NULL,Xcoarse;

    459:   if (PetscLogPrintInfo) {
    460:     PetscInt finelevel,coarselevel,fineclevel,coarseclevel;
    461:     DMGetRefineLevel(dmfine,&finelevel);
    462:     DMGetCoarsenLevel(dmfine,&fineclevel);
    463:     DMGetRefineLevel(dmcoarse,&coarselevel);
    464:     DMGetCoarsenLevel(dmcoarse,&coarseclevel);
    465:     PetscInfo4(dmfine,"Restricting SNES solution vector from level %D-%D to level %D-%D\n",finelevel,fineclevel,coarselevel,coarseclevel);
    466:   }
    467:   if (dmfine == snes->dm) Xfine = snes->vec_sol;
    468:   else {
    469:     DMGetNamedGlobalVector(dmfine,"SNESVecSol",&Xfine_named);
    470:     Xfine = Xfine_named;
    471:   }
    472:   DMGetNamedGlobalVector(dmcoarse,"SNESVecSol",&Xcoarse);
    473:   MatRestrict(Restrict,Xfine,Xcoarse);
    474:   VecPointwiseMult(Xcoarse,Xcoarse,Rscale);
    475:   DMRestoreNamedGlobalVector(dmcoarse,"SNESVecSol",&Xcoarse);
    476:   if (Xfine_named) {DMRestoreNamedGlobalVector(dmfine,"SNESVecSol",&Xfine_named);}
    477:   return(0);
    478: }

    482: static PetscErrorCode DMCoarsenHook_SNESVecSol(DM dm,DM dmc,void *ctx)
    483: {

    487:   DMCoarsenHookAdd(dmc,DMCoarsenHook_SNESVecSol,DMRestrictHook_SNESVecSol,ctx);
    488:   return(0);
    489: }

    493: /* This may be called to rediscretize the operator on levels of linear multigrid. The DM shuffle is so the user can
    494:  * safely call SNESGetDM() in their residual evaluation routine. */
    495: static PetscErrorCode KSPComputeOperators_SNES(KSP ksp,Mat A,Mat B,MatStructure *mstruct,void *ctx)
    496: {
    497:   SNES           snes = (SNES)ctx;
    499:   Mat            Asave = A,Bsave = B;
    500:   Vec            X,Xnamed = NULL;
    501:   DM             dmsave;
    502:   void           *ctxsave;
    503:   PetscErrorCode (*jac)(SNES,Vec,Mat*,Mat*,MatStructure*,void*);

    506:   dmsave = snes->dm;
    507:   KSPGetDM(ksp,&snes->dm);
    508:   if (dmsave == snes->dm) X = snes->vec_sol; /* We are on the finest level */
    509:   else {                                     /* We are on a coarser level, this vec was initialized using a DM restrict hook */
    510:     DMGetNamedGlobalVector(snes->dm,"SNESVecSol",&Xnamed);
    511:     X    = Xnamed;
    512:     SNESGetJacobian(snes,NULL,NULL,&jac,&ctxsave);
    513:     /* If the DM's don't match up, the MatFDColoring context needed for the jacobian won't match up either -- fixit. */
    514:     if (jac == SNESComputeJacobianDefaultColor) {
    515:       SNESSetJacobian(snes,NULL,NULL,SNESComputeJacobianDefaultColor,0);
    516:     }
    517:   }
    518:   /* put the previous context back */

    520:   SNESComputeJacobian(snes,X,&A,&B,mstruct);
    521:   if (snes->dm != dmsave && jac == SNESComputeJacobianDefaultColor) {
    522:     SNESSetJacobian(snes,NULL,NULL,jac,ctxsave);
    523:   }

    525:   if (A != Asave || B != Bsave) SETERRQ(PetscObjectComm((PetscObject)snes),PETSC_ERR_SUP,"No support for changing matrices at this time");
    526:   if (Xnamed) {
    527:     DMRestoreNamedGlobalVector(snes->dm,"SNESVecSol",&Xnamed);
    528:   }
    529:   snes->dm = dmsave;
    530:   return(0);
    531: }

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

    538:    Collective

    540:    Input Arguments:
    541: .  snes - snes to configure

    543:    Level: developer

    545: .seealso: SNESSetUp()
    546: @*/
    547: PetscErrorCode SNESSetUpMatrices(SNES snes)
    548: {
    550:   DM             dm;
    551:   DMSNES         sdm;

    554:   SNESGetDM(snes,&dm);
    555:   DMGetDMSNES(dm,&sdm);
    556:   if (!sdm->ops->computejacobian) SETERRQ(PetscObjectComm((PetscObject)snes),PETSC_ERR_PLIB,"DMSNES not properly configured");
    557:   else if (!snes->jacobian && snes->mf) {
    558:     Mat  J;
    559:     void *functx;
    560:     MatCreateSNESMF(snes,&J);
    561:     MatMFFDSetOptionsPrefix(J,((PetscObject)snes)->prefix);
    562:     MatSetFromOptions(J);
    563:     SNESGetFunction(snes,NULL,NULL,&functx);
    564:     SNESSetJacobian(snes,J,J,0,0);
    565:     MatDestroy(&J);
    566:   } else if (snes->mf_operator && !snes->jacobian_pre && !snes->jacobian) {
    567:     Mat J,B;
    568:     MatCreateSNESMF(snes,&J);
    569:     MatMFFDSetOptionsPrefix(J,((PetscObject)snes)->prefix);
    570:     MatSetFromOptions(J);
    571:     DMCreateMatrix(snes->dm,MATAIJ,&B);
    572:     /* sdm->computejacobian was already set to reach here */
    573:     SNESSetJacobian(snes,J,B,NULL,NULL);
    574:     MatDestroy(&J);
    575:     MatDestroy(&B);
    576:   } else if (!snes->jacobian_pre) {
    577:     Mat J,B;
    578:     J    = snes->jacobian;
    579:     DMCreateMatrix(snes->dm,MATAIJ,&B);
    580:     SNESSetJacobian(snes,J ? J : B,B,NULL,NULL);
    581:     MatDestroy(&B);
    582:   }
    583:   {
    584:     KSP ksp;
    585:     SNESGetKSP(snes,&ksp);
    586:     KSPSetComputeOperators(ksp,KSPComputeOperators_SNES,snes);
    587:     DMCoarsenHookAdd(snes->dm,DMCoarsenHook_SNESVecSol,DMRestrictHook_SNESVecSol,snes);
    588:   }
    589:   return(0);
    590: }

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

    597:    Collective on SNES

    599:    Input Parameter:
    600: .  snes - the SNES context

    602:    Options Database Keys:
    603: +  -snes_type <type> - ls, tr, ngmres, ncg, richardson, qn, vi, fas
    604: .  -snes_stol - convergence tolerance in terms of the norm
    605:                 of the change in the solution between steps
    606: .  -snes_atol <abstol> - absolute tolerance of residual norm
    607: .  -snes_rtol <rtol> - relative decrease in tolerance norm from initial
    608: .  -snes_max_it <max_it> - maximum number of iterations
    609: .  -snes_max_funcs <max_funcs> - maximum number of function evaluations
    610: .  -snes_max_fail <max_fail> - maximum number of line search failures allowed before stopping, default is none
    611: .  -snes_max_linear_solve_fail - number of linear solver failures before SNESSolve() stops
    612: .  -snes_lag_preconditioner <lag> - how often preconditioner is rebuilt (use -1 to never rebuild)
    613: .  -snes_lag_jacobian <lag> - how often Jacobian is rebuilt (use -1 to never rebuild)
    614: .  -snes_trtol <trtol> - trust region tolerance
    615: .  -snes_no_convergence_test - skip convergence test in nonlinear
    616:                                solver; hence iterations will continue until max_it
    617:                                or some other criterion is reached. Saves expense
    618:                                of convergence test
    619: .  -snes_monitor <optional filename> - prints residual norm at each iteration. if no
    620:                                        filename given prints to stdout
    621: .  -snes_monitor_solution - plots solution at each iteration
    622: .  -snes_monitor_residual - plots residual (not its norm) at each iteration
    623: .  -snes_monitor_solution_update - plots update to solution at each iteration
    624: .  -snes_monitor_lg_residualnorm - plots residual norm at each iteration
    625: .  -snes_monitor_lg_range - plots residual norm at each iteration
    626: .  -snes_fd - use finite differences to compute Jacobian; very slow, only for testing
    627: .  -snes_fd_color - use finite differences with coloring to compute Jacobian
    628: .  -snes_mf_ksp_monitor - if using matrix-free multiply then print h at each KSP iteration
    629: -  -snes_converged_reason - print the reason for convergence/divergence after each solve

    631:     Options Database for Eisenstat-Walker method:
    632: +  -snes_ksp_ew - use Eisenstat-Walker method for determining linear system convergence
    633: .  -snes_ksp_ew_version ver - version of  Eisenstat-Walker method
    634: .  -snes_ksp_ew_rtol0 <rtol0> - Sets rtol0
    635: .  -snes_ksp_ew_rtolmax <rtolmax> - Sets rtolmax
    636: .  -snes_ksp_ew_gamma <gamma> - Sets gamma
    637: .  -snes_ksp_ew_alpha <alpha> - Sets alpha
    638: .  -snes_ksp_ew_alpha2 <alpha2> - Sets alpha2
    639: -  -snes_ksp_ew_threshold <threshold> - Sets threshold

    641:    Notes:
    642:    To see all options, run your program with the -help option or consult
    643:    the <A href="../../docs/manual.pdf#nameddest=ch_snes">SNES chapter of the users manual</A>.

    645:    Level: beginner

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

    649: .seealso: SNESSetOptionsPrefix()
    650: @*/
    651: PetscErrorCode  SNESSetFromOptions(SNES snes)
    652: {
    653:   PetscBool      flg,pcset;
    654:   PetscInt       i,indx,lag,grids;
    655:   MatStructure   matflag;
    656:   const char     *deft        = SNESNEWTONLS;
    657:   const char     *convtests[] = {"default","skip"};
    658:   SNESKSPEW      *kctx        = NULL;
    659:   char           type[256], monfilename[PETSC_MAX_PATH_LEN];
    660:   PetscViewer    monviewer;
    662:   PCSide         pcside;
    663:   const char     *optionsprefix;

    667:   if (!SNESRegisterAllCalled) {SNESRegisterAll();}
    668:   PetscObjectOptionsBegin((PetscObject)snes);
    669:   if (((PetscObject)snes)->type_name) deft = ((PetscObject)snes)->type_name;
    670:   PetscOptionsList("-snes_type","Nonlinear solver method","SNESSetType",SNESList,deft,type,256,&flg);
    671:   if (flg) {
    672:     SNESSetType(snes,type);
    673:   } else if (!((PetscObject)snes)->type_name) {
    674:     SNESSetType(snes,deft);
    675:   }
    676:   /* not used here, but called so will go into help messaage */
    677:   PetscOptionsName("-snes_view","Print detailed information on solver used","SNESView",0);

    679:   PetscOptionsReal("-snes_stol","Stop if step length less than","SNESSetTolerances",snes->stol,&snes->stol,0);
    680:   PetscOptionsReal("-snes_atol","Stop if function norm less than","SNESSetTolerances",snes->abstol,&snes->abstol,0);

    682:   PetscOptionsReal("-snes_rtol","Stop if decrease in function norm less than","SNESSetTolerances",snes->rtol,&snes->rtol,0);
    683:   PetscOptionsInt("-snes_max_it","Maximum iterations","SNESSetTolerances",snes->max_its,&snes->max_its,NULL);
    684:   PetscOptionsInt("-snes_max_funcs","Maximum function evaluations","SNESSetTolerances",snes->max_funcs,&snes->max_funcs,NULL);
    685:   PetscOptionsInt("-snes_max_fail","Maximum nonlinear step failures","SNESSetMaxNonlinearStepFailures",snes->maxFailures,&snes->maxFailures,NULL);
    686:   PetscOptionsInt("-snes_max_linear_solve_fail","Maximum failures in linear solves allowed","SNESSetMaxLinearSolveFailures",snes->maxLinearSolveFailures,&snes->maxLinearSolveFailures,NULL);
    687:   PetscOptionsBool("-snes_error_if_not_converged","Generate error if solver does not converge","SNESSetErrorIfNotConverged",snes->errorifnotconverged,&snes->errorifnotconverged,NULL);

    689:   PetscOptionsInt("-snes_lag_preconditioner","How often to rebuild preconditioner","SNESSetLagPreconditioner",snes->lagpreconditioner,&lag,&flg);
    690:   if (flg) {
    691:     SNESSetLagPreconditioner(snes,lag);
    692:   }
    693:   PetscOptionsInt("-snes_lag_jacobian","How often to rebuild Jacobian","SNESSetLagJacobian",snes->lagjacobian,&lag,&flg);
    694:   if (flg) {
    695:     SNESSetLagJacobian(snes,lag);
    696:   }
    697:   PetscOptionsInt("-snes_grid_sequence","Use grid sequencing to generate initial guess","SNESSetGridSequence",snes->gridsequence,&grids,&flg);
    698:   if (flg) {
    699:     SNESSetGridSequence(snes,grids);
    700:   }

    702:   PetscOptionsEList("-snes_convergence_test","Convergence test","SNESSetConvergenceTest",convtests,2,"default",&indx,&flg);
    703:   if (flg) {
    704:     switch (indx) {
    705:     case 0: SNESSetConvergenceTest(snes,SNESConvergedDefault,NULL,NULL); break;
    706:     case 1: SNESSetConvergenceTest(snes,SNESSkipConverged,NULL,NULL);    break;
    707:     }
    708:   }

    710:   PetscOptionsBool("-snes_converged_reason","Print reason for converged or diverged","SNESSolve",snes->printreason,&snes->printreason,NULL);

    712:   PetscOptionsEList("-snes_norm_type","SNES Norm type","SNESSetNormType",SNESNormTypes,5,"function",&indx,&flg);
    713:   if (flg) { SNESSetNormType(snes,(SNESNormType)indx); }

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

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

    719:   PetscOptionsInt("-snes_ksp_ew_version","Version 1, 2 or 3","SNESKSPSetParametersEW",kctx->version,&kctx->version,0);
    720:   PetscOptionsReal("-snes_ksp_ew_rtol0","0 <= rtol0 < 1","SNESKSPSetParametersEW",kctx->rtol_0,&kctx->rtol_0,0);
    721:   PetscOptionsReal("-snes_ksp_ew_rtolmax","0 <= rtolmax < 1","SNESKSPSetParametersEW",kctx->rtol_max,&kctx->rtol_max,0);
    722:   PetscOptionsReal("-snes_ksp_ew_gamma","0 <= gamma <= 1","SNESKSPSetParametersEW",kctx->gamma,&kctx->gamma,0);
    723:   PetscOptionsReal("-snes_ksp_ew_alpha","1 < alpha <= 2","SNESKSPSetParametersEW",kctx->alpha,&kctx->alpha,0);
    724:   PetscOptionsReal("-snes_ksp_ew_alpha2","alpha2","SNESKSPSetParametersEW",kctx->alpha2,&kctx->alpha2,0);
    725:   PetscOptionsReal("-snes_ksp_ew_threshold","0 < threshold < 1","SNESKSPSetParametersEW",kctx->threshold,&kctx->threshold,0);

    727:   flg  = PETSC_FALSE;
    728:   PetscOptionsBool("-snes_check_jacobian","Check each Jacobian with a differenced one","SNESUpdateCheckJacobian",flg,&flg,NULL);
    729:   if (flg) {
    730:     SNESSetUpdate(snes,SNESUpdateCheckJacobian);
    731:   }

    733:   flg  = PETSC_FALSE;
    734:   PetscOptionsBool("-snes_monitor_cancel","Remove all monitors","SNESMonitorCancel",flg,&flg,NULL);
    735:   if (flg) {SNESMonitorCancel(snes);}

    737:   PetscOptionsString("-snes_monitor","Monitor norm of function","SNESMonitorSet","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);
    738:   if (flg) {
    739:     PetscViewerASCIIOpen(PetscObjectComm((PetscObject)snes),monfilename,&monviewer);
    740:     SNESMonitorSet(snes,SNESMonitorDefault,monviewer,(PetscErrorCode (*)(void**))PetscViewerDestroy);
    741:   }

    743:   PetscOptionsString("-snes_monitor_range","Monitor range of elements of function","SNESMonitorSet","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);
    744:   if (flg) {
    745:     SNESMonitorSet(snes,SNESMonitorRange,0,0);
    746:   }

    748:   PetscOptionsString("-snes_ratiomonitor","Monitor ratios of norms of function","SNESMonitorSetRatio","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);
    749:   if (flg) {
    750:     PetscViewerASCIIOpen(PetscObjectComm((PetscObject)snes),monfilename,&monviewer);
    751:     SNESMonitorSetRatio(snes,monviewer);
    752:   }

    754:   PetscOptionsString("-snes_monitor_short","Monitor norm of function (fewer digits)","SNESMonitorSet","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);
    755:   if (flg) {
    756:     PetscViewerASCIIOpen(PetscObjectComm((PetscObject)snes),monfilename,&monviewer);
    757:     SNESMonitorSet(snes,SNESMonitorDefaultShort,monviewer,(PetscErrorCode (*)(void**))PetscViewerDestroy);
    758:   }

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

    763:   flg  = PETSC_FALSE;
    764:   PetscOptionsBool("-snes_monitor_solution","Plot solution at each iteration","SNESMonitorSolution",flg,&flg,NULL);
    765:   if (flg) {SNESMonitorSet(snes,SNESMonitorSolution,0,0);}
    766:   flg  = PETSC_FALSE;
    767:   PetscOptionsBool("-snes_monitor_solution_update","Plot correction at each iteration","SNESMonitorSolutionUpdate",flg,&flg,NULL);
    768:   if (flg) {SNESMonitorSet(snes,SNESMonitorSolutionUpdate,0,0);}
    769:   flg  = PETSC_FALSE;
    770:   PetscOptionsBool("-snes_monitor_residual","Plot residual at each iteration","SNESMonitorResidual",flg,&flg,NULL);
    771:   if (flg) {SNESMonitorSet(snes,SNESMonitorResidual,0,0);}
    772:   flg  = PETSC_FALSE;
    773:   PetscOptionsBool("-snes_monitor_lg_residualnorm","Plot function norm at each iteration","SNESMonitorLGResidualNorm",flg,&flg,NULL);
    774:   if (flg) {
    775:     PetscDrawLG ctx;

    777:     SNESMonitorLGCreate(0,0,PETSC_DECIDE,PETSC_DECIDE,300,300,&ctx);
    778:     SNESMonitorSet(snes,SNESMonitorLGResidualNorm,ctx,(PetscErrorCode (*)(void**))SNESMonitorLGDestroy);
    779:   }
    780:   flg  = PETSC_FALSE;
    781:   PetscOptionsBool("-snes_monitor_lg_range","Plot function range at each iteration","SNESMonitorLGRange",flg,&flg,NULL);
    782:   if (flg) {
    783:     PetscViewer ctx;

    785:     PetscViewerDrawOpen(PetscObjectComm((PetscObject)snes),0,0,PETSC_DECIDE,PETSC_DECIDE,300,300,&ctx);
    786:     SNESMonitorSet(snes,SNESMonitorLGRange,ctx,(PetscErrorCode (*)(void**))PetscViewerDestroy);
    787:   }

    789:   flg  = PETSC_FALSE;
    790:   PetscOptionsBool("-snes_monitor_jacupdate_spectrum","Print the change in the spectrum of the Jacobian","SNESMonitorJacUpdateSpectrum",flg,&flg,NULL);
    791:   if (flg) {SNESMonitorSet(snes,SNESMonitorJacUpdateSpectrum,0,0);}

    793:   flg  = PETSC_FALSE;
    794:   PetscOptionsBool("-snes_fd","Use finite differences (slow) to compute Jacobian","SNESComputeJacobianDefault",flg,&flg,NULL);
    795:   if (flg) {
    796:     void *functx;
    797:     SNESGetFunction(snes,NULL,NULL,&functx);
    798:     SNESSetJacobian(snes,snes->jacobian,snes->jacobian_pre,SNESComputeJacobianDefault,functx);
    799:     PetscInfo(snes,"Setting default finite difference Jacobian matrix\n");
    800:   }

    802:   flg  = PETSC_FALSE;
    803:   PetscOptionsBool("-snes_fd_function","Use finite differences (slow) to compute function from user objective","SNESObjectiveComputeFunctionDefaultFD",flg,&flg,NULL);
    804:   if (flg) {
    805:     SNESSetFunction(snes,NULL,SNESObjectiveComputeFunctionDefaultFD,NULL);
    806:   }

    808:   flg  = PETSC_FALSE;
    809:   PetscOptionsBool("-snes_fd_color","Use finite differences with coloring to compute Jacobian","SNESComputeJacobianDefaultColor",flg,&flg,NULL);
    810:   if (flg) {
    811:     DM             dm;
    812:     DMSNES         sdm;
    813:     SNESGetDM(snes,&dm);
    814:     DMGetDMSNES(dm,&sdm);
    815:     sdm->jacobianctx = NULL;
    816:     SNESSetJacobian(snes,snes->jacobian,snes->jacobian_pre,SNESComputeJacobianDefaultColor,0);
    817:     PetscInfo(snes,"Setting default finite difference coloring Jacobian matrix\n");
    818:   }

    820:   flg  = PETSC_FALSE;
    821:   PetscOptionsBool("-snes_mf_operator","Use a Matrix-Free Jacobian with user-provided preconditioner matrix","MatCreateSNESMF",PETSC_FALSE,&snes->mf_operator,&flg);
    822:   if (flg && snes->mf_operator) {
    823:     snes->mf_operator = PETSC_TRUE;
    824:     snes->mf          = PETSC_TRUE;
    825:   }
    826:   flg  = PETSC_FALSE;
    827:   PetscOptionsBool("-snes_mf","Use a Matrix-Free Jacobian with no preconditioner matrix","MatCreateSNESMF",PETSC_FALSE,&snes->mf,&flg);
    828:   if (!flg && snes->mf_operator) snes->mf = PETSC_TRUE;
    829:   PetscOptionsInt("-snes_mf_version","Matrix-Free routines version 1 or 2","None",snes->mf_version,&snes->mf_version,0);

    831:   flg  = PETSC_FALSE;
    832:   SNESGetPCSide(snes,&pcside);
    833:   PetscOptionsEnum("-snes_npc_side","SNES nonlinear preconditioner side","SNESSetPCSide",PCSides,(PetscEnum)pcside,(PetscEnum*)&pcside,&flg);
    834:   if (flg) {SNESSetPCSide(snes,pcside);}

    836: #if defined(PETSC_HAVE_AMS)
    837:   {
    838:   PetscBool set;
    839:   flg  = PETSC_FALSE;
    840:   PetscOptionsBool("-snes_ams_block","Block for AMS memory snooper at end of SNESSolve","PetscObjectAMSBlock",((PetscObject)snes)->amspublishblock,&flg,&set);
    841:   if (set) {
    842:     PetscObjectAMSSetBlock((PetscObject)snes,flg);
    843:   }
    844:   }
    845: #endif

    847:   for (i = 0; i < numberofsetfromoptions; i++) {
    848:     (*othersetfromoptions[i])(snes);
    849:   }

    851:   if (snes->ops->setfromoptions) {
    852:     (*snes->ops->setfromoptions)(snes);
    853:   }

    855:   /* process any options handlers added with PetscObjectAddOptionsHandler() */
    856:   PetscObjectProcessOptionsHandlers((PetscObject)snes);
    857:   PetscOptionsEnd();

    859:   if (!snes->ksp) {SNESGetKSP(snes,&snes->ksp);}
    860:   KSPGetOperators(snes->ksp,NULL,NULL,&matflag);
    861:   KSPSetOperators(snes->ksp,snes->jacobian,snes->jacobian_pre,matflag);
    862:   KSPSetFromOptions(snes->ksp);

    864:   if (!snes->linesearch) {
    865:     SNESGetLineSearch(snes, &snes->linesearch);
    866:   }
    867:   SNESLineSearchSetFromOptions(snes->linesearch);

    869:   /* if someone has set the SNES PC type, create it. */
    870:   SNESGetOptionsPrefix(snes, &optionsprefix);
    871:   PetscOptionsHasName(optionsprefix, "-npc_snes_type", &pcset);
    872:   if (pcset && (!snes->pc)) {
    873:     SNESGetPC(snes, &snes->pc);
    874:   }
    875:   return(0);
    876: }

    880: /*@C
    881:    SNESSetComputeApplicationContext - Sets an optional function to compute a user-defined context for
    882:    the nonlinear solvers.

    884:    Logically Collective on SNES

    886:    Input Parameters:
    887: +  snes - the SNES context
    888: .  compute - function to compute the context
    889: -  destroy - function to destroy the context

    891:    Level: intermediate

    893:    Notes:
    894:    This function is currently not available from Fortran.

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

    898: .seealso: SNESGetApplicationContext(), SNESSetComputeApplicationContext(), SNESGetApplicationContext()
    899: @*/
    900: PetscErrorCode  SNESSetComputeApplicationContext(SNES snes,PetscErrorCode (*compute)(SNES,void**),PetscErrorCode (*destroy)(void**))
    901: {
    904:   snes->ops->usercompute = compute;
    905:   snes->ops->userdestroy = destroy;
    906:   return(0);
    907: }

    911: /*@
    912:    SNESSetApplicationContext - Sets the optional user-defined context for
    913:    the nonlinear solvers.

    915:    Logically Collective on SNES

    917:    Input Parameters:
    918: +  snes - the SNES context
    919: -  usrP - optional user context

    921:    Level: intermediate

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

    925: .seealso: SNESGetApplicationContext()
    926: @*/
    927: PetscErrorCode  SNESSetApplicationContext(SNES snes,void *usrP)
    928: {
    930:   KSP            ksp;

    934:   SNESGetKSP(snes,&ksp);
    935:   KSPSetApplicationContext(ksp,usrP);
    936:   snes->user = usrP;
    937:   return(0);
    938: }

    942: /*@
    943:    SNESGetApplicationContext - Gets the user-defined context for the
    944:    nonlinear solvers.

    946:    Not Collective

    948:    Input Parameter:
    949: .  snes - SNES context

    951:    Output Parameter:
    952: .  usrP - user context

    954:    Level: intermediate

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

    958: .seealso: SNESSetApplicationContext()
    959: @*/
    960: PetscErrorCode  SNESGetApplicationContext(SNES snes,void *usrP)
    961: {
    964:   *(void**)usrP = snes->user;
    965:   return(0);
    966: }

    970: /*@
    971:    SNESGetIterationNumber - Gets the number of nonlinear iterations completed
    972:    at this time.

    974:    Not Collective

    976:    Input Parameter:
    977: .  snes - SNES context

    979:    Output Parameter:
    980: .  iter - iteration number

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

    985:    This is useful for using lagged Jacobians (where one does not recompute the
    986:    Jacobian at each SNES iteration). For example, the code
    987: .vb
    988:       SNESGetIterationNumber(snes,&it);
    989:       if (!(it % 2)) {
    990:         [compute Jacobian here]
    991:       }
    992: .ve
    993:    can be used in your ComputeJacobian() function to cause the Jacobian to be
    994:    recomputed every second SNES iteration.

    996:    Level: intermediate

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

    1000: .seealso:   SNESGetFunctionNorm(), SNESGetLinearSolveIterations()
    1001: @*/
    1002: PetscErrorCode  SNESGetIterationNumber(SNES snes,PetscInt *iter)
    1003: {
    1007:   *iter = snes->iter;
    1008:   return(0);
    1009: }

    1013: /*@
    1014:    SNESSetIterationNumber - Sets the current iteration number.

    1016:    Not Collective

    1018:    Input Parameter:
    1019: .  snes - SNES context
    1020: .  iter - iteration number

    1022:    Level: developer

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

    1026: .seealso:   SNESGetFunctionNorm(), SNESGetLinearSolveIterations()
    1027: @*/
    1028: PetscErrorCode  SNESSetIterationNumber(SNES snes,PetscInt iter)
    1029: {

    1034:   PetscObjectAMSTakeAccess((PetscObject)snes);
    1035:   snes->iter = iter;
    1036:   PetscObjectAMSGrantAccess((PetscObject)snes);
    1037:   return(0);
    1038: }

    1042: /*@
    1043:    SNESGetFunctionNorm - Gets the norm of the current function that was set
    1044:    with SNESSSetFunction().

    1046:    Collective on SNES

    1048:    Input Parameter:
    1049: .  snes - SNES context

    1051:    Output Parameter:
    1052: .  fnorm - 2-norm of function

    1054:    Level: intermediate

    1056: .keywords: SNES, nonlinear, get, function, norm

    1058: .seealso: SNESGetFunction(), SNESGetIterationNumber(), SNESGetLinearSolveIterations()
    1059: @*/
    1060: PetscErrorCode  SNESGetFunctionNorm(SNES snes,PetscReal *fnorm)
    1061: {
    1065:   *fnorm = snes->norm;
    1066:   return(0);
    1067: }

    1072: /*@
    1073:    SNESSetFunctionNorm - Sets the 2-norm of the current function computed using VecNorm().

    1075:    Collective on SNES

    1077:    Input Parameter:
    1078: .  snes - SNES context
    1079: .  fnorm - 2-norm of function

    1081:    Level: developer

    1083: .keywords: SNES, nonlinear, set, function, norm

    1085: .seealso: SNESSetFunction(), SNESSetIterationNumber(), VecNorm().
    1086: @*/
    1087: PetscErrorCode  SNESSetFunctionNorm(SNES snes,PetscReal fnorm)
    1088: {

    1094:   PetscObjectAMSTakeAccess((PetscObject)snes);
    1095:   snes->norm = fnorm;
    1096:   PetscObjectAMSGrantAccess((PetscObject)snes);
    1097:   return(0);
    1098: }

    1102: /*@
    1103:    SNESGetNonlinearStepFailures - Gets the number of unsuccessful steps
    1104:    attempted by the nonlinear solver.

    1106:    Not Collective

    1108:    Input Parameter:
    1109: .  snes - SNES context

    1111:    Output Parameter:
    1112: .  nfails - number of unsuccessful steps attempted

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

    1117:    Level: intermediate

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

    1121: .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), SNESGetLinearSolveFailures(),
    1122:           SNESSetMaxNonlinearStepFailures(), SNESGetMaxNonlinearStepFailures()
    1123: @*/
    1124: PetscErrorCode  SNESGetNonlinearStepFailures(SNES snes,PetscInt *nfails)
    1125: {
    1129:   *nfails = snes->numFailures;
    1130:   return(0);
    1131: }

    1135: /*@
    1136:    SNESSetMaxNonlinearStepFailures - Sets the maximum number of unsuccessful steps
    1137:    attempted by the nonlinear solver before it gives up.

    1139:    Not Collective

    1141:    Input Parameters:
    1142: +  snes     - SNES context
    1143: -  maxFails - maximum of unsuccessful steps

    1145:    Level: intermediate

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

    1149: .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), SNESGetLinearSolveFailures(),
    1150:           SNESGetMaxNonlinearStepFailures(), SNESGetNonlinearStepFailures()
    1151: @*/
    1152: PetscErrorCode  SNESSetMaxNonlinearStepFailures(SNES snes, PetscInt maxFails)
    1153: {
    1156:   snes->maxFailures = maxFails;
    1157:   return(0);
    1158: }

    1162: /*@
    1163:    SNESGetMaxNonlinearStepFailures - Gets the maximum number of unsuccessful steps
    1164:    attempted by the nonlinear solver before it gives up.

    1166:    Not Collective

    1168:    Input Parameter:
    1169: .  snes     - SNES context

    1171:    Output Parameter:
    1172: .  maxFails - maximum of unsuccessful steps

    1174:    Level: intermediate

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

    1178: .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), SNESGetLinearSolveFailures(),
    1179:           SNESSetMaxNonlinearStepFailures(), SNESGetNonlinearStepFailures()

    1181: @*/
    1182: PetscErrorCode  SNESGetMaxNonlinearStepFailures(SNES snes, PetscInt *maxFails)
    1183: {
    1187:   *maxFails = snes->maxFailures;
    1188:   return(0);
    1189: }

    1193: /*@
    1194:    SNESGetNumberFunctionEvals - Gets the number of user provided function evaluations
    1195:      done by SNES.

    1197:    Not Collective

    1199:    Input Parameter:
    1200: .  snes     - SNES context

    1202:    Output Parameter:
    1203: .  nfuncs - number of evaluations

    1205:    Level: intermediate

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

    1209: .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), SNESGetLinearSolveFailures()
    1210: @*/
    1211: PetscErrorCode  SNESGetNumberFunctionEvals(SNES snes, PetscInt *nfuncs)
    1212: {
    1216:   *nfuncs = snes->nfuncs;
    1217:   return(0);
    1218: }

    1222: /*@
    1223:    SNESGetLinearSolveFailures - Gets the number of failed (non-converged)
    1224:    linear solvers.

    1226:    Not Collective

    1228:    Input Parameter:
    1229: .  snes - SNES context

    1231:    Output Parameter:
    1232: .  nfails - number of failed solves

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

    1237:    Level: intermediate

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

    1241: .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures()
    1242: @*/
    1243: PetscErrorCode  SNESGetLinearSolveFailures(SNES snes,PetscInt *nfails)
    1244: {
    1248:   *nfails = snes->numLinearSolveFailures;
    1249:   return(0);
    1250: }

    1254: /*@
    1255:    SNESSetMaxLinearSolveFailures - the number of failed linear solve attempts
    1256:    allowed before SNES returns with a diverged reason of SNES_DIVERGED_LINEAR_SOLVE

    1258:    Logically Collective on SNES

    1260:    Input Parameters:
    1261: +  snes     - SNES context
    1262: -  maxFails - maximum allowed linear solve failures

    1264:    Level: intermediate

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

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

    1270: .seealso: SNESGetLinearSolveFailures(), SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations()
    1271: @*/
    1272: PetscErrorCode  SNESSetMaxLinearSolveFailures(SNES snes, PetscInt maxFails)
    1273: {
    1277:   snes->maxLinearSolveFailures = maxFails;
    1278:   return(0);
    1279: }

    1283: /*@
    1284:    SNESGetMaxLinearSolveFailures - gets the maximum number of linear solve failures that
    1285:      are allowed before SNES terminates

    1287:    Not Collective

    1289:    Input Parameter:
    1290: .  snes     - SNES context

    1292:    Output Parameter:
    1293: .  maxFails - maximum of unsuccessful solves allowed

    1295:    Level: intermediate

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

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

    1301: .seealso: SNESGetLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(),
    1302: @*/
    1303: PetscErrorCode  SNESGetMaxLinearSolveFailures(SNES snes, PetscInt *maxFails)
    1304: {
    1308:   *maxFails = snes->maxLinearSolveFailures;
    1309:   return(0);
    1310: }

    1314: /*@
    1315:    SNESGetLinearSolveIterations - Gets the total number of linear iterations
    1316:    used by the nonlinear solver.

    1318:    Not Collective

    1320:    Input Parameter:
    1321: .  snes - SNES context

    1323:    Output Parameter:
    1324: .  lits - number of linear iterations

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

    1329:    Level: intermediate

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

    1333: .seealso:  SNESGetIterationNumber(), SNESGetFunctionNorm(), SNESGetLinearSolveFailures(), SNESGetMaxLinearSolveFailures()
    1334: @*/
    1335: PetscErrorCode  SNESGetLinearSolveIterations(SNES snes,PetscInt *lits)
    1336: {
    1340:   *lits = snes->linear_its;
    1341:   return(0);
    1342: }

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

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

    1352:    Input Parameters:
    1353: +  snes - the SNES context
    1354: -  ksp - the KSP context

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

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

    1363:    Level: developer

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

    1367: .seealso: KSPGetPC(), SNESCreate(), KSPCreate(), SNESSetKSP()
    1368: @*/
    1369: PetscErrorCode  SNESSetKSP(SNES snes,KSP ksp)
    1370: {

    1377:   PetscObjectReference((PetscObject)ksp);
    1378:   if (snes->ksp) {PetscObjectDereference((PetscObject)snes->ksp);}
    1379:   snes->ksp = ksp;
    1380:   return(0);
    1381: }

    1383: /* -----------------------------------------------------------*/
    1386: /*@
    1387:    SNESCreate - Creates a nonlinear solver context.

    1389:    Collective on MPI_Comm

    1391:    Input Parameters:
    1392: .  comm - MPI communicator

    1394:    Output Parameter:
    1395: .  outsnes - the new SNES context

    1397:    Options Database Keys:
    1398: +   -snes_mf - Activates default matrix-free Jacobian-vector products,
    1399:                and no preconditioning matrix
    1400: .   -snes_mf_operator - Activates default matrix-free Jacobian-vector
    1401:                products, and a user-provided preconditioning matrix
    1402:                as set by SNESSetJacobian()
    1403: -   -snes_fd - Uses (slow!) finite differences to compute Jacobian

    1405:    Level: beginner

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

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

    1411: @*/
    1412: PetscErrorCode  SNESCreate(MPI_Comm comm,SNES *outsnes)
    1413: {
    1415:   SNES           snes;
    1416:   SNESKSPEW      *kctx;

    1420:   *outsnes = NULL;
    1421: #if !defined(PETSC_USE_DYNAMIC_LIBRARIES)
    1422:   SNESInitializePackage();
    1423: #endif

    1425:   PetscHeaderCreate(snes,_p_SNES,struct _SNESOps,SNES_CLASSID,"SNES","Nonlinear solver","SNES",comm,SNESDestroy,SNESView);

    1427:   snes->ops->converged    = SNESConvergedDefault;
    1428:   snes->usesksp           = PETSC_TRUE;
    1429:   snes->tolerancesset     = PETSC_FALSE;
    1430:   snes->max_its           = 50;
    1431:   snes->max_funcs         = 10000;
    1432:   snes->norm              = 0.0;
    1433:   snes->normtype          = SNES_NORM_FUNCTION;
    1434:   snes->rtol              = 1.e-8;
    1435:   snes->ttol              = 0.0;
    1436:   snes->abstol            = 1.e-50;
    1437:   snes->stol              = 1.e-8;
    1438:   snes->deltatol          = 1.e-12;
    1439:   snes->nfuncs            = 0;
    1440:   snes->numFailures       = 0;
    1441:   snes->maxFailures       = 1;
    1442:   snes->linear_its        = 0;
    1443:   snes->lagjacobian       = 1;
    1444:   snes->lagpreconditioner = 1;
    1445:   snes->numbermonitors    = 0;
    1446:   snes->data              = 0;
    1447:   snes->setupcalled       = PETSC_FALSE;
    1448:   snes->ksp_ewconv        = PETSC_FALSE;
    1449:   snes->nwork             = 0;
    1450:   snes->work              = 0;
    1451:   snes->nvwork            = 0;
    1452:   snes->vwork             = 0;
    1453:   snes->conv_hist_len     = 0;
    1454:   snes->conv_hist_max     = 0;
    1455:   snes->conv_hist         = NULL;
    1456:   snes->conv_hist_its     = NULL;
    1457:   snes->conv_hist_reset   = PETSC_TRUE;
    1458:   snes->vec_func_init_set = PETSC_FALSE;
    1459:   snes->norm_init         = 0.;
    1460:   snes->norm_init_set     = PETSC_FALSE;
    1461:   snes->reason            = SNES_CONVERGED_ITERATING;
    1462:   snes->pcside            = PC_RIGHT;

    1464:   snes->mf          = PETSC_FALSE;
    1465:   snes->mf_operator = PETSC_FALSE;
    1466:   snes->mf_version  = 1;

    1468:   snes->numLinearSolveFailures = 0;
    1469:   snes->maxLinearSolveFailures = 1;

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

    1474:   snes->kspconvctx  = (void*)kctx;
    1475:   kctx->version     = 2;
    1476:   kctx->rtol_0      = .3; /* Eisenstat and Walker suggest rtol_0=.5, but
    1477:                              this was too large for some test cases */
    1478:   kctx->rtol_last   = 0.0;
    1479:   kctx->rtol_max    = .9;
    1480:   kctx->gamma       = 1.0;
    1481:   kctx->alpha       = .5*(1.0 + PetscSqrtReal(5.0));
    1482:   kctx->alpha2      = kctx->alpha;
    1483:   kctx->threshold   = .1;
    1484:   kctx->lresid_last = 0.0;
    1485:   kctx->norm_last   = 0.0;

    1487:   *outsnes = snes;
    1488:   return(0);
    1489: }

    1491: /*MC
    1492:     SNESFunction - functional form used to convey the nonlinear function to be solved by SNES

    1494:      Synopsis:
    1495:      #include "petscsnes.h"
    1496:      SNESFunction(SNES snes,Vec x,Vec f,void *ctx);

    1498:      Input Parameters:
    1499: +     snes - the SNES context
    1500: .     x    - state at which to evaluate residual
    1501: -     ctx     - optional user-defined function context, passed in with SNESSetFunction()

    1503:      Output Parameter:
    1504: .     f  - vector to put residual (function value)

    1506:    Level: intermediate

    1508: .seealso:   SNESSetFunction(), SNESGetFunction()
    1509: M*/

    1513: /*@C
    1514:    SNESSetFunction - Sets the function evaluation routine and function
    1515:    vector for use by the SNES routines in solving systems of nonlinear
    1516:    equations.

    1518:    Logically Collective on SNES

    1520:    Input Parameters:
    1521: +  snes - the SNES context
    1522: .  r - vector to store function value
    1523: .  SNESFunction - function evaluation routine
    1524: -  ctx - [optional] user-defined context for private data for the
    1525:          function evaluation routine (may be NULL)

    1527:    Notes:
    1528:    The Newton-like methods typically solve linear systems of the form
    1529: $      f'(x) x = -f(x),
    1530:    where f'(x) denotes the Jacobian matrix and f(x) is the function.

    1532:    Level: beginner

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

    1536: .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetPicard(), SNESFunction
    1537: @*/
    1538: PetscErrorCode  SNESSetFunction(SNES snes,Vec r,PetscErrorCode (*SNESFunction)(SNES,Vec,Vec,void*),void *ctx)
    1539: {
    1541:   DM             dm;

    1545:   if (r) {
    1548:     PetscObjectReference((PetscObject)r);
    1549:     VecDestroy(&snes->vec_func);

    1551:     snes->vec_func = r;
    1552:   }
    1553:   SNESGetDM(snes,&dm);
    1554:   DMSNESSetFunction(dm,SNESFunction,ctx);
    1555:   return(0);
    1556: }

    1561: /*@C
    1562:    SNESSetInitialFunction - Sets the function vector to be used as the
    1563:    function norm at the initialization of the method.  In some
    1564:    instances, the user has precomputed the function before calling
    1565:    SNESSolve.  This function allows one to avoid a redundant call
    1566:    to SNESComputeFunction in that case.

    1568:    Logically Collective on SNES

    1570:    Input Parameters:
    1571: +  snes - the SNES context
    1572: -  f - vector to store function value

    1574:    Notes:
    1575:    This should not be modified during the solution procedure.

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

    1579:    Level: developer

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

    1583: .seealso: SNESSetFunction(), SNESComputeFunction(), SNESSetInitialFunctionNorm()
    1584: @*/
    1585: PetscErrorCode  SNESSetInitialFunction(SNES snes, Vec f)
    1586: {
    1588:   Vec            vec_func;

    1594:   SNESGetFunction(snes,&vec_func,NULL,NULL);
    1595:   VecCopy(f, vec_func);

    1597:   snes->vec_func_init_set = PETSC_TRUE;
    1598:   return(0);
    1599: }

    1604: /*@C
    1605:    SNESSetInitialFunctionNorm - Sets the function norm to be used as the function norm
    1606:    at the initialization of the  method.  In some instances, the user has precomputed
    1607:    the function and its norm before calling SNESSolve.  This function allows one to
    1608:    avoid a redundant call to SNESComputeFunction() and VecNorm() in that case.

    1610:    Logically Collective on SNES

    1612:    Input Parameters:
    1613: +  snes - the SNES context
    1614: -  fnorm - the norm of F as set by SNESSetInitialFunction()

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

    1618:    Level: developer

    1620: .keywords: SNES, nonlinear, set, function, norm

    1622: .seealso: SNESSetFunction(), SNESComputeFunction(), SNESSetInitialFunction()
    1623: @*/
    1624: PetscErrorCode  SNESSetInitialFunctionNorm(SNES snes, PetscReal fnorm)
    1625: {
    1628:   snes->norm_init     = fnorm;
    1629:   snes->norm_init_set = PETSC_TRUE;
    1630:   return(0);
    1631: }

    1635: /*@
    1636:    SNESSetNormType - Sets the SNESNormType used in covergence and monitoring
    1637:    of the SNES method.

    1639:    Logically Collective on SNES

    1641:    Input Parameters:
    1642: +  snes - the SNES context
    1643: -  normtype - the type of the norm used

    1645:    Notes:
    1646:    Only certain SNES methods support certain SNESNormTypes.  Most require evaluation
    1647:    of the nonlinear function and the taking of its norm at every iteration to
    1648:    even ensure convergence at all.  However, methods such as custom Gauss-Seidel methods
    1649:    (SNESGS) and the like do not require the norm of the function to be computed, and therfore
    1650:    may either be monitored for convergence or not.  As these are often used as nonlinear
    1651:    preconditioners, monitoring the norm of their error is not a useful enterprise within
    1652:    their solution.

    1654:    Level: developer

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

    1658: .seealso: SNESGetNormType(), SNESComputeFunction(), VecNorm(), SNESSetFunction(), SNESSetInitialFunction(), SNESNormType
    1659: @*/
    1660: PetscErrorCode  SNESSetNormType(SNES snes, SNESNormType normtype)
    1661: {
    1664:   snes->normtype = normtype;
    1665:   return(0);
    1666: }

    1671: /*@
    1672:    SNESGetNormType - Gets the SNESNormType used in covergence and monitoring
    1673:    of the SNES method.

    1675:    Logically Collective on SNES

    1677:    Input Parameters:
    1678: +  snes - the SNES context
    1679: -  normtype - the type of the norm used

    1681:    Level: advanced

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

    1685: .seealso: SNESSetNormType(), SNESComputeFunction(), VecNorm(), SNESSetFunction(), SNESSetInitialFunction(), SNESNormType
    1686: @*/
    1687: PetscErrorCode  SNESGetNormType(SNES snes, SNESNormType *normtype)
    1688: {
    1691:   *normtype = snes->normtype;
    1692:   return(0);
    1693: }

    1695: /*MC
    1696:     SNESGSFunction - function used to convey a Gauss-Seidel sweep on the nonlinear function

    1698:      Synopsis:
    1699:      #include "petscsnes.h"
    1700: $    SNESGSFunction(SNES snes,Vec x,Vec b,void *ctx);

    1702: +  X   - solution vector
    1703: .  B   - RHS vector
    1704: -  ctx - optional user-defined Gauss-Seidel context

    1706:    Level: intermediate

    1708: .seealso:   SNESSetGS(), SNESGetGS()
    1709: M*/

    1713: /*@C
    1714:    SNESSetGS - Sets the user nonlinear Gauss-Seidel routine for
    1715:    use with composed nonlinear solvers.

    1717:    Input Parameters:
    1718: +  snes   - the SNES context
    1719: .  SNESGSFunction - function evaluation routine
    1720: -  ctx    - [optional] user-defined context for private data for the
    1721:             smoother evaluation routine (may be NULL)

    1723:    Notes:
    1724:    The GS routines are used by the composed nonlinear solver to generate
    1725:     a problem appropriate update to the solution, particularly FAS.

    1727:    Level: intermediate

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

    1731: .seealso: SNESGetFunction(), SNESComputeGS()
    1732: @*/
    1733: PetscErrorCode SNESSetGS(SNES snes,PetscErrorCode (*SNESGSFunction)(SNES,Vec,Vec,void*),void *ctx)
    1734: {
    1736:   DM             dm;

    1740:   SNESGetDM(snes,&dm);
    1741:   DMSNESSetGS(dm,SNESGSFunction,ctx);
    1742:   return(0);
    1743: }

    1747: PETSC_EXTERN PetscErrorCode SNESPicardComputeFunction(SNES snes,Vec x,Vec f,void *ctx)
    1748: {
    1750:   DM             dm;
    1751:   DMSNES         sdm;

    1754:   SNESGetDM(snes,&dm);
    1755:   DMGetDMSNES(dm,&sdm);
    1756:   /*  A(x)*x - b(x) */
    1757:   if (sdm->ops->computepfunction) {
    1758:     (*sdm->ops->computepfunction)(snes,x,f,sdm->pctx);
    1759:   } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE, "Must call SNESSetPicard() to provide Picard function.");

    1761:   if (sdm->ops->computepjacobian) {
    1762:     (*sdm->ops->computepjacobian)(snes,x,&snes->jacobian,&snes->jacobian_pre,&snes->matstruct,sdm->pctx);
    1763:   } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE, "Must call SNESSetPicard() to provide Picard matrix.");
    1764:   VecScale(f,-1.0);
    1765:   MatMultAdd(snes->jacobian,x,f,f);
    1766:   return(0);
    1767: }

    1771: PETSC_EXTERN PetscErrorCode SNESPicardComputeJacobian(SNES snes,Vec x1,Mat *J,Mat *B,MatStructure *flag,void *ctx)
    1772: {
    1774:   /* the jacobian matrix should be pre-filled in SNESPicardComputeFunction */
    1775:   *flag = snes->matstruct;
    1776:   return(0);
    1777: }

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

    1784:    Logically Collective on SNES

    1786:    Input Parameters:
    1787: +  snes - the SNES context
    1788: .  r - vector to store function value
    1789: .  SNESFunction - function evaluation routine
    1790: .  Amat - matrix with which A(x) x - b(x) is to be computed
    1791: .  Pmat - matrix from which preconditioner is computed (usually the same as Amat)
    1792: .  SNESJacobianFunction  - function to compute matrix value
    1793: -  ctx - [optional] user-defined context for private data for the
    1794:          function evaluation routine (may be NULL)

    1796:    Notes:
    1797:     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
    1798:     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.

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

    1802: $     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}
    1803: $     Note that when an exact solver is used this corresponds to the "classic" Picard A(x^{n}) x^{n+1} = b(x^{n}) iteration.

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

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

    1810:    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
    1811:    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
    1812:    different please contact us at petsc-dev@mcs.anl.gov and we'll have an entirely new argument :-).

    1814:    Level: intermediate

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

    1818: .seealso: SNESGetFunction(), SNESSetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESGetPicard(), SNESLineSearchPreCheckPicard()
    1819: @*/
    1820: PetscErrorCode  SNESSetPicard(SNES snes,Vec r,PetscErrorCode (*SNESFunction)(SNES,Vec,Vec,void*),Mat Amat, Mat Pmat, PetscErrorCode (*SNESJacobianFunction)(SNES,Vec,Mat*,Mat*,MatStructure*,void*),void *ctx)
    1821: {
    1823:   DM             dm;

    1827:   SNESGetDM(snes, &dm);
    1828:   DMSNESSetPicard(dm,SNESFunction,SNESJacobianFunction,ctx);
    1829:   SNESSetFunction(snes,r,SNESPicardComputeFunction,ctx);
    1830:   SNESSetJacobian(snes,Amat,Pmat,SNESPicardComputeJacobian,ctx);
    1831:   return(0);
    1832: }

    1836: /*@C
    1837:    SNESGetPicard - Returns the context for the Picard iteration

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

    1841:    Input Parameter:
    1842: .  snes - the SNES context

    1844:    Output Parameter:
    1845: +  r - the function (or NULL)
    1846: .  SNESFunction - the function (or NULL)
    1847: .  Amat - the matrix used to defined the operation A(x) x - b(x) (or NULL)
    1848: .  Pmat  - the matrix from which the preconditioner will be constructed (or NULL)
    1849: .  SNESJacobianFunction - the function for matrix evaluation (or NULL)
    1850: -  ctx - the function context (or NULL)

    1852:    Level: advanced

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

    1856: .seealso: SNESSetPicard(), SNESGetFunction(), SNESGetJacobian(), SNESGetDM(), SNESFunction, SNESJacobianFunction
    1857: @*/
    1858: PetscErrorCode  SNESGetPicard(SNES snes,Vec *r,PetscErrorCode (**SNESFunction)(SNES,Vec,Vec,void*),Mat *Amat, Mat *Pmat, PetscErrorCode (**SNESJacobianFunction)(SNES,Vec,Mat*,Mat*,MatStructure*,void*),void **ctx)
    1859: {
    1861:   DM             dm;

    1865:   SNESGetFunction(snes,r,NULL,NULL);
    1866:   SNESGetJacobian(snes,Amat,Pmat,NULL,NULL);
    1867:   SNESGetDM(snes,&dm);
    1868:   DMSNESGetPicard(dm,SNESFunction,SNESJacobianFunction,ctx);
    1869:   return(0);
    1870: }

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

    1877:    Logically Collective on SNES

    1879:    Input Parameters:
    1880: +  snes - the SNES context
    1881: .  func - function evaluation routine
    1882: -  ctx - [optional] user-defined context for private data for the
    1883:          function evaluation routine (may be NULL)

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

    1888: .  f - function vector
    1889: -  ctx - optional user-defined function context

    1891:    Level: intermediate

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

    1895: .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian()
    1896: @*/
    1897: PetscErrorCode  SNESSetComputeInitialGuess(SNES snes,PetscErrorCode (*func)(SNES,Vec,void*),void *ctx)
    1898: {
    1901:   if (func) snes->ops->computeinitialguess = func;
    1902:   if (ctx)  snes->initialguessP            = ctx;
    1903:   return(0);
    1904: }

    1906: /* --------------------------------------------------------------- */
    1909: /*@C
    1910:    SNESGetRhs - Gets the vector for solving F(x) = rhs. If rhs is not set
    1911:    it assumes a zero right hand side.

    1913:    Logically Collective on SNES

    1915:    Input Parameter:
    1916: .  snes - the SNES context

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

    1921:    Level: intermediate

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

    1925: .seealso: SNESGetSolution(), SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction()
    1926: @*/
    1927: PetscErrorCode  SNESGetRhs(SNES snes,Vec *rhs)
    1928: {
    1932:   *rhs = snes->vec_rhs;
    1933:   return(0);
    1934: }

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

    1941:    Collective on SNES

    1943:    Input Parameters:
    1944: +  snes - the SNES context
    1945: -  x - input vector

    1947:    Output Parameter:
    1948: .  y - function vector, as set by SNESSetFunction()

    1950:    Notes:
    1951:    SNESComputeFunction() is typically used within nonlinear solvers
    1952:    implementations, so most users would not generally call this routine
    1953:    themselves.

    1955:    Level: developer

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

    1959: .seealso: SNESSetFunction(), SNESGetFunction()
    1960: @*/
    1961: PetscErrorCode  SNESComputeFunction(SNES snes,Vec x,Vec y)
    1962: {
    1964:   DM             dm;
    1965:   DMSNES         sdm;

    1973:   VecValidValues(x,2,PETSC_TRUE);

    1975:   SNESGetDM(snes,&dm);
    1976:   DMGetDMSNES(dm,&sdm);
    1977:   if (snes->pc && snes->pcside == PC_LEFT) {
    1978:     VecCopy(x,y);
    1979:     PetscLogEventBegin(SNES_NPCSolve,snes->pc,x,y,0);
    1980:     SNESSolve(snes->pc,snes->vec_rhs,y);
    1981:     PetscLogEventEnd(SNES_NPCSolve,snes->pc,x,y,0);
    1982:     VecAYPX(y,-1.0,x);
    1983:     VecValidValues(y,3,PETSC_FALSE);
    1984:     return(0);
    1985:   } else if (sdm->ops->computefunction) {
    1986:     PetscLogEventBegin(SNES_FunctionEval,snes,x,y,0);
    1987:     PetscStackPush("SNES user function");
    1988:     (*sdm->ops->computefunction)(snes,x,y,sdm->functionctx);
    1989:     PetscStackPop;
    1990:     PetscLogEventEnd(SNES_FunctionEval,snes,x,y,0);
    1991:   } else if (snes->vec_rhs) {
    1992:     MatMult(snes->jacobian, x, y);
    1993:   } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE, "Must call SNESSetFunction() or SNESSetDM() before SNESComputeFunction(), likely called from SNESSolve().");
    1994:   if (snes->vec_rhs) {
    1995:     VecAXPY(y,-1.0,snes->vec_rhs);
    1996:   }
    1997:   snes->nfuncs++;
    1998:   VecValidValues(y,3,PETSC_FALSE);
    1999:   return(0);
    2000: }

    2004: /*@
    2005:    SNESComputeGS - Calls the Gauss-Seidel function that has been set with  SNESSetGS().

    2007:    Collective on SNES

    2009:    Input Parameters:
    2010: +  snes - the SNES context
    2011: .  x - input vector
    2012: -  b - rhs vector

    2014:    Output Parameter:
    2015: .  x - new solution vector

    2017:    Notes:
    2018:    SNESComputeGS() is typically used within composed nonlinear solver
    2019:    implementations, so most users would not generally call this routine
    2020:    themselves.

    2022:    Level: developer

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

    2026: .seealso: SNESSetGS(), SNESComputeFunction()
    2027: @*/
    2028: PetscErrorCode  SNESComputeGS(SNES snes,Vec b,Vec x)
    2029: {
    2031:   DM             dm;
    2032:   DMSNES         sdm;

    2040:   if (b) {VecValidValues(b,2,PETSC_TRUE);}
    2041:   PetscLogEventBegin(SNES_GSEval,snes,x,b,0);
    2042:   SNESGetDM(snes,&dm);
    2043:   DMGetDMSNES(dm,&sdm);
    2044:   if (sdm->ops->computegs) {
    2045:     PetscStackPush("SNES user GS");
    2046:     (*sdm->ops->computegs)(snes,x,b,sdm->gsctx);
    2047:     PetscStackPop;
    2048:   } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE, "Must call SNESSetGS() before SNESComputeGS(), likely called from SNESSolve().");
    2049:   PetscLogEventEnd(SNES_GSEval,snes,x,b,0);
    2050:   VecValidValues(x,3,PETSC_FALSE);
    2051:   return(0);
    2052: }

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

    2059:    Collective on SNES and Mat

    2061:    Input Parameters:
    2062: +  snes - the SNES context
    2063: -  x - input vector

    2065:    Output Parameters:
    2066: +  A - Jacobian matrix
    2067: .  B - optional preconditioning matrix
    2068: -  flag - flag indicating matrix structure (one of, SAME_NONZERO_PATTERN,DIFFERENT_NONZERO_PATTERN,SAME_PRECONDITIONER)

    2070:   Options Database Keys:
    2071: +    -snes_lag_preconditioner <lag>
    2072: .    -snes_lag_jacobian <lag>
    2073: .    -snes_compare_explicit - Compare the computed Jacobian to the finite difference Jacobian and output the differences
    2074: .    -snes_compare_explicit_draw  - Compare the computed Jacobian to the finite difference Jacobian and draw the result
    2075: .    -snes_compare_explicit_contour  - Compare the computed Jacobian to the finite difference Jacobian and draw a contour plot with the result
    2076: .    -snes_compare_operator  - Make the comparison options above use the operator instead of the preconditioning matrix
    2077: .    -snes_compare_coloring - Compute the finite differece Jacobian using coloring and display norms of difference
    2078: .    -snes_compare_coloring_display - Compute the finite differece Jacobian using coloring and display verbose differences
    2079: .    -snes_compare_coloring_threshold - Display only those matrix entries that differ by more than a given threshold
    2080: .    -snes_compare_coloring_threshold_atol - Absolute tolerance for difference in matrix entries to be displayed by -snes_compare_coloring_threshold
    2081: .    -snes_compare_coloring_threshold_rtol - Relative tolerance for difference in matrix entries to be displayed by -snes_compare_coloring_threshold
    2082: .    -snes_compare_coloring_draw - Compute the finite differece Jacobian using coloring and draw differences
    2083: -    -snes_compare_coloring_draw_contour - Compute the finite differece Jacobian using coloring and show contours of matrices and differences

    2086:    Notes:
    2087:    Most users should not need to explicitly call this routine, as it
    2088:    is used internally within the nonlinear solvers.

    2090:    See KSPSetOperators() for important information about setting the
    2091:    flag parameter.

    2093:    Level: developer

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

    2097: .seealso:  SNESSetJacobian(), KSPSetOperators(), MatStructure, SNESSetLagPreconditioner(), SNESSetLagJacobian()
    2098: @*/
    2099: PetscErrorCode  SNESComputeJacobian(SNES snes,Vec X,Mat *A,Mat *B,MatStructure *flg)
    2100: {
    2102:   PetscBool      flag;
    2103:   DM             dm;
    2104:   DMSNES         sdm;

    2111:   VecValidValues(X,2,PETSC_TRUE);
    2112:   SNESGetDM(snes,&dm);
    2113:   DMGetDMSNES(dm,&sdm);

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

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

    2119:   if (snes->lagjacobian == -2) {
    2120:     snes->lagjacobian = -1;

    2122:     PetscInfo(snes,"Recomputing Jacobian/preconditioner because lag is -2 (means compute Jacobian, but then never again) \n");
    2123:   } else if (snes->lagjacobian == -1) {
    2124:     *flg = SAME_PRECONDITIONER;
    2125:     PetscInfo(snes,"Reusing Jacobian/preconditioner because lag is -1\n");
    2126:     PetscObjectTypeCompare((PetscObject)*A,MATMFFD,&flag);
    2127:     if (flag) {
    2128:       MatAssemblyBegin(*A,MAT_FINAL_ASSEMBLY);
    2129:       MatAssemblyEnd(*A,MAT_FINAL_ASSEMBLY);
    2130:     }
    2131:     return(0);
    2132:   } else if (snes->lagjacobian > 1 && snes->iter % snes->lagjacobian) {
    2133:     *flg = SAME_PRECONDITIONER;
    2134:     PetscInfo2(snes,"Reusing Jacobian/preconditioner because lag is %D and SNES iteration is %D\n",snes->lagjacobian,snes->iter);
    2135:     PetscObjectTypeCompare((PetscObject)*A,MATMFFD,&flag);
    2136:     if (flag) {
    2137:       MatAssemblyBegin(*A,MAT_FINAL_ASSEMBLY);
    2138:       MatAssemblyEnd(*A,MAT_FINAL_ASSEMBLY);
    2139:     }
    2140:     return(0);
    2141:   }
    2142:   if (snes->pc && snes->pcside == PC_LEFT) {
    2143:       MatAssemblyBegin(*A,MAT_FINAL_ASSEMBLY);
    2144:       MatAssemblyEnd(*A,MAT_FINAL_ASSEMBLY);
    2145:       return(0);
    2146:   }

    2148:   *flg = DIFFERENT_NONZERO_PATTERN;
    2149:   PetscLogEventBegin(SNES_JacobianEval,snes,X,*A,*B);

    2151:   PetscStackPush("SNES user Jacobian function");
    2152:   (*sdm->ops->computejacobian)(snes,X,A,B,flg,sdm->jacobianctx);
    2153:   PetscStackPop;

    2155:   PetscLogEventEnd(SNES_JacobianEval,snes,X,*A,*B);

    2157:   if (snes->lagpreconditioner == -2) {
    2158:     PetscInfo(snes,"Rebuilding preconditioner exactly once since lag is -2\n");

    2160:     snes->lagpreconditioner = -1;
    2161:   } else if (snes->lagpreconditioner == -1) {
    2162:     *flg = SAME_PRECONDITIONER;
    2163:     PetscInfo(snes,"Reusing preconditioner because lag is -1\n");
    2164:   } else if (snes->lagpreconditioner > 1 && snes->iter % snes->lagpreconditioner) {
    2165:     *flg = SAME_PRECONDITIONER;
    2166:     PetscInfo2(snes,"Reusing preconditioner because lag is %D and SNES iteration is %D\n",snes->lagpreconditioner,snes->iter);
    2167:   }

    2169:   /* make sure user returned a correct Jacobian and preconditioner */
    2172:   {
    2173:     PetscBool flag = PETSC_FALSE,flag_draw = PETSC_FALSE,flag_contour = PETSC_FALSE,flag_operator = PETSC_FALSE;
    2174:     PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_explicit",&flag,NULL);
    2175:     PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_explicit_draw",&flag_draw,NULL);
    2176:     PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_explicit_draw_contour",&flag_contour,NULL);
    2177:     PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_operator",&flag_operator,NULL);
    2178:     if (flag || flag_draw || flag_contour) {
    2179:       Mat          Bexp_mine = NULL,Bexp,FDexp;
    2180:       MatStructure mstruct;
    2181:       PetscViewer  vdraw,vstdout;
    2182:       PetscBool    flg;
    2183:       if (flag_operator) {
    2184:         MatComputeExplicitOperator(*A,&Bexp_mine);
    2185:         Bexp = Bexp_mine;
    2186:       } else {
    2187:         /* See if the preconditioning matrix can be viewed and added directly */
    2188:         PetscObjectTypeCompareAny((PetscObject)*B,&flg,MATSEQAIJ,MATMPIAIJ,MATSEQDENSE,MATMPIDENSE,MATSEQBAIJ,MATMPIBAIJ,MATSEQSBAIJ,MATMPIBAIJ,"");
    2189:         if (flg) Bexp = *B;
    2190:         else {
    2191:           /* If the "preconditioning" matrix is itself MATSHELL or some other type without direct support */
    2192:           MatComputeExplicitOperator(*B,&Bexp_mine);
    2193:           Bexp = Bexp_mine;
    2194:         }
    2195:       }
    2196:       MatConvert(Bexp,MATSAME,MAT_INITIAL_MATRIX,&FDexp);
    2197:       SNESComputeJacobianDefault(snes,X,&FDexp,&FDexp,&mstruct,NULL);
    2198:       PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)snes),&vstdout);
    2199:       if (flag_draw || flag_contour) {
    2200:         PetscViewerDrawOpen(PetscObjectComm((PetscObject)snes),0,"Explicit Jacobians",PETSC_DECIDE,PETSC_DECIDE,300,300,&vdraw);
    2201:         if (flag_contour) {PetscViewerPushFormat(vdraw,PETSC_VIEWER_DRAW_CONTOUR);}
    2202:       } else vdraw = NULL;
    2203:       PetscViewerASCIIPrintf(vstdout,"Explicit %s\n",flag_operator ? "Jacobian" : "preconditioning Jacobian");
    2204:       if (flag) {MatView(Bexp,vstdout);}
    2205:       if (vdraw) {MatView(Bexp,vdraw);}
    2206:       PetscViewerASCIIPrintf(vstdout,"Finite difference Jacobian\n");
    2207:       if (flag) {MatView(FDexp,vstdout);}
    2208:       if (vdraw) {MatView(FDexp,vdraw);}
    2209:       MatAYPX(FDexp,-1.0,Bexp,SAME_NONZERO_PATTERN);
    2210:       PetscViewerASCIIPrintf(vstdout,"User-provided matrix minus finite difference Jacobian\n");
    2211:       if (flag) {MatView(FDexp,vstdout);}
    2212:       if (vdraw) {              /* Always use contour for the difference */
    2213:         PetscViewerPushFormat(vdraw,PETSC_VIEWER_DRAW_CONTOUR);
    2214:         MatView(FDexp,vdraw);
    2215:         PetscViewerPopFormat(vdraw);
    2216:       }
    2217:       if (flag_contour) {PetscViewerPopFormat(vdraw);}
    2218:       PetscViewerDestroy(&vdraw);
    2219:       MatDestroy(&Bexp_mine);
    2220:       MatDestroy(&FDexp);
    2221:     }
    2222:   }
    2223:   {
    2224:     PetscBool flag = PETSC_FALSE,flag_display = PETSC_FALSE,flag_draw = PETSC_FALSE,flag_contour = PETSC_FALSE,flag_threshold = PETSC_FALSE;
    2225:     PetscReal threshold_atol = PETSC_SQRT_MACHINE_EPSILON,threshold_rtol = 10*PETSC_SQRT_MACHINE_EPSILON;
    2226:     PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_coloring",&flag,NULL);
    2227:     PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_coloring_display",&flag_display,NULL);
    2228:     PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_coloring_draw",&flag_draw,NULL);
    2229:     PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_coloring_draw_contour",&flag_contour,NULL);
    2230:     PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_coloring_threshold",&flag_threshold,NULL);
    2231:     PetscOptionsGetReal(((PetscObject)snes)->prefix,"-snes_compare_coloring_threshold_rtol",&threshold_rtol,NULL);
    2232:     PetscOptionsGetReal(((PetscObject)snes)->prefix,"-snes_compare_coloring_threshold_atol",&threshold_atol,NULL);
    2233:     if (flag || flag_display || flag_draw || flag_contour || flag_threshold) {
    2234:       Mat            Bfd;
    2235:       MatStructure   mstruct;
    2236:       PetscViewer    vdraw,vstdout;
    2237:       ISColoring     iscoloring;
    2238:       MatFDColoring  matfdcoloring;
    2239:       PetscErrorCode (*func)(SNES,Vec,Vec,void*);
    2240:       void           *funcctx;
    2241:       PetscReal      norm1,norm2,normmax;

    2243:       MatDuplicate(*B,MAT_DO_NOT_COPY_VALUES,&Bfd);
    2244:       MatGetColoring(Bfd,MATCOLORINGSL,&iscoloring);
    2245:       MatFDColoringCreate(Bfd,iscoloring,&matfdcoloring);
    2246:       ISColoringDestroy(&iscoloring);

    2248:       /* This method of getting the function is currently unreliable since it doesn't work for DM local functions. */
    2249:       SNESGetFunction(snes,NULL,&func,&funcctx);
    2250:       MatFDColoringSetFunction(matfdcoloring,(PetscErrorCode (*)(void))func,funcctx);
    2251:       PetscObjectSetOptionsPrefix((PetscObject)matfdcoloring,((PetscObject)snes)->prefix);
    2252:       PetscObjectAppendOptionsPrefix((PetscObject)matfdcoloring,"coloring_");
    2253:       MatFDColoringSetFromOptions(matfdcoloring);
    2254:       MatFDColoringApply(Bfd,matfdcoloring,X,&mstruct,snes);
    2255:       MatFDColoringDestroy(&matfdcoloring);

    2257:       PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)snes),&vstdout);
    2258:       if (flag_draw || flag_contour) {
    2259:         PetscViewerDrawOpen(PetscObjectComm((PetscObject)snes),0,"Colored Jacobians",PETSC_DECIDE,PETSC_DECIDE,300,300,&vdraw);
    2260:         if (flag_contour) {PetscViewerPushFormat(vdraw,PETSC_VIEWER_DRAW_CONTOUR);}
    2261:       } else vdraw = NULL;
    2262:       PetscViewerASCIIPrintf(vstdout,"Explicit preconditioning Jacobian\n");
    2263:       if (flag_display) {MatView(*B,vstdout);}
    2264:       if (vdraw) {MatView(*B,vdraw);}
    2265:       PetscViewerASCIIPrintf(vstdout,"Colored Finite difference Jacobian\n");
    2266:       if (flag_display) {MatView(Bfd,vstdout);}
    2267:       if (vdraw) {MatView(Bfd,vdraw);}
    2268:       MatAYPX(Bfd,-1.0,*B,SAME_NONZERO_PATTERN);
    2269:       MatNorm(Bfd,NORM_1,&norm1);
    2270:       MatNorm(Bfd,NORM_FROBENIUS,&norm2);
    2271:       MatNorm(Bfd,NORM_MAX,&normmax);
    2272:       PetscViewerASCIIPrintf(vstdout,"User-provided matrix minus finite difference Jacobian, norm1=%G normFrob=%G normmax=%G\n",norm1,norm2,normmax);
    2273:       if (flag_display) {MatView(Bfd,vstdout);}
    2274:       if (vdraw) {              /* Always use contour for the difference */
    2275:         PetscViewerPushFormat(vdraw,PETSC_VIEWER_DRAW_CONTOUR);
    2276:         MatView(Bfd,vdraw);
    2277:         PetscViewerPopFormat(vdraw);
    2278:       }
    2279:       if (flag_contour) {PetscViewerPopFormat(vdraw);}

    2281:       if (flag_threshold) {
    2282:         PetscInt bs,rstart,rend,i;
    2283:         MatGetBlockSize(*B,&bs);
    2284:         MatGetOwnershipRange(*B,&rstart,&rend);
    2285:         for (i=rstart; i<rend; i++) {
    2286:           const PetscScalar *ba,*ca;
    2287:           const PetscInt    *bj,*cj;
    2288:           PetscInt          bn,cn,j,maxentrycol = -1,maxdiffcol = -1,maxrdiffcol = -1;
    2289:           PetscReal         maxentry = 0,maxdiff = 0,maxrdiff = 0;
    2290:           MatGetRow(*B,i,&bn,&bj,&ba);
    2291:           MatGetRow(Bfd,i,&cn,&cj,&ca);
    2292:           if (bn != cn) SETERRQ(((PetscObject)*A)->comm,PETSC_ERR_PLIB,"Unexpected different nonzero pattern in -snes_compare_coloring_threshold");
    2293:           for (j=0; j<bn; j++) {
    2294:             PetscReal rdiff = PetscAbsScalar(ca[j]) / (threshold_atol + threshold_rtol*PetscAbsScalar(ba[j]));
    2295:             if (PetscAbsScalar(ba[j]) > PetscAbs(maxentry)) {
    2296:               maxentrycol = bj[j];
    2297:               maxentry    = PetscRealPart(ba[j]);
    2298:             }
    2299:             if (PetscAbsScalar(ca[j]) > PetscAbs(maxdiff)) {
    2300:               maxdiffcol = bj[j];
    2301:               maxdiff    = PetscRealPart(ca[j]);
    2302:             }
    2303:             if (rdiff > maxrdiff) {
    2304:               maxrdiffcol = bj[j];
    2305:               maxrdiff    = rdiff;
    2306:             }
    2307:           }
    2308:           if (maxrdiff > 1) {
    2309:             PetscViewerASCIIPrintf(vstdout,"row %D (maxentry=%G at %D, maxdiff=%G at %D, maxrdiff=%G at %D):",i,maxentry,maxentrycol,maxdiff,maxdiffcol,maxrdiff,maxrdiffcol);
    2310:             for (j=0; j<bn; j++) {
    2311:               PetscReal rdiff;
    2312:               rdiff = PetscAbsScalar(ca[j]) / (threshold_atol + threshold_rtol*PetscAbsScalar(ba[j]));
    2313:               if (rdiff > 1) {
    2314:                 PetscViewerASCIIPrintf(vstdout," (%D,%G:%G)",bj[j],PetscRealPart(ba[j]),PetscRealPart(ca[j]));
    2315:               }
    2316:             }
    2317:             PetscViewerASCIIPrintf(vstdout,"\n",i,maxentry,maxdiff,maxrdiff);
    2318:           }
    2319:           MatRestoreRow(*B,i,&bn,&bj,&ba);
    2320:           MatRestoreRow(Bfd,i,&cn,&cj,&ca);
    2321:         }
    2322:       }
    2323:       PetscViewerDestroy(&vdraw);
    2324:       MatDestroy(&Bfd);
    2325:     }
    2326:   }
    2327:   return(0);
    2328: }

    2330: /*MC
    2331:     SNESJacobianFunction - function used to convey the nonlinear Jacobian of the function to be solved by SNES

    2333:      Synopsis:
    2334:      #include "petscsnes.h"
    2335: $     SNESJacobianFunction(SNES snes,Vec x,Mat *Amat,Mat *Pmat,int *flag,void *ctx);

    2337: +  x - input vector
    2338: .  Amat - the matrix that defines the (approximate) Jacobian
    2339: .  Pmat - the matrix to be used in constructing the preconditioner, usually the same as Amat.
    2340: .  flag - flag indicating information about the preconditioner matrix
    2341:    structure (same as flag in KSPSetOperators()), one of SAME_NONZERO_PATTERN,DIFFERENT_NONZERO_PATTERN,SAME_PRECONDITIONER
    2342: -  ctx - [optional] user-defined Jacobian context

    2344:    Level: intermediate

    2346: .seealso:   SNESSetFunction(), SNESGetFunction(), SNESSetJacobian(), SNESGetJacobian()
    2347: M*/

    2351: /*@C
    2352:    SNESSetJacobian - Sets the function to compute Jacobian as well as the
    2353:    location to store the matrix.

    2355:    Logically Collective on SNES and Mat

    2357:    Input Parameters:
    2358: +  snes - the SNES context
    2359: .  Amat - the matrix that defines the (approximate) Jacobian
    2360: .  Pmat - the matrix to be used in constructing the preconditioner, usually the same as Amat.
    2361: .  SNESJacobianFunction - Jacobian evaluation routine (if NULL then SNES retains any previously set value)
    2362: -  ctx - [optional] user-defined context for private data for the
    2363:          Jacobian evaluation routine (may be NULL) (if NULL then SNES retains any previously set value)

    2365:    Notes:
    2366:    See KSPSetOperators() for important information about setting the flag
    2367:    output parameter in the routine func().  Be sure to read this information!

    2369:    The routine func() takes Mat * as the matrix arguments rather than Mat.
    2370:    This allows the Jacobian evaluation routine to replace A and/or B with a
    2371:    completely new new matrix structure (not just different matrix elements)
    2372:    when appropriate, for instance, if the nonzero structure is changing
    2373:    throughout the global iterations.

    2375:    If the Amat matrix and Pmat matrix are different you must call MatAssemblyBegin/End() on
    2376:    each matrix.

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

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

    2384:    Level: beginner

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

    2388: .seealso: KSPSetOperators(), SNESSetFunction(), MatMFFDComputeJacobian(), SNESComputeJacobianDefaultColor(), MatStructure, SNESJacobianFunction, SNESSetPicard()
    2389: @*/
    2390: PetscErrorCode  SNESSetJacobian(SNES snes,Mat Amat,Mat Pmat,PetscErrorCode (*SNESJacobianFunction)(SNES,Vec,Mat*,Mat*,MatStructure*,void*),void *ctx)
    2391: {
    2393:   DM             dm;

    2401:   SNESGetDM(snes,&dm);
    2402:   DMSNESSetJacobian(dm,SNESJacobianFunction,ctx);
    2403:   if (Amat) {
    2404:     PetscObjectReference((PetscObject)Amat);
    2405:     MatDestroy(&snes->jacobian);

    2407:     snes->jacobian = Amat;
    2408:   }
    2409:   if (Pmat) {
    2410:     PetscObjectReference((PetscObject)Pmat);
    2411:     MatDestroy(&snes->jacobian_pre);

    2413:     snes->jacobian_pre = Pmat;
    2414:   }
    2415:   return(0);
    2416: }

    2420: /*@C
    2421:    SNESGetJacobian - Returns the Jacobian matrix and optionally the user
    2422:    provided context for evaluating the Jacobian.

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

    2426:    Input Parameter:
    2427: .  snes - the nonlinear solver context

    2429:    Output Parameters:
    2430: +  Amat - location to stash (approximate) Jacobian matrix (or NULL)
    2431: .  Pmat - location to stash matrix used to compute the preconditioner (or NULL)
    2432: .  SNESJacobianFunction - location to put Jacobian function (or NULL)
    2433: -  ctx - location to stash Jacobian ctx (or NULL)

    2435:    Level: advanced

    2437: .seealso: SNESSetJacobian(), SNESComputeJacobian()
    2438: @*/
    2439: PetscErrorCode SNESGetJacobian(SNES snes,Mat *Amat,Mat *Pmat,PetscErrorCode (**SNESJacobianFunction)(SNES,Vec,Mat*,Mat*,MatStructure*,void*),void **ctx)
    2440: {
    2442:   DM             dm;
    2443:   DMSNES         sdm;

    2447:   if (Amat) *Amat = snes->jacobian;
    2448:   if (Pmat) *Pmat = snes->jacobian_pre;
    2449:   SNESGetDM(snes,&dm);
    2450:   DMGetDMSNES(dm,&sdm);
    2451:   if (SNESJacobianFunction) *SNESJacobianFunction = sdm->ops->computejacobian;
    2452:   if (ctx) *ctx = sdm->jacobianctx;
    2453:   return(0);
    2454: }

    2458: /*@
    2459:    SNESSetUp - Sets up the internal data structures for the later use
    2460:    of a nonlinear solver.

    2462:    Collective on SNES

    2464:    Input Parameters:
    2465: .  snes - the SNES context

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

    2474:    Level: advanced

    2476: .keywords: SNES, nonlinear, setup

    2478: .seealso: SNESCreate(), SNESSolve(), SNESDestroy()
    2479: @*/
    2480: PetscErrorCode  SNESSetUp(SNES snes)
    2481: {
    2483:   DM             dm;
    2484:   DMSNES         sdm;
    2485:   SNESLineSearch linesearch, pclinesearch;
    2486:   void           *lsprectx,*lspostctx;
    2487:   PetscErrorCode (*precheck)(SNESLineSearch,Vec,Vec,PetscBool*,void*);
    2488:   PetscErrorCode (*postcheck)(SNESLineSearch,Vec,Vec,Vec,PetscBool*,PetscBool*,void*);
    2489:   PetscErrorCode (*func)(SNES,Vec,Vec,void*);
    2490:   Vec            f,fpc;
    2491:   void           *funcctx;
    2492:   PetscErrorCode (*jac)(SNES,Vec,Mat*,Mat*,MatStructure*,void*);
    2493:   void           *jacctx,*appctx;
    2494:   Mat            A,B;

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

    2500:   if (!((PetscObject)snes)->type_name) {
    2501:     SNESSetType(snes,SNESNEWTONLS);
    2502:   }

    2504:   SNESGetFunction(snes,&snes->vec_func,NULL,NULL);
    2505:   if (snes->vec_func == snes->vec_sol) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_IDN,"Solution vector cannot be function vector");
    2506:   if (snes->vec_rhs  == snes->vec_sol) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_IDN,"Solution vector cannot be right hand side vector");

    2508:   if (!snes->vec_sol_update /* && snes->vec_sol */) {
    2509:     VecDuplicate(snes->vec_sol,&snes->vec_sol_update);
    2510:     PetscLogObjectParent(snes,snes->vec_sol_update);
    2511:   }

    2513:   SNESGetDM(snes,&dm);
    2514:   DMShellSetGlobalVector(snes->dm,snes->vec_sol);
    2515:   DMGetDMSNES(dm,&sdm);
    2516:   if (!sdm->ops->computefunction) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_WRONGSTATE,"Function never provided to SNES object");
    2517:   if (!sdm->ops->computejacobian) {
    2518:     DMSNESSetJacobian(dm,SNESComputeJacobianDefaultColor,NULL);
    2519:   }
    2520:   if (!snes->vec_func) {
    2521:     DMCreateGlobalVector(dm,&snes->vec_func);
    2522:   }

    2524:   if (!snes->ksp) {
    2525:     SNESGetKSP(snes, &snes->ksp);
    2526:   }

    2528:   if (!snes->linesearch) {
    2529:     SNESGetLineSearch(snes, &snes->linesearch);
    2530:   }

    2532:   if (snes->pc && (snes->pcside == PC_LEFT)) {
    2533:     snes->mf          = PETSC_TRUE;
    2534:     snes->mf_operator = PETSC_FALSE;
    2535:   }

    2537:   if (snes->mf) {
    2538:     SNESSetUpMatrixFree_Private(snes, snes->mf_operator, snes->mf_version);
    2539:   }

    2541:   if (snes->ops->usercompute && !snes->user) {
    2542:     (*snes->ops->usercompute)(snes,(void**)&snes->user);
    2543:   }

    2545:   if (snes->pc) {
    2546:     /* copy the DM over */
    2547:     SNESGetDM(snes,&dm);
    2548:     SNESSetDM(snes->pc,dm);

    2550:     SNESGetFunction(snes,&f,&func,&funcctx);
    2551:     VecDuplicate(f,&fpc);
    2552:     SNESSetFunction(snes->pc,fpc,func,funcctx);
    2553:     SNESGetJacobian(snes,&A,&B,&jac,&jacctx);
    2554:     SNESSetJacobian(snes->pc,A,B,jac,jacctx);
    2555:     SNESGetApplicationContext(snes,&appctx);
    2556:     SNESSetApplicationContext(snes->pc,appctx);
    2557:     VecDestroy(&fpc);

    2559:     /* copy the function pointers over */
    2560:     PetscObjectCopyFortranFunctionPointers((PetscObject)snes,(PetscObject)snes->pc);

    2562:     /* default to 1 iteration */
    2563:     SNESSetTolerances(snes->pc,0.0,0.0,0.0,1,snes->pc->max_funcs);
    2564:     if (snes->pcside==PC_RIGHT) {
    2565:       SNESSetNormType(snes->pc,SNES_NORM_FINAL_ONLY);
    2566:     } else {
    2567:       SNESSetNormType(snes->pc,SNES_NORM_NONE);
    2568:     }
    2569:     SNESSetFromOptions(snes->pc);

    2571:     /* copy the line search context over */
    2572:     SNESGetLineSearch(snes,&linesearch);
    2573:     SNESGetLineSearch(snes->pc,&pclinesearch);
    2574:     SNESLineSearchGetPreCheck(linesearch,&precheck,&lsprectx);
    2575:     SNESLineSearchGetPostCheck(linesearch,&postcheck,&lspostctx);
    2576:     SNESLineSearchSetPreCheck(pclinesearch,precheck,lsprectx);
    2577:     SNESLineSearchSetPostCheck(pclinesearch,postcheck,lspostctx);
    2578:     PetscObjectCopyFortranFunctionPointers((PetscObject)linesearch, (PetscObject)pclinesearch);
    2579:   }

    2581:   if (snes->ops->setup) {
    2582:     (*snes->ops->setup)(snes);
    2583:   }

    2585:   snes->setupcalled = PETSC_TRUE;
    2586:   return(0);
    2587: }

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

    2594:    Collective on SNES

    2596:    Input Parameter:
    2597: .  snes - iterative context obtained from SNESCreate()

    2599:    Level: intermediate

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

    2603: .keywords: SNES, destroy

    2605: .seealso: SNESCreate(), SNESSetUp(), SNESSolve()
    2606: @*/
    2607: PetscErrorCode  SNESReset(SNES snes)
    2608: {

    2613:   if (snes->ops->userdestroy && snes->user) {
    2614:     (*snes->ops->userdestroy)((void**)&snes->user);
    2615:     snes->user = NULL;
    2616:   }
    2617:   if (snes->pc) {
    2618:     SNESReset(snes->pc);
    2619:   }

    2621:   if (snes->ops->reset) {
    2622:     (*snes->ops->reset)(snes);
    2623:   }
    2624:   if (snes->ksp) {
    2625:     KSPReset(snes->ksp);
    2626:   }

    2628:   if (snes->linesearch) {
    2629:     SNESLineSearchReset(snes->linesearch);
    2630:   }

    2632:   VecDestroy(&snes->vec_rhs);
    2633:   VecDestroy(&snes->vec_sol);
    2634:   VecDestroy(&snes->vec_sol_update);
    2635:   VecDestroy(&snes->vec_func);
    2636:   MatDestroy(&snes->jacobian);
    2637:   MatDestroy(&snes->jacobian_pre);
    2638:   VecDestroyVecs(snes->nwork,&snes->work);
    2639:   VecDestroyVecs(snes->nvwork,&snes->vwork);

    2641:   snes->nwork       = snes->nvwork = 0;
    2642:   snes->setupcalled = PETSC_FALSE;
    2643:   return(0);
    2644: }

    2648: /*@
    2649:    SNESDestroy - Destroys the nonlinear solver context that was created
    2650:    with SNESCreate().

    2652:    Collective on SNES

    2654:    Input Parameter:
    2655: .  snes - the SNES context

    2657:    Level: beginner

    2659: .keywords: SNES, nonlinear, destroy

    2661: .seealso: SNESCreate(), SNESSolve()
    2662: @*/
    2663: PetscErrorCode  SNESDestroy(SNES *snes)
    2664: {

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

    2672:   SNESReset((*snes));
    2673:   SNESDestroy(&(*snes)->pc);

    2675:   /* if memory was published with AMS then destroy it */
    2676:   PetscObjectAMSViewOff((PetscObject)*snes);
    2677:   if ((*snes)->ops->destroy) {(*((*snes))->ops->destroy)((*snes));}

    2679:   DMDestroy(&(*snes)->dm);
    2680:   KSPDestroy(&(*snes)->ksp);
    2681:   SNESLineSearchDestroy(&(*snes)->linesearch);

    2683:   PetscFree((*snes)->kspconvctx);
    2684:   if ((*snes)->ops->convergeddestroy) {
    2685:     (*(*snes)->ops->convergeddestroy)((*snes)->cnvP);
    2686:   }
    2687:   if ((*snes)->conv_malloc) {
    2688:     PetscFree((*snes)->conv_hist);
    2689:     PetscFree((*snes)->conv_hist_its);
    2690:   }
    2691:   SNESMonitorCancel((*snes));
    2692:   PetscHeaderDestroy(snes);
    2693:   return(0);
    2694: }

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

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

    2703:    Logically Collective on SNES

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

    2710:    Options Database Keys:
    2711: .    -snes_lag_preconditioner <lag>

    2713:    Notes:
    2714:    The default is 1
    2715:    The preconditioner is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1
    2716:    If  -1 is used before the very first nonlinear solve the preconditioner is still built because there is no previous preconditioner to use

    2718:    Level: intermediate

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

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

    2724: @*/
    2725: PetscErrorCode  SNESSetLagPreconditioner(SNES snes,PetscInt lag)
    2726: {
    2729:   if (lag < -2) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag must be -2, -1, 1 or greater");
    2730:   if (!lag) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag cannot be 0");
    2732:   snes->lagpreconditioner = lag;
    2733:   return(0);
    2734: }

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

    2741:    Logically Collective on SNES

    2743:    Input Parameters:
    2744: +  snes - the SNES context
    2745: -  steps - the number of refinements to do, defaults to 0

    2747:    Options Database Keys:
    2748: .    -snes_grid_sequence <steps>

    2750:    Level: intermediate

    2752:    Notes:
    2753:    Use SNESGetSolution() to extract the fine grid solution after grid sequencing.

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

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

    2759: @*/
    2760: PetscErrorCode  SNESSetGridSequence(SNES snes,PetscInt steps)
    2761: {
    2765:   snes->gridsequence = steps;
    2766:   return(0);
    2767: }

    2771: /*@
    2772:    SNESGetLagPreconditioner - Indicates how often the preconditioner is rebuilt

    2774:    Not Collective

    2776:    Input Parameter:
    2777: .  snes - the SNES context

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

    2783:    Options Database Keys:
    2784: .    -snes_lag_preconditioner <lag>

    2786:    Notes:
    2787:    The default is 1
    2788:    The preconditioner is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1

    2790:    Level: intermediate

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

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

    2796: @*/
    2797: PetscErrorCode  SNESGetLagPreconditioner(SNES snes,PetscInt *lag)
    2798: {
    2801:   *lag = snes->lagpreconditioner;
    2802:   return(0);
    2803: }

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

    2811:    Logically Collective on SNES

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

    2818:    Options Database Keys:
    2819: .    -snes_lag_jacobian <lag>

    2821:    Notes:
    2822:    The default is 1
    2823:    The Jacobian is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1
    2824:    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
    2825:    at the next Newton step but never again (unless it is reset to another value)

    2827:    Level: intermediate

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

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

    2833: @*/
    2834: PetscErrorCode  SNESSetLagJacobian(SNES snes,PetscInt lag)
    2835: {
    2838:   if (lag < -2) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag must be -2, -1, 1 or greater");
    2839:   if (!lag) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag cannot be 0");
    2841:   snes->lagjacobian = lag;
    2842:   return(0);
    2843: }

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

    2850:    Not Collective

    2852:    Input Parameter:
    2853: .  snes - the SNES context

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

    2859:    Options Database Keys:
    2860: .    -snes_lag_jacobian <lag>

    2862:    Notes:
    2863:    The default is 1
    2864:    The jacobian is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1

    2866:    Level: intermediate

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

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

    2872: @*/
    2873: PetscErrorCode  SNESGetLagJacobian(SNES snes,PetscInt *lag)
    2874: {
    2877:   *lag = snes->lagjacobian;
    2878:   return(0);
    2879: }

    2883: /*@
    2884:    SNESSetTolerances - Sets various parameters used in convergence tests.

    2886:    Logically Collective on SNES

    2888:    Input Parameters:
    2889: +  snes - the SNES context
    2890: .  abstol - absolute convergence tolerance
    2891: .  rtol - relative convergence tolerance
    2892: .  stol -  convergence tolerance in terms of the norm of the change in the solution between steps,  || delta x || < stol*|| x ||
    2893: .  maxit - maximum number of iterations
    2894: -  maxf - maximum number of function evaluations

    2896:    Options Database Keys:
    2897: +    -snes_atol <abstol> - Sets abstol
    2898: .    -snes_rtol <rtol> - Sets rtol
    2899: .    -snes_stol <stol> - Sets stol
    2900: .    -snes_max_it <maxit> - Sets maxit
    2901: -    -snes_max_funcs <maxf> - Sets maxf

    2903:    Notes:
    2904:    The default maximum number of iterations is 50.
    2905:    The default maximum number of function evaluations is 1000.

    2907:    Level: intermediate

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

    2911: .seealso: SNESSetTrustRegionTolerance()
    2912: @*/
    2913: PetscErrorCode  SNESSetTolerances(SNES snes,PetscReal abstol,PetscReal rtol,PetscReal stol,PetscInt maxit,PetscInt maxf)
    2914: {

    2923:   if (abstol != PETSC_DEFAULT) {
    2924:     if (abstol < 0.0) SETERRQ1(PetscObjectComm((PetscObject)snes),PETSC_ERR_ARG_OUTOFRANGE,"Absolute tolerance %G must be non-negative",abstol);
    2925:     snes->abstol = abstol;
    2926:   }
    2927:   if (rtol != PETSC_DEFAULT) {
    2928:     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",rtol);
    2929:     snes->rtol = rtol;
    2930:   }
    2931:   if (stol != PETSC_DEFAULT) {
    2932:     if (stol < 0.0) SETERRQ1(PetscObjectComm((PetscObject)snes),PETSC_ERR_ARG_OUTOFRANGE,"Step tolerance %G must be non-negative",stol);
    2933:     snes->stol = stol;
    2934:   }
    2935:   if (maxit != PETSC_DEFAULT) {
    2936:     if (maxit < 0) SETERRQ1(PetscObjectComm((PetscObject)snes),PETSC_ERR_ARG_OUTOFRANGE,"Maximum number of iterations %D must be non-negative",maxit);
    2937:     snes->max_its = maxit;
    2938:   }
    2939:   if (maxf != PETSC_DEFAULT) {
    2940:     if (maxf < 0) SETERRQ1(PetscObjectComm((PetscObject)snes),PETSC_ERR_ARG_OUTOFRANGE,"Maximum number of function evaluations %D must be non-negative",maxf);
    2941:     snes->max_funcs = maxf;
    2942:   }
    2943:   snes->tolerancesset = PETSC_TRUE;
    2944:   return(0);
    2945: }

    2949: /*@
    2950:    SNESGetTolerances - Gets various parameters used in convergence tests.

    2952:    Not Collective

    2954:    Input Parameters:
    2955: +  snes - the SNES context
    2956: .  atol - absolute convergence tolerance
    2957: .  rtol - relative convergence tolerance
    2958: .  stol -  convergence tolerance in terms of the norm
    2959:            of the change in the solution between steps
    2960: .  maxit - maximum number of iterations
    2961: -  maxf - maximum number of function evaluations

    2963:    Notes:
    2964:    The user can specify NULL for any parameter that is not needed.

    2966:    Level: intermediate

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

    2970: .seealso: SNESSetTolerances()
    2971: @*/
    2972: PetscErrorCode  SNESGetTolerances(SNES snes,PetscReal *atol,PetscReal *rtol,PetscReal *stol,PetscInt *maxit,PetscInt *maxf)
    2973: {
    2976:   if (atol)  *atol  = snes->abstol;
    2977:   if (rtol)  *rtol  = snes->rtol;
    2978:   if (stol)  *stol  = snes->stol;
    2979:   if (maxit) *maxit = snes->max_its;
    2980:   if (maxf)  *maxf  = snes->max_funcs;
    2981:   return(0);
    2982: }

    2986: /*@
    2987:    SNESSetTrustRegionTolerance - Sets the trust region parameter tolerance.

    2989:    Logically Collective on SNES

    2991:    Input Parameters:
    2992: +  snes - the SNES context
    2993: -  tol - tolerance

    2995:    Options Database Key:
    2996: .  -snes_trtol <tol> - Sets tol

    2998:    Level: intermediate

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

    3002: .seealso: SNESSetTolerances()
    3003: @*/
    3004: PetscErrorCode  SNESSetTrustRegionTolerance(SNES snes,PetscReal tol)
    3005: {
    3009:   snes->deltatol = tol;
    3010:   return(0);
    3011: }

    3013: /*
    3014:    Duplicate the lg monitors for SNES from KSP; for some reason with
    3015:    dynamic libraries things don't work under Sun4 if we just use
    3016:    macros instead of functions
    3017: */
    3020: PetscErrorCode  SNESMonitorLGResidualNorm(SNES snes,PetscInt it,PetscReal norm,void *ctx)
    3021: {

    3026:   KSPMonitorLGResidualNorm((KSP)snes,it,norm,ctx);
    3027:   return(0);
    3028: }

    3032: PetscErrorCode  SNESMonitorLGCreate(const char host[],const char label[],int x,int y,int m,int n,PetscDrawLG *draw)
    3033: {

    3037:   KSPMonitorLGResidualNormCreate(host,label,x,y,m,n,draw);
    3038:   return(0);
    3039: }

    3043: PetscErrorCode  SNESMonitorLGDestroy(PetscDrawLG *draw)
    3044: {

    3048:   KSPMonitorLGResidualNormDestroy(draw);
    3049:   return(0);
    3050: }

    3052: extern PetscErrorCode  SNESMonitorRange_Private(SNES,PetscInt,PetscReal*);
    3055: PetscErrorCode  SNESMonitorLGRange(SNES snes,PetscInt n,PetscReal rnorm,void *monctx)
    3056: {
    3057:   PetscDrawLG      lg;
    3058:   PetscErrorCode   ierr;
    3059:   PetscReal        x,y,per;
    3060:   PetscViewer      v = (PetscViewer)monctx;
    3061:   static PetscReal prev; /* should be in the context */
    3062:   PetscDraw        draw;

    3065:   PetscViewerDrawGetDrawLG(v,0,&lg);
    3066:   if (!n) {PetscDrawLGReset(lg);}
    3067:   PetscDrawLGGetDraw(lg,&draw);
    3068:   PetscDrawSetTitle(draw,"Residual norm");
    3069:   x    = (PetscReal)n;
    3070:   if (rnorm > 0.0) y = log10(rnorm);
    3071:   else y = -15.0;
    3072:   PetscDrawLGAddPoint(lg,&x,&y);
    3073:   if (n < 20 || !(n % 5)) {
    3074:     PetscDrawLGDraw(lg);
    3075:   }

    3077:   PetscViewerDrawGetDrawLG(v,1,&lg);
    3078:   if (!n) {PetscDrawLGReset(lg);}
    3079:   PetscDrawLGGetDraw(lg,&draw);
    3080:   PetscDrawSetTitle(draw,"% elemts > .2*max elemt");
    3081:    SNESMonitorRange_Private(snes,n,&per);
    3082:   x    = (PetscReal)n;
    3083:   y    = 100.0*per;
    3084:   PetscDrawLGAddPoint(lg,&x,&y);
    3085:   if (n < 20 || !(n % 5)) {
    3086:     PetscDrawLGDraw(lg);
    3087:   }

    3089:   PetscViewerDrawGetDrawLG(v,2,&lg);
    3090:   if (!n) {prev = rnorm;PetscDrawLGReset(lg);}
    3091:   PetscDrawLGGetDraw(lg,&draw);
    3092:   PetscDrawSetTitle(draw,"(norm -oldnorm)/oldnorm");
    3093:   x    = (PetscReal)n;
    3094:   y    = (prev - rnorm)/prev;
    3095:   PetscDrawLGAddPoint(lg,&x,&y);
    3096:   if (n < 20 || !(n % 5)) {
    3097:     PetscDrawLGDraw(lg);
    3098:   }

    3100:   PetscViewerDrawGetDrawLG(v,3,&lg);
    3101:   if (!n) {PetscDrawLGReset(lg);}
    3102:   PetscDrawLGGetDraw(lg,&draw);
    3103:   PetscDrawSetTitle(draw,"(norm -oldnorm)/oldnorm*(% > .2 max)");
    3104:   x    = (PetscReal)n;
    3105:   y    = (prev - rnorm)/(prev*per);
    3106:   if (n > 2) { /*skip initial crazy value */
    3107:     PetscDrawLGAddPoint(lg,&x,&y);
    3108:   }
    3109:   if (n < 20 || !(n % 5)) {
    3110:     PetscDrawLGDraw(lg);
    3111:   }
    3112:   prev = rnorm;
    3113:   return(0);
    3114: }

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

    3121:    Collective on SNES

    3123:    Input Parameters:
    3124: +  snes - nonlinear solver context obtained from SNESCreate()
    3125: .  iter - iteration number
    3126: -  rnorm - relative norm of the residual

    3128:    Notes:
    3129:    This routine is called by the SNES implementations.
    3130:    It does not typically need to be called by the user.

    3132:    Level: developer

    3134: .seealso: SNESMonitorSet()
    3135: @*/
    3136: PetscErrorCode  SNESMonitor(SNES snes,PetscInt iter,PetscReal rnorm)
    3137: {
    3139:   PetscInt       i,n = snes->numbermonitors;

    3142:   for (i=0; i<n; i++) {
    3143:     (*snes->monitor[i])(snes,iter,rnorm,snes->monitorcontext[i]);
    3144:   }
    3145:   return(0);
    3146: }

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

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

    3153:      Synopsis:
    3154:      #include "petscsnes.h"
    3155: $    PetscErrorCode SNESMonitorFunction(SNES snes,PetscInt its, PetscReal norm,void *mctx)

    3157: +    snes - the SNES context
    3158: .    its - iteration number
    3159: .    norm - 2-norm function value (may be estimated)
    3160: -    mctx - [optional] monitoring context

    3162:    Level: advanced

    3164: .seealso:   SNESMonitorSet(), SNESMonitorGet()
    3165: M*/

    3169: /*@C
    3170:    SNESMonitorSet - Sets an ADDITIONAL function that is to be used at every
    3171:    iteration of the nonlinear solver to display the iteration's
    3172:    progress.

    3174:    Logically Collective on SNES

    3176:    Input Parameters:
    3177: +  snes - the SNES context
    3178: .  SNESMonitorFunction - monitoring routine
    3179: .  mctx - [optional] user-defined context for private data for the
    3180:           monitor routine (use NULL if no context is desired)
    3181: -  monitordestroy - [optional] routine that frees monitor context
    3182:           (may be NULL)

    3184:    Options Database Keys:
    3185: +    -snes_monitor        - sets SNESMonitorDefault()
    3186: .    -snes_monitor_lg_residualnorm    - sets line graph monitor,
    3187:                             uses SNESMonitorLGCreate()
    3188: -    -snes_monitor_cancel - cancels all monitors that have
    3189:                             been hardwired into a code by
    3190:                             calls to SNESMonitorSet(), but
    3191:                             does not cancel those set via
    3192:                             the options database.

    3194:    Notes:
    3195:    Several different monitoring routines may be set by calling
    3196:    SNESMonitorSet() multiple times; all will be called in the
    3197:    order in which they were set.

    3199:    Fortran notes: Only a single monitor function can be set for each SNES object

    3201:    Level: intermediate

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

    3205: .seealso: SNESMonitorDefault(), SNESMonitorCancel(), SNESMonitorFunction
    3206: @*/
    3207: PetscErrorCode  SNESMonitorSet(SNES snes,PetscErrorCode (*SNESMonitorFunction)(SNES,PetscInt,PetscReal,void*),void *mctx,PetscErrorCode (*monitordestroy)(void**))
    3208: {
    3209:   PetscInt       i;

    3214:   if (snes->numbermonitors >= MAXSNESMONITORS) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Too many monitors set");
    3215:   for (i=0; i<snes->numbermonitors;i++) {
    3216:     if (SNESMonitorFunction == snes->monitor[i] && monitordestroy == snes->monitordestroy[i] && mctx == snes->monitorcontext[i]) {
    3217:       if (monitordestroy) {
    3218:         (*monitordestroy)(&mctx);
    3219:       }
    3220:       return(0);
    3221:     }
    3222:   }
    3223:   snes->monitor[snes->numbermonitors]          = SNESMonitorFunction;
    3224:   snes->monitordestroy[snes->numbermonitors]   = monitordestroy;
    3225:   snes->monitorcontext[snes->numbermonitors++] = (void*)mctx;
    3226:   return(0);
    3227: }

    3231: /*@C
    3232:    SNESMonitorCancel - Clears all the monitor functions for a SNES object.

    3234:    Logically Collective on SNES

    3236:    Input Parameters:
    3237: .  snes - the SNES context

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

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

    3247:    Level: intermediate

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

    3251: .seealso: SNESMonitorDefault(), SNESMonitorSet()
    3252: @*/
    3253: PetscErrorCode  SNESMonitorCancel(SNES snes)
    3254: {
    3256:   PetscInt       i;

    3260:   for (i=0; i<snes->numbermonitors; i++) {
    3261:     if (snes->monitordestroy[i]) {
    3262:       (*snes->monitordestroy[i])(&snes->monitorcontext[i]);
    3263:     }
    3264:   }
    3265:   snes->numbermonitors = 0;
    3266:   return(0);
    3267: }

    3269: /*MC
    3270:     SNESConvergenceTestFunction - functional form used for testing of convergence of nonlinear solver

    3272:      Synopsis:
    3273:      #include "petscsnes.h"
    3274: $     PetscErrorCode SNESConvergenceTest(SNES snes,PetscInt it,PetscReal xnorm,PetscReal gnorm,PetscReal f,SNESConvergedReason *reason,void *cctx)

    3276: +    snes - the SNES context
    3277: .    it - current iteration (0 is the first and is before any Newton step)
    3278: .    cctx - [optional] convergence context
    3279: .    reason - reason for convergence/divergence
    3280: .    xnorm - 2-norm of current iterate
    3281: .    gnorm - 2-norm of current step
    3282: -    f - 2-norm of function

    3284:    Level: intermediate

    3286: .seealso:   SNESSetConvergenceTest(), SNESGetConvergenceTest()
    3287: M*/

    3291: /*@C
    3292:    SNESSetConvergenceTest - Sets the function that is to be used
    3293:    to test for convergence of the nonlinear iterative solution.

    3295:    Logically Collective on SNES

    3297:    Input Parameters:
    3298: +  snes - the SNES context
    3299: .  SNESConvergenceTestFunction - routine to test for convergence
    3300: .  cctx - [optional] context for private data for the convergence routine  (may be NULL)
    3301: -  destroy - [optional] destructor for the context (may be NULL; NULL_FUNCTION in Fortran)

    3303:    Level: advanced

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

    3307: .seealso: SNESConvergedDefault(), SNESSkipConverged(), SNESConvergenceTestFunction
    3308: @*/
    3309: PetscErrorCode  SNESSetConvergenceTest(SNES snes,PetscErrorCode (*SNESConvergenceTestFunction)(SNES,PetscInt,PetscReal,PetscReal,PetscReal,SNESConvergedReason*,void*),void *cctx,PetscErrorCode (*destroy)(void*))
    3310: {

    3315:   if (!SNESConvergenceTestFunction) SNESConvergenceTestFunction = SNESSkipConverged;
    3316:   if (snes->ops->convergeddestroy) {
    3317:     (*snes->ops->convergeddestroy)(snes->cnvP);
    3318:   }
    3319:   snes->ops->converged        = SNESConvergenceTestFunction;
    3320:   snes->ops->convergeddestroy = destroy;
    3321:   snes->cnvP                  = cctx;
    3322:   return(0);
    3323: }

    3327: /*@
    3328:    SNESGetConvergedReason - Gets the reason the SNES iteration was stopped.

    3330:    Not Collective

    3332:    Input Parameter:
    3333: .  snes - the SNES context

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

    3339:    Level: intermediate

    3341:    Notes: Can only be called after the call the SNESSolve() is complete.

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

    3345: .seealso: SNESSetConvergenceTest(), SNESConvergedReason
    3346: @*/
    3347: PetscErrorCode  SNESGetConvergedReason(SNES snes,SNESConvergedReason *reason)
    3348: {
    3352:   *reason = snes->reason;
    3353:   return(0);
    3354: }

    3358: /*@
    3359:    SNESSetConvergenceHistory - Sets the array used to hold the convergence history.

    3361:    Logically Collective on SNES

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

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

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

    3379:    Level: intermediate

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

    3383: .seealso: SNESGetConvergenceHistory()

    3385: @*/
    3386: PetscErrorCode  SNESSetConvergenceHistory(SNES snes,PetscReal a[],PetscInt its[],PetscInt na,PetscBool reset)
    3387: {

    3394:   if (!a) {
    3395:     if (na == PETSC_DECIDE || na == PETSC_DEFAULT) na = 1000;
    3396:     PetscMalloc(na*sizeof(PetscReal),&a);
    3397:     PetscMalloc(na*sizeof(PetscInt),&its);

    3399:     snes->conv_malloc = PETSC_TRUE;
    3400:   }
    3401:   snes->conv_hist       = a;
    3402:   snes->conv_hist_its   = its;
    3403:   snes->conv_hist_max   = na;
    3404:   snes->conv_hist_len   = 0;
    3405:   snes->conv_hist_reset = reset;
    3406:   return(0);
    3407: }

    3409: #if defined(PETSC_HAVE_MATLAB_ENGINE)
    3410: #include <engine.h>   /* MATLAB include file */
    3411: #include <mex.h>      /* MATLAB include file */

    3415: PETSC_EXTERN mxArray *SNESGetConvergenceHistoryMatlab(SNES snes)
    3416: {
    3417:   mxArray   *mat;
    3418:   PetscInt  i;
    3419:   PetscReal *ar;

    3422:   mat = mxCreateDoubleMatrix(snes->conv_hist_len,1,mxREAL);
    3423:   ar  = (PetscReal*) mxGetData(mat);
    3424:   for (i=0; i<snes->conv_hist_len; i++) ar[i] = snes->conv_hist[i];
    3425:   PetscFunctionReturn(mat);
    3426: }
    3427: #endif

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

    3434:    Not Collective

    3436:    Input Parameter:
    3437: .  snes - iterative context obtained from SNESCreate()

    3439:    Output Parameters:
    3440: .  a   - array to hold history
    3441: .  its - integer array holds the number of linear iterations (or
    3442:          negative if not converged) for each solve.
    3443: -  na  - size of a and its

    3445:    Notes:
    3446:     The calling sequence for this routine in Fortran is
    3447: $   call SNESGetConvergenceHistory(SNES snes, integer na, integer ierr)

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

    3453:    Level: intermediate

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

    3457: .seealso: SNESSetConvergencHistory()

    3459: @*/
    3460: PetscErrorCode  SNESGetConvergenceHistory(SNES snes,PetscReal *a[],PetscInt *its[],PetscInt *na)
    3461: {
    3464:   if (a)   *a   = snes->conv_hist;
    3465:   if (its) *its = snes->conv_hist_its;
    3466:   if (na)  *na  = snes->conv_hist_len;
    3467:   return(0);
    3468: }

    3472: /*@C
    3473:   SNESSetUpdate - Sets the general-purpose update function called
    3474:   at the beginning of every iteration of the nonlinear solve. Specifically
    3475:   it is called just before the Jacobian is "evaluated".

    3477:   Logically Collective on SNES

    3479:   Input Parameters:
    3480: . snes - The nonlinear solver context
    3481: . func - The function

    3483:   Calling sequence of func:
    3484: . func (SNES snes, PetscInt step);

    3486: . step - The current step of the iteration

    3488:   Level: advanced

    3490:   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()
    3491:         This is not used by most users.

    3493: .keywords: SNES, update

    3495: .seealso SNESSetJacobian(), SNESSolve()
    3496: @*/
    3497: PetscErrorCode  SNESSetUpdate(SNES snes, PetscErrorCode (*func)(SNES, PetscInt))
    3498: {
    3501:   snes->ops->update = func;
    3502:   return(0);
    3503: }

    3507: /*
    3508:    SNESScaleStep_Private - Scales a step so that its length is less than the
    3509:    positive parameter delta.

    3511:     Input Parameters:
    3512: +   snes - the SNES context
    3513: .   y - approximate solution of linear system
    3514: .   fnorm - 2-norm of current function
    3515: -   delta - trust region size

    3517:     Output Parameters:
    3518: +   gpnorm - predicted function norm at the new point, assuming local
    3519:     linearization.  The value is zero if the step lies within the trust
    3520:     region, and exceeds zero otherwise.
    3521: -   ynorm - 2-norm of the step

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

    3527: .keywords: SNES, nonlinear, scale, step
    3528: */
    3529: PetscErrorCode SNESScaleStep_Private(SNES snes,Vec y,PetscReal *fnorm,PetscReal *delta,PetscReal *gpnorm,PetscReal *ynorm)
    3530: {
    3531:   PetscReal      nrm;
    3532:   PetscScalar    cnorm;

    3540:   VecNorm(y,NORM_2,&nrm);
    3541:   if (nrm > *delta) {
    3542:     nrm     = *delta/nrm;
    3543:     *gpnorm = (1.0 - nrm)*(*fnorm);
    3544:     cnorm   = nrm;
    3545:     VecScale(y,cnorm);
    3546:     *ynorm  = *delta;
    3547:   } else {
    3548:     *gpnorm = 0.0;
    3549:     *ynorm  = nrm;
    3550:   }
    3551:   return(0);
    3552: }

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

    3560:    Collective on SNES

    3562:    Input Parameters:
    3563: +  snes - the SNES context
    3564: .  b - the constant part of the equation F(x) = b, or NULL to use zero.
    3565: -  x - the solution vector.

    3567:    Notes:
    3568:    The user should initialize the vector,x, with the initial guess
    3569:    for the nonlinear solve prior to calling SNESSolve.  In particular,
    3570:    to employ an initial guess of zero, the user should explicitly set
    3571:    this vector to zero by calling VecSet().

    3573:    Level: beginner

    3575: .keywords: SNES, nonlinear, solve

    3577: .seealso: SNESCreate(), SNESDestroy(), SNESSetFunction(), SNESSetJacobian(), SNESSetGridSequence(), SNESGetSolution()
    3578: @*/
    3579: PetscErrorCode  SNESSolve(SNES snes,Vec b,Vec x)
    3580: {
    3581:   PetscErrorCode    ierr;
    3582:   PetscBool         flg;
    3583:   PetscViewer       viewer;
    3584:   PetscInt          grid;
    3585:   Vec               xcreated = NULL;
    3586:   DM                dm;
    3587:   PetscViewerFormat format;

    3596:   if (!x) {
    3597:     SNESGetDM(snes,&dm);
    3598:     DMCreateGlobalVector(dm,&xcreated);
    3599:     x    = xcreated;
    3600:   }

    3602:   PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes),((PetscObject)snes)->prefix,"-snes_view_pre",&viewer,&format,&flg);
    3603:   if (flg && !PetscPreLoadingOn) {
    3604:     PetscViewerPushFormat(viewer,format);
    3605:     SNESView(snes,viewer);
    3606:     PetscViewerPopFormat(viewer);
    3607:     PetscViewerDestroy(&viewer);
    3608:   }

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

    3613:     /* set solution vector */
    3614:     if (!grid) {PetscObjectReference((PetscObject)x);}
    3615:     VecDestroy(&snes->vec_sol);
    3616:     snes->vec_sol = x;
    3617:     SNESGetDM(snes,&dm);

    3619:     /* set affine vector if provided */
    3620:     if (b) { PetscObjectReference((PetscObject)b); }
    3621:     VecDestroy(&snes->vec_rhs);
    3622:     snes->vec_rhs = b;

    3624:     SNESSetUp(snes);

    3626:     if (!grid) {
    3627:       if (snes->ops->computeinitialguess) {
    3628:         (*snes->ops->computeinitialguess)(snes,snes->vec_sol,snes->initialguessP);
    3629:       }
    3630:     }

    3632:     if (snes->conv_hist_reset) snes->conv_hist_len = 0;
    3633:     snes->nfuncs = 0; snes->linear_its = 0; snes->numFailures = 0;

    3635:     PetscLogEventBegin(SNES_Solve,snes,0,0,0);
    3636:     (*snes->ops->solve)(snes);
    3637:     PetscLogEventEnd(SNES_Solve,snes,0,0,0);
    3638:     if (snes->domainerror) {
    3639:       snes->reason      = SNES_DIVERGED_FUNCTION_DOMAIN;
    3640:       snes->domainerror = PETSC_FALSE;
    3641:     }
    3642:     if (!snes->reason) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Internal error, solver returned without setting converged reason");

    3644:     flg  = PETSC_FALSE;
    3645:     PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_test_local_min",&flg,NULL);
    3646:     if (flg && !PetscPreLoadingOn) { SNESTestLocalMin(snes); }
    3647:     if (snes->printreason) {
    3648:       PetscViewerASCIIAddTab(PETSC_VIEWER_STDOUT_(PetscObjectComm((PetscObject)snes)),((PetscObject)snes)->tablevel);
    3649:       if (snes->reason > 0) {
    3650:         PetscViewerASCIIPrintf(PETSC_VIEWER_STDOUT_(PetscObjectComm((PetscObject)snes)),"Nonlinear solve converged due to %s iterations %D\n",SNESConvergedReasons[snes->reason],snes->iter);
    3651:       } else {
    3652:         PetscViewerASCIIPrintf(PETSC_VIEWER_STDOUT_(PetscObjectComm((PetscObject)snes)),"Nonlinear solve did not converge due to %s iterations %D\n",SNESConvergedReasons[snes->reason],snes->iter);
    3653:       }
    3654:       PetscViewerASCIISubtractTab(PETSC_VIEWER_STDOUT_(PetscObjectComm((PetscObject)snes)),((PetscObject)snes)->tablevel);
    3655:     }

    3657:     if (snes->errorifnotconverged && snes->reason < 0) SETERRQ(PetscObjectComm((PetscObject)snes),PETSC_ERR_NOT_CONVERGED,"SNESSolve has not converged");
    3658:     if (grid <  snes->gridsequence) {
    3659:       DM  fine;
    3660:       Vec xnew;
    3661:       Mat interp;

    3663:       DMRefine(snes->dm,PetscObjectComm((PetscObject)snes),&fine);
    3664:       if (!fine) SETERRQ(PetscObjectComm((PetscObject)snes),PETSC_ERR_ARG_INCOMP,"DMRefine() did not perform any refinement, cannot continue grid sequencing");
    3665:       DMCreateInterpolation(snes->dm,fine,&interp,NULL);
    3666:       DMCreateGlobalVector(fine,&xnew);
    3667:       MatInterpolate(interp,x,xnew);
    3668:       DMInterpolate(snes->dm,interp,fine);
    3669:       MatDestroy(&interp);
    3670:       x    = xnew;

    3672:       SNESReset(snes);
    3673:       SNESSetDM(snes,fine);
    3674:       DMDestroy(&fine);
    3675:       PetscViewerASCIIPopTab(PETSC_VIEWER_STDOUT_(PetscObjectComm((PetscObject)snes)));
    3676:     }
    3677:   }
    3678:   /* monitoring and viewing */
    3679:   PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes),((PetscObject)snes)->prefix,"-snes_view",&viewer,&format,&flg);
    3680:   if (flg && !PetscPreLoadingOn) {
    3681:     PetscViewerPushFormat(viewer,format);
    3682:     SNESView(snes,viewer);
    3683:     PetscViewerPopFormat(viewer);
    3684:     PetscViewerDestroy(&viewer);
    3685:   }
    3686:   VecViewFromOptions(snes->vec_sol,((PetscObject)snes)->prefix,"-snes_view_solution");

    3688:   VecDestroy(&xcreated);
    3689:   PetscObjectAMSBlock((PetscObject)snes);
    3690:   return(0);
    3691: }

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

    3697: /*@C
    3698:    SNESSetType - Sets the method for the nonlinear solver.

    3700:    Collective on SNES

    3702:    Input Parameters:
    3703: +  snes - the SNES context
    3704: -  type - a known method

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

    3710:    Notes:
    3711:    See "petsc/include/petscsnes.h" for available methods (for instance)
    3712: +    SNESNEWTONLS - Newton's method with line search
    3713:      (systems of nonlinear equations)
    3714: .    SNESNEWTONTR - Newton's method with trust region
    3715:      (systems of nonlinear equations)

    3717:   Normally, it is best to use the SNESSetFromOptions() command and then
    3718:   set the SNES solver type from the options database rather than by using
    3719:   this routine.  Using the options database provides the user with
    3720:   maximum flexibility in evaluating the many nonlinear solvers.
    3721:   The SNESSetType() routine is provided for those situations where it
    3722:   is necessary to set the nonlinear solver independently of the command
    3723:   line or options database.  This might be the case, for example, when
    3724:   the choice of solver changes during the execution of the program,
    3725:   and the user's application is taking responsibility for choosing the
    3726:   appropriate method.

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

    3731:   Level: intermediate

    3733: .keywords: SNES, set, type

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

    3737: @*/
    3738: PetscErrorCode  SNESSetType(SNES snes,SNESType type)
    3739: {
    3740:   PetscErrorCode ierr,(*r)(SNES);
    3741:   PetscBool      match;

    3747:   PetscObjectTypeCompare((PetscObject)snes,type,&match);
    3748:   if (match) return(0);

    3750:    PetscFunctionListFind(SNESList,type,&r);
    3751:   if (!r) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_UNKNOWN_TYPE,"Unable to find requested SNES type %s",type);
    3752:   /* Destroy the previous private SNES context */
    3753:   if (snes->ops->destroy) {
    3754:     (*(snes)->ops->destroy)(snes);
    3755:     snes->ops->destroy = NULL;
    3756:   }
    3757:   /* Reinitialize function pointers in SNESOps structure */
    3758:   snes->ops->setup          = 0;
    3759:   snes->ops->solve          = 0;
    3760:   snes->ops->view           = 0;
    3761:   snes->ops->setfromoptions = 0;
    3762:   snes->ops->destroy        = 0;
    3763:   /* Call the SNESCreate_XXX routine for this particular Nonlinear solver */
    3764:   snes->setupcalled = PETSC_FALSE;

    3766:   PetscObjectChangeTypeName((PetscObject)snes,type);
    3767:   (*r)(snes);
    3768:   return(0);
    3769: }

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

    3776:    Not Collective

    3778:    Input Parameter:
    3779: .  snes - nonlinear solver context

    3781:    Output Parameter:
    3782: .  type - SNES method (a character string)

    3784:    Level: intermediate

    3786: .keywords: SNES, nonlinear, get, type, name
    3787: @*/
    3788: PetscErrorCode  SNESGetType(SNES snes,SNESType *type)
    3789: {
    3793:   *type = ((PetscObject)snes)->type_name;
    3794:   return(0);
    3795: }

    3799: /*@
    3800:    SNESGetSolution - Returns the vector where the approximate solution is
    3801:    stored. This is the fine grid solution when using SNESSetGridSequence().

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

    3805:    Input Parameter:
    3806: .  snes - the SNES context

    3808:    Output Parameter:
    3809: .  x - the solution

    3811:    Level: intermediate

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

    3815: .seealso:  SNESGetSolutionUpdate(), SNESGetFunction()
    3816: @*/
    3817: PetscErrorCode  SNESGetSolution(SNES snes,Vec *x)
    3818: {
    3822:   *x = snes->vec_sol;
    3823:   return(0);
    3824: }

    3828: /*@
    3829:    SNESGetSolutionUpdate - Returns the vector where the solution update is
    3830:    stored.

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

    3834:    Input Parameter:
    3835: .  snes - the SNES context

    3837:    Output Parameter:
    3838: .  x - the solution update

    3840:    Level: advanced

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

    3844: .seealso: SNESGetSolution(), SNESGetFunction()
    3845: @*/
    3846: PetscErrorCode  SNESGetSolutionUpdate(SNES snes,Vec *x)
    3847: {
    3851:   *x = snes->vec_sol_update;
    3852:   return(0);
    3853: }

    3857: /*@C
    3858:    SNESGetFunction - Returns the vector where the function is stored.

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

    3862:    Input Parameter:
    3863: .  snes - the SNES context

    3865:    Output Parameter:
    3866: +  r - the vector that is used to store residuals (or NULL if you don't want it)
    3867: .  SNESFunction- the function (or NULL if you don't want it)
    3868: -  ctx - the function context (or NULL if you don't want it)

    3870:    Level: advanced

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

    3874: .seealso: SNESSetFunction(), SNESGetSolution(), SNESFunction
    3875: @*/
    3876: PetscErrorCode  SNESGetFunction(SNES snes,Vec *r,PetscErrorCode (**SNESFunction)(SNES,Vec,Vec,void*),void **ctx)
    3877: {
    3879:   DM             dm;

    3883:   if (r) {
    3884:     if (!snes->vec_func) {
    3885:       if (snes->vec_rhs) {
    3886:         VecDuplicate(snes->vec_rhs,&snes->vec_func);
    3887:       } else if (snes->vec_sol) {
    3888:         VecDuplicate(snes->vec_sol,&snes->vec_func);
    3889:       } else if (snes->dm) {
    3890:         DMCreateGlobalVector(snes->dm,&snes->vec_func);
    3891:       }
    3892:     }
    3893:     *r = snes->vec_func;
    3894:   }
    3895:   SNESGetDM(snes,&dm);
    3896:   DMSNESGetFunction(dm,SNESFunction,ctx);
    3897:   return(0);
    3898: }

    3900: /*@C
    3901:    SNESGetGS - Returns the GS function and context.

    3903:    Input Parameter:
    3904: .  snes - the SNES context

    3906:    Output Parameter:
    3907: +  SNESGSFunction - the function (or NULL)
    3908: -  ctx    - the function context (or NULL)

    3910:    Level: advanced

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

    3914: .seealso: SNESSetGS(), SNESGetFunction()
    3915: @*/

    3919: PetscErrorCode SNESGetGS (SNES snes, PetscErrorCode (**SNESGSFunction)(SNES, Vec, Vec, void*), void ** ctx)
    3920: {
    3922:   DM             dm;

    3926:   SNESGetDM(snes,&dm);
    3927:   DMSNESGetGS(dm,SNESGSFunction,ctx);
    3928:   return(0);
    3929: }

    3933: /*@C
    3934:    SNESSetOptionsPrefix - Sets the prefix used for searching for all
    3935:    SNES options in the database.

    3937:    Logically Collective on SNES

    3939:    Input Parameter:
    3940: +  snes - the SNES context
    3941: -  prefix - the prefix to prepend to all option names

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

    3947:    Level: advanced

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

    3951: .seealso: SNESSetFromOptions()
    3952: @*/
    3953: PetscErrorCode  SNESSetOptionsPrefix(SNES snes,const char prefix[])
    3954: {

    3959:   PetscObjectSetOptionsPrefix((PetscObject)snes,prefix);
    3960:   if (!snes->ksp) {SNESGetKSP(snes,&snes->ksp);}
    3961:   if (snes->linesearch) {
    3962:     SNESGetLineSearch(snes,&snes->linesearch);
    3963:     PetscObjectSetOptionsPrefix((PetscObject)snes->linesearch,prefix);
    3964:   }
    3965:   KSPSetOptionsPrefix(snes->ksp,prefix);
    3966:   return(0);
    3967: }

    3971: /*@C
    3972:    SNESAppendOptionsPrefix - Appends to the prefix used for searching for all
    3973:    SNES options in the database.

    3975:    Logically Collective on SNES

    3977:    Input Parameters:
    3978: +  snes - the SNES context
    3979: -  prefix - the prefix to prepend to all option names

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

    3985:    Level: advanced

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

    3989: .seealso: SNESGetOptionsPrefix()
    3990: @*/
    3991: PetscErrorCode  SNESAppendOptionsPrefix(SNES snes,const char prefix[])
    3992: {

    3997:   PetscObjectAppendOptionsPrefix((PetscObject)snes,prefix);
    3998:   if (!snes->ksp) {SNESGetKSP(snes,&snes->ksp);}
    3999:   if (snes->linesearch) {
    4000:     SNESGetLineSearch(snes,&snes->linesearch);
    4001:     PetscObjectAppendOptionsPrefix((PetscObject)snes->linesearch,prefix);
    4002:   }
    4003:   KSPAppendOptionsPrefix(snes->ksp,prefix);
    4004:   return(0);
    4005: }

    4009: /*@C
    4010:    SNESGetOptionsPrefix - Sets the prefix used for searching for all
    4011:    SNES options in the database.

    4013:    Not Collective

    4015:    Input Parameter:
    4016: .  snes - the SNES context

    4018:    Output Parameter:
    4019: .  prefix - pointer to the prefix string used

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

    4024:    Level: advanced

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

    4028: .seealso: SNESAppendOptionsPrefix()
    4029: @*/
    4030: PetscErrorCode  SNESGetOptionsPrefix(SNES snes,const char *prefix[])
    4031: {

    4036:   PetscObjectGetOptionsPrefix((PetscObject)snes,prefix);
    4037:   return(0);
    4038: }

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

    4046:    Not collective

    4048:    Input Parameters:
    4049: +  name_solver - name of a new user-defined solver
    4050: -  routine_create - routine to create method context

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

    4055:    Sample usage:
    4056: .vb
    4057:    SNESRegister("my_solver",MySolverCreate);
    4058: .ve

    4060:    Then, your solver can be chosen with the procedural interface via
    4061: $     SNESSetType(snes,"my_solver")
    4062:    or at runtime via the option
    4063: $     -snes_type my_solver

    4065:    Level: advanced

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

    4069: .keywords: SNES, nonlinear, register

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

    4073:   Level: advanced
    4074: @*/
    4075: PetscErrorCode  SNESRegister(const char sname[],PetscErrorCode (*function)(SNES))
    4076: {

    4080:   PetscFunctionListAdd(&SNESList,sname,function);
    4081:   return(0);
    4082: }

    4086: PetscErrorCode  SNESTestLocalMin(SNES snes)
    4087: {
    4089:   PetscInt       N,i,j;
    4090:   Vec            u,uh,fh;
    4091:   PetscScalar    value;
    4092:   PetscReal      norm;

    4095:   SNESGetSolution(snes,&u);
    4096:   VecDuplicate(u,&uh);
    4097:   VecDuplicate(u,&fh);

    4099:   /* currently only works for sequential */
    4100:   PetscPrintf(PETSC_COMM_WORLD,"Testing FormFunction() for local min\n");
    4101:   VecGetSize(u,&N);
    4102:   for (i=0; i<N; i++) {
    4103:     VecCopy(u,uh);
    4104:     PetscPrintf(PETSC_COMM_WORLD,"i = %D\n",i);
    4105:     for (j=-10; j<11; j++) {
    4106:       value = PetscSign(j)*exp(PetscAbs(j)-10.0);
    4107:       VecSetValue(uh,i,value,ADD_VALUES);
    4108:       SNESComputeFunction(snes,uh,fh);
    4109:       VecNorm(fh,NORM_2,&norm);
    4110:       PetscPrintf(PETSC_COMM_WORLD,"       j norm %D %18.16e\n",j,norm);
    4111:       value = -value;
    4112:       VecSetValue(uh,i,value,ADD_VALUES);
    4113:     }
    4114:   }
    4115:   VecDestroy(&uh);
    4116:   VecDestroy(&fh);
    4117:   return(0);
    4118: }

    4122: /*@
    4123:    SNESKSPSetUseEW - Sets SNES use Eisenstat-Walker method for
    4124:    computing relative tolerance for linear solvers within an inexact
    4125:    Newton method.

    4127:    Logically Collective on SNES

    4129:    Input Parameters:
    4130: +  snes - SNES context
    4131: -  flag - PETSC_TRUE or PETSC_FALSE

    4133:     Options Database:
    4134: +  -snes_ksp_ew - use Eisenstat-Walker method for determining linear system convergence
    4135: .  -snes_ksp_ew_version ver - version of  Eisenstat-Walker method
    4136: .  -snes_ksp_ew_rtol0 <rtol0> - Sets rtol0
    4137: .  -snes_ksp_ew_rtolmax <rtolmax> - Sets rtolmax
    4138: .  -snes_ksp_ew_gamma <gamma> - Sets gamma
    4139: .  -snes_ksp_ew_alpha <alpha> - Sets alpha
    4140: .  -snes_ksp_ew_alpha2 <alpha2> - Sets alpha2
    4141: -  -snes_ksp_ew_threshold <threshold> - Sets threshold

    4143:    Notes:
    4144:    Currently, the default is to use a constant relative tolerance for
    4145:    the inner linear solvers.  Alternatively, one can use the
    4146:    Eisenstat-Walker method, where the relative convergence tolerance
    4147:    is reset at each Newton iteration according progress of the nonlinear
    4148:    solver.

    4150:    Level: advanced

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

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

    4158: .seealso: SNESKSPGetUseEW(), SNESKSPGetParametersEW(), SNESKSPSetParametersEW()
    4159: @*/
    4160: PetscErrorCode  SNESKSPSetUseEW(SNES snes,PetscBool flag)
    4161: {
    4165:   snes->ksp_ewconv = flag;
    4166:   return(0);
    4167: }

    4171: /*@
    4172:    SNESKSPGetUseEW - Gets if SNES is using Eisenstat-Walker method
    4173:    for computing relative tolerance for linear solvers within an
    4174:    inexact Newton method.

    4176:    Not Collective

    4178:    Input Parameter:
    4179: .  snes - SNES context

    4181:    Output Parameter:
    4182: .  flag - PETSC_TRUE or PETSC_FALSE

    4184:    Notes:
    4185:    Currently, the default is to use a constant relative tolerance for
    4186:    the inner linear solvers.  Alternatively, one can use the
    4187:    Eisenstat-Walker method, where the relative convergence tolerance
    4188:    is reset at each Newton iteration according progress of the nonlinear
    4189:    solver.

    4191:    Level: advanced

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

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

    4199: .seealso: SNESKSPSetUseEW(), SNESKSPGetParametersEW(), SNESKSPSetParametersEW()
    4200: @*/
    4201: PetscErrorCode  SNESKSPGetUseEW(SNES snes, PetscBool  *flag)
    4202: {
    4206:   *flag = snes->ksp_ewconv;
    4207:   return(0);
    4208: }

    4212: /*@
    4213:    SNESKSPSetParametersEW - Sets parameters for Eisenstat-Walker
    4214:    convergence criteria for the linear solvers within an inexact
    4215:    Newton method.

    4217:    Logically Collective on SNES

    4219:    Input Parameters:
    4220: +    snes - SNES context
    4221: .    version - version 1, 2 (default is 2) or 3
    4222: .    rtol_0 - initial relative tolerance (0 <= rtol_0 < 1)
    4223: .    rtol_max - maximum relative tolerance (0 <= rtol_max < 1)
    4224: .    gamma - multiplicative factor for version 2 rtol computation
    4225:              (0 <= gamma2 <= 1)
    4226: .    alpha - power for version 2 rtol computation (1 < alpha <= 2)
    4227: .    alpha2 - power for safeguard
    4228: -    threshold - threshold for imposing safeguard (0 < threshold < 1)

    4230:    Note:
    4231:    Version 3 was contributed by Luis Chacon, June 2006.

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

    4235:    Level: advanced

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

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

    4244: .seealso: SNESKSPSetUseEW(), SNESKSPGetUseEW(), SNESKSPGetParametersEW()
    4245: @*/
    4246: PetscErrorCode  SNESKSPSetParametersEW(SNES snes,PetscInt version,PetscReal rtol_0,PetscReal rtol_max,PetscReal gamma,PetscReal alpha,PetscReal alpha2,PetscReal threshold)
    4247: {
    4248:   SNESKSPEW *kctx;

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

    4262:   if (version != PETSC_DEFAULT)   kctx->version   = version;
    4263:   if (rtol_0 != PETSC_DEFAULT)    kctx->rtol_0    = rtol_0;
    4264:   if (rtol_max != PETSC_DEFAULT)  kctx->rtol_max  = rtol_max;
    4265:   if (gamma != PETSC_DEFAULT)     kctx->gamma     = gamma;
    4266:   if (alpha != PETSC_DEFAULT)     kctx->alpha     = alpha;
    4267:   if (alpha2 != PETSC_DEFAULT)    kctx->alpha2    = alpha2;
    4268:   if (threshold != PETSC_DEFAULT) kctx->threshold = threshold;

    4270:   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);
    4271:   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",kctx->rtol_0);
    4272:   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",kctx->rtol_max);
    4273:   if (kctx->gamma < 0.0 || kctx->gamma > 1.0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"0.0 <= gamma (%G) <= 1.0\n",kctx->gamma);
    4274:   if (kctx->alpha <= 1.0 || kctx->alpha > 2.0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"1.0 < alpha (%G) <= 2.0\n",kctx->alpha);
    4275:   if (kctx->threshold <= 0.0 || kctx->threshold >= 1.0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"0.0 < threshold (%G) < 1.0\n",kctx->threshold);
    4276:   return(0);
    4277: }

    4281: /*@
    4282:    SNESKSPGetParametersEW - Gets parameters for Eisenstat-Walker
    4283:    convergence criteria for the linear solvers within an inexact
    4284:    Newton method.

    4286:    Not Collective

    4288:    Input Parameters:
    4289:      snes - SNES context

    4291:    Output Parameters:
    4292: +    version - version 1, 2 (default is 2) or 3
    4293: .    rtol_0 - initial relative tolerance (0 <= rtol_0 < 1)
    4294: .    rtol_max - maximum relative tolerance (0 <= rtol_max < 1)
    4295: .    gamma - multiplicative factor for version 2 rtol computation (0 <= gamma2 <= 1)
    4296: .    alpha - power for version 2 rtol computation (1 < alpha <= 2)
    4297: .    alpha2 - power for safeguard
    4298: -    threshold - threshold for imposing safeguard (0 < threshold < 1)

    4300:    Level: advanced

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

    4304: .seealso: SNESKSPSetUseEW(), SNESKSPGetUseEW(), SNESKSPSetParametersEW()
    4305: @*/
    4306: PetscErrorCode  SNESKSPGetParametersEW(SNES snes,PetscInt *version,PetscReal *rtol_0,PetscReal *rtol_max,PetscReal *gamma,PetscReal *alpha,PetscReal *alpha2,PetscReal *threshold)
    4307: {
    4308:   SNESKSPEW *kctx;

    4312:   kctx = (SNESKSPEW*)snes->kspconvctx;
    4313:   if (!kctx) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context existing");
    4314:   if (version)   *version   = kctx->version;
    4315:   if (rtol_0)    *rtol_0    = kctx->rtol_0;
    4316:   if (rtol_max)  *rtol_max  = kctx->rtol_max;
    4317:   if (gamma)     *gamma     = kctx->gamma;
    4318:   if (alpha)     *alpha     = kctx->alpha;
    4319:   if (alpha2)    *alpha2    = kctx->alpha2;
    4320:   if (threshold) *threshold = kctx->threshold;
    4321:   return(0);
    4322: }

    4326:  PetscErrorCode SNESKSPEW_PreSolve(KSP ksp, Vec b, Vec x, SNES snes)
    4327: {
    4329:   SNESKSPEW      *kctx = (SNESKSPEW*)snes->kspconvctx;
    4330:   PetscReal      rtol  = PETSC_DEFAULT,stol;

    4333:   if (!snes->ksp_ewconv) return(0);
    4334:   if (!snes->iter) rtol = kctx->rtol_0; /* first time in, so use the original user rtol */
    4335:   else {
    4336:     if (kctx->version == 1) {
    4337:       rtol = (snes->norm - kctx->lresid_last)/kctx->norm_last;
    4338:       if (rtol < 0.0) rtol = -rtol;
    4339:       stol = PetscPowReal(kctx->rtol_last,kctx->alpha2);
    4340:       if (stol > kctx->threshold) rtol = PetscMax(rtol,stol);
    4341:     } else if (kctx->version == 2) {
    4342:       rtol = kctx->gamma * PetscPowReal(snes->norm/kctx->norm_last,kctx->alpha);
    4343:       stol = kctx->gamma * PetscPowReal(kctx->rtol_last,kctx->alpha);
    4344:       if (stol > kctx->threshold) rtol = PetscMax(rtol,stol);
    4345:     } else if (kctx->version == 3) { /* contributed by Luis Chacon, June 2006. */
    4346:       rtol = kctx->gamma * PetscPowReal(snes->norm/kctx->norm_last,kctx->alpha);
    4347:       /* safeguard: avoid sharp decrease of rtol */
    4348:       stol = kctx->gamma*PetscPowReal(kctx->rtol_last,kctx->alpha);
    4349:       stol = PetscMax(rtol,stol);
    4350:       rtol = PetscMin(kctx->rtol_0,stol);
    4351:       /* safeguard: avoid oversolving */
    4352:       stol = kctx->gamma*(snes->ttol)/snes->norm;
    4353:       stol = PetscMax(rtol,stol);
    4354:       rtol = PetscMin(kctx->rtol_0,stol);
    4355:     } else SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Only versions 1, 2 or 3 are supported: %D",kctx->version);
    4356:   }
    4357:   /* safeguard: avoid rtol greater than one */
    4358:   rtol = PetscMin(rtol,kctx->rtol_max);
    4359:   KSPSetTolerances(ksp,rtol,PETSC_DEFAULT,PETSC_DEFAULT,PETSC_DEFAULT);
    4360:   PetscInfo3(snes,"iter %D, Eisenstat-Walker (version %D) KSP rtol=%G\n",snes->iter,kctx->version,rtol);
    4361:   return(0);
    4362: }

    4366: PetscErrorCode SNESKSPEW_PostSolve(KSP ksp, Vec b, Vec x, SNES snes)
    4367: {
    4369:   SNESKSPEW      *kctx = (SNESKSPEW*)snes->kspconvctx;
    4370:   PCSide         pcside;
    4371:   Vec            lres;

    4374:   if (!snes->ksp_ewconv) return(0);
    4375:   KSPGetTolerances(ksp,&kctx->rtol_last,0,0,0);
    4376:   SNESGetFunctionNorm(snes,&kctx->norm_last);
    4377:   if (kctx->version == 1) {
    4378:     KSPGetPCSide(ksp,&pcside);
    4379:     if (pcside == PC_RIGHT) { /* XXX Should we also test KSP_UNPRECONDITIONED_NORM ? */
    4380:       /* KSP residual is true linear residual */
    4381:       KSPGetResidualNorm(ksp,&kctx->lresid_last);
    4382:     } else {
    4383:       /* KSP residual is preconditioned residual */
    4384:       /* compute true linear residual norm */
    4385:       VecDuplicate(b,&lres);
    4386:       MatMult(snes->jacobian,x,lres);
    4387:       VecAYPX(lres,-1.0,b);
    4388:       VecNorm(lres,NORM_2,&kctx->lresid_last);
    4389:       VecDestroy(&lres);
    4390:     }
    4391:   }
    4392:   return(0);
    4393: }

    4397: /*@
    4398:    SNESGetKSP - Returns the KSP context for a SNES solver.

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

    4402:    Input Parameter:
    4403: .  snes - the SNES context

    4405:    Output Parameter:
    4406: .  ksp - the KSP context

    4408:    Notes:
    4409:    The user can then directly manipulate the KSP context to set various
    4410:    options, etc.  Likewise, the user can then extract and manipulate the
    4411:    PC contexts as well.

    4413:    Level: beginner

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

    4417: .seealso: KSPGetPC(), SNESCreate(), KSPCreate(), SNESSetKSP()
    4418: @*/
    4419: PetscErrorCode  SNESGetKSP(SNES snes,KSP *ksp)
    4420: {

    4427:   if (!snes->ksp) {
    4428:     KSPCreate(PetscObjectComm((PetscObject)snes),&snes->ksp);
    4429:     PetscObjectIncrementTabLevel((PetscObject)snes->ksp,(PetscObject)snes,1);
    4430:     PetscLogObjectParent(snes,snes->ksp);

    4432:     KSPSetPreSolve(snes->ksp,(PetscErrorCode (*)(KSP,Vec,Vec,void*))SNESKSPEW_PreSolve,snes);
    4433:     KSPSetPostSolve(snes->ksp,(PetscErrorCode (*)(KSP,Vec,Vec,void*))SNESKSPEW_PostSolve,snes);
    4434:   }
    4435:   *ksp = snes->ksp;
    4436:   return(0);
    4437: }

    4440: #include <petsc-private/dmimpl.h>
    4443: /*@
    4444:    SNESSetDM - Sets the DM that may be used by some preconditioners

    4446:    Logically Collective on SNES

    4448:    Input Parameters:
    4449: +  snes - the preconditioner context
    4450: -  dm - the dm

    4452:    Level: intermediate

    4454: .seealso: SNESGetDM(), KSPSetDM(), KSPGetDM()
    4455: @*/
    4456: PetscErrorCode  SNESSetDM(SNES snes,DM dm)
    4457: {
    4459:   KSP            ksp;
    4460:   DMSNES         sdm;

    4464:   if (dm) {PetscObjectReference((PetscObject)dm);}
    4465:   if (snes->dm) {               /* Move the DMSNES context over to the new DM unless the new DM already has one */
    4466:     if (snes->dm->dmsnes && snes->dmAuto && !dm->dmsnes) {
    4467:       DMCopyDMSNES(snes->dm,dm);
    4468:       DMGetDMSNES(snes->dm,&sdm);
    4469:       if (sdm->originaldm == snes->dm) sdm->originaldm = dm; /* Grant write privileges to the replacement DM */
    4470:     }
    4471:     DMDestroy(&snes->dm);
    4472:   }
    4473:   snes->dm     = dm;
    4474:   snes->dmAuto = PETSC_FALSE;

    4476:   SNESGetKSP(snes,&ksp);
    4477:   KSPSetDM(ksp,dm);
    4478:   KSPSetDMActive(ksp,PETSC_FALSE);
    4479:   if (snes->pc) {
    4480:     SNESSetDM(snes->pc, snes->dm);
    4481:     SNESSetPCSide(snes,snes->pcside);
    4482:   }
    4483:   return(0);
    4484: }

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

    4491:    Not Collective but DM obtained is parallel on SNES

    4493:    Input Parameter:
    4494: . snes - the preconditioner context

    4496:    Output Parameter:
    4497: .  dm - the dm

    4499:    Level: intermediate

    4501: .seealso: SNESSetDM(), KSPSetDM(), KSPGetDM()
    4502: @*/
    4503: PetscErrorCode  SNESGetDM(SNES snes,DM *dm)
    4504: {

    4509:   if (!snes->dm) {
    4510:     DMShellCreate(PetscObjectComm((PetscObject)snes),&snes->dm);
    4511:     snes->dmAuto = PETSC_TRUE;
    4512:   }
    4513:   *dm = snes->dm;
    4514:   return(0);
    4515: }

    4519: /*@
    4520:   SNESSetPC - Sets the nonlinear preconditioner to be used.

    4522:   Collective on SNES

    4524:   Input Parameters:
    4525: + snes - iterative context obtained from SNESCreate()
    4526: - pc   - the preconditioner object

    4528:   Notes:
    4529:   Use SNESGetPC() to retrieve the preconditioner context (for example,
    4530:   to configure it using the API).

    4532:   Level: developer

    4534: .keywords: SNES, set, precondition
    4535: .seealso: SNESGetPC()
    4536: @*/
    4537: PetscErrorCode SNESSetPC(SNES snes, SNES pc)
    4538: {

    4545:   PetscObjectReference((PetscObject) pc);
    4546:   SNESDestroy(&snes->pc);
    4547:   snes->pc = pc;
    4548:   PetscLogObjectParent(snes, snes->pc);
    4549:   return(0);
    4550: }

    4554: /*@
    4555:   SNESGetPC - Returns a pointer to the nonlinear preconditioning context set with SNESSetPC().

    4557:   Not Collective

    4559:   Input Parameter:
    4560: . snes - iterative context obtained from SNESCreate()

    4562:   Output Parameter:
    4563: . pc - preconditioner context

    4565:   Level: developer

    4567: .keywords: SNES, get, preconditioner
    4568: .seealso: SNESSetPC()
    4569: @*/
    4570: PetscErrorCode SNESGetPC(SNES snes, SNES *pc)
    4571: {
    4573:   const char     *optionsprefix;

    4578:   if (!snes->pc) {
    4579:     SNESCreate(PetscObjectComm((PetscObject)snes),&snes->pc);
    4580:     PetscObjectIncrementTabLevel((PetscObject)snes->pc,(PetscObject)snes,1);
    4581:     PetscLogObjectParent(snes,snes->pc);
    4582:     SNESGetOptionsPrefix(snes,&optionsprefix);
    4583:     SNESSetOptionsPrefix(snes->pc,optionsprefix);
    4584:     SNESAppendOptionsPrefix(snes->pc,"npc_");
    4585:   }
    4586:   *pc = snes->pc;
    4587:   return(0);
    4588: }

    4592: /*@
    4593:     SNESSetPCSide - Sets the preconditioning side.

    4595:     Logically Collective on SNES

    4597:     Input Parameter:
    4598: .   snes - iterative context obtained from SNESCreate()

    4600:     Output Parameter:
    4601: .   side - the preconditioning side, where side is one of
    4602: .vb
    4603:       PC_LEFT - left preconditioning (default)
    4604:       PC_RIGHT - right preconditioning
    4605: .ve

    4607:     Options Database Keys:
    4608: .   -snes_pc_side <right,left>

    4610:     Level: intermediate

    4612: .keywords: SNES, set, right, left, side, preconditioner, flag

    4614: .seealso: SNESGetPCSide(), KSPSetPCSide()
    4615: @*/
    4616: PetscErrorCode  SNESSetPCSide(SNES snes,PCSide side)
    4617: {
    4621:   snes->pcside = side;
    4622:   return(0);
    4623: }

    4627: /*@
    4628:     SNESGetPCSide - Gets the preconditioning side.

    4630:     Not Collective

    4632:     Input Parameter:
    4633: .   snes - iterative context obtained from SNESCreate()

    4635:     Output Parameter:
    4636: .   side - the preconditioning side, where side is one of
    4637: .vb
    4638:       PC_LEFT - left preconditioning (default)
    4639:       PC_RIGHT - right preconditioning
    4640: .ve

    4642:     Level: intermediate

    4644: .keywords: SNES, get, right, left, side, preconditioner, flag

    4646: .seealso: SNESSetPCSide(), KSPGetPCSide()
    4647: @*/
    4648: PetscErrorCode  SNESGetPCSide(SNES snes,PCSide *side)
    4649: {
    4653:   *side = snes->pcside;
    4654:   return(0);
    4655: }

    4659: /*@
    4660:   SNESSetLineSearch - Sets the linesearch on the SNES instance.

    4662:   Collective on SNES

    4664:   Input Parameters:
    4665: + snes - iterative context obtained from SNESCreate()
    4666: - linesearch   - the linesearch object

    4668:   Notes:
    4669:   Use SNESGetLineSearch() to retrieve the preconditioner context (for example,
    4670:   to configure it using the API).

    4672:   Level: developer

    4674: .keywords: SNES, set, linesearch
    4675: .seealso: SNESGetLineSearch()
    4676: @*/
    4677: PetscErrorCode SNESSetLineSearch(SNES snes, SNESLineSearch linesearch)
    4678: {

    4685:   PetscObjectReference((PetscObject) linesearch);
    4686:   SNESLineSearchDestroy(&snes->linesearch);

    4688:   snes->linesearch = linesearch;

    4690:   PetscLogObjectParent(snes, snes->linesearch);
    4691:   return(0);
    4692: }

    4696: /*@
    4697:   SNESGetLineSearch - Returns a pointer to the line search context set with SNESSetLineSearch()
    4698:   or creates a default line search instance associated with the SNES and returns it.

    4700:   Not Collective

    4702:   Input Parameter:
    4703: . snes - iterative context obtained from SNESCreate()

    4705:   Output Parameter:
    4706: . linesearch - linesearch context

    4708:   Level: developer

    4710: .keywords: SNES, get, linesearch
    4711: .seealso: SNESSetLineSearch()
    4712: @*/
    4713: PetscErrorCode SNESGetLineSearch(SNES snes, SNESLineSearch *linesearch)
    4714: {
    4716:   const char     *optionsprefix;

    4721:   if (!snes->linesearch) {
    4722:     SNESGetOptionsPrefix(snes, &optionsprefix);
    4723:     SNESLineSearchCreate(PetscObjectComm((PetscObject)snes), &snes->linesearch);
    4724:     SNESLineSearchSetSNES(snes->linesearch, snes);
    4725:     SNESLineSearchAppendOptionsPrefix(snes->linesearch, optionsprefix);
    4726:     PetscObjectIncrementTabLevel((PetscObject) snes->linesearch, (PetscObject) snes, 1);
    4727:     PetscLogObjectParent(snes, snes->linesearch);
    4728:   }
    4729:   *linesearch = snes->linesearch;
    4730:   return(0);
    4731: }

    4733: #if defined(PETSC_HAVE_MATLAB_ENGINE)
    4734: #include <mex.h>

    4736: typedef struct {char *funcname; mxArray *ctx;} SNESMatlabContext;

    4740: /*
    4741:    SNESComputeFunction_Matlab - Calls the function that has been set with SNESSetFunctionMatlab().

    4743:    Collective on SNES

    4745:    Input Parameters:
    4746: +  snes - the SNES context
    4747: -  x - input vector

    4749:    Output Parameter:
    4750: .  y - function vector, as set by SNESSetFunction()

    4752:    Notes:
    4753:    SNESComputeFunction() is typically used within nonlinear solvers
    4754:    implementations, so most users would not generally call this routine
    4755:    themselves.

    4757:    Level: developer

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

    4761: .seealso: SNESSetFunction(), SNESGetFunction()
    4762: */
    4763: PetscErrorCode  SNESComputeFunction_Matlab(SNES snes,Vec x,Vec y, void *ctx)
    4764: {
    4765:   PetscErrorCode    ierr;
    4766:   SNESMatlabContext *sctx = (SNESMatlabContext*)ctx;
    4767:   int               nlhs  = 1,nrhs = 5;
    4768:   mxArray           *plhs[1],*prhs[5];
    4769:   long long int     lx = 0,ly = 0,ls = 0;

    4778:   /* call Matlab function in ctx with arguments x and y */

    4780:   PetscMemcpy(&ls,&snes,sizeof(snes));
    4781:   PetscMemcpy(&lx,&x,sizeof(x));
    4782:   PetscMemcpy(&ly,&y,sizeof(x));
    4783:   prhs[0] = mxCreateDoubleScalar((double)ls);
    4784:   prhs[1] = mxCreateDoubleScalar((double)lx);
    4785:   prhs[2] = mxCreateDoubleScalar((double)ly);
    4786:   prhs[3] = mxCreateString(sctx->funcname);
    4787:   prhs[4] = sctx->ctx;
    4788:   mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscSNESComputeFunctionInternal");
    4789:   mxGetScalar(plhs[0]);
    4790:   mxDestroyArray(prhs[0]);
    4791:   mxDestroyArray(prhs[1]);
    4792:   mxDestroyArray(prhs[2]);
    4793:   mxDestroyArray(prhs[3]);
    4794:   mxDestroyArray(plhs[0]);
    4795:   return(0);
    4796: }

    4800: /*
    4801:    SNESSetFunctionMatlab - Sets the function evaluation routine and function
    4802:    vector for use by the SNES routines in solving systems of nonlinear
    4803:    equations from MATLAB. Here the function is a string containing the name of a MATLAB function

    4805:    Logically Collective on SNES

    4807:    Input Parameters:
    4808: +  snes - the SNES context
    4809: .  r - vector to store function value
    4810: -  SNESFunction - function evaluation routine

    4812:    Notes:
    4813:    The Newton-like methods typically solve linear systems of the form
    4814: $      f'(x) x = -f(x),
    4815:    where f'(x) denotes the Jacobian matrix and f(x) is the function.

    4817:    Level: beginner

    4819:    Developer Note:  This bleeds the allocated memory SNESMatlabContext *sctx;

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

    4823: .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction()
    4824: */
    4825: PetscErrorCode  SNESSetFunctionMatlab(SNES snes,Vec r,const char *SNESFunction,mxArray *ctx)
    4826: {
    4827:   PetscErrorCode    ierr;
    4828:   SNESMatlabContext *sctx;

    4831:   /* currently sctx is memory bleed */
    4832:   PetscMalloc(sizeof(SNESMatlabContext),&sctx);
    4833:   PetscStrallocpy(SNESFunction,&sctx->funcname);
    4834:   /*
    4835:      This should work, but it doesn't
    4836:   sctx->ctx = ctx;
    4837:   mexMakeArrayPersistent(sctx->ctx);
    4838:   */
    4839:   sctx->ctx = mxDuplicateArray(ctx);
    4840:   SNESSetFunction(snes,r,SNESComputeFunction_Matlab,sctx);
    4841:   return(0);
    4842: }

    4846: /*
    4847:    SNESComputeJacobian_Matlab - Calls the function that has been set with SNESSetJacobianMatlab().

    4849:    Collective on SNES

    4851:    Input Parameters:
    4852: +  snes - the SNES context
    4853: .  x - input vector
    4854: .  A, B - the matrices
    4855: -  ctx - user context

    4857:    Output Parameter:
    4858: .  flag - structure of the matrix

    4860:    Level: developer

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

    4864: .seealso: SNESSetFunction(), SNESGetFunction()
    4865: @*/
    4866: PetscErrorCode  SNESComputeJacobian_Matlab(SNES snes,Vec x,Mat *A,Mat *B,MatStructure *flag, void *ctx)
    4867: {
    4868:   PetscErrorCode    ierr;
    4869:   SNESMatlabContext *sctx = (SNESMatlabContext*)ctx;
    4870:   int               nlhs  = 2,nrhs = 6;
    4871:   mxArray           *plhs[2],*prhs[6];
    4872:   long long int     lx = 0,lA = 0,ls = 0, lB = 0;

    4878:   /* call Matlab function in ctx with arguments x and y */

    4880:   PetscMemcpy(&ls,&snes,sizeof(snes));
    4881:   PetscMemcpy(&lx,&x,sizeof(x));
    4882:   PetscMemcpy(&lA,A,sizeof(x));
    4883:   PetscMemcpy(&lB,B,sizeof(x));
    4884:   prhs[0] = mxCreateDoubleScalar((double)ls);
    4885:   prhs[1] = mxCreateDoubleScalar((double)lx);
    4886:   prhs[2] = mxCreateDoubleScalar((double)lA);
    4887:   prhs[3] = mxCreateDoubleScalar((double)lB);
    4888:   prhs[4] = mxCreateString(sctx->funcname);
    4889:   prhs[5] = sctx->ctx;
    4890:   mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscSNESComputeJacobianInternal");
    4891:   mxGetScalar(plhs[0]);
    4892:   *flag   = (MatStructure) mxGetScalar(plhs[1]);
    4893:   mxDestroyArray(prhs[0]);
    4894:   mxDestroyArray(prhs[1]);
    4895:   mxDestroyArray(prhs[2]);
    4896:   mxDestroyArray(prhs[3]);
    4897:   mxDestroyArray(prhs[4]);
    4898:   mxDestroyArray(plhs[0]);
    4899:   mxDestroyArray(plhs[1]);
    4900:   return(0);
    4901: }

    4905: /*
    4906:    SNESSetJacobianMatlab - Sets the Jacobian function evaluation routine and two empty Jacobian matrices
    4907:    vector for use by the SNES routines in solving systems of nonlinear
    4908:    equations from MATLAB. Here the function is a string containing the name of a MATLAB function

    4910:    Logically Collective on SNES

    4912:    Input Parameters:
    4913: +  snes - the SNES context
    4914: .  A,B - Jacobian matrices
    4915: .  SNESJacobianFunction - function evaluation routine
    4916: -  ctx - user context

    4918:    Level: developer

    4920:    Developer Note:  This bleeds the allocated memory SNESMatlabContext *sctx;

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

    4924: .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction(), SNESJacobianFunction
    4925: */
    4926: PetscErrorCode  SNESSetJacobianMatlab(SNES snes,Mat A,Mat B,const char *SNESJacobianFunction,mxArray *ctx)
    4927: {
    4928:   PetscErrorCode    ierr;
    4929:   SNESMatlabContext *sctx;

    4932:   /* currently sctx is memory bleed */
    4933:   PetscMalloc(sizeof(SNESMatlabContext),&sctx);
    4934:   PetscStrallocpy(SNESJacobianFunction,&sctx->funcname);
    4935:   /*
    4936:      This should work, but it doesn't
    4937:   sctx->ctx = ctx;
    4938:   mexMakeArrayPersistent(sctx->ctx);
    4939:   */
    4940:   sctx->ctx = mxDuplicateArray(ctx);
    4941:   SNESSetJacobian(snes,A,B,SNESComputeJacobian_Matlab,sctx);
    4942:   return(0);
    4943: }

    4947: /*
    4948:    SNESMonitor_Matlab - Calls the function that has been set with SNESMonitorSetMatlab().

    4950:    Collective on SNES

    4952: .seealso: SNESSetFunction(), SNESGetFunction()
    4953: @*/
    4954: PetscErrorCode  SNESMonitor_Matlab(SNES snes,PetscInt it, PetscReal fnorm, void *ctx)
    4955: {
    4956:   PetscErrorCode    ierr;
    4957:   SNESMatlabContext *sctx = (SNESMatlabContext*)ctx;
    4958:   int               nlhs  = 1,nrhs = 6;
    4959:   mxArray           *plhs[1],*prhs[6];
    4960:   long long int     lx = 0,ls = 0;
    4961:   Vec               x  = snes->vec_sol;

    4966:   PetscMemcpy(&ls,&snes,sizeof(snes));
    4967:   PetscMemcpy(&lx,&x,sizeof(x));
    4968:   prhs[0] = mxCreateDoubleScalar((double)ls);
    4969:   prhs[1] = mxCreateDoubleScalar((double)it);
    4970:   prhs[2] = mxCreateDoubleScalar((double)fnorm);
    4971:   prhs[3] = mxCreateDoubleScalar((double)lx);
    4972:   prhs[4] = mxCreateString(sctx->funcname);
    4973:   prhs[5] = sctx->ctx;
    4974:   mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscSNESMonitorInternal");
    4975:   mxGetScalar(plhs[0]);
    4976:   mxDestroyArray(prhs[0]);
    4977:   mxDestroyArray(prhs[1]);
    4978:   mxDestroyArray(prhs[2]);
    4979:   mxDestroyArray(prhs[3]);
    4980:   mxDestroyArray(prhs[4]);
    4981:   mxDestroyArray(plhs[0]);
    4982:   return(0);
    4983: }

    4987: /*
    4988:    SNESMonitorSetMatlab - Sets the monitor function from MATLAB

    4990:    Level: developer

    4992:    Developer Note:  This bleeds the allocated memory SNESMatlabContext *sctx;

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

    4996: .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction()
    4997: */
    4998: PetscErrorCode  SNESMonitorSetMatlab(SNES snes,const char *SNESMonitorFunction,mxArray *ctx)
    4999: {
    5000:   PetscErrorCode    ierr;
    5001:   SNESMatlabContext *sctx;

    5004:   /* currently sctx is memory bleed */
    5005:   PetscMalloc(sizeof(SNESMatlabContext),&sctx);
    5006:   PetscStrallocpy(SNESMonitorFunction,&sctx->funcname);
    5007:   /*
    5008:      This should work, but it doesn't
    5009:   sctx->ctx = ctx;
    5010:   mexMakeArrayPersistent(sctx->ctx);
    5011:   */
    5012:   sctx->ctx = mxDuplicateArray(ctx);
    5013:   SNESMonitorSet(snes,SNESMonitor_Matlab,sctx,NULL);
    5014:   return(0);
    5015: }

    5017: #endif