Actual source code: snes.c

petsc-3.4.0 2013-05-13
  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->ops->view) {
250:       PetscViewerASCIIPushTab(viewer);
251:       (*snes->ops->view)(snes,viewer);
252:       PetscViewerASCIIPopTab(viewer);
253:     }
254:     PetscViewerASCIIPrintf(viewer,"  maximum iterations=%D, maximum function evaluations=%D\n",snes->max_its,snes->max_funcs);
255:     PetscViewerASCIIPrintf(viewer,"  tolerances: relative=%G, absolute=%G, solution=%G\n",snes->rtol,snes->abstol,snes->stol);
256:     PetscViewerASCIIPrintf(viewer,"  total number of linear solver iterations=%D\n",snes->linear_its);
257:     PetscViewerASCIIPrintf(viewer,"  total number of function evaluations=%D\n",snes->nfuncs);
258:     if (snes->gridsequence) {
259:       PetscViewerASCIIPrintf(viewer,"  total number of grid sequence refinements=%D\n",snes->gridsequence);
260:     }
261:     if (snes->ksp_ewconv) {
262:       kctx = (SNESKSPEW*)snes->kspconvctx;
263:       if (kctx) {
264:         PetscViewerASCIIPrintf(viewer,"  Eisenstat-Walker computation of KSP relative tolerance (version %D)\n",kctx->version);
265:         PetscViewerASCIIPrintf(viewer,"    rtol_0=%G, rtol_max=%G, threshold=%G\n",kctx->rtol_0,kctx->rtol_max,kctx->threshold);
266:         PetscViewerASCIIPrintf(viewer,"    gamma=%G, alpha=%G, alpha2=%G\n",kctx->gamma,kctx->alpha,kctx->alpha2);
267:       }
268:     }
269:     if (snes->lagpreconditioner == -1) {
270:       PetscViewerASCIIPrintf(viewer,"  Preconditioned is never rebuilt\n");
271:     } else if (snes->lagpreconditioner > 1) {
272:       PetscViewerASCIIPrintf(viewer,"  Preconditioned is rebuilt every %D new Jacobians\n",snes->lagpreconditioner);
273:     }
274:     if (snes->lagjacobian == -1) {
275:       PetscViewerASCIIPrintf(viewer,"  Jacobian is never rebuilt\n");
276:     } else if (snes->lagjacobian > 1) {
277:       PetscViewerASCIIPrintf(viewer,"  Jacobian is rebuilt every %D SNES iterations\n",snes->lagjacobian);
278:     }
279:   } else if (isstring) {
280:     const char *type;
281:     SNESGetType(snes,&type);
282:     PetscViewerStringSPrintf(viewer," %-3.3s",type);
283:   } else if (isbinary) {
284:     PetscInt    classid = SNES_FILE_CLASSID;
285:     MPI_Comm    comm;
286:     PetscMPIInt rank;
287:     char        type[256];

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

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

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

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

370:   Not Collective

372:   Input Parameter:
373: . snescheck - function that checks for options

375:   Level: developer

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

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

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


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

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

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

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

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

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

479: static PetscErrorCode DMCoarsenHook_SNESVecSol(DM dm,DM dmc,void *ctx)
480: {

484:   DMCoarsenHookAdd(dmc,DMCoarsenHook_SNESVecSol,DMRestrictHook_SNESVecSol,ctx);
485:   return(0);
486: }

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

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

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

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

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

535:    Collective

537:    Input Arguments:
538: .  snes - snes to configure

540:    Level: developer

542: .seealso: SNESSetUp()
543: @*/
544: PetscErrorCode SNESSetUpMatrices(SNES snes)
545: {
547:   DM             dm;
548:   DMSNES         sdm;

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

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

594:    Collective on SNES

596:    Input Parameter:
597: .  snes - the SNES context

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

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

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

642:    Level: beginner

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

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


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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

806:   flg  = PETSC_FALSE;
807:   PetscOptionsBool("-snes_fd_color","Use finite differences with coloring to compute Jacobian","SNESComputeJacobianDefaultColor",flg,&flg,NULL);
808:   if (flg) {
809:     void *functx;
810:     SNESGetFunction(snes,NULL,NULL,&functx);
811:     SNESSetJacobian(snes,snes->jacobian,snes->jacobian_pre,SNESComputeJacobianDefaultColor,0);
812:     PetscInfo(snes,"Setting default finite difference coloring Jacobian matrix\n");
813:   }

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

826:   flg  = PETSC_FALSE;
827:   SNESGetPCSide(snes,&pcside);
828:   PetscOptionsEnum("-snes_npc_side","SNES nonlinear preconditioner side","SNESSetPCSide",PCSides,(PetscEnum)pcside,(PetscEnum*)&pcside,&flg);
829:   if (flg) {SNESSetPCSide(snes,pcside);}

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

842:   for (i = 0; i < numberofsetfromoptions; i++) {
843:     (*othersetfromoptions[i])(snes);
844:   }

846:   if (snes->ops->setfromoptions) {
847:     (*snes->ops->setfromoptions)(snes);
848:   }

850:   /* process any options handlers added with PetscObjectAddOptionsHandler() */
851:   PetscObjectProcessOptionsHandlers((PetscObject)snes);
852:   PetscOptionsEnd();

854:   if (!snes->ksp) {SNESGetKSP(snes,&snes->ksp);}
855:   KSPGetOperators(snes->ksp,NULL,NULL,&matflag);
856:   KSPSetOperators(snes->ksp,snes->jacobian,snes->jacobian_pre,matflag);
857:   KSPSetFromOptions(snes->ksp);

859:   if (!snes->linesearch) {
860:     SNESGetLineSearch(snes, &snes->linesearch);
861:   }
862:   SNESLineSearchSetFromOptions(snes->linesearch);

864:   /* if someone has set the SNES PC type, create it. */
865:   SNESGetOptionsPrefix(snes, &optionsprefix);
866:   PetscOptionsHasName(optionsprefix, "-npc_snes_type", &pcset);
867:   if (pcset && (!snes->pc)) {
868:     SNESGetPC(snes, &snes->pc);
869:   }
870:   return(0);
871: }

875: /*@C
876:    SNESSetComputeApplicationContext - Sets an optional function to compute a user-defined context for
877:    the nonlinear solvers.

879:    Logically Collective on SNES

881:    Input Parameters:
882: +  snes - the SNES context
883: .  compute - function to compute the context
884: -  destroy - function to destroy the context

886:    Level: intermediate

888:    Notes:
889:    This function is currently not available from Fortran.

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

893: .seealso: SNESGetApplicationContext(), SNESSetComputeApplicationContext(), SNESGetApplicationContext()
894: @*/
895: PetscErrorCode  SNESSetComputeApplicationContext(SNES snes,PetscErrorCode (*compute)(SNES,void**),PetscErrorCode (*destroy)(void**))
896: {
899:   snes->ops->usercompute = compute;
900:   snes->ops->userdestroy = destroy;
901:   return(0);
902: }

906: /*@
907:    SNESSetApplicationContext - Sets the optional user-defined context for
908:    the nonlinear solvers.

910:    Logically Collective on SNES

912:    Input Parameters:
913: +  snes - the SNES context
914: -  usrP - optional user context

916:    Level: intermediate

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

920: .seealso: SNESGetApplicationContext()
921: @*/
922: PetscErrorCode  SNESSetApplicationContext(SNES snes,void *usrP)
923: {
925:   KSP            ksp;

929:   SNESGetKSP(snes,&ksp);
930:   KSPSetApplicationContext(ksp,usrP);
931:   snes->user = usrP;
932:   return(0);
933: }

937: /*@
938:    SNESGetApplicationContext - Gets the user-defined context for the
939:    nonlinear solvers.

941:    Not Collective

943:    Input Parameter:
944: .  snes - SNES context

946:    Output Parameter:
947: .  usrP - user context

949:    Level: intermediate

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

953: .seealso: SNESSetApplicationContext()
954: @*/
955: PetscErrorCode  SNESGetApplicationContext(SNES snes,void *usrP)
956: {
959:   *(void**)usrP = snes->user;
960:   return(0);
961: }

965: /*@
966:    SNESGetIterationNumber - Gets the number of nonlinear iterations completed
967:    at this time.

969:    Not Collective

971:    Input Parameter:
972: .  snes - SNES context

974:    Output Parameter:
975: .  iter - iteration number

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

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

991:    Level: intermediate

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

995: .seealso:   SNESGetFunctionNorm(), SNESGetLinearSolveIterations()
996: @*/
997: PetscErrorCode  SNESGetIterationNumber(SNES snes,PetscInt *iter)
998: {
1002:   *iter = snes->iter;
1003:   return(0);
1004: }

1008: /*@
1009:    SNESSetIterationNumber - Sets the current iteration number.

1011:    Not Collective

1013:    Input Parameter:
1014: .  snes - SNES context
1015: .  iter - iteration number

1017:    Level: developer

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

1021: .seealso:   SNESGetFunctionNorm(), SNESGetLinearSolveIterations()
1022: @*/
1023: PetscErrorCode  SNESSetIterationNumber(SNES snes,PetscInt iter)
1024: {

1029:   PetscObjectAMSTakeAccess((PetscObject)snes);
1030:   snes->iter = iter;
1031:   PetscObjectAMSGrantAccess((PetscObject)snes);
1032:   return(0);
1033: }

1037: /*@
1038:    SNESGetFunctionNorm - Gets the norm of the current function that was set
1039:    with SNESSSetFunction().

1041:    Collective on SNES

1043:    Input Parameter:
1044: .  snes - SNES context

1046:    Output Parameter:
1047: .  fnorm - 2-norm of function

1049:    Level: intermediate

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

1053: .seealso: SNESGetFunction(), SNESGetIterationNumber(), SNESGetLinearSolveIterations()
1054: @*/
1055: PetscErrorCode  SNESGetFunctionNorm(SNES snes,PetscReal *fnorm)
1056: {
1060:   *fnorm = snes->norm;
1061:   return(0);
1062: }


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

1070:    Collective on SNES

1072:    Input Parameter:
1073: .  snes - SNES context
1074: .  fnorm - 2-norm of function

1076:    Level: developer

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

1080: .seealso: SNESSetFunction(), SNESSetIterationNumber(), VecNorm().
1081: @*/
1082: PetscErrorCode  SNESSetFunctionNorm(SNES snes,PetscReal fnorm)
1083: {


1089:   PetscObjectAMSTakeAccess((PetscObject)snes);
1090:   snes->norm = fnorm;
1091:   PetscObjectAMSGrantAccess((PetscObject)snes);
1092:   return(0);
1093: }

1097: /*@
1098:    SNESGetNonlinearStepFailures - Gets the number of unsuccessful steps
1099:    attempted by the nonlinear solver.

1101:    Not Collective

1103:    Input Parameter:
1104: .  snes - SNES context

1106:    Output Parameter:
1107: .  nfails - number of unsuccessful steps attempted

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

1112:    Level: intermediate

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

1116: .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), SNESGetLinearSolveFailures(),
1117:           SNESSetMaxNonlinearStepFailures(), SNESGetMaxNonlinearStepFailures()
1118: @*/
1119: PetscErrorCode  SNESGetNonlinearStepFailures(SNES snes,PetscInt *nfails)
1120: {
1124:   *nfails = snes->numFailures;
1125:   return(0);
1126: }

1130: /*@
1131:    SNESSetMaxNonlinearStepFailures - Sets the maximum number of unsuccessful steps
1132:    attempted by the nonlinear solver before it gives up.

1134:    Not Collective

1136:    Input Parameters:
1137: +  snes     - SNES context
1138: -  maxFails - maximum of unsuccessful steps

1140:    Level: intermediate

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

1144: .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), SNESGetLinearSolveFailures(),
1145:           SNESGetMaxNonlinearStepFailures(), SNESGetNonlinearStepFailures()
1146: @*/
1147: PetscErrorCode  SNESSetMaxNonlinearStepFailures(SNES snes, PetscInt maxFails)
1148: {
1151:   snes->maxFailures = maxFails;
1152:   return(0);
1153: }

1157: /*@
1158:    SNESGetMaxNonlinearStepFailures - Gets the maximum number of unsuccessful steps
1159:    attempted by the nonlinear solver before it gives up.

1161:    Not Collective

1163:    Input Parameter:
1164: .  snes     - SNES context

1166:    Output Parameter:
1167: .  maxFails - maximum of unsuccessful steps

1169:    Level: intermediate

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

1173: .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), SNESGetLinearSolveFailures(),
1174:           SNESSetMaxNonlinearStepFailures(), SNESGetNonlinearStepFailures()

1176: @*/
1177: PetscErrorCode  SNESGetMaxNonlinearStepFailures(SNES snes, PetscInt *maxFails)
1178: {
1182:   *maxFails = snes->maxFailures;
1183:   return(0);
1184: }

1188: /*@
1189:    SNESGetNumberFunctionEvals - Gets the number of user provided function evaluations
1190:      done by SNES.

1192:    Not Collective

1194:    Input Parameter:
1195: .  snes     - SNES context

1197:    Output Parameter:
1198: .  nfuncs - number of evaluations

1200:    Level: intermediate

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

1204: .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), SNESGetLinearSolveFailures()
1205: @*/
1206: PetscErrorCode  SNESGetNumberFunctionEvals(SNES snes, PetscInt *nfuncs)
1207: {
1211:   *nfuncs = snes->nfuncs;
1212:   return(0);
1213: }

1217: /*@
1218:    SNESGetLinearSolveFailures - Gets the number of failed (non-converged)
1219:    linear solvers.

1221:    Not Collective

1223:    Input Parameter:
1224: .  snes - SNES context

1226:    Output Parameter:
1227: .  nfails - number of failed solves

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

1232:    Level: intermediate

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

1236: .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures()
1237: @*/
1238: PetscErrorCode  SNESGetLinearSolveFailures(SNES snes,PetscInt *nfails)
1239: {
1243:   *nfails = snes->numLinearSolveFailures;
1244:   return(0);
1245: }

1249: /*@
1250:    SNESSetMaxLinearSolveFailures - the number of failed linear solve attempts
1251:    allowed before SNES returns with a diverged reason of SNES_DIVERGED_LINEAR_SOLVE

1253:    Logically Collective on SNES

1255:    Input Parameters:
1256: +  snes     - SNES context
1257: -  maxFails - maximum allowed linear solve failures

1259:    Level: intermediate

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

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

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

1278: /*@
1279:    SNESGetMaxLinearSolveFailures - gets the maximum number of linear solve failures that
1280:      are allowed before SNES terminates

1282:    Not Collective

1284:    Input Parameter:
1285: .  snes     - SNES context

1287:    Output Parameter:
1288: .  maxFails - maximum of unsuccessful solves allowed

1290:    Level: intermediate

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

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

1296: .seealso: SNESGetLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(),
1297: @*/
1298: PetscErrorCode  SNESGetMaxLinearSolveFailures(SNES snes, PetscInt *maxFails)
1299: {
1303:   *maxFails = snes->maxLinearSolveFailures;
1304:   return(0);
1305: }

1309: /*@
1310:    SNESGetLinearSolveIterations - Gets the total number of linear iterations
1311:    used by the nonlinear solver.

1313:    Not Collective

1315:    Input Parameter:
1316: .  snes - SNES context

1318:    Output Parameter:
1319: .  lits - number of linear iterations

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

1324:    Level: intermediate

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

1328: .seealso:  SNESGetIterationNumber(), SNESGetFunctionNorm(), SNESGetLinearSolveFailures(), SNESGetMaxLinearSolveFailures()
1329: @*/
1330: PetscErrorCode  SNESGetLinearSolveIterations(SNES snes,PetscInt *lits)
1331: {
1335:   *lits = snes->linear_its;
1336:   return(0);
1337: }


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

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

1347:    Input Parameters:
1348: +  snes - the SNES context
1349: -  ksp - the KSP context

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

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

1358:    Level: developer

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

1362: .seealso: KSPGetPC(), SNESCreate(), KSPCreate(), SNESSetKSP()
1363: @*/
1364: PetscErrorCode  SNESSetKSP(SNES snes,KSP ksp)
1365: {

1372:   PetscObjectReference((PetscObject)ksp);
1373:   if (snes->ksp) {PetscObjectDereference((PetscObject)snes->ksp);}
1374:   snes->ksp = ksp;
1375:   return(0);
1376: }

1378: /* -----------------------------------------------------------*/
1381: /*@
1382:    SNESCreate - Creates a nonlinear solver context.

1384:    Collective on MPI_Comm

1386:    Input Parameters:
1387: .  comm - MPI communicator

1389:    Output Parameter:
1390: .  outsnes - the new SNES context

1392:    Options Database Keys:
1393: +   -snes_mf - Activates default matrix-free Jacobian-vector products,
1394:                and no preconditioning matrix
1395: .   -snes_mf_operator - Activates default matrix-free Jacobian-vector
1396:                products, and a user-provided preconditioning matrix
1397:                as set by SNESSetJacobian()
1398: -   -snes_fd - Uses (slow!) finite differences to compute Jacobian

1400:    Level: beginner

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

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

1406: @*/
1407: PetscErrorCode  SNESCreate(MPI_Comm comm,SNES *outsnes)
1408: {
1410:   SNES           snes;
1411:   SNESKSPEW      *kctx;

1415:   *outsnes = NULL;
1416: #if !defined(PETSC_USE_DYNAMIC_LIBRARIES)
1417:   SNESInitializePackage();
1418: #endif

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

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

1459:   snes->mf          = PETSC_FALSE;
1460:   snes->mf_operator = PETSC_FALSE;
1461:   snes->mf_version  = 1;

1463:   snes->numLinearSolveFailures = 0;
1464:   snes->maxLinearSolveFailures = 1;

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

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

1482:   *outsnes = snes;
1483:   return(0);
1484: }

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

1489:      Synopsis:
1490:      #include "petscsnes.h"
1491:      SNESFunction(SNES snes,Vec x,Vec f,void *ctx);

1493:      Input Parameters:
1494: +     snes - the SNES context
1495: .     x    - state at which to evaluate residual
1496: -     ctx     - optional user-defined function context, passed in with SNESSetFunction()

1498:      Output Parameter:
1499: .     f  - vector to put residual (function value)

1501:    Level: intermediate

1503: .seealso:   SNESSetFunction(), SNESGetFunction()
1504: M*/

1508: /*@C
1509:    SNESSetFunction - Sets the function evaluation routine and function
1510:    vector for use by the SNES routines in solving systems of nonlinear
1511:    equations.

1513:    Logically Collective on SNES

1515:    Input Parameters:
1516: +  snes - the SNES context
1517: .  r - vector to store function value
1518: .  SNESFunction - function evaluation routine
1519: -  ctx - [optional] user-defined context for private data for the
1520:          function evaluation routine (may be NULL)

1522:    Notes:
1523:    The Newton-like methods typically solve linear systems of the form
1524: $      f'(x) x = -f(x),
1525:    where f'(x) denotes the Jacobian matrix and f(x) is the function.

1527:    Level: beginner

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

1531: .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetPicard(), SNESFunction
1532: @*/
1533: PetscErrorCode  SNESSetFunction(SNES snes,Vec r,PetscErrorCode (*SNESFunction)(SNES,Vec,Vec,void*),void *ctx)
1534: {
1536:   DM             dm;

1540:   if (r) {
1543:     PetscObjectReference((PetscObject)r);
1544:     VecDestroy(&snes->vec_func);

1546:     snes->vec_func = r;
1547:   }
1548:   SNESGetDM(snes,&dm);
1549:   DMSNESSetFunction(dm,SNESFunction,ctx);
1550:   return(0);
1551: }


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

1563:    Logically Collective on SNES

1565:    Input Parameters:
1566: +  snes - the SNES context
1567: -  f - vector to store function value

1569:    Notes:
1570:    This should not be modified during the solution procedure.

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

1574:    Level: developer

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

1578: .seealso: SNESSetFunction(), SNESComputeFunction(), SNESSetInitialFunctionNorm()
1579: @*/
1580: PetscErrorCode  SNESSetInitialFunction(SNES snes, Vec f)
1581: {
1583:   Vec            vec_func;

1589:   SNESGetFunction(snes,&vec_func,NULL,NULL);
1590:   VecCopy(f, vec_func);

1592:   snes->vec_func_init_set = PETSC_TRUE;
1593:   return(0);
1594: }


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

1605:    Logically Collective on SNES

1607:    Input Parameters:
1608: +  snes - the SNES context
1609: -  fnorm - the norm of F as set by SNESSetInitialFunction()

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

1613:    Level: developer

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

1617: .seealso: SNESSetFunction(), SNESComputeFunction(), SNESSetInitialFunction()
1618: @*/
1619: PetscErrorCode  SNESSetInitialFunctionNorm(SNES snes, PetscReal fnorm)
1620: {
1623:   snes->norm_init     = fnorm;
1624:   snes->norm_init_set = PETSC_TRUE;
1625:   return(0);
1626: }

1630: /*@
1631:    SNESSetNormType - Sets the SNESNormType used in covergence and monitoring
1632:    of the SNES method.

1634:    Logically Collective on SNES

1636:    Input Parameters:
1637: +  snes - the SNES context
1638: -  normtype - the type of the norm used

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

1649:    Level: developer

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

1653: .seealso: SNESGetNormType(), SNESComputeFunction(), VecNorm(), SNESSetFunction(), SNESSetInitialFunction(), SNESNormType
1654: @*/
1655: PetscErrorCode  SNESSetNormType(SNES snes, SNESNormType normtype)
1656: {
1659:   snes->normtype = normtype;
1660:   return(0);
1661: }


1666: /*@
1667:    SNESGetNormType - Gets the SNESNormType used in covergence and monitoring
1668:    of the SNES method.

1670:    Logically Collective on SNES

1672:    Input Parameters:
1673: +  snes - the SNES context
1674: -  normtype - the type of the norm used

1676:    Level: advanced

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

1680: .seealso: SNESSetNormType(), SNESComputeFunction(), VecNorm(), SNESSetFunction(), SNESSetInitialFunction(), SNESNormType
1681: @*/
1682: PetscErrorCode  SNESGetNormType(SNES snes, SNESNormType *normtype)
1683: {
1686:   *normtype = snes->normtype;
1687:   return(0);
1688: }

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

1693:      Synopsis:
1694:      #include "petscsnes.h"
1695: $    SNESGSFunction(SNES snes,Vec x,Vec b,void *ctx);

1697: +  X   - solution vector
1698: .  B   - RHS vector
1699: -  ctx - optional user-defined Gauss-Seidel context

1701:    Level: intermediate

1703: .seealso:   SNESSetGS(), SNESGetGS()
1704: M*/

1708: /*@C
1709:    SNESSetGS - Sets the user nonlinear Gauss-Seidel routine for
1710:    use with composed nonlinear solvers.

1712:    Input Parameters:
1713: +  snes   - the SNES context
1714: .  SNESGSFunction - function evaluation routine
1715: -  ctx    - [optional] user-defined context for private data for the
1716:             smoother evaluation routine (may be NULL)

1718:    Notes:
1719:    The GS routines are used by the composed nonlinear solver to generate
1720:     a problem appropriate update to the solution, particularly FAS.

1722:    Level: intermediate

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

1726: .seealso: SNESGetFunction(), SNESComputeGS()
1727: @*/
1728: PetscErrorCode SNESSetGS(SNES snes,PetscErrorCode (*SNESGSFunction)(SNES,Vec,Vec,void*),void *ctx)
1729: {
1731:   DM             dm;

1735:   SNESGetDM(snes,&dm);
1736:   DMSNESSetGS(dm,SNESGSFunction,ctx);
1737:   return(0);
1738: }

1742: PETSC_EXTERN PetscErrorCode SNESPicardComputeFunction(SNES snes,Vec x,Vec f,void *ctx)
1743: {
1745:   DM             dm;
1746:   DMSNES         sdm;

1749:   SNESGetDM(snes,&dm);
1750:   DMGetDMSNES(dm,&sdm);
1751:   /*  A(x)*x - b(x) */
1752:   if (sdm->ops->computepfunction) {
1753:     (*sdm->ops->computepfunction)(snes,x,f,sdm->pctx);
1754:   } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE, "Must call SNESSetPicard() to provide Picard function.");

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

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

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

1779:    Logically Collective on SNES

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

1791:    Notes:
1792:     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
1793:     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.

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

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

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

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

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

1809:    Level: intermediate

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

1813: .seealso: SNESGetFunction(), SNESSetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESGetPicard(), SNESLineSearchPreCheckPicard()
1814: @*/
1815: 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)
1816: {
1818:   DM             dm;

1822:   SNESGetDM(snes, &dm);
1823:   DMSNESSetPicard(dm,SNESFunction,SNESJacobianFunction,ctx);
1824:   SNESSetFunction(snes,r,SNESPicardComputeFunction,ctx);
1825:   SNESSetJacobian(snes,Amat,Pmat,SNESPicardComputeJacobian,ctx);
1826:   return(0);
1827: }

1831: /*@C
1832:    SNESGetPicard - Returns the context for the Picard iteration

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

1836:    Input Parameter:
1837: .  snes - the SNES context

1839:    Output Parameter:
1840: +  r - the function (or NULL)
1841: .  SNESFunction - the function (or NULL)
1842: .  Amat - the matrix used to defined the operation A(x) x - b(x) (or NULL)
1843: .  Pmat  - the matrix from which the preconditioner will be constructed (or NULL)
1844: .  SNESJacobianFunction - the function for matrix evaluation (or NULL)
1845: -  ctx - the function context (or NULL)

1847:    Level: advanced

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

1851: .seealso: SNESSetPicard(), SNESGetFunction(), SNESGetJacobian(), SNESGetDM(), SNESFunction, SNESJacobianFunction
1852: @*/
1853: 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)
1854: {
1856:   DM             dm;

1860:   SNESGetFunction(snes,r,NULL,NULL);
1861:   SNESGetJacobian(snes,Amat,Pmat,NULL,NULL);
1862:   SNESGetDM(snes,&dm);
1863:   DMSNESGetPicard(dm,SNESFunction,SNESJacobianFunction,ctx);
1864:   return(0);
1865: }

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

1872:    Logically Collective on SNES

1874:    Input Parameters:
1875: +  snes - the SNES context
1876: .  func - function evaluation routine
1877: -  ctx - [optional] user-defined context for private data for the
1878:          function evaluation routine (may be NULL)

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

1883: .  f - function vector
1884: -  ctx - optional user-defined function context

1886:    Level: intermediate

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

1890: .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian()
1891: @*/
1892: PetscErrorCode  SNESSetComputeInitialGuess(SNES snes,PetscErrorCode (*func)(SNES,Vec,void*),void *ctx)
1893: {
1896:   if (func) snes->ops->computeinitialguess = func;
1897:   if (ctx)  snes->initialguessP            = ctx;
1898:   return(0);
1899: }

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

1908:    Logically Collective on SNES

1910:    Input Parameter:
1911: .  snes - the SNES context

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

1916:    Level: intermediate

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

1920: .seealso: SNESGetSolution(), SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction()
1921: @*/
1922: PetscErrorCode  SNESGetRhs(SNES snes,Vec *rhs)
1923: {
1927:   *rhs = snes->vec_rhs;
1928:   return(0);
1929: }

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

1936:    Collective on SNES

1938:    Input Parameters:
1939: +  snes - the SNES context
1940: -  x - input vector

1942:    Output Parameter:
1943: .  y - function vector, as set by SNESSetFunction()

1945:    Notes:
1946:    SNESComputeFunction() is typically used within nonlinear solvers
1947:    implementations, so most users would not generally call this routine
1948:    themselves.

1950:    Level: developer

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

1954: .seealso: SNESSetFunction(), SNESGetFunction()
1955: @*/
1956: PetscErrorCode  SNESComputeFunction(SNES snes,Vec x,Vec y)
1957: {
1959:   DM             dm;
1960:   DMSNES         sdm;

1968:   VecValidValues(x,2,PETSC_TRUE);

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

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

2002:    Collective on SNES

2004:    Input Parameters:
2005: +  snes - the SNES context
2006: .  x - input vector
2007: -  b - rhs vector

2009:    Output Parameter:
2010: .  x - new solution vector

2012:    Notes:
2013:    SNESComputeGS() is typically used within composed nonlinear solver
2014:    implementations, so most users would not generally call this routine
2015:    themselves.

2017:    Level: developer

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

2021: .seealso: SNESSetGS(), SNESComputeFunction()
2022: @*/
2023: PetscErrorCode  SNESComputeGS(SNES snes,Vec b,Vec x)
2024: {
2026:   DM             dm;
2027:   DMSNES         sdm;

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

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

2054:    Collective on SNES and Mat

2056:    Input Parameters:
2057: +  snes - the SNES context
2058: -  x - input vector

2060:    Output Parameters:
2061: +  A - Jacobian matrix
2062: .  B - optional preconditioning matrix
2063: -  flag - flag indicating matrix structure (one of, SAME_NONZERO_PATTERN,DIFFERENT_NONZERO_PATTERN,SAME_PRECONDITIONER)

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


2081:    Notes:
2082:    Most users should not need to explicitly call this routine, as it
2083:    is used internally within the nonlinear solvers.

2085:    See KSPSetOperators() for important information about setting the
2086:    flag parameter.

2088:    Level: developer

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

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

2106:   VecValidValues(X,2,PETSC_TRUE);
2107:   SNESGetDM(snes,&dm);
2108:   DMGetDMSNES(dm,&sdm);

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

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

2114:   if (snes->lagjacobian == -2) {
2115:     snes->lagjacobian = -1;

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

2143:   *flg = DIFFERENT_NONZERO_PATTERN;
2144:   PetscLogEventBegin(SNES_JacobianEval,snes,X,*A,*B);

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

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

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

2155:     snes->lagpreconditioner = -1;
2156:   } else if (snes->lagpreconditioner == -1) {
2157:     *flg = SAME_PRECONDITIONER;
2158:     PetscInfo(snes,"Reusing preconditioner because lag is -1\n");
2159:   } else if (snes->lagpreconditioner > 1 && snes->iter % snes->lagpreconditioner) {
2160:     *flg = SAME_PRECONDITIONER;
2161:     PetscInfo2(snes,"Reusing preconditioner because lag is %D and SNES iteration is %D\n",snes->lagpreconditioner,snes->iter);
2162:   }

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

2238:       MatDuplicate(*B,MAT_DO_NOT_COPY_VALUES,&Bfd);
2239:       MatGetColoring(Bfd,MATCOLORINGSL,&iscoloring);
2240:       MatFDColoringCreate(Bfd,iscoloring,&matfdcoloring);
2241:       ISColoringDestroy(&iscoloring);

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

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

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

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

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

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

2339:    Level: intermediate

2341: .seealso:   SNESSetFunction(), SNESGetFunction(), SNESSetJacobian(), SNESGetJacobian()
2342: M*/

2346: /*@C
2347:    SNESSetJacobian - Sets the function to compute Jacobian as well as the
2348:    location to store the matrix.

2350:    Logically Collective on SNES and Mat

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

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

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

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

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

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

2379:    Level: beginner

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

2383: .seealso: KSPSetOperators(), SNESSetFunction(), MatMFFDComputeJacobian(), SNESComputeJacobianDefaultColor(), MatStructure, SNESJacobianFunction, SNESSetPicard()
2384: @*/
2385: PetscErrorCode  SNESSetJacobian(SNES snes,Mat Amat,Mat Pmat,PetscErrorCode (*SNESJacobianFunction)(SNES,Vec,Mat*,Mat*,MatStructure*,void*),void *ctx)
2386: {
2388:   DM             dm;

2396:   SNESGetDM(snes,&dm);
2397:   DMSNESSetJacobian(dm,SNESJacobianFunction,ctx);
2398:   if (Amat) {
2399:     PetscObjectReference((PetscObject)Amat);
2400:     MatDestroy(&snes->jacobian);

2402:     snes->jacobian = Amat;
2403:   }
2404:   if (Pmat) {
2405:     PetscObjectReference((PetscObject)Pmat);
2406:     MatDestroy(&snes->jacobian_pre);

2408:     snes->jacobian_pre = Pmat;
2409:   }
2410:   return(0);
2411: }

2415: /*@C
2416:    SNESGetJacobian - Returns the Jacobian matrix and optionally the user
2417:    provided context for evaluating the Jacobian.

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

2421:    Input Parameter:
2422: .  snes - the nonlinear solver context

2424:    Output Parameters:
2425: +  Amat - location to stash (approximate) Jacobian matrix (or NULL)
2426: .  Pmat - location to stash matrix used to compute the preconditioner (or NULL)
2427: .  SNESJacobianFunction - location to put Jacobian function (or NULL)
2428: -  ctx - location to stash Jacobian ctx (or NULL)

2430:    Level: advanced

2432: .seealso: SNESSetJacobian(), SNESComputeJacobian()
2433: @*/
2434: PetscErrorCode SNESGetJacobian(SNES snes,Mat *Amat,Mat *Pmat,PetscErrorCode (**SNESJacobianFunction)(SNES,Vec,Mat*,Mat*,MatStructure*,void*),void **ctx)
2435: {
2437:   DM             dm;
2438:   DMSNES         sdm;

2442:   if (Amat) *Amat = snes->jacobian;
2443:   if (Pmat) *Pmat = snes->jacobian_pre;
2444:   SNESGetDM(snes,&dm);
2445:   DMGetDMSNES(dm,&sdm);
2446:   if (SNESJacobianFunction) *SNESJacobianFunction = sdm->ops->computejacobian;
2447:   if (ctx) *ctx = sdm->jacobianctx;
2448:   return(0);
2449: }

2453: /*@
2454:    SNESSetUp - Sets up the internal data structures for the later use
2455:    of a nonlinear solver.

2457:    Collective on SNES

2459:    Input Parameters:
2460: .  snes - the SNES context

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

2469:    Level: advanced

2471: .keywords: SNES, nonlinear, setup

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

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

2495:   if (!((PetscObject)snes)->type_name) {
2496:     SNESSetType(snes,SNESNEWTONLS);
2497:   }

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

2503:   if (!snes->vec_sol_update /* && snes->vec_sol */) {
2504:     VecDuplicate(snes->vec_sol,&snes->vec_sol_update);
2505:     PetscLogObjectParent(snes,snes->vec_sol_update);
2506:   }

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

2519:   if (!snes->ksp) {
2520:     SNESGetKSP(snes, &snes->ksp);
2521:   }

2523:   if (!snes->linesearch) {
2524:     SNESGetLineSearch(snes, &snes->linesearch);
2525:   }

2527:   if (snes->pc && (snes->pcside == PC_LEFT)) {
2528:     snes->mf          = PETSC_TRUE;
2529:     snes->mf_operator = PETSC_FALSE;
2530:   }

2532:   if (snes->mf) {
2533:     SNESSetUpMatrixFree_Private(snes, snes->mf_operator, snes->mf_version);
2534:   }

2536:   if (snes->ops->usercompute && !snes->user) {
2537:     (*snes->ops->usercompute)(snes,(void**)&snes->user);
2538:   }

2540:   if (snes->pc) {
2541:     /* copy the DM over */
2542:     SNESGetDM(snes,&dm);
2543:     SNESSetDM(snes->pc,dm);

2545:     SNESGetFunction(snes,&f,&func,&funcctx);
2546:     VecDuplicate(f,&fpc);
2547:     SNESSetFunction(snes->pc,fpc,func,funcctx);
2548:     SNESGetJacobian(snes,&A,&B,&jac,&jacctx);
2549:     SNESSetJacobian(snes->pc,A,B,jac,jacctx);
2550:     SNESGetApplicationContext(snes,&appctx);
2551:     SNESSetApplicationContext(snes->pc,appctx);
2552:     VecDestroy(&fpc);

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

2557:     /* default to 1 iteration */
2558:     SNESSetTolerances(snes->pc,0.0,0.0,0.0,1,snes->pc->max_funcs);
2559:     if (snes->pcside==PC_RIGHT) {
2560:       SNESSetNormType(snes->pc,SNES_NORM_FINAL_ONLY);
2561:     } else {
2562:       SNESSetNormType(snes->pc,SNES_NORM_NONE);
2563:     }
2564:     SNESSetFromOptions(snes->pc);

2566:     /* copy the line search context over */
2567:     SNESGetLineSearch(snes,&linesearch);
2568:     SNESGetLineSearch(snes->pc,&pclinesearch);
2569:     SNESLineSearchGetPreCheck(linesearch,&precheck,&lsprectx);
2570:     SNESLineSearchGetPostCheck(linesearch,&postcheck,&lspostctx);
2571:     SNESLineSearchSetPreCheck(pclinesearch,precheck,lsprectx);
2572:     SNESLineSearchSetPostCheck(pclinesearch,postcheck,lspostctx);
2573:     PetscObjectCopyFortranFunctionPointers((PetscObject)linesearch, (PetscObject)pclinesearch);
2574:   }

2576:   if (snes->ops->setup) {
2577:     (*snes->ops->setup)(snes);
2578:   }

2580:   snes->setupcalled = PETSC_TRUE;
2581:   return(0);
2582: }

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

2589:    Collective on SNES

2591:    Input Parameter:
2592: .  snes - iterative context obtained from SNESCreate()

2594:    Level: intermediate

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

2598: .keywords: SNES, destroy

2600: .seealso: SNESCreate(), SNESSetUp(), SNESSolve()
2601: @*/
2602: PetscErrorCode  SNESReset(SNES snes)
2603: {

2608:   if (snes->ops->userdestroy && snes->user) {
2609:     (*snes->ops->userdestroy)((void**)&snes->user);
2610:     snes->user = NULL;
2611:   }
2612:   if (snes->pc) {
2613:     SNESReset(snes->pc);
2614:   }

2616:   if (snes->ops->reset) {
2617:     (*snes->ops->reset)(snes);
2618:   }
2619:   if (snes->ksp) {
2620:     KSPReset(snes->ksp);
2621:   }

2623:   if (snes->linesearch) {
2624:     SNESLineSearchReset(snes->linesearch);
2625:   }

2627:   VecDestroy(&snes->vec_rhs);
2628:   VecDestroy(&snes->vec_sol);
2629:   VecDestroy(&snes->vec_sol_update);
2630:   VecDestroy(&snes->vec_func);
2631:   MatDestroy(&snes->jacobian);
2632:   MatDestroy(&snes->jacobian_pre);
2633:   VecDestroyVecs(snes->nwork,&snes->work);
2634:   VecDestroyVecs(snes->nvwork,&snes->vwork);

2636:   snes->nwork       = snes->nvwork = 0;
2637:   snes->setupcalled = PETSC_FALSE;
2638:   return(0);
2639: }

2643: /*@
2644:    SNESDestroy - Destroys the nonlinear solver context that was created
2645:    with SNESCreate().

2647:    Collective on SNES

2649:    Input Parameter:
2650: .  snes - the SNES context

2652:    Level: beginner

2654: .keywords: SNES, nonlinear, destroy

2656: .seealso: SNESCreate(), SNESSolve()
2657: @*/
2658: PetscErrorCode  SNESDestroy(SNES *snes)
2659: {

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

2667:   SNESReset((*snes));
2668:   SNESDestroy(&(*snes)->pc);

2670:   /* if memory was published with AMS then destroy it */
2671:   PetscObjectAMSViewOff((PetscObject)*snes);
2672:   if ((*snes)->ops->destroy) {(*((*snes))->ops->destroy)((*snes));}

2674:   DMDestroy(&(*snes)->dm);
2675:   KSPDestroy(&(*snes)->ksp);
2676:   SNESLineSearchDestroy(&(*snes)->linesearch);

2678:   PetscFree((*snes)->kspconvctx);
2679:   if ((*snes)->ops->convergeddestroy) {
2680:     (*(*snes)->ops->convergeddestroy)((*snes)->cnvP);
2681:   }
2682:   if ((*snes)->conv_malloc) {
2683:     PetscFree((*snes)->conv_hist);
2684:     PetscFree((*snes)->conv_hist_its);
2685:   }
2686:   SNESMonitorCancel((*snes));
2687:   PetscHeaderDestroy(snes);
2688:   return(0);
2689: }

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

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

2698:    Logically Collective on SNES

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

2705:    Options Database Keys:
2706: .    -snes_lag_preconditioner <lag>

2708:    Notes:
2709:    The default is 1
2710:    The preconditioner is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1
2711:    If  -1 is used before the very first nonlinear solve the preconditioner is still built because there is no previous preconditioner to use

2713:    Level: intermediate

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

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

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

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

2736:    Logically Collective on SNES

2738:    Input Parameters:
2739: +  snes - the SNES context
2740: -  steps - the number of refinements to do, defaults to 0

2742:    Options Database Keys:
2743: .    -snes_grid_sequence <steps>

2745:    Level: intermediate

2747:    Notes:
2748:    Use SNESGetSolution() to extract the fine grid solution after grid sequencing.

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

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

2754: @*/
2755: PetscErrorCode  SNESSetGridSequence(SNES snes,PetscInt steps)
2756: {
2760:   snes->gridsequence = steps;
2761:   return(0);
2762: }

2766: /*@
2767:    SNESGetLagPreconditioner - Indicates how often the preconditioner is rebuilt

2769:    Not Collective

2771:    Input Parameter:
2772: .  snes - the SNES context

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

2778:    Options Database Keys:
2779: .    -snes_lag_preconditioner <lag>

2781:    Notes:
2782:    The default is 1
2783:    The preconditioner is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1

2785:    Level: intermediate

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

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

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

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

2806:    Logically Collective on SNES

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

2813:    Options Database Keys:
2814: .    -snes_lag_jacobian <lag>

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

2822:    Level: intermediate

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

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

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

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

2845:    Not Collective

2847:    Input Parameter:
2848: .  snes - the SNES context

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

2854:    Options Database Keys:
2855: .    -snes_lag_jacobian <lag>

2857:    Notes:
2858:    The default is 1
2859:    The jacobian is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1

2861:    Level: intermediate

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

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

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

2878: /*@
2879:    SNESSetTolerances - Sets various parameters used in convergence tests.

2881:    Logically Collective on SNES

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

2891:    Options Database Keys:
2892: +    -snes_atol <abstol> - Sets abstol
2893: .    -snes_rtol <rtol> - Sets rtol
2894: .    -snes_stol <stol> - Sets stol
2895: .    -snes_max_it <maxit> - Sets maxit
2896: -    -snes_max_funcs <maxf> - Sets maxf

2898:    Notes:
2899:    The default maximum number of iterations is 50.
2900:    The default maximum number of function evaluations is 1000.

2902:    Level: intermediate

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

2906: .seealso: SNESSetTrustRegionTolerance()
2907: @*/
2908: PetscErrorCode  SNESSetTolerances(SNES snes,PetscReal abstol,PetscReal rtol,PetscReal stol,PetscInt maxit,PetscInt maxf)
2909: {

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

2944: /*@
2945:    SNESGetTolerances - Gets various parameters used in convergence tests.

2947:    Not Collective

2949:    Input Parameters:
2950: +  snes - the SNES context
2951: .  atol - absolute convergence tolerance
2952: .  rtol - relative convergence tolerance
2953: .  stol -  convergence tolerance in terms of the norm
2954:            of the change in the solution between steps
2955: .  maxit - maximum number of iterations
2956: -  maxf - maximum number of function evaluations

2958:    Notes:
2959:    The user can specify NULL for any parameter that is not needed.

2961:    Level: intermediate

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

2965: .seealso: SNESSetTolerances()
2966: @*/
2967: PetscErrorCode  SNESGetTolerances(SNES snes,PetscReal *atol,PetscReal *rtol,PetscReal *stol,PetscInt *maxit,PetscInt *maxf)
2968: {
2971:   if (atol)  *atol  = snes->abstol;
2972:   if (rtol)  *rtol  = snes->rtol;
2973:   if (stol)  *stol  = snes->stol;
2974:   if (maxit) *maxit = snes->max_its;
2975:   if (maxf)  *maxf  = snes->max_funcs;
2976:   return(0);
2977: }

2981: /*@
2982:    SNESSetTrustRegionTolerance - Sets the trust region parameter tolerance.

2984:    Logically Collective on SNES

2986:    Input Parameters:
2987: +  snes - the SNES context
2988: -  tol - tolerance

2990:    Options Database Key:
2991: .  -snes_trtol <tol> - Sets tol

2993:    Level: intermediate

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

2997: .seealso: SNESSetTolerances()
2998: @*/
2999: PetscErrorCode  SNESSetTrustRegionTolerance(SNES snes,PetscReal tol)
3000: {
3004:   snes->deltatol = tol;
3005:   return(0);
3006: }

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

3021:   KSPMonitorLGResidualNorm((KSP)snes,it,norm,ctx);
3022:   return(0);
3023: }

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

3032:   KSPMonitorLGResidualNormCreate(host,label,x,y,m,n,draw);
3033:   return(0);
3034: }

3038: PetscErrorCode  SNESMonitorLGDestroy(PetscDrawLG *draw)
3039: {

3043:   KSPMonitorLGResidualNormDestroy(draw);
3044:   return(0);
3045: }

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

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

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

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

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

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

3116:    Collective on SNES

3118:    Input Parameters:
3119: +  snes - nonlinear solver context obtained from SNESCreate()
3120: .  iter - iteration number
3121: -  rnorm - relative norm of the residual

3123:    Notes:
3124:    This routine is called by the SNES implementations.
3125:    It does not typically need to be called by the user.

3127:    Level: developer

3129: .seealso: SNESMonitorSet()
3130: @*/
3131: PetscErrorCode  SNESMonitor(SNES snes,PetscInt iter,PetscReal rnorm)
3132: {
3134:   PetscInt       i,n = snes->numbermonitors;

3137:   for (i=0; i<n; i++) {
3138:     (*snes->monitor[i])(snes,iter,rnorm,snes->monitorcontext[i]);
3139:   }
3140:   return(0);
3141: }

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

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

3148:      Synopsis:
3149:      #include "petscsnes.h"
3150: $    PetscErrorCode SNESMonitorFunction(SNES snes,PetscInt its, PetscReal norm,void *mctx)

3152: +    snes - the SNES context
3153: .    its - iteration number
3154: .    norm - 2-norm function value (may be estimated)
3155: -    mctx - [optional] monitoring context

3157:    Level: advanced

3159: .seealso:   SNESMonitorSet(), SNESMonitorGet()
3160: M*/

3164: /*@C
3165:    SNESMonitorSet - Sets an ADDITIONAL function that is to be used at every
3166:    iteration of the nonlinear solver to display the iteration's
3167:    progress.

3169:    Logically Collective on SNES

3171:    Input Parameters:
3172: +  snes - the SNES context
3173: .  SNESMonitorFunction - monitoring routine
3174: .  mctx - [optional] user-defined context for private data for the
3175:           monitor routine (use NULL if no context is desired)
3176: -  monitordestroy - [optional] routine that frees monitor context
3177:           (may be NULL)

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

3189:    Notes:
3190:    Several different monitoring routines may be set by calling
3191:    SNESMonitorSet() multiple times; all will be called in the
3192:    order in which they were set.

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

3196:    Level: intermediate

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

3200: .seealso: SNESMonitorDefault(), SNESMonitorCancel(), SNESMonitorFunction
3201: @*/
3202: PetscErrorCode  SNESMonitorSet(SNES snes,PetscErrorCode (*SNESMonitorFunction)(SNES,PetscInt,PetscReal,void*),void *mctx,PetscErrorCode (*monitordestroy)(void**))
3203: {
3204:   PetscInt       i;

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

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

3229:    Logically Collective on SNES

3231:    Input Parameters:
3232: .  snes - the SNES context

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

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

3242:    Level: intermediate

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

3246: .seealso: SNESMonitorDefault(), SNESMonitorSet()
3247: @*/
3248: PetscErrorCode  SNESMonitorCancel(SNES snes)
3249: {
3251:   PetscInt       i;

3255:   for (i=0; i<snes->numbermonitors; i++) {
3256:     if (snes->monitordestroy[i]) {
3257:       (*snes->monitordestroy[i])(&snes->monitorcontext[i]);
3258:     }
3259:   }
3260:   snes->numbermonitors = 0;
3261:   return(0);
3262: }

3264: /*MC
3265:     SNESConvergenceTestFunction - functional form used for testing of convergence of nonlinear solver

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

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

3279:    Level: intermediate

3281: .seealso:   SNESSetConvergenceTest(), SNESGetConvergenceTest()
3282: M*/

3286: /*@C
3287:    SNESSetConvergenceTest - Sets the function that is to be used
3288:    to test for convergence of the nonlinear iterative solution.

3290:    Logically Collective on SNES

3292:    Input Parameters:
3293: +  snes - the SNES context
3294: .  SNESConvergenceTestFunction - routine to test for convergence
3295: .  cctx - [optional] context for private data for the convergence routine  (may be NULL)
3296: -  destroy - [optional] destructor for the context (may be NULL; NULL_FUNCTION in Fortran)

3298:    Level: advanced

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

3302: .seealso: SNESConvergedDefault(), SNESSkipConverged(), SNESConvergenceTestFunction
3303: @*/
3304: PetscErrorCode  SNESSetConvergenceTest(SNES snes,PetscErrorCode (*SNESConvergenceTestFunction)(SNES,PetscInt,PetscReal,PetscReal,PetscReal,SNESConvergedReason*,void*),void *cctx,PetscErrorCode (*destroy)(void*))
3305: {

3310:   if (!SNESConvergenceTestFunction) SNESConvergenceTestFunction = SNESSkipConverged;
3311:   if (snes->ops->convergeddestroy) {
3312:     (*snes->ops->convergeddestroy)(snes->cnvP);
3313:   }
3314:   snes->ops->converged        = SNESConvergenceTestFunction;
3315:   snes->ops->convergeddestroy = destroy;
3316:   snes->cnvP                  = cctx;
3317:   return(0);
3318: }

3322: /*@
3323:    SNESGetConvergedReason - Gets the reason the SNES iteration was stopped.

3325:    Not Collective

3327:    Input Parameter:
3328: .  snes - the SNES context

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

3334:    Level: intermediate

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

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

3340: .seealso: SNESSetConvergenceTest(), SNESConvergedReason
3341: @*/
3342: PetscErrorCode  SNESGetConvergedReason(SNES snes,SNESConvergedReason *reason)
3343: {
3347:   *reason = snes->reason;
3348:   return(0);
3349: }

3353: /*@
3354:    SNESSetConvergenceHistory - Sets the array used to hold the convergence history.

3356:    Logically Collective on SNES

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

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

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

3374:    Level: intermediate

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

3378: .seealso: SNESGetConvergenceHistory()

3380: @*/
3381: PetscErrorCode  SNESSetConvergenceHistory(SNES snes,PetscReal a[],PetscInt its[],PetscInt na,PetscBool reset)
3382: {

3389:   if (!a) {
3390:     if (na == PETSC_DECIDE || na == PETSC_DEFAULT) na = 1000;
3391:     PetscMalloc(na*sizeof(PetscReal),&a);
3392:     PetscMalloc(na*sizeof(PetscInt),&its);

3394:     snes->conv_malloc = PETSC_TRUE;
3395:   }
3396:   snes->conv_hist       = a;
3397:   snes->conv_hist_its   = its;
3398:   snes->conv_hist_max   = na;
3399:   snes->conv_hist_len   = 0;
3400:   snes->conv_hist_reset = reset;
3401:   return(0);
3402: }

3404: #if defined(PETSC_HAVE_MATLAB_ENGINE)
3405: #include <engine.h>   /* MATLAB include file */
3406: #include <mex.h>      /* MATLAB include file */

3410: PETSC_EXTERN mxArray *SNESGetConvergenceHistoryMatlab(SNES snes)
3411: {
3412:   mxArray   *mat;
3413:   PetscInt  i;
3414:   PetscReal *ar;

3417:   mat = mxCreateDoubleMatrix(snes->conv_hist_len,1,mxREAL);
3418:   ar  = (PetscReal*) mxGetData(mat);
3419:   for (i=0; i<snes->conv_hist_len; i++) ar[i] = snes->conv_hist[i];
3420:   PetscFunctionReturn(mat);
3421: }
3422: #endif

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

3429:    Not Collective

3431:    Input Parameter:
3432: .  snes - iterative context obtained from SNESCreate()

3434:    Output Parameters:
3435: .  a   - array to hold history
3436: .  its - integer array holds the number of linear iterations (or
3437:          negative if not converged) for each solve.
3438: -  na  - size of a and its

3440:    Notes:
3441:     The calling sequence for this routine in Fortran is
3442: $   call SNESGetConvergenceHistory(SNES snes, integer na, integer ierr)

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

3448:    Level: intermediate

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

3452: .seealso: SNESSetConvergencHistory()

3454: @*/
3455: PetscErrorCode  SNESGetConvergenceHistory(SNES snes,PetscReal *a[],PetscInt *its[],PetscInt *na)
3456: {
3459:   if (a)   *a   = snes->conv_hist;
3460:   if (its) *its = snes->conv_hist_its;
3461:   if (na)  *na  = snes->conv_hist_len;
3462:   return(0);
3463: }

3467: /*@C
3468:   SNESSetUpdate - Sets the general-purpose update function called
3469:   at the beginning of every iteration of the nonlinear solve. Specifically
3470:   it is called just before the Jacobian is "evaluated".

3472:   Logically Collective on SNES

3474:   Input Parameters:
3475: . snes - The nonlinear solver context
3476: . func - The function

3478:   Calling sequence of func:
3479: . func (SNES snes, PetscInt step);

3481: . step - The current step of the iteration

3483:   Level: advanced

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

3488: .keywords: SNES, update

3490: .seealso SNESSetJacobian(), SNESSolve()
3491: @*/
3492: PetscErrorCode  SNESSetUpdate(SNES snes, PetscErrorCode (*func)(SNES, PetscInt))
3493: {
3496:   snes->ops->update = func;
3497:   return(0);
3498: }

3502: /*
3503:    SNESScaleStep_Private - Scales a step so that its length is less than the
3504:    positive parameter delta.

3506:     Input Parameters:
3507: +   snes - the SNES context
3508: .   y - approximate solution of linear system
3509: .   fnorm - 2-norm of current function
3510: -   delta - trust region size

3512:     Output Parameters:
3513: +   gpnorm - predicted function norm at the new point, assuming local
3514:     linearization.  The value is zero if the step lies within the trust
3515:     region, and exceeds zero otherwise.
3516: -   ynorm - 2-norm of the step

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

3522: .keywords: SNES, nonlinear, scale, step
3523: */
3524: PetscErrorCode SNESScaleStep_Private(SNES snes,Vec y,PetscReal *fnorm,PetscReal *delta,PetscReal *gpnorm,PetscReal *ynorm)
3525: {
3526:   PetscReal      nrm;
3527:   PetscScalar    cnorm;


3535:   VecNorm(y,NORM_2,&nrm);
3536:   if (nrm > *delta) {
3537:     nrm     = *delta/nrm;
3538:     *gpnorm = (1.0 - nrm)*(*fnorm);
3539:     cnorm   = nrm;
3540:     VecScale(y,cnorm);
3541:     *ynorm  = *delta;
3542:   } else {
3543:     *gpnorm = 0.0;
3544:     *ynorm  = nrm;
3545:   }
3546:   return(0);
3547: }

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

3555:    Collective on SNES

3557:    Input Parameters:
3558: +  snes - the SNES context
3559: .  b - the constant part of the equation F(x) = b, or NULL to use zero.
3560: -  x - the solution vector.

3562:    Notes:
3563:    The user should initialize the vector,x, with the initial guess
3564:    for the nonlinear solve prior to calling SNESSolve.  In particular,
3565:    to employ an initial guess of zero, the user should explicitly set
3566:    this vector to zero by calling VecSet().

3568:    Level: beginner

3570: .keywords: SNES, nonlinear, solve

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


3591:   if (!x) {
3592:     SNESGetDM(snes,&dm);
3593:     DMCreateGlobalVector(dm,&xcreated);
3594:     x    = xcreated;
3595:   }

3597:   PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes),((PetscObject)snes)->prefix,"-snes_view_pre",&viewer,&format,&flg);
3598:   if (flg && !PetscPreLoadingOn) {
3599:     PetscViewerPushFormat(viewer,format);
3600:     SNESView(snes,viewer);
3601:     PetscViewerPopFormat(viewer);
3602:     PetscViewerDestroy(&viewer);
3603:   }

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

3608:     /* set solution vector */
3609:     if (!grid) {PetscObjectReference((PetscObject)x);}
3610:     VecDestroy(&snes->vec_sol);
3611:     snes->vec_sol = x;
3612:     SNESGetDM(snes,&dm);

3614:     /* set affine vector if provided */
3615:     if (b) { PetscObjectReference((PetscObject)b); }
3616:     VecDestroy(&snes->vec_rhs);
3617:     snes->vec_rhs = b;

3619:     SNESSetUp(snes);

3621:     if (!grid) {
3622:       if (snes->ops->computeinitialguess) {
3623:         (*snes->ops->computeinitialguess)(snes,snes->vec_sol,snes->initialguessP);
3624:       }
3625:     }

3627:     if (snes->conv_hist_reset) snes->conv_hist_len = 0;
3628:     snes->nfuncs = 0; snes->linear_its = 0; snes->numFailures = 0;

3630:     PetscLogEventBegin(SNES_Solve,snes,0,0,0);
3631:     (*snes->ops->solve)(snes);
3632:     PetscLogEventEnd(SNES_Solve,snes,0,0,0);
3633:     if (snes->domainerror) {
3634:       snes->reason      = SNES_DIVERGED_FUNCTION_DOMAIN;
3635:       snes->domainerror = PETSC_FALSE;
3636:     }
3637:     if (!snes->reason) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Internal error, solver returned without setting converged reason");

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

3652:     if (snes->errorifnotconverged && snes->reason < 0) SETERRQ(PetscObjectComm((PetscObject)snes),PETSC_ERR_NOT_CONVERGED,"SNESSolve has not converged");
3653:     if (grid <  snes->gridsequence) {
3654:       DM  fine;
3655:       Vec xnew;
3656:       Mat interp;

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

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

3683:   VecDestroy(&xcreated);
3684:   PetscObjectAMSBlock((PetscObject)snes);
3685:   return(0);
3686: }

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

3692: /*@C
3693:    SNESSetType - Sets the method for the nonlinear solver.

3695:    Collective on SNES

3697:    Input Parameters:
3698: +  snes - the SNES context
3699: -  type - a known method

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

3705:    Notes:
3706:    See "petsc/include/petscsnes.h" for available methods (for instance)
3707: +    SNESNEWTONLS - Newton's method with line search
3708:      (systems of nonlinear equations)
3709: .    SNESNEWTONTR - Newton's method with trust region
3710:      (systems of nonlinear equations)

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

3723:   Level: intermediate

3725: .keywords: SNES, set, type

3727: .seealso: SNESType, SNESCreate()

3729: @*/
3730: PetscErrorCode  SNESSetType(SNES snes,SNESType type)
3731: {
3732:   PetscErrorCode ierr,(*r)(SNES);
3733:   PetscBool      match;


3739:   PetscObjectTypeCompare((PetscObject)snes,type,&match);
3740:   if (match) return(0);

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

3758:   PetscObjectChangeTypeName((PetscObject)snes,type);
3759:   (*r)(snes);
3760:   return(0);
3761: }

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

3768:    Not Collective

3770:    Input Parameter:
3771: .  snes - nonlinear solver context

3773:    Output Parameter:
3774: .  type - SNES method (a character string)

3776:    Level: intermediate

3778: .keywords: SNES, nonlinear, get, type, name
3779: @*/
3780: PetscErrorCode  SNESGetType(SNES snes,SNESType *type)
3781: {
3785:   *type = ((PetscObject)snes)->type_name;
3786:   return(0);
3787: }

3791: /*@
3792:    SNESGetSolution - Returns the vector where the approximate solution is
3793:    stored. This is the fine grid solution when using SNESSetGridSequence().

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

3797:    Input Parameter:
3798: .  snes - the SNES context

3800:    Output Parameter:
3801: .  x - the solution

3803:    Level: intermediate

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

3807: .seealso:  SNESGetSolutionUpdate(), SNESGetFunction()
3808: @*/
3809: PetscErrorCode  SNESGetSolution(SNES snes,Vec *x)
3810: {
3814:   *x = snes->vec_sol;
3815:   return(0);
3816: }

3820: /*@
3821:    SNESGetSolutionUpdate - Returns the vector where the solution update is
3822:    stored.

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

3826:    Input Parameter:
3827: .  snes - the SNES context

3829:    Output Parameter:
3830: .  x - the solution update

3832:    Level: advanced

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

3836: .seealso: SNESGetSolution(), SNESGetFunction()
3837: @*/
3838: PetscErrorCode  SNESGetSolutionUpdate(SNES snes,Vec *x)
3839: {
3843:   *x = snes->vec_sol_update;
3844:   return(0);
3845: }

3849: /*@C
3850:    SNESGetFunction - Returns the vector where the function is stored.

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

3854:    Input Parameter:
3855: .  snes - the SNES context

3857:    Output Parameter:
3858: +  r - the vector that is used to store residuals (or NULL if you don't want it)
3859: .  SNESFunction- the function (or NULL if you don't want it)
3860: -  ctx - the function context (or NULL if you don't want it)

3862:    Level: advanced

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

3866: .seealso: SNESSetFunction(), SNESGetSolution(), SNESFunction
3867: @*/
3868: PetscErrorCode  SNESGetFunction(SNES snes,Vec *r,PetscErrorCode (**SNESFunction)(SNES,Vec,Vec,void*),void **ctx)
3869: {
3871:   DM             dm;

3875:   if (r) {
3876:     if (!snes->vec_func) {
3877:       if (snes->vec_rhs) {
3878:         VecDuplicate(snes->vec_rhs,&snes->vec_func);
3879:       } else if (snes->vec_sol) {
3880:         VecDuplicate(snes->vec_sol,&snes->vec_func);
3881:       } else if (snes->dm) {
3882:         DMCreateGlobalVector(snes->dm,&snes->vec_func);
3883:       }
3884:     }
3885:     *r = snes->vec_func;
3886:   }
3887:   SNESGetDM(snes,&dm);
3888:   DMSNESGetFunction(dm,SNESFunction,ctx);
3889:   return(0);
3890: }

3892: /*@C
3893:    SNESGetGS - Returns the GS function and context.

3895:    Input Parameter:
3896: .  snes - the SNES context

3898:    Output Parameter:
3899: +  SNESGSFunction - the function (or NULL)
3900: -  ctx    - the function context (or NULL)

3902:    Level: advanced

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

3906: .seealso: SNESSetGS(), SNESGetFunction()
3907: @*/

3911: PetscErrorCode SNESGetGS (SNES snes, PetscErrorCode (**SNESGSFunction)(SNES, Vec, Vec, void*), void ** ctx)
3912: {
3914:   DM             dm;

3918:   SNESGetDM(snes,&dm);
3919:   DMSNESGetGS(dm,SNESGSFunction,ctx);
3920:   return(0);
3921: }

3925: /*@C
3926:    SNESSetOptionsPrefix - Sets the prefix used for searching for all
3927:    SNES options in the database.

3929:    Logically Collective on SNES

3931:    Input Parameter:
3932: +  snes - the SNES context
3933: -  prefix - the prefix to prepend to all option names

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

3939:    Level: advanced

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

3943: .seealso: SNESSetFromOptions()
3944: @*/
3945: PetscErrorCode  SNESSetOptionsPrefix(SNES snes,const char prefix[])
3946: {

3951:   PetscObjectSetOptionsPrefix((PetscObject)snes,prefix);
3952:   if (!snes->ksp) {SNESGetKSP(snes,&snes->ksp);}
3953:   if (snes->linesearch) {
3954:     SNESGetLineSearch(snes,&snes->linesearch);
3955:     PetscObjectSetOptionsPrefix((PetscObject)snes->linesearch,prefix);
3956:   }
3957:   KSPSetOptionsPrefix(snes->ksp,prefix);
3958:   return(0);
3959: }

3963: /*@C
3964:    SNESAppendOptionsPrefix - Appends to the prefix used for searching for all
3965:    SNES options in the database.

3967:    Logically Collective on SNES

3969:    Input Parameters:
3970: +  snes - the SNES context
3971: -  prefix - the prefix to prepend to all option names

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

3977:    Level: advanced

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

3981: .seealso: SNESGetOptionsPrefix()
3982: @*/
3983: PetscErrorCode  SNESAppendOptionsPrefix(SNES snes,const char prefix[])
3984: {

3989:   PetscObjectAppendOptionsPrefix((PetscObject)snes,prefix);
3990:   if (!snes->ksp) {SNESGetKSP(snes,&snes->ksp);}
3991:   if (snes->linesearch) {
3992:     SNESGetLineSearch(snes,&snes->linesearch);
3993:     PetscObjectAppendOptionsPrefix((PetscObject)snes->linesearch,prefix);
3994:   }
3995:   KSPAppendOptionsPrefix(snes->ksp,prefix);
3996:   return(0);
3997: }

4001: /*@C
4002:    SNESGetOptionsPrefix - Sets the prefix used for searching for all
4003:    SNES options in the database.

4005:    Not Collective

4007:    Input Parameter:
4008: .  snes - the SNES context

4010:    Output Parameter:
4011: .  prefix - pointer to the prefix string used

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

4016:    Level: advanced

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

4020: .seealso: SNESAppendOptionsPrefix()
4021: @*/
4022: PetscErrorCode  SNESGetOptionsPrefix(SNES snes,const char *prefix[])
4023: {

4028:   PetscObjectGetOptionsPrefix((PetscObject)snes,prefix);
4029:   return(0);
4030: }


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

4038:    Not collective

4040:    Input Parameters:
4041: +  name_solver - name of a new user-defined solver
4042: -  routine_create - routine to create method context

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

4047:    Sample usage:
4048: .vb
4049:    SNESRegister("my_solver",MySolverCreate);
4050: .ve

4052:    Then, your solver can be chosen with the procedural interface via
4053: $     SNESSetType(snes,"my_solver")
4054:    or at runtime via the option
4055: $     -snes_type my_solver

4057:    Level: advanced

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

4061: .keywords: SNES, nonlinear, register

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

4065:   Level: advanced
4066: @*/
4067: PetscErrorCode  SNESRegister(const char sname[],PetscErrorCode (*function)(SNES))
4068: {

4072:   PetscFunctionListAdd(&SNESList,sname,function);
4073:   return(0);
4074: }

4078: PetscErrorCode  SNESTestLocalMin(SNES snes)
4079: {
4081:   PetscInt       N,i,j;
4082:   Vec            u,uh,fh;
4083:   PetscScalar    value;
4084:   PetscReal      norm;

4087:   SNESGetSolution(snes,&u);
4088:   VecDuplicate(u,&uh);
4089:   VecDuplicate(u,&fh);

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

4114: /*@
4115:    SNESKSPSetUseEW - Sets SNES use Eisenstat-Walker method for
4116:    computing relative tolerance for linear solvers within an inexact
4117:    Newton method.

4119:    Logically Collective on SNES

4121:    Input Parameters:
4122: +  snes - SNES context
4123: -  flag - PETSC_TRUE or PETSC_FALSE

4125:     Options Database:
4126: +  -snes_ksp_ew - use Eisenstat-Walker method for determining linear system convergence
4127: .  -snes_ksp_ew_version ver - version of  Eisenstat-Walker method
4128: .  -snes_ksp_ew_rtol0 <rtol0> - Sets rtol0
4129: .  -snes_ksp_ew_rtolmax <rtolmax> - Sets rtolmax
4130: .  -snes_ksp_ew_gamma <gamma> - Sets gamma
4131: .  -snes_ksp_ew_alpha <alpha> - Sets alpha
4132: .  -snes_ksp_ew_alpha2 <alpha2> - Sets alpha2
4133: -  -snes_ksp_ew_threshold <threshold> - Sets threshold

4135:    Notes:
4136:    Currently, the default is to use a constant relative tolerance for
4137:    the inner linear solvers.  Alternatively, one can use the
4138:    Eisenstat-Walker method, where the relative convergence tolerance
4139:    is reset at each Newton iteration according progress of the nonlinear
4140:    solver.

4142:    Level: advanced

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

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

4150: .seealso: SNESKSPGetUseEW(), SNESKSPGetParametersEW(), SNESKSPSetParametersEW()
4151: @*/
4152: PetscErrorCode  SNESKSPSetUseEW(SNES snes,PetscBool flag)
4153: {
4157:   snes->ksp_ewconv = flag;
4158:   return(0);
4159: }

4163: /*@
4164:    SNESKSPGetUseEW - Gets if SNES is using Eisenstat-Walker method
4165:    for computing relative tolerance for linear solvers within an
4166:    inexact Newton method.

4168:    Not Collective

4170:    Input Parameter:
4171: .  snes - SNES context

4173:    Output Parameter:
4174: .  flag - PETSC_TRUE or PETSC_FALSE

4176:    Notes:
4177:    Currently, the default is to use a constant relative tolerance for
4178:    the inner linear solvers.  Alternatively, one can use the
4179:    Eisenstat-Walker method, where the relative convergence tolerance
4180:    is reset at each Newton iteration according progress of the nonlinear
4181:    solver.

4183:    Level: advanced

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

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

4191: .seealso: SNESKSPSetUseEW(), SNESKSPGetParametersEW(), SNESKSPSetParametersEW()
4192: @*/
4193: PetscErrorCode  SNESKSPGetUseEW(SNES snes, PetscBool  *flag)
4194: {
4198:   *flag = snes->ksp_ewconv;
4199:   return(0);
4200: }

4204: /*@
4205:    SNESKSPSetParametersEW - Sets parameters for Eisenstat-Walker
4206:    convergence criteria for the linear solvers within an inexact
4207:    Newton method.

4209:    Logically Collective on SNES

4211:    Input Parameters:
4212: +    snes - SNES context
4213: .    version - version 1, 2 (default is 2) or 3
4214: .    rtol_0 - initial relative tolerance (0 <= rtol_0 < 1)
4215: .    rtol_max - maximum relative tolerance (0 <= rtol_max < 1)
4216: .    gamma - multiplicative factor for version 2 rtol computation
4217:              (0 <= gamma2 <= 1)
4218: .    alpha - power for version 2 rtol computation (1 < alpha <= 2)
4219: .    alpha2 - power for safeguard
4220: -    threshold - threshold for imposing safeguard (0 < threshold < 1)

4222:    Note:
4223:    Version 3 was contributed by Luis Chacon, June 2006.

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

4227:    Level: advanced

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

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

4236: .seealso: SNESKSPSetUseEW(), SNESKSPGetUseEW(), SNESKSPGetParametersEW()
4237: @*/
4238: PetscErrorCode  SNESKSPSetParametersEW(SNES snes,PetscInt version,PetscReal rtol_0,PetscReal rtol_max,PetscReal gamma,PetscReal alpha,PetscReal alpha2,PetscReal threshold)
4239: {
4240:   SNESKSPEW *kctx;

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

4254:   if (version != PETSC_DEFAULT)   kctx->version   = version;
4255:   if (rtol_0 != PETSC_DEFAULT)    kctx->rtol_0    = rtol_0;
4256:   if (rtol_max != PETSC_DEFAULT)  kctx->rtol_max  = rtol_max;
4257:   if (gamma != PETSC_DEFAULT)     kctx->gamma     = gamma;
4258:   if (alpha != PETSC_DEFAULT)     kctx->alpha     = alpha;
4259:   if (alpha2 != PETSC_DEFAULT)    kctx->alpha2    = alpha2;
4260:   if (threshold != PETSC_DEFAULT) kctx->threshold = threshold;

4262:   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);
4263:   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);
4264:   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);
4265:   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);
4266:   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);
4267:   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);
4268:   return(0);
4269: }

4273: /*@
4274:    SNESKSPGetParametersEW - Gets parameters for Eisenstat-Walker
4275:    convergence criteria for the linear solvers within an inexact
4276:    Newton method.

4278:    Not Collective

4280:    Input Parameters:
4281:      snes - SNES context

4283:    Output Parameters:
4284: +    version - version 1, 2 (default is 2) or 3
4285: .    rtol_0 - initial relative tolerance (0 <= rtol_0 < 1)
4286: .    rtol_max - maximum relative tolerance (0 <= rtol_max < 1)
4287: .    gamma - multiplicative factor for version 2 rtol computation (0 <= gamma2 <= 1)
4288: .    alpha - power for version 2 rtol computation (1 < alpha <= 2)
4289: .    alpha2 - power for safeguard
4290: -    threshold - threshold for imposing safeguard (0 < threshold < 1)

4292:    Level: advanced

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

4296: .seealso: SNESKSPSetUseEW(), SNESKSPGetUseEW(), SNESKSPSetParametersEW()
4297: @*/
4298: PetscErrorCode  SNESKSPGetParametersEW(SNES snes,PetscInt *version,PetscReal *rtol_0,PetscReal *rtol_max,PetscReal *gamma,PetscReal *alpha,PetscReal *alpha2,PetscReal *threshold)
4299: {
4300:   SNESKSPEW *kctx;

4304:   kctx = (SNESKSPEW*)snes->kspconvctx;
4305:   if (!kctx) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context existing");
4306:   if (version)   *version   = kctx->version;
4307:   if (rtol_0)    *rtol_0    = kctx->rtol_0;
4308:   if (rtol_max)  *rtol_max  = kctx->rtol_max;
4309:   if (gamma)     *gamma     = kctx->gamma;
4310:   if (alpha)     *alpha     = kctx->alpha;
4311:   if (alpha2)    *alpha2    = kctx->alpha2;
4312:   if (threshold) *threshold = kctx->threshold;
4313:   return(0);
4314: }

4318:  PetscErrorCode SNESKSPEW_PreSolve(KSP ksp, Vec b, Vec x, SNES snes)
4319: {
4321:   SNESKSPEW      *kctx = (SNESKSPEW*)snes->kspconvctx;
4322:   PetscReal      rtol  = PETSC_DEFAULT,stol;

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

4358: PetscErrorCode SNESKSPEW_PostSolve(KSP ksp, Vec b, Vec x, SNES snes)
4359: {
4361:   SNESKSPEW      *kctx = (SNESKSPEW*)snes->kspconvctx;
4362:   PCSide         pcside;
4363:   Vec            lres;

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

4389: /*@
4390:    SNESGetKSP - Returns the KSP context for a SNES solver.

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

4394:    Input Parameter:
4395: .  snes - the SNES context

4397:    Output Parameter:
4398: .  ksp - the KSP context

4400:    Notes:
4401:    The user can then directly manipulate the KSP context to set various
4402:    options, etc.  Likewise, the user can then extract and manipulate the
4403:    PC contexts as well.

4405:    Level: beginner

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

4409: .seealso: KSPGetPC(), SNESCreate(), KSPCreate(), SNESSetKSP()
4410: @*/
4411: PetscErrorCode  SNESGetKSP(SNES snes,KSP *ksp)
4412: {


4419:   if (!snes->ksp) {
4420:     KSPCreate(PetscObjectComm((PetscObject)snes),&snes->ksp);
4421:     PetscObjectIncrementTabLevel((PetscObject)snes->ksp,(PetscObject)snes,1);
4422:     PetscLogObjectParent(snes,snes->ksp);

4424:     KSPSetPreSolve(snes->ksp,(PetscErrorCode (*)(KSP,Vec,Vec,void*))SNESKSPEW_PreSolve,snes);
4425:     KSPSetPostSolve(snes->ksp,(PetscErrorCode (*)(KSP,Vec,Vec,void*))SNESKSPEW_PostSolve,snes);
4426:   }
4427:   *ksp = snes->ksp;
4428:   return(0);
4429: }


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

4438:    Logically Collective on SNES

4440:    Input Parameters:
4441: +  snes - the preconditioner context
4442: -  dm - the dm

4444:    Level: intermediate

4446: .seealso: SNESGetDM(), KSPSetDM(), KSPGetDM()
4447: @*/
4448: PetscErrorCode  SNESSetDM(SNES snes,DM dm)
4449: {
4451:   KSP            ksp;
4452:   DMSNES         sdm;

4456:   if (dm) {PetscObjectReference((PetscObject)dm);}
4457:   if (snes->dm) {               /* Move the DMSNES context over to the new DM unless the new DM already has one */
4458:     if (snes->dm->dmsnes && snes->dmAuto && !dm->dmsnes) {
4459:       DMCopyDMSNES(snes->dm,dm);
4460:       DMGetDMSNES(snes->dm,&sdm);
4461:       if (sdm->originaldm == snes->dm) sdm->originaldm = dm; /* Grant write privileges to the replacement DM */
4462:     }
4463:     DMDestroy(&snes->dm);
4464:   }
4465:   snes->dm     = dm;
4466:   snes->dmAuto = PETSC_FALSE;

4468:   SNESGetKSP(snes,&ksp);
4469:   KSPSetDM(ksp,dm);
4470:   KSPSetDMActive(ksp,PETSC_FALSE);
4471:   if (snes->pc) {
4472:     SNESSetDM(snes->pc, snes->dm);
4473:     SNESSetPCSide(snes,snes->pcside);
4474:   }
4475:   return(0);
4476: }

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

4483:    Not Collective but DM obtained is parallel on SNES

4485:    Input Parameter:
4486: . snes - the preconditioner context

4488:    Output Parameter:
4489: .  dm - the dm

4491:    Level: intermediate

4493: .seealso: SNESSetDM(), KSPSetDM(), KSPGetDM()
4494: @*/
4495: PetscErrorCode  SNESGetDM(SNES snes,DM *dm)
4496: {

4501:   if (!snes->dm) {
4502:     DMShellCreate(PetscObjectComm((PetscObject)snes),&snes->dm);
4503:     snes->dmAuto = PETSC_TRUE;
4504:   }
4505:   *dm = snes->dm;
4506:   return(0);
4507: }

4511: /*@
4512:   SNESSetPC - Sets the nonlinear preconditioner to be used.

4514:   Collective on SNES

4516:   Input Parameters:
4517: + snes - iterative context obtained from SNESCreate()
4518: - pc   - the preconditioner object

4520:   Notes:
4521:   Use SNESGetPC() to retrieve the preconditioner context (for example,
4522:   to configure it using the API).

4524:   Level: developer

4526: .keywords: SNES, set, precondition
4527: .seealso: SNESGetPC()
4528: @*/
4529: PetscErrorCode SNESSetPC(SNES snes, SNES pc)
4530: {

4537:   PetscObjectReference((PetscObject) pc);
4538:   SNESDestroy(&snes->pc);
4539:   snes->pc = pc;
4540:   PetscLogObjectParent(snes, snes->pc);
4541:   return(0);
4542: }

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

4549:   Not Collective

4551:   Input Parameter:
4552: . snes - iterative context obtained from SNESCreate()

4554:   Output Parameter:
4555: . pc - preconditioner context

4557:   Level: developer

4559: .keywords: SNES, get, preconditioner
4560: .seealso: SNESSetPC()
4561: @*/
4562: PetscErrorCode SNESGetPC(SNES snes, SNES *pc)
4563: {
4565:   const char     *optionsprefix;

4570:   if (!snes->pc) {
4571:     SNESCreate(PetscObjectComm((PetscObject)snes),&snes->pc);
4572:     PetscObjectIncrementTabLevel((PetscObject)snes->pc,(PetscObject)snes,1);
4573:     PetscLogObjectParent(snes,snes->pc);
4574:     SNESGetOptionsPrefix(snes,&optionsprefix);
4575:     SNESSetOptionsPrefix(snes->pc,optionsprefix);
4576:     SNESAppendOptionsPrefix(snes->pc,"npc_");
4577:   }
4578:   *pc = snes->pc;
4579:   return(0);
4580: }

4584: /*@
4585:     SNESSetPCSide - Sets the preconditioning side.

4587:     Logically Collective on SNES

4589:     Input Parameter:
4590: .   snes - iterative context obtained from SNESCreate()

4592:     Output Parameter:
4593: .   side - the preconditioning side, where side is one of
4594: .vb
4595:       PC_LEFT - left preconditioning (default)
4596:       PC_RIGHT - right preconditioning
4597: .ve

4599:     Options Database Keys:
4600: .   -snes_pc_side <right,left>

4602:     Level: intermediate

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

4606: .seealso: SNESGetPCSide(), KSPSetPCSide()
4607: @*/
4608: PetscErrorCode  SNESSetPCSide(SNES snes,PCSide side)
4609: {
4613:   snes->pcside = side;
4614:   return(0);
4615: }

4619: /*@
4620:     SNESGetPCSide - Gets the preconditioning side.

4622:     Not Collective

4624:     Input Parameter:
4625: .   snes - iterative context obtained from SNESCreate()

4627:     Output Parameter:
4628: .   side - the preconditioning side, where side is one of
4629: .vb
4630:       PC_LEFT - left preconditioning (default)
4631:       PC_RIGHT - right preconditioning
4632: .ve

4634:     Level: intermediate

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

4638: .seealso: SNESSetPCSide(), KSPGetPCSide()
4639: @*/
4640: PetscErrorCode  SNESGetPCSide(SNES snes,PCSide *side)
4641: {
4645:   *side = snes->pcside;
4646:   return(0);
4647: }

4651: /*@
4652:   SNESSetLineSearch - Sets the linesearch on the SNES instance.

4654:   Collective on SNES

4656:   Input Parameters:
4657: + snes - iterative context obtained from SNESCreate()
4658: - linesearch   - the linesearch object

4660:   Notes:
4661:   Use SNESGetLineSearch() to retrieve the preconditioner context (for example,
4662:   to configure it using the API).

4664:   Level: developer

4666: .keywords: SNES, set, linesearch
4667: .seealso: SNESGetLineSearch()
4668: @*/
4669: PetscErrorCode SNESSetLineSearch(SNES snes, SNESLineSearch linesearch)
4670: {

4677:   PetscObjectReference((PetscObject) linesearch);
4678:   SNESLineSearchDestroy(&snes->linesearch);

4680:   snes->linesearch = linesearch;

4682:   PetscLogObjectParent(snes, snes->linesearch);
4683:   return(0);
4684: }

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

4692:   Not Collective

4694:   Input Parameter:
4695: . snes - iterative context obtained from SNESCreate()

4697:   Output Parameter:
4698: . linesearch - linesearch context

4700:   Level: developer

4702: .keywords: SNES, get, linesearch
4703: .seealso: SNESSetLineSearch()
4704: @*/
4705: PetscErrorCode SNESGetLineSearch(SNES snes, SNESLineSearch *linesearch)
4706: {
4708:   const char     *optionsprefix;

4713:   if (!snes->linesearch) {
4714:     SNESGetOptionsPrefix(snes, &optionsprefix);
4715:     SNESLineSearchCreate(PetscObjectComm((PetscObject)snes), &snes->linesearch);
4716:     SNESLineSearchSetSNES(snes->linesearch, snes);
4717:     SNESLineSearchAppendOptionsPrefix(snes->linesearch, optionsprefix);
4718:     PetscObjectIncrementTabLevel((PetscObject) snes->linesearch, (PetscObject) snes, 1);
4719:     PetscLogObjectParent(snes, snes->linesearch);
4720:   }
4721:   *linesearch = snes->linesearch;
4722:   return(0);
4723: }

4725: #if defined(PETSC_HAVE_MATLAB_ENGINE)
4726: #include <mex.h>

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

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

4735:    Collective on SNES

4737:    Input Parameters:
4738: +  snes - the SNES context
4739: -  x - input vector

4741:    Output Parameter:
4742: .  y - function vector, as set by SNESSetFunction()

4744:    Notes:
4745:    SNESComputeFunction() is typically used within nonlinear solvers
4746:    implementations, so most users would not generally call this routine
4747:    themselves.

4749:    Level: developer

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

4753: .seealso: SNESSetFunction(), SNESGetFunction()
4754: */
4755: PetscErrorCode  SNESComputeFunction_Matlab(SNES snes,Vec x,Vec y, void *ctx)
4756: {
4757:   PetscErrorCode    ierr;
4758:   SNESMatlabContext *sctx = (SNESMatlabContext*)ctx;
4759:   int               nlhs  = 1,nrhs = 5;
4760:   mxArray           *plhs[1],*prhs[5];
4761:   long long int     lx = 0,ly = 0,ls = 0;


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

4772:   PetscMemcpy(&ls,&snes,sizeof(snes));
4773:   PetscMemcpy(&lx,&x,sizeof(x));
4774:   PetscMemcpy(&ly,&y,sizeof(x));
4775:   prhs[0] = mxCreateDoubleScalar((double)ls);
4776:   prhs[1] = mxCreateDoubleScalar((double)lx);
4777:   prhs[2] = mxCreateDoubleScalar((double)ly);
4778:   prhs[3] = mxCreateString(sctx->funcname);
4779:   prhs[4] = sctx->ctx;
4780:   mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscSNESComputeFunctionInternal");
4781:   mxGetScalar(plhs[0]);
4782:   mxDestroyArray(prhs[0]);
4783:   mxDestroyArray(prhs[1]);
4784:   mxDestroyArray(prhs[2]);
4785:   mxDestroyArray(prhs[3]);
4786:   mxDestroyArray(plhs[0]);
4787:   return(0);
4788: }

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

4797:    Logically Collective on SNES

4799:    Input Parameters:
4800: +  snes - the SNES context
4801: .  r - vector to store function value
4802: -  SNESFunction - function evaluation routine

4804:    Notes:
4805:    The Newton-like methods typically solve linear systems of the form
4806: $      f'(x) x = -f(x),
4807:    where f'(x) denotes the Jacobian matrix and f(x) is the function.

4809:    Level: beginner

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

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

4815: .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction()
4816: */
4817: PetscErrorCode  SNESSetFunctionMatlab(SNES snes,Vec r,const char *SNESFunction,mxArray *ctx)
4818: {
4819:   PetscErrorCode    ierr;
4820:   SNESMatlabContext *sctx;

4823:   /* currently sctx is memory bleed */
4824:   PetscMalloc(sizeof(SNESMatlabContext),&sctx);
4825:   PetscStrallocpy(SNESFunction,&sctx->funcname);
4826:   /*
4827:      This should work, but it doesn't
4828:   sctx->ctx = ctx;
4829:   mexMakeArrayPersistent(sctx->ctx);
4830:   */
4831:   sctx->ctx = mxDuplicateArray(ctx);
4832:   SNESSetFunction(snes,r,SNESComputeFunction_Matlab,sctx);
4833:   return(0);
4834: }

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

4841:    Collective on SNES

4843:    Input Parameters:
4844: +  snes - the SNES context
4845: .  x - input vector
4846: .  A, B - the matrices
4847: -  ctx - user context

4849:    Output Parameter:
4850: .  flag - structure of the matrix

4852:    Level: developer

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

4856: .seealso: SNESSetFunction(), SNESGetFunction()
4857: @*/
4858: PetscErrorCode  SNESComputeJacobian_Matlab(SNES snes,Vec x,Mat *A,Mat *B,MatStructure *flag, void *ctx)
4859: {
4860:   PetscErrorCode    ierr;
4861:   SNESMatlabContext *sctx = (SNESMatlabContext*)ctx;
4862:   int               nlhs  = 2,nrhs = 6;
4863:   mxArray           *plhs[2],*prhs[6];
4864:   long long int     lx = 0,lA = 0,ls = 0, lB = 0;


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

4872:   PetscMemcpy(&ls,&snes,sizeof(snes));
4873:   PetscMemcpy(&lx,&x,sizeof(x));
4874:   PetscMemcpy(&lA,A,sizeof(x));
4875:   PetscMemcpy(&lB,B,sizeof(x));
4876:   prhs[0] = mxCreateDoubleScalar((double)ls);
4877:   prhs[1] = mxCreateDoubleScalar((double)lx);
4878:   prhs[2] = mxCreateDoubleScalar((double)lA);
4879:   prhs[3] = mxCreateDoubleScalar((double)lB);
4880:   prhs[4] = mxCreateString(sctx->funcname);
4881:   prhs[5] = sctx->ctx;
4882:   mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscSNESComputeJacobianInternal");
4883:   mxGetScalar(plhs[0]);
4884:   *flag   = (MatStructure) mxGetScalar(plhs[1]);
4885:   mxDestroyArray(prhs[0]);
4886:   mxDestroyArray(prhs[1]);
4887:   mxDestroyArray(prhs[2]);
4888:   mxDestroyArray(prhs[3]);
4889:   mxDestroyArray(prhs[4]);
4890:   mxDestroyArray(plhs[0]);
4891:   mxDestroyArray(plhs[1]);
4892:   return(0);
4893: }

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

4902:    Logically Collective on SNES

4904:    Input Parameters:
4905: +  snes - the SNES context
4906: .  A,B - Jacobian matrices
4907: .  SNESJacobianFunction - function evaluation routine
4908: -  ctx - user context

4910:    Level: developer

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

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

4916: .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction(), SNESJacobianFunction
4917: */
4918: PetscErrorCode  SNESSetJacobianMatlab(SNES snes,Mat A,Mat B,const char *SNESJacobianFunction,mxArray *ctx)
4919: {
4920:   PetscErrorCode    ierr;
4921:   SNESMatlabContext *sctx;

4924:   /* currently sctx is memory bleed */
4925:   PetscMalloc(sizeof(SNESMatlabContext),&sctx);
4926:   PetscStrallocpy(SNESJacobianFunction,&sctx->funcname);
4927:   /*
4928:      This should work, but it doesn't
4929:   sctx->ctx = ctx;
4930:   mexMakeArrayPersistent(sctx->ctx);
4931:   */
4932:   sctx->ctx = mxDuplicateArray(ctx);
4933:   SNESSetJacobian(snes,A,B,SNESComputeJacobian_Matlab,sctx);
4934:   return(0);
4935: }

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

4942:    Collective on SNES

4944: .seealso: SNESSetFunction(), SNESGetFunction()
4945: @*/
4946: PetscErrorCode  SNESMonitor_Matlab(SNES snes,PetscInt it, PetscReal fnorm, void *ctx)
4947: {
4948:   PetscErrorCode    ierr;
4949:   SNESMatlabContext *sctx = (SNESMatlabContext*)ctx;
4950:   int               nlhs  = 1,nrhs = 6;
4951:   mxArray           *plhs[1],*prhs[6];
4952:   long long int     lx = 0,ls = 0;
4953:   Vec               x  = snes->vec_sol;


4958:   PetscMemcpy(&ls,&snes,sizeof(snes));
4959:   PetscMemcpy(&lx,&x,sizeof(x));
4960:   prhs[0] = mxCreateDoubleScalar((double)ls);
4961:   prhs[1] = mxCreateDoubleScalar((double)it);
4962:   prhs[2] = mxCreateDoubleScalar((double)fnorm);
4963:   prhs[3] = mxCreateDoubleScalar((double)lx);
4964:   prhs[4] = mxCreateString(sctx->funcname);
4965:   prhs[5] = sctx->ctx;
4966:   mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscSNESMonitorInternal");
4967:   mxGetScalar(plhs[0]);
4968:   mxDestroyArray(prhs[0]);
4969:   mxDestroyArray(prhs[1]);
4970:   mxDestroyArray(prhs[2]);
4971:   mxDestroyArray(prhs[3]);
4972:   mxDestroyArray(prhs[4]);
4973:   mxDestroyArray(plhs[0]);
4974:   return(0);
4975: }

4979: /*
4980:    SNESMonitorSetMatlab - Sets the monitor function from MATLAB

4982:    Level: developer

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

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

4988: .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction()
4989: */
4990: PetscErrorCode  SNESMonitorSetMatlab(SNES snes,const char *SNESMonitorFunction,mxArray *ctx)
4991: {
4992:   PetscErrorCode    ierr;
4993:   SNESMatlabContext *sctx;

4996:   /* currently sctx is memory bleed */
4997:   PetscMalloc(sizeof(SNESMatlabContext),&sctx);
4998:   PetscStrallocpy(SNESMonitorFunction,&sctx->funcname);
4999:   /*
5000:      This should work, but it doesn't
5001:   sctx->ctx = ctx;
5002:   mexMakeArrayPersistent(sctx->ctx);
5003:   */
5004:   sctx->ctx = mxDuplicateArray(ctx);
5005:   SNESMonitorSet(snes,SNESMonitor_Matlab,sctx,NULL);
5006:   return(0);
5007: }

5009: #endif