xref: /petsc/src/snes/interface/snes.c (revision 4ffacfe27a72f4cdf51b68a3bbb6aed96040fb2f)
1 #include <petsc/private/snesimpl.h>      /*I "petscsnes.h"  I*/
2 #include <petscdmshell.h>
3 #include <petscdraw.h>
4 #include <petscds.h>
5 #include <petscdmadaptor.h>
6 #include <petscconvest.h>
7 
8 PetscBool         SNESRegisterAllCalled = PETSC_FALSE;
9 PetscFunctionList SNESList              = NULL;
10 
11 /* Logging support */
12 PetscClassId  SNES_CLASSID, DMSNES_CLASSID;
13 PetscLogEvent SNES_Solve, SNES_Setup, SNES_FunctionEval, SNES_JacobianEval, SNES_NGSEval, SNES_NGSFuncEval, SNES_NPCSolve, SNES_ObjectiveEval;
14 
15 /*@
16    SNESSetErrorIfNotConverged - Causes SNESSolve() to generate an error if the solver has not converged.
17 
18    Logically Collective on SNES
19 
20    Input Parameters:
21 +  snes - iterative context obtained from SNESCreate()
22 -  flg - PETSC_TRUE indicates you want the error generated
23 
24    Options database keys:
25 .  -snes_error_if_not_converged <true,false> - cause an immediate error condition and stop the program if the solver does not converge
26 
27    Level: intermediate
28 
29    Notes:
30     Normally PETSc continues if a linear solver fails to converge, you can call SNESGetConvergedReason() after a SNESSolve()
31     to determine if it has converged.
32 
33 .seealso: `SNESGetErrorIfNotConverged()`, `KSPGetErrorIfNotConverged()`, `KSPSetErrorIfNotConverged()`
34 @*/
35 PetscErrorCode  SNESSetErrorIfNotConverged(SNES snes,PetscBool flg)
36 {
37   PetscFunctionBegin;
38   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
39   PetscValidLogicalCollectiveBool(snes,flg,2);
40   snes->errorifnotconverged = flg;
41   PetscFunctionReturn(0);
42 }
43 
44 /*@
45    SNESGetErrorIfNotConverged - Will SNESSolve() generate an error if the solver does not converge?
46 
47    Not Collective
48 
49    Input Parameter:
50 .  snes - iterative context obtained from SNESCreate()
51 
52    Output Parameter:
53 .  flag - PETSC_TRUE if it will generate an error, else PETSC_FALSE
54 
55    Level: intermediate
56 
57 .seealso: `SNESSetErrorIfNotConverged()`, `KSPGetErrorIfNotConverged()`, `KSPSetErrorIfNotConverged()`
58 @*/
59 PetscErrorCode  SNESGetErrorIfNotConverged(SNES snes,PetscBool  *flag)
60 {
61   PetscFunctionBegin;
62   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
63   PetscValidBoolPointer(flag,2);
64   *flag = snes->errorifnotconverged;
65   PetscFunctionReturn(0);
66 }
67 
68 /*@
69     SNESSetAlwaysComputesFinalResidual - does the SNES always compute the residual at the final solution?
70 
71    Logically Collective on SNES
72 
73     Input Parameters:
74 +   snes - the shell SNES
75 -   flg - is the residual computed?
76 
77    Level: advanced
78 
79 .seealso: `SNESGetAlwaysComputesFinalResidual()`
80 @*/
81 PetscErrorCode  SNESSetAlwaysComputesFinalResidual(SNES snes, PetscBool flg)
82 {
83   PetscFunctionBegin;
84   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
85   snes->alwayscomputesfinalresidual = flg;
86   PetscFunctionReturn(0);
87 }
88 
89 /*@
90     SNESGetAlwaysComputesFinalResidual - does the SNES always compute the residual at the final solution?
91 
92    Logically Collective on SNES
93 
94     Input Parameter:
95 .   snes - the shell SNES
96 
97     Output Parameter:
98 .   flg - is the residual computed?
99 
100    Level: advanced
101 
102 .seealso: `SNESSetAlwaysComputesFinalResidual()`
103 @*/
104 PetscErrorCode  SNESGetAlwaysComputesFinalResidual(SNES snes, PetscBool *flg)
105 {
106   PetscFunctionBegin;
107   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
108   *flg = snes->alwayscomputesfinalresidual;
109   PetscFunctionReturn(0);
110 }
111 
112 /*@
113    SNESSetFunctionDomainError - tells SNES that the input vector to your SNESFunction is not
114      in the functions domain. For example, a step with negative pressure.
115 
116    Logically Collective on SNES
117 
118    Input Parameters:
119 .  snes - the SNES context
120 
121    Level: advanced
122 
123    Note:
124    You can direct `SNES` to avoid certain steps by using `SNESVISetVariableBounds()`, `SNESVISetComputeVariableBounds()` or
125    `SNESLineSearchSetPreCheck()`, `SNESLineSearchSetPostCheck()`
126 
127 .seealso: `SNESCreate()`, `SNESSetFunction()`, `SNESFunction`, `SNESSetJacobianDomainError()`, `SNESVISetVariableBounds()`,
128           `SNESVISetComputeVariableBounds()`, `SNESLineSearchSetPreCheck()`, `SNESLineSearchSetPostCheck()`
129 @*/
130 PetscErrorCode  SNESSetFunctionDomainError(SNES snes)
131 {
132   PetscFunctionBegin;
133   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
134   PetscCheck(!snes->errorifnotconverged,PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"User code indicates input vector is not in the function domain");
135   snes->domainerror = PETSC_TRUE;
136   PetscFunctionReturn(0);
137 }
138 
139 /*@
140    SNESSetJacobianDomainError - tells SNES that computeJacobian does not make sense at the proposed step. For example there is a negative element transformation.
141 
142    Logically Collective on SNES
143 
144    Input Parameters:
145 .  snes - the SNES context
146 
147    Level: advanced
148 
149    Note:
150    You can direct `SNES` to avoid certain steps by using `SNESVISetVariableBounds()`, `SNESVISetComputeVariableBounds()` or
151    `SNESLineSearchSetPreCheck()`, `SNESLineSearchSetPostCheck()`
152 
153 .seealso: `SNESCreate()`, `SNESSetFunction()`, `SNESFunction()`, `SNESSetFunctionDomainError()`, `SNESVISetVariableBounds()`,
154           `SNESVISetComputeVariableBounds()`, `SNESLineSearchSetPreCheck()`, `SNESLineSearchSetPostCheck()`
155 @*/
156 PetscErrorCode SNESSetJacobianDomainError(SNES snes)
157 {
158   PetscFunctionBegin;
159   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
160   PetscCheck(!snes->errorifnotconverged,PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"User code indicates computeJacobian does not make sense");
161   snes->jacobiandomainerror = PETSC_TRUE;
162   PetscFunctionReturn(0);
163 }
164 
165 /*@
166    SNESSetCheckJacobianDomainError - if or not to check jacobian domain error after each Jacobian evaluation. By default, we check Jacobian domain error
167    in the debug mode, and do not check it in the optimized mode.
168 
169    Logically Collective on SNES
170 
171    Input Parameters:
172 +  snes - the SNES context
173 -  flg  - indicates if or not to check jacobian domain error after each Jacobian evaluation
174 
175    Level: advanced
176 
177 .seealso: `SNESCreate()`, `SNESSetFunction()`, `SNESFunction()`, `SNESSetFunctionDomainError()`, `SNESGetCheckJacobianDomainError()`
178 @*/
179 PetscErrorCode SNESSetCheckJacobianDomainError(SNES snes, PetscBool flg)
180 {
181   PetscFunctionBegin;
182   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
183   snes->checkjacdomainerror = flg;
184   PetscFunctionReturn(0);
185 }
186 
187 /*@
188    SNESGetCheckJacobianDomainError - Get an indicator whether or not we are checking Jacobian domain errors after each Jacobian evaluation.
189 
190    Logically Collective on SNES
191 
192    Input Parameters:
193 .  snes - the SNES context
194 
195    Output Parameters:
196 .  flg  - PETSC_FALSE indicates that we don't check jacobian domain errors after each Jacobian evaluation
197 
198    Level: advanced
199 
200 .seealso: `SNESCreate()`, `SNESSetFunction()`, `SNESFunction()`, `SNESSetFunctionDomainError()`, `SNESSetCheckJacobianDomainError()`
201 @*/
202 PetscErrorCode SNESGetCheckJacobianDomainError(SNES snes, PetscBool *flg)
203 {
204   PetscFunctionBegin;
205   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
206   PetscValidBoolPointer(flg,2);
207   *flg = snes->checkjacdomainerror;
208   PetscFunctionReturn(0);
209 }
210 
211 /*@
212    SNESGetFunctionDomainError - Gets the status of the domain error after a call to SNESComputeFunction;
213 
214    Logically Collective on SNES
215 
216    Input Parameters:
217 .  snes - the SNES context
218 
219    Output Parameters:
220 .  domainerror - Set to PETSC_TRUE if there's a domain error; PETSC_FALSE otherwise.
221 
222    Level: advanced
223 
224 .seealso: `SNESSetFunctionDomainError()`, `SNESComputeFunction()`
225 @*/
226 PetscErrorCode  SNESGetFunctionDomainError(SNES snes, PetscBool *domainerror)
227 {
228   PetscFunctionBegin;
229   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
230   PetscValidBoolPointer(domainerror,2);
231   *domainerror = snes->domainerror;
232   PetscFunctionReturn(0);
233 }
234 
235 /*@
236    SNESGetJacobianDomainError - Gets the status of the Jacobian domain error after a call to SNESComputeJacobian;
237 
238    Logically Collective on SNES
239 
240    Input Parameters:
241 .  snes - the SNES context
242 
243    Output Parameters:
244 .  domainerror - Set to PETSC_TRUE if there's a jacobian domain error; PETSC_FALSE otherwise.
245 
246    Level: advanced
247 
248 .seealso: `SNESSetFunctionDomainError()`, `SNESComputeFunction()`, `SNESGetFunctionDomainError()`
249 @*/
250 PetscErrorCode SNESGetJacobianDomainError(SNES snes, PetscBool *domainerror)
251 {
252   PetscFunctionBegin;
253   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
254   PetscValidBoolPointer(domainerror,2);
255   *domainerror = snes->jacobiandomainerror;
256   PetscFunctionReturn(0);
257 }
258 
259 /*@C
260   SNESLoad - Loads a SNES that has been stored in binary  with SNESView().
261 
262   Collective on PetscViewer
263 
264   Input Parameters:
265 + newdm - the newly loaded SNES, this needs to have been created with SNESCreate() or
266            some related function before a call to SNESLoad().
267 - viewer - binary file viewer, obtained from PetscViewerBinaryOpen()
268 
269    Level: intermediate
270 
271   Notes:
272    The type is determined by the data in the file, any type set into the SNES before this call is ignored.
273 
274   Notes for advanced users:
275   Most users should not need to know the details of the binary storage
276   format, since SNESLoad() and TSView() completely hide these details.
277   But for anyone who's interested, the standard binary matrix storage
278   format is
279 .vb
280      has not yet been determined
281 .ve
282 
283 .seealso: `PetscViewerBinaryOpen()`, `SNESView()`, `MatLoad()`, `VecLoad()`
284 @*/
285 PetscErrorCode  SNESLoad(SNES snes, PetscViewer viewer)
286 {
287   PetscBool      isbinary;
288   PetscInt       classid;
289   char           type[256];
290   KSP            ksp;
291   DM             dm;
292   DMSNES         dmsnes;
293 
294   PetscFunctionBegin;
295   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
296   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2);
297   PetscCall(PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&isbinary));
298   PetscCheck(isbinary,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Invalid viewer; open viewer with PetscViewerBinaryOpen()");
299 
300   PetscCall(PetscViewerBinaryRead(viewer,&classid,1,NULL,PETSC_INT));
301   PetscCheck(classid == SNES_FILE_CLASSID,PetscObjectComm((PetscObject)snes),PETSC_ERR_ARG_WRONG,"Not SNES next in file");
302   PetscCall(PetscViewerBinaryRead(viewer,type,256,NULL,PETSC_CHAR));
303   PetscCall(SNESSetType(snes, type));
304   if (snes->ops->load) PetscCall((*snes->ops->load)(snes,viewer));
305   PetscCall(SNESGetDM(snes,&dm));
306   PetscCall(DMGetDMSNES(dm,&dmsnes));
307   PetscCall(DMSNESLoad(dmsnes,viewer));
308   PetscCall(SNESGetKSP(snes,&ksp));
309   PetscCall(KSPLoad(ksp,viewer));
310   PetscFunctionReturn(0);
311 }
312 
313 #include <petscdraw.h>
314 #if defined(PETSC_HAVE_SAWS)
315 #include <petscviewersaws.h>
316 #endif
317 
318 /*@C
319    SNESViewFromOptions - View from Options
320 
321    Collective on SNES
322 
323    Input Parameters:
324 +  A - the application ordering context
325 .  obj - Optional object
326 -  name - command line option
327 
328    Level: intermediate
329 .seealso: `SNES`, `SNESView`, `PetscObjectViewFromOptions()`, `SNESCreate()`
330 @*/
331 PetscErrorCode  SNESViewFromOptions(SNES A,PetscObject obj,const char name[])
332 {
333   PetscFunctionBegin;
334   PetscValidHeaderSpecific(A,SNES_CLASSID,1);
335   PetscCall(PetscObjectViewFromOptions((PetscObject)A,obj,name));
336   PetscFunctionReturn(0);
337 }
338 
339 PETSC_EXTERN PetscErrorCode SNESComputeJacobian_DMDA(SNES,Vec,Mat,Mat,void*);
340 
341 /*@C
342    SNESView - Prints the SNES data structure.
343 
344    Collective on SNES
345 
346    Input Parameters:
347 +  SNES - the SNES context
348 -  viewer - visualization context
349 
350    Options Database Key:
351 .  -snes_view - Calls SNESView() at end of SNESSolve()
352 
353    Notes:
354    The available visualization contexts include
355 +     PETSC_VIEWER_STDOUT_SELF - standard output (default)
356 -     PETSC_VIEWER_STDOUT_WORLD - synchronized standard
357          output where only the first processor opens
358          the file.  All other processors send their
359          data to the first processor to print.
360 
361    The available formats include
362 +     PETSC_VIEWER_DEFAULT - standard output (default)
363 -     PETSC_VIEWER_ASCII_INFO_DETAIL - more verbose output for SNESNASM
364 
365    The user can open an alternative visualization context with
366    PetscViewerASCIIOpen() - output to a specified file.
367 
368   In the debugger you can do "call SNESView(snes,0)" to display the SNES solver. (The same holds for any PETSc object viewer).
369 
370    Level: beginner
371 
372 .seealso: `PetscViewerASCIIOpen()`
373 @*/
374 PetscErrorCode  SNESView(SNES snes,PetscViewer viewer)
375 {
376   SNESKSPEW      *kctx;
377   KSP            ksp;
378   SNESLineSearch linesearch;
379   PetscBool      iascii,isstring,isbinary,isdraw;
380   DMSNES         dmsnes;
381 #if defined(PETSC_HAVE_SAWS)
382   PetscBool      issaws;
383 #endif
384 
385   PetscFunctionBegin;
386   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
387   if (!viewer) {
388     PetscCall(PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)snes),&viewer));
389   }
390   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2);
391   PetscCheckSameComm(snes,1,viewer,2);
392 
393   PetscCall(PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii));
394   PetscCall(PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERSTRING,&isstring));
395   PetscCall(PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&isbinary));
396   PetscCall(PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERDRAW,&isdraw));
397 #if defined(PETSC_HAVE_SAWS)
398   PetscCall(PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERSAWS,&issaws));
399 #endif
400   if (iascii) {
401     SNESNormSchedule normschedule;
402     DM               dm;
403     PetscErrorCode   (*cJ)(SNES,Vec,Mat,Mat,void*);
404     void             *ctx;
405     const char       *pre = "";
406 
407     PetscCall(PetscObjectPrintClassNamePrefixType((PetscObject)snes,viewer));
408     if (!snes->setupcalled) {
409       PetscCall(PetscViewerASCIIPrintf(viewer,"  SNES has not been set up so information may be incomplete\n"));
410     }
411     if (snes->ops->view) {
412       PetscCall(PetscViewerASCIIPushTab(viewer));
413       PetscCall((*snes->ops->view)(snes,viewer));
414       PetscCall(PetscViewerASCIIPopTab(viewer));
415     }
416     PetscCall(PetscViewerASCIIPrintf(viewer,"  maximum iterations=%" PetscInt_FMT ", maximum function evaluations=%" PetscInt_FMT "\n",snes->max_its,snes->max_funcs));
417     PetscCall(PetscViewerASCIIPrintf(viewer,"  tolerances: relative=%g, absolute=%g, solution=%g\n",(double)snes->rtol,(double)snes->abstol,(double)snes->stol));
418     if (snes->usesksp) {
419       PetscCall(PetscViewerASCIIPrintf(viewer,"  total number of linear solver iterations=%" PetscInt_FMT "\n",snes->linear_its));
420     }
421     PetscCall(PetscViewerASCIIPrintf(viewer,"  total number of function evaluations=%" PetscInt_FMT "\n",snes->nfuncs));
422     PetscCall(SNESGetNormSchedule(snes, &normschedule));
423     if (normschedule > 0) PetscCall(PetscViewerASCIIPrintf(viewer,"  norm schedule %s\n",SNESNormSchedules[normschedule]));
424     if (snes->gridsequence) {
425       PetscCall(PetscViewerASCIIPrintf(viewer,"  total number of grid sequence refinements=%" PetscInt_FMT "\n",snes->gridsequence));
426     }
427     if (snes->ksp_ewconv) {
428       kctx = (SNESKSPEW*)snes->kspconvctx;
429       if (kctx) {
430         PetscCall(PetscViewerASCIIPrintf(viewer,"  Eisenstat-Walker computation of KSP relative tolerance (version %" PetscInt_FMT ")\n",kctx->version));
431         PetscCall(PetscViewerASCIIPrintf(viewer,"    rtol_0=%g, rtol_max=%g, threshold=%g\n",(double)kctx->rtol_0,(double)kctx->rtol_max,(double)kctx->threshold));
432         PetscCall(PetscViewerASCIIPrintf(viewer,"    gamma=%g, alpha=%g, alpha2=%g\n",(double)kctx->gamma,(double)kctx->alpha,(double)kctx->alpha2));
433       }
434     }
435     if (snes->lagpreconditioner == -1) {
436       PetscCall(PetscViewerASCIIPrintf(viewer,"  Preconditioned is never rebuilt\n"));
437     } else if (snes->lagpreconditioner > 1) {
438       PetscCall(PetscViewerASCIIPrintf(viewer,"  Preconditioned is rebuilt every %" PetscInt_FMT " new Jacobians\n",snes->lagpreconditioner));
439     }
440     if (snes->lagjacobian == -1) {
441       PetscCall(PetscViewerASCIIPrintf(viewer,"  Jacobian is never rebuilt\n"));
442     } else if (snes->lagjacobian > 1) {
443       PetscCall(PetscViewerASCIIPrintf(viewer,"  Jacobian is rebuilt every %" PetscInt_FMT " SNES iterations\n",snes->lagjacobian));
444     }
445     PetscCall(SNESGetDM(snes,&dm));
446     PetscCall(DMSNESGetJacobian(dm,&cJ,&ctx));
447     if (snes->mf_operator) {
448       PetscCall(PetscViewerASCIIPrintf(viewer,"  Jacobian is applied matrix-free with differencing\n"));
449       pre  = "Preconditioning ";
450     }
451     if (cJ == SNESComputeJacobianDefault) {
452       PetscCall(PetscViewerASCIIPrintf(viewer,"  %sJacobian is built using finite differences one column at a time\n",pre));
453     } else if (cJ == SNESComputeJacobianDefaultColor) {
454       PetscCall(PetscViewerASCIIPrintf(viewer,"  %sJacobian is built using finite differences with coloring\n",pre));
455     /* it slightly breaks data encapsulation for access the DMDA information directly */
456     } else if (cJ == SNESComputeJacobian_DMDA) {
457       MatFDColoring fdcoloring;
458       PetscCall(PetscObjectQuery((PetscObject)dm,"DMDASNES_FDCOLORING",(PetscObject*)&fdcoloring));
459       if (fdcoloring) {
460         PetscCall(PetscViewerASCIIPrintf(viewer,"  %sJacobian is built using colored finite differences on a DMDA\n",pre));
461       } else {
462         PetscCall(PetscViewerASCIIPrintf(viewer,"  %sJacobian is built using a DMDA local Jacobian\n",pre));
463       }
464     } else if (snes->mf) {
465       PetscCall(PetscViewerASCIIPrintf(viewer,"  Jacobian is applied matrix-free with differencing, no explicit Jacobian\n"));
466     }
467   } else if (isstring) {
468     const char *type;
469     PetscCall(SNESGetType(snes,&type));
470     PetscCall(PetscViewerStringSPrintf(viewer," SNESType: %-7.7s",type));
471     if (snes->ops->view) PetscCall((*snes->ops->view)(snes,viewer));
472   } else if (isbinary) {
473     PetscInt    classid = SNES_FILE_CLASSID;
474     MPI_Comm    comm;
475     PetscMPIInt rank;
476     char        type[256];
477 
478     PetscCall(PetscObjectGetComm((PetscObject)snes,&comm));
479     PetscCallMPI(MPI_Comm_rank(comm,&rank));
480     if (rank == 0) {
481       PetscCall(PetscViewerBinaryWrite(viewer,&classid,1,PETSC_INT));
482       PetscCall(PetscStrncpy(type,((PetscObject)snes)->type_name,sizeof(type)));
483       PetscCall(PetscViewerBinaryWrite(viewer,type,sizeof(type),PETSC_CHAR));
484     }
485     if (snes->ops->view) PetscCall((*snes->ops->view)(snes,viewer));
486   } else if (isdraw) {
487     PetscDraw draw;
488     char      str[36];
489     PetscReal x,y,bottom,h;
490 
491     PetscCall(PetscViewerDrawGetDraw(viewer,0,&draw));
492     PetscCall(PetscDrawGetCurrentPoint(draw,&x,&y));
493     PetscCall(PetscStrncpy(str,"SNES: ",sizeof(str)));
494     PetscCall(PetscStrlcat(str,((PetscObject)snes)->type_name,sizeof(str)));
495     PetscCall(PetscDrawStringBoxed(draw,x,y,PETSC_DRAW_BLUE,PETSC_DRAW_BLACK,str,NULL,&h));
496     bottom = y - h;
497     PetscCall(PetscDrawPushCurrentPoint(draw,x,bottom));
498     if (snes->ops->view) PetscCall((*snes->ops->view)(snes,viewer));
499 #if defined(PETSC_HAVE_SAWS)
500   } else if (issaws) {
501     PetscMPIInt rank;
502     const char *name;
503 
504     PetscCall(PetscObjectGetName((PetscObject)snes,&name));
505     PetscCallMPI(MPI_Comm_rank(PETSC_COMM_WORLD,&rank));
506     if (!((PetscObject)snes)->amsmem && rank == 0) {
507       char       dir[1024];
508 
509       PetscCall(PetscObjectViewSAWs((PetscObject)snes,viewer));
510       PetscCall(PetscSNPrintf(dir,1024,"/PETSc/Objects/%s/its",name));
511       PetscStackCallSAWs(SAWs_Register,(dir,&snes->iter,1,SAWs_READ,SAWs_INT));
512       if (!snes->conv_hist) {
513         PetscCall(SNESSetConvergenceHistory(snes,NULL,NULL,PETSC_DECIDE,PETSC_TRUE));
514       }
515       PetscCall(PetscSNPrintf(dir,1024,"/PETSc/Objects/%s/conv_hist",name));
516       PetscStackCallSAWs(SAWs_Register,(dir,snes->conv_hist,10,SAWs_READ,SAWs_DOUBLE));
517     }
518 #endif
519   }
520   if (snes->linesearch) {
521     PetscCall(SNESGetLineSearch(snes, &linesearch));
522     PetscCall(PetscViewerASCIIPushTab(viewer));
523     PetscCall(SNESLineSearchView(linesearch, viewer));
524     PetscCall(PetscViewerASCIIPopTab(viewer));
525   }
526   if (snes->npc && snes->usesnpc) {
527     PetscCall(PetscViewerASCIIPushTab(viewer));
528     PetscCall(SNESView(snes->npc, viewer));
529     PetscCall(PetscViewerASCIIPopTab(viewer));
530   }
531   PetscCall(PetscViewerASCIIPushTab(viewer));
532   PetscCall(DMGetDMSNES(snes->dm,&dmsnes));
533   PetscCall(DMSNESView(dmsnes, viewer));
534   PetscCall(PetscViewerASCIIPopTab(viewer));
535   if (snes->usesksp) {
536     PetscCall(SNESGetKSP(snes,&ksp));
537     PetscCall(PetscViewerASCIIPushTab(viewer));
538     PetscCall(KSPView(ksp,viewer));
539     PetscCall(PetscViewerASCIIPopTab(viewer));
540   }
541   if (isdraw) {
542     PetscDraw draw;
543     PetscCall(PetscViewerDrawGetDraw(viewer,0,&draw));
544     PetscCall(PetscDrawPopCurrentPoint(draw));
545   }
546   PetscFunctionReturn(0);
547 }
548 
549 /*
550   We retain a list of functions that also take SNES command
551   line options. These are called at the end SNESSetFromOptions()
552 */
553 #define MAXSETFROMOPTIONS 5
554 static PetscInt numberofsetfromoptions;
555 static PetscErrorCode (*othersetfromoptions[MAXSETFROMOPTIONS])(SNES);
556 
557 /*@C
558   SNESAddOptionsChecker - Adds an additional function to check for SNES options.
559 
560   Not Collective
561 
562   Input Parameter:
563 . snescheck - function that checks for options
564 
565   Level: developer
566 
567 .seealso: `SNESSetFromOptions()`
568 @*/
569 PetscErrorCode  SNESAddOptionsChecker(PetscErrorCode (*snescheck)(SNES))
570 {
571   PetscFunctionBegin;
572   PetscCheck(numberofsetfromoptions < MAXSETFROMOPTIONS,PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE, "Too many options checkers, only %d allowed", MAXSETFROMOPTIONS);
573   othersetfromoptions[numberofsetfromoptions++] = snescheck;
574   PetscFunctionReturn(0);
575 }
576 
577 PETSC_INTERN PetscErrorCode SNESDefaultMatrixFreeCreate2(SNES,Vec,Mat*);
578 
579 static PetscErrorCode SNESSetUpMatrixFree_Private(SNES snes, PetscBool hasOperator, PetscInt version)
580 {
581   Mat            J;
582   MatNullSpace   nullsp;
583 
584   PetscFunctionBegin;
585   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
586 
587   if (!snes->vec_func && (snes->jacobian || snes->jacobian_pre)) {
588     Mat A = snes->jacobian, B = snes->jacobian_pre;
589     PetscCall(MatCreateVecs(A ? A : B, NULL,&snes->vec_func));
590   }
591 
592   if (version == 1) {
593     PetscCall(MatCreateSNESMF(snes,&J));
594     PetscCall(MatMFFDSetOptionsPrefix(J,((PetscObject)snes)->prefix));
595     PetscCall(MatSetFromOptions(J));
596     /* TODO: the version 2 code should be merged into the MatCreateSNESMF() and MatCreateMFFD() infrastructure and then removed */
597   } else if (version == 2) {
598     PetscCheck(snes->vec_func,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"SNESSetFunction() must be called first");
599 #if !defined(PETSC_USE_COMPLEX) && !defined(PETSC_USE_REAL_SINGLE) && !defined(PETSC_USE_REAL___FLOAT128) && !defined(PETSC_USE_REAL___FP16)
600     PetscCall(SNESDefaultMatrixFreeCreate2(snes,snes->vec_func,&J));
601 #else
602     SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP, "matrix-free operator routines (version 2)");
603 #endif
604   } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE, "matrix-free operator routines, only version 1 and 2");
605 
606   /* attach any user provided null space that was on Amat to the newly created matrix free matrix */
607   if (snes->jacobian) {
608     PetscCall(MatGetNullSpace(snes->jacobian,&nullsp));
609     if (nullsp) PetscCall(MatSetNullSpace(J,nullsp));
610   }
611 
612   PetscCall(PetscInfo(snes,"Setting default matrix-free operator routines (version %" PetscInt_FMT ")\n", version));
613   if (hasOperator) {
614 
615     /* This version replaces the user provided Jacobian matrix with a
616        matrix-free version but still employs the user-provided preconditioner matrix. */
617     PetscCall(SNESSetJacobian(snes,J,NULL,NULL,NULL));
618   } else {
619     /* This version replaces both the user-provided Jacobian and the user-
620      provided preconditioner Jacobian with the default matrix free version. */
621     if (snes->npcside == PC_LEFT && snes->npc) {
622       if (!snes->jacobian) PetscCall(SNESSetJacobian(snes,J,NULL,NULL,NULL));
623     } else {
624       KSP       ksp;
625       PC        pc;
626       PetscBool match;
627 
628       PetscCall(SNESSetJacobian(snes,J,J,MatMFFDComputeJacobian,NULL));
629       /* Force no preconditioner */
630       PetscCall(SNESGetKSP(snes,&ksp));
631       PetscCall(KSPGetPC(ksp,&pc));
632       PetscCall(PetscObjectTypeCompareAny((PetscObject)pc,&match,PCSHELL,PCH2OPUS,""));
633       if (!match) {
634         PetscCall(PetscInfo(snes,"Setting default matrix-free preconditioner routines\nThat is no preconditioner is being used\n"));
635         PetscCall(PCSetType(pc,PCNONE));
636       }
637     }
638   }
639   PetscCall(MatDestroy(&J));
640   PetscFunctionReturn(0);
641 }
642 
643 static PetscErrorCode DMRestrictHook_SNESVecSol(DM dmfine,Mat Restrict,Vec Rscale,Mat Inject,DM dmcoarse,void *ctx)
644 {
645   SNES           snes = (SNES)ctx;
646   Vec            Xfine,Xfine_named = NULL,Xcoarse;
647 
648   PetscFunctionBegin;
649   if (PetscLogPrintInfo) {
650     PetscInt finelevel,coarselevel,fineclevel,coarseclevel;
651     PetscCall(DMGetRefineLevel(dmfine,&finelevel));
652     PetscCall(DMGetCoarsenLevel(dmfine,&fineclevel));
653     PetscCall(DMGetRefineLevel(dmcoarse,&coarselevel));
654     PetscCall(DMGetCoarsenLevel(dmcoarse,&coarseclevel));
655     PetscCall(PetscInfo(dmfine,"Restricting SNES solution vector from level %" PetscInt_FMT "-%" PetscInt_FMT " to level %" PetscInt_FMT "-%" PetscInt_FMT "\n",finelevel,fineclevel,coarselevel,coarseclevel));
656   }
657   if (dmfine == snes->dm) Xfine = snes->vec_sol;
658   else {
659     PetscCall(DMGetNamedGlobalVector(dmfine,"SNESVecSol",&Xfine_named));
660     Xfine = Xfine_named;
661   }
662   PetscCall(DMGetNamedGlobalVector(dmcoarse,"SNESVecSol",&Xcoarse));
663   if (Inject) {
664     PetscCall(MatRestrict(Inject,Xfine,Xcoarse));
665   } else {
666     PetscCall(MatRestrict(Restrict,Xfine,Xcoarse));
667     PetscCall(VecPointwiseMult(Xcoarse,Xcoarse,Rscale));
668   }
669   PetscCall(DMRestoreNamedGlobalVector(dmcoarse,"SNESVecSol",&Xcoarse));
670   if (Xfine_named) PetscCall(DMRestoreNamedGlobalVector(dmfine,"SNESVecSol",&Xfine_named));
671   PetscFunctionReturn(0);
672 }
673 
674 static PetscErrorCode DMCoarsenHook_SNESVecSol(DM dm,DM dmc,void *ctx)
675 {
676   PetscFunctionBegin;
677   PetscCall(DMCoarsenHookAdd(dmc,DMCoarsenHook_SNESVecSol,DMRestrictHook_SNESVecSol,ctx));
678   PetscFunctionReturn(0);
679 }
680 
681 /* This may be called to rediscretize the operator on levels of linear multigrid. The DM shuffle is so the user can
682  * safely call SNESGetDM() in their residual evaluation routine. */
683 static PetscErrorCode KSPComputeOperators_SNES(KSP ksp,Mat A,Mat B,void *ctx)
684 {
685   SNES           snes = (SNES)ctx;
686   Vec            X,Xnamed = NULL;
687   DM             dmsave;
688   void           *ctxsave;
689   PetscErrorCode (*jac)(SNES,Vec,Mat,Mat,void*) = NULL;
690 
691   PetscFunctionBegin;
692   dmsave = snes->dm;
693   PetscCall(KSPGetDM(ksp,&snes->dm));
694   if (dmsave == snes->dm) X = snes->vec_sol; /* We are on the finest level */
695   else {                                     /* We are on a coarser level, this vec was initialized using a DM restrict hook */
696     PetscCall(DMGetNamedGlobalVector(snes->dm,"SNESVecSol",&Xnamed));
697     X    = Xnamed;
698     PetscCall(SNESGetJacobian(snes,NULL,NULL,&jac,&ctxsave));
699     /* If the DM's don't match up, the MatFDColoring context needed for the jacobian won't match up either -- fixit. */
700     if (jac == SNESComputeJacobianDefaultColor) {
701       PetscCall(SNESSetJacobian(snes,NULL,NULL,SNESComputeJacobianDefaultColor,NULL));
702     }
703   }
704   /* Make sure KSP DM has the Jacobian computation routine */
705   {
706     DMSNES sdm;
707 
708     PetscCall(DMGetDMSNES(snes->dm, &sdm));
709     if (!sdm->ops->computejacobian) {
710       PetscCall(DMCopyDMSNES(dmsave, snes->dm));
711     }
712   }
713   /* Compute the operators */
714   PetscCall(SNESComputeJacobian(snes,X,A,B));
715   /* Put the previous context back */
716   if (snes->dm != dmsave && jac == SNESComputeJacobianDefaultColor) {
717     PetscCall(SNESSetJacobian(snes,NULL,NULL,jac,ctxsave));
718   }
719 
720   if (Xnamed) PetscCall(DMRestoreNamedGlobalVector(snes->dm,"SNESVecSol",&Xnamed));
721   snes->dm = dmsave;
722   PetscFunctionReturn(0);
723 }
724 
725 /*@
726    SNESSetUpMatrices - ensures that matrices are available for SNES, to be called by SNESSetUp_XXX()
727 
728    Collective
729 
730    Input Parameter:
731 .  snes - snes to configure
732 
733    Level: developer
734 
735 .seealso: `SNESSetUp()`
736 @*/
737 PetscErrorCode SNESSetUpMatrices(SNES snes)
738 {
739   DM             dm;
740   DMSNES         sdm;
741 
742   PetscFunctionBegin;
743   PetscCall(SNESGetDM(snes,&dm));
744   PetscCall(DMGetDMSNES(dm,&sdm));
745   if (!snes->jacobian && snes->mf) {
746     Mat  J;
747     void *functx;
748     PetscCall(MatCreateSNESMF(snes,&J));
749     PetscCall(MatMFFDSetOptionsPrefix(J,((PetscObject)snes)->prefix));
750     PetscCall(MatSetFromOptions(J));
751     PetscCall(SNESGetFunction(snes,NULL,NULL,&functx));
752     PetscCall(SNESSetJacobian(snes,J,J,NULL,NULL));
753     PetscCall(MatDestroy(&J));
754   } else if (snes->mf_operator && !snes->jacobian_pre && !snes->jacobian) {
755     Mat J,B;
756     PetscCall(MatCreateSNESMF(snes,&J));
757     PetscCall(MatMFFDSetOptionsPrefix(J,((PetscObject)snes)->prefix));
758     PetscCall(MatSetFromOptions(J));
759     PetscCall(DMCreateMatrix(snes->dm,&B));
760     /* sdm->computejacobian was already set to reach here */
761     PetscCall(SNESSetJacobian(snes,J,B,NULL,NULL));
762     PetscCall(MatDestroy(&J));
763     PetscCall(MatDestroy(&B));
764   } else if (!snes->jacobian_pre) {
765     PetscDS   prob;
766     Mat       J, B;
767     PetscBool hasPrec   = PETSC_FALSE;
768 
769     J    = snes->jacobian;
770     PetscCall(DMGetDS(dm, &prob));
771     if (prob) PetscCall(PetscDSHasJacobianPreconditioner(prob, &hasPrec));
772     if (J)            PetscCall(PetscObjectReference((PetscObject) J));
773     else if (hasPrec) PetscCall(DMCreateMatrix(snes->dm, &J));
774     PetscCall(DMCreateMatrix(snes->dm, &B));
775     PetscCall(SNESSetJacobian(snes, J ? J : B, B, NULL, NULL));
776     PetscCall(MatDestroy(&J));
777     PetscCall(MatDestroy(&B));
778   }
779   {
780     KSP ksp;
781     PetscCall(SNESGetKSP(snes,&ksp));
782     PetscCall(KSPSetComputeOperators(ksp,KSPComputeOperators_SNES,snes));
783     PetscCall(DMCoarsenHookAdd(snes->dm,DMCoarsenHook_SNESVecSol,DMRestrictHook_SNESVecSol,snes));
784   }
785   PetscFunctionReturn(0);
786 }
787 
788 static PetscErrorCode SNESMonitorPauseFinal_Internal(SNES snes)
789 {
790   PetscInt       i;
791 
792   PetscFunctionBegin;
793   if (!snes->pauseFinal) PetscFunctionReturn(0);
794   for (i = 0; i < snes->numbermonitors; ++i) {
795     PetscViewerAndFormat *vf = (PetscViewerAndFormat *) snes->monitorcontext[i];
796     PetscDraw             draw;
797     PetscReal             lpause;
798 
799     if (!vf) continue;
800     if (vf->lg) {
801       if (!PetscCheckPointer(vf->lg, PETSC_OBJECT)) continue;
802       if (((PetscObject) vf->lg)->classid != PETSC_DRAWLG_CLASSID) continue;
803       PetscCall(PetscDrawLGGetDraw(vf->lg, &draw));
804       PetscCall(PetscDrawGetPause(draw, &lpause));
805       PetscCall(PetscDrawSetPause(draw, -1.0));
806       PetscCall(PetscDrawPause(draw));
807       PetscCall(PetscDrawSetPause(draw, lpause));
808     } else {
809       PetscBool isdraw;
810 
811       if (!PetscCheckPointer(vf->viewer, PETSC_OBJECT)) continue;
812       if (((PetscObject) vf->viewer)->classid != PETSC_VIEWER_CLASSID) continue;
813       PetscCall(PetscObjectTypeCompare((PetscObject) vf->viewer, PETSCVIEWERDRAW, &isdraw));
814       if (!isdraw) continue;
815       PetscCall(PetscViewerDrawGetDraw(vf->viewer, 0, &draw));
816       PetscCall(PetscDrawGetPause(draw, &lpause));
817       PetscCall(PetscDrawSetPause(draw, -1.0));
818       PetscCall(PetscDrawPause(draw));
819       PetscCall(PetscDrawSetPause(draw, lpause));
820     }
821   }
822   PetscFunctionReturn(0);
823 }
824 
825 /*@C
826    SNESMonitorSetFromOptions - Sets a monitor function and viewer appropriate for the type indicated by the user
827 
828    Collective on SNES
829 
830    Input Parameters:
831 +  snes - SNES object you wish to monitor
832 .  name - the monitor type one is seeking
833 .  help - message indicating what monitoring is done
834 .  manual - manual page for the monitor
835 .  monitor - the monitor function
836 -  monitorsetup - a function that is called once ONLY if the user selected this monitor that may set additional features of the SNES or PetscViewer objects
837 
838    Level: developer
839 
840 .seealso: `PetscOptionsGetViewer()`, `PetscOptionsGetReal()`, `PetscOptionsHasName()`, `PetscOptionsGetString()`,
841           `PetscOptionsGetIntArray()`, `PetscOptionsGetRealArray()`, `PetscOptionsBool()`
842           `PetscOptionsInt()`, `PetscOptionsString()`, `PetscOptionsReal()`, `PetscOptionsBool()`,
843           `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
844           `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
845           `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
846           `PetscOptionsFList()`, `PetscOptionsEList()`
847 @*/
848 PetscErrorCode  SNESMonitorSetFromOptions(SNES snes,const char name[],const char help[], const char manual[],PetscErrorCode (*monitor)(SNES,PetscInt,PetscReal,PetscViewerAndFormat*),PetscErrorCode (*monitorsetup)(SNES,PetscViewerAndFormat*))
849 {
850   PetscViewer       viewer;
851   PetscViewerFormat format;
852   PetscBool         flg;
853 
854   PetscFunctionBegin;
855   PetscCall(PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes),((PetscObject) snes)->options,((PetscObject)snes)->prefix,name,&viewer,&format,&flg));
856   if (flg) {
857     PetscViewerAndFormat *vf;
858     PetscCall(PetscViewerAndFormatCreate(viewer,format,&vf));
859     PetscCall(PetscObjectDereference((PetscObject)viewer));
860     if (monitorsetup) PetscCall((*monitorsetup)(snes,vf));
861     PetscCall(SNESMonitorSet(snes,(PetscErrorCode (*)(SNES,PetscInt,PetscReal,void*))monitor,vf,(PetscErrorCode (*)(void**))PetscViewerAndFormatDestroy));
862   }
863   PetscFunctionReturn(0);
864 }
865 
866 PetscErrorCode SNESEWSetFromOptions_Private(SNESKSPEW* kctx, MPI_Comm comm, const char* prefix)
867 {
868   PetscFunctionBegin;
869   PetscOptionsBegin(comm,prefix,"Eisenstat and Walker type forcing options","KSP");
870   PetscCall(PetscOptionsInt("-ksp_ew_version","Version 1, 2 or 3",NULL,kctx->version,&kctx->version,NULL));
871   PetscCall(PetscOptionsReal("-ksp_ew_rtol0","0 <= rtol0 < 1",NULL,kctx->rtol_0,&kctx->rtol_0,NULL));
872   PetscCall(PetscOptionsReal("-ksp_ew_rtolmax","0 <= rtolmax < 1",NULL,kctx->rtol_max,&kctx->rtol_max,NULL));
873   PetscCall(PetscOptionsReal("-ksp_ew_gamma","0 <= gamma <= 1",NULL,kctx->gamma,&kctx->gamma,NULL));
874   PetscCall(PetscOptionsReal("-ksp_ew_alpha","1 < alpha <= 2",NULL,kctx->alpha,&kctx->alpha,NULL));
875   PetscCall(PetscOptionsReal("-ksp_ew_alpha2","alpha2",NULL,kctx->alpha2,&kctx->alpha2,NULL));
876   PetscCall(PetscOptionsReal("-ksp_ew_threshold","0 < threshold < 1",NULL,kctx->threshold,&kctx->threshold,NULL));
877   PetscCall(PetscOptionsReal("-ksp_ew_v4_p1","p1",NULL,kctx->v4_p1,&kctx->v4_p1,NULL));
878   PetscCall(PetscOptionsReal("-ksp_ew_v4_p2","p2",NULL,kctx->v4_p2,&kctx->v4_p2,NULL));
879   PetscCall(PetscOptionsReal("-ksp_ew_v4_p3","p3",NULL,kctx->v4_p3,&kctx->v4_p3,NULL));
880   PetscCall(PetscOptionsReal("-ksp_ew_v4_m1","Scaling when rk-1 in [p2,p3)",NULL,kctx->v4_m1,&kctx->v4_m1,NULL));
881   PetscCall(PetscOptionsReal("-ksp_ew_v4_m2","Scaling when rk-1 in [p3,+infty)",NULL,kctx->v4_m2,&kctx->v4_m2,NULL));
882   PetscCall(PetscOptionsReal("-ksp_ew_v4_m3","Threshold for successive rtol (0.1 in Eq.7)",NULL,kctx->v4_m3,&kctx->v4_m3,NULL));
883   PetscCall(PetscOptionsReal("-ksp_ew_v4_m4","Adaptation scaling (0.5 in Eq.7)",NULL,kctx->v4_m4,&kctx->v4_m4,NULL));
884   PetscOptionsEnd();
885   PetscFunctionReturn(0);
886 }
887 
888 /*@
889    SNESSetFromOptions - Sets various SNES and KSP parameters from user options.
890 
891    Collective on SNES
892 
893    Input Parameter:
894 .  snes - the SNES context
895 
896    Options Database Keys:
897 +  -snes_type <type> - newtonls, newtontr, ngmres, ncg, nrichardson, qn, vi, fas, SNESType for complete list
898 .  -snes_stol - convergence tolerance in terms of the norm
899                 of the change in the solution between steps
900 .  -snes_atol <abstol> - absolute tolerance of residual norm
901 .  -snes_rtol <rtol> - relative decrease in tolerance norm from initial
902 .  -snes_divergence_tolerance <divtol> - if the residual goes above divtol*rnorm0, exit with divergence
903 .  -snes_force_iteration <force> - force SNESSolve() to take at least one iteration
904 .  -snes_max_it <max_it> - maximum number of iterations
905 .  -snes_max_funcs <max_funcs> - maximum number of function evaluations
906 .  -snes_max_fail <max_fail> - maximum number of line search failures allowed before stopping, default is none
907 .  -snes_max_linear_solve_fail - number of linear solver failures before SNESSolve() stops
908 .  -snes_lag_preconditioner <lag> - how often preconditioner is rebuilt (use -1 to never rebuild)
909 .  -snes_lag_preconditioner_persists <true,false> - retains the -snes_lag_preconditioner information across multiple SNESSolve()
910 .  -snes_lag_jacobian <lag> - how often Jacobian is rebuilt (use -1 to never rebuild)
911 .  -snes_lag_jacobian_persists <true,false> - retains the -snes_lag_jacobian information across multiple SNESSolve()
912 .  -snes_trtol <trtol> - trust region tolerance
913 .  -snes_convergence_test - <default,skip,correct_pressure> convergence test in nonlinear solver.
914                                default SNESConvergedDefault(). skip SNESConvergedSkip() means continue iterating until max_it or some other criterion is reached, saving expense
915                                of convergence test. correct_pressure SNESConvergedCorrectPressure() has special handling of a pressure null space.
916 .  -snes_monitor [ascii][:filename][:viewer format] - prints residual norm at each iteration. if no filename given prints to stdout
917 .  -snes_monitor_solution [ascii binary draw][:filename][:viewer format] - plots solution at each iteration
918 .  -snes_monitor_residual [ascii binary draw][:filename][:viewer format] - plots residual (not its norm) at each iteration
919 .  -snes_monitor_solution_update [ascii binary draw][:filename][:viewer format] - plots update to solution at each iteration
920 .  -snes_monitor_lg_residualnorm - plots residual norm at each iteration
921 .  -snes_monitor_lg_range - plots residual norm at each iteration
922 .  -snes_monitor_pause_final - Pauses all monitor drawing after the solver ends
923 .  -snes_fd - use finite differences to compute Jacobian; very slow, only for testing
924 .  -snes_fd_color - use finite differences with coloring to compute Jacobian
925 .  -snes_mf_ksp_monitor - if using matrix-free multiply then print h at each KSP iteration
926 .  -snes_converged_reason - print the reason for convergence/divergence after each solve
927 .  -npc_snes_type <type> - the SNES type to use as a nonlinear preconditioner
928 .   -snes_test_jacobian <optional threshold> - compare the user provided Jacobian with one computed via finite differences to check for errors.  If a threshold is given, display only those entries whose difference is greater than the threshold.
929 -   -snes_test_jacobian_view - display the user provided Jacobian, the finite difference Jacobian and the difference between them to help users detect the location of errors in the user provided Jacobian.
930 
931     Options Database for Eisenstat-Walker method:
932 +  -snes_ksp_ew - use Eisenstat-Walker method for determining linear system convergence
933 .  -snes_ksp_ew_version ver - version of  Eisenstat-Walker method
934 .  -snes_ksp_ew_rtol0 <rtol0> - Sets rtol0
935 .  -snes_ksp_ew_rtolmax <rtolmax> - Sets rtolmax
936 .  -snes_ksp_ew_gamma <gamma> - Sets gamma
937 .  -snes_ksp_ew_alpha <alpha> - Sets alpha
938 .  -snes_ksp_ew_alpha2 <alpha2> - Sets alpha2
939 -  -snes_ksp_ew_threshold <threshold> - Sets threshold
940 
941    Notes:
942    To see all options, run your program with the -help option or consult the users manual
943 
944    Notes:
945       SNES supports three approaches for computing (approximate) Jacobians: user provided via SNESSetJacobian(), matrix free, and computing explicitly with
946       finite differences and coloring using MatFDColoring. It is also possible to use automatic differentiation and the MatFDColoring object.
947 
948    Level: beginner
949 
950 .seealso: `SNESSetOptionsPrefix()`, `SNESResetFromOptions()`, `SNES`, `SNESCreate()`
951 @*/
952 PetscErrorCode  SNESSetFromOptions(SNES snes)
953 {
954   PetscBool      flg,pcset,persist,set;
955   PetscInt       i,indx,lag,grids;
956   const char     *deft        = SNESNEWTONLS;
957   const char     *convtests[] = {"default","skip","correct_pressure"};
958   SNESKSPEW      *kctx        = NULL;
959   char           type[256], monfilename[PETSC_MAX_PATH_LEN], ewprefix[256];
960   PCSide         pcside;
961   const char     *optionsprefix;
962 
963   PetscFunctionBegin;
964   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
965   PetscCall(SNESRegisterAll());
966   PetscObjectOptionsBegin((PetscObject)snes);
967   if (((PetscObject)snes)->type_name) deft = ((PetscObject)snes)->type_name;
968   PetscCall(PetscOptionsFList("-snes_type","Nonlinear solver method","SNESSetType",SNESList,deft,type,256,&flg));
969   if (flg) {
970     PetscCall(SNESSetType(snes,type));
971   } else if (!((PetscObject)snes)->type_name) {
972     PetscCall(SNESSetType(snes,deft));
973   }
974   PetscCall(PetscOptionsReal("-snes_stol","Stop if step length less than","SNESSetTolerances",snes->stol,&snes->stol,NULL));
975   PetscCall(PetscOptionsReal("-snes_atol","Stop if function norm less than","SNESSetTolerances",snes->abstol,&snes->abstol,NULL));
976 
977   PetscCall(PetscOptionsReal("-snes_rtol","Stop if decrease in function norm less than","SNESSetTolerances",snes->rtol,&snes->rtol,NULL));
978   PetscCall(PetscOptionsReal("-snes_divergence_tolerance","Stop if residual norm increases by this factor","SNESSetDivergenceTolerance",snes->divtol,&snes->divtol,NULL));
979   PetscCall(PetscOptionsInt("-snes_max_it","Maximum iterations","SNESSetTolerances",snes->max_its,&snes->max_its,NULL));
980   PetscCall(PetscOptionsInt("-snes_max_funcs","Maximum function evaluations","SNESSetTolerances",snes->max_funcs,&snes->max_funcs,NULL));
981   PetscCall(PetscOptionsInt("-snes_max_fail","Maximum nonlinear step failures","SNESSetMaxNonlinearStepFailures",snes->maxFailures,&snes->maxFailures,NULL));
982   PetscCall(PetscOptionsInt("-snes_max_linear_solve_fail","Maximum failures in linear solves allowed","SNESSetMaxLinearSolveFailures",snes->maxLinearSolveFailures,&snes->maxLinearSolveFailures,NULL));
983   PetscCall(PetscOptionsBool("-snes_error_if_not_converged","Generate error if solver does not converge","SNESSetErrorIfNotConverged",snes->errorifnotconverged,&snes->errorifnotconverged,NULL));
984   PetscCall(PetscOptionsBool("-snes_force_iteration","Force SNESSolve() to take at least one iteration","SNESSetForceIteration",snes->forceiteration,&snes->forceiteration,NULL));
985   PetscCall(PetscOptionsBool("-snes_check_jacobian_domain_error","Check Jacobian domain error after Jacobian evaluation","SNESCheckJacobianDomainError",snes->checkjacdomainerror,&snes->checkjacdomainerror,NULL));
986 
987   PetscCall(PetscOptionsInt("-snes_lag_preconditioner","How often to rebuild preconditioner","SNESSetLagPreconditioner",snes->lagpreconditioner,&lag,&flg));
988   if (flg) {
989     PetscCheck(lag != -1,PetscObjectComm((PetscObject)snes),PETSC_ERR_USER,"Cannot set the lag to -1 from the command line since the preconditioner must be built as least once, perhaps you mean -2");
990     PetscCall(SNESSetLagPreconditioner(snes,lag));
991   }
992   PetscCall(PetscOptionsBool("-snes_lag_preconditioner_persists","Preconditioner lagging through multiple SNES solves","SNESSetLagPreconditionerPersists",snes->lagjac_persist,&persist,&flg));
993   if (flg) PetscCall(SNESSetLagPreconditionerPersists(snes,persist));
994   PetscCall(PetscOptionsInt("-snes_lag_jacobian","How often to rebuild Jacobian","SNESSetLagJacobian",snes->lagjacobian,&lag,&flg));
995   if (flg) {
996     PetscCheck(lag != -1,PetscObjectComm((PetscObject)snes),PETSC_ERR_USER,"Cannot set the lag to -1 from the command line since the Jacobian must be built as least once, perhaps you mean -2");
997     PetscCall(SNESSetLagJacobian(snes,lag));
998   }
999   PetscCall(PetscOptionsBool("-snes_lag_jacobian_persists","Jacobian lagging through multiple SNES solves","SNESSetLagJacobianPersists",snes->lagjac_persist,&persist,&flg));
1000   if (flg) PetscCall(SNESSetLagJacobianPersists(snes,persist));
1001 
1002   PetscCall(PetscOptionsInt("-snes_grid_sequence","Use grid sequencing to generate initial guess","SNESSetGridSequence",snes->gridsequence,&grids,&flg));
1003   if (flg) PetscCall(SNESSetGridSequence(snes,grids));
1004 
1005   PetscCall(PetscOptionsEList("-snes_convergence_test","Convergence test","SNESSetConvergenceTest",convtests,sizeof(convtests)/sizeof(char*),"default",&indx,&flg));
1006   if (flg) {
1007     switch (indx) {
1008     case 0: PetscCall(SNESSetConvergenceTest(snes,SNESConvergedDefault,NULL,NULL)); break;
1009     case 1: PetscCall(SNESSetConvergenceTest(snes,SNESConvergedSkip,NULL,NULL)); break;
1010     case 2: PetscCall(SNESSetConvergenceTest(snes,SNESConvergedCorrectPressure,NULL,NULL)); break;
1011     }
1012   }
1013 
1014   PetscCall(PetscOptionsEList("-snes_norm_schedule","SNES Norm schedule","SNESSetNormSchedule",SNESNormSchedules,5,"function",&indx,&flg));
1015   if (flg) PetscCall(SNESSetNormSchedule(snes,(SNESNormSchedule)indx));
1016 
1017   PetscCall(PetscOptionsEList("-snes_function_type","SNES Norm schedule","SNESSetFunctionType",SNESFunctionTypes,2,"unpreconditioned",&indx,&flg));
1018   if (flg) PetscCall(SNESSetFunctionType(snes,(SNESFunctionType)indx));
1019 
1020   kctx = (SNESKSPEW*)snes->kspconvctx;
1021 
1022   PetscCall(PetscOptionsBool("-snes_ksp_ew","Use Eisentat-Walker linear system convergence test","SNESKSPSetUseEW",snes->ksp_ewconv,&snes->ksp_ewconv,NULL));
1023 
1024   PetscCall(SNESGetOptionsPrefix(snes,&optionsprefix));
1025   PetscCall(PetscSNPrintf(ewprefix,sizeof(ewprefix),"%s%s",optionsprefix ? optionsprefix : "","snes_"));
1026   PetscCall(SNESEWSetFromOptions_Private(kctx,PetscObjectComm((PetscObject)snes),ewprefix));
1027 
1028   PetscCall(PetscOptionsInt("-snes_ksp_ew_version","Version 1, 2 or 3","SNESKSPSetParametersEW",kctx->version,&kctx->version,NULL));
1029   PetscCall(PetscOptionsReal("-snes_ksp_ew_rtol0","0 <= rtol0 < 1","SNESKSPSetParametersEW",kctx->rtol_0,&kctx->rtol_0,NULL));
1030   PetscCall(PetscOptionsReal("-snes_ksp_ew_rtolmax","0 <= rtolmax < 1","SNESKSPSetParametersEW",kctx->rtol_max,&kctx->rtol_max,NULL));
1031   PetscCall(PetscOptionsReal("-snes_ksp_ew_gamma","0 <= gamma <= 1","SNESKSPSetParametersEW",kctx->gamma,&kctx->gamma,NULL));
1032   PetscCall(PetscOptionsReal("-snes_ksp_ew_alpha","1 < alpha <= 2","SNESKSPSetParametersEW",kctx->alpha,&kctx->alpha,NULL));
1033   PetscCall(PetscOptionsReal("-snes_ksp_ew_alpha2","alpha2","SNESKSPSetParametersEW",kctx->alpha2,&kctx->alpha2,NULL));
1034   PetscCall(PetscOptionsReal("-snes_ksp_ew_threshold","0 < threshold < 1","SNESKSPSetParametersEW",kctx->threshold,&kctx->threshold,NULL));
1035 
1036   flg  = PETSC_FALSE;
1037   PetscCall(PetscOptionsBool("-snes_monitor_cancel","Remove all monitors","SNESMonitorCancel",flg,&flg,&set));
1038   if (set && flg) PetscCall(SNESMonitorCancel(snes));
1039 
1040   PetscCall(SNESMonitorSetFromOptions(snes,"-snes_monitor","Monitor norm of function","SNESMonitorDefault",SNESMonitorDefault,SNESMonitorDefaultSetUp));
1041   PetscCall(SNESMonitorSetFromOptions(snes,"-snes_monitor_short","Monitor norm of function with fewer digits","SNESMonitorDefaultShort",SNESMonitorDefaultShort,NULL));
1042   PetscCall(SNESMonitorSetFromOptions(snes,"-snes_monitor_range","Monitor range of elements of function","SNESMonitorRange",SNESMonitorRange,NULL));
1043 
1044   PetscCall(SNESMonitorSetFromOptions(snes,"-snes_monitor_ratio","Monitor ratios of the norm of function for consecutive steps","SNESMonitorRatio",SNESMonitorRatio,SNESMonitorRatioSetUp));
1045   PetscCall(SNESMonitorSetFromOptions(snes,"-snes_monitor_field","Monitor norm of function (split into fields)","SNESMonitorDefaultField",SNESMonitorDefaultField,NULL));
1046   PetscCall(SNESMonitorSetFromOptions(snes,"-snes_monitor_solution","View solution at each iteration","SNESMonitorSolution",SNESMonitorSolution,NULL));
1047   PetscCall(SNESMonitorSetFromOptions(snes,"-snes_monitor_solution_update","View correction at each iteration","SNESMonitorSolutionUpdate",SNESMonitorSolutionUpdate,NULL));
1048   PetscCall(SNESMonitorSetFromOptions(snes,"-snes_monitor_residual","View residual at each iteration","SNESMonitorResidual",SNESMonitorResidual,NULL));
1049   PetscCall(SNESMonitorSetFromOptions(snes,"-snes_monitor_jacupdate_spectrum","Print the change in the spectrum of the Jacobian","SNESMonitorJacUpdateSpectrum",SNESMonitorJacUpdateSpectrum,NULL));
1050   PetscCall(SNESMonitorSetFromOptions(snes,"-snes_monitor_fields","Monitor norm of function per field","SNESMonitorSet",SNESMonitorFields,NULL));
1051   PetscCall(PetscOptionsBool("-snes_monitor_pause_final", "Pauses all draw monitors at the final iterate", "SNESMonitorPauseFinal_Internal", PETSC_FALSE, &snes->pauseFinal, NULL));
1052 
1053   PetscCall(PetscOptionsString("-snes_monitor_python","Use Python function","SNESMonitorSet",NULL,monfilename,sizeof(monfilename),&flg));
1054   if (flg) PetscCall(PetscPythonMonitorSet((PetscObject)snes,monfilename));
1055 
1056   flg  = PETSC_FALSE;
1057   PetscCall(PetscOptionsBool("-snes_monitor_lg_range","Plot function range at each iteration","SNESMonitorLGRange",flg,&flg,NULL));
1058   if (flg) {
1059     PetscViewer ctx;
1060 
1061     PetscCall(PetscViewerDrawOpen(PetscObjectComm((PetscObject)snes),NULL,NULL,PETSC_DECIDE,PETSC_DECIDE,400,300,&ctx));
1062     PetscCall(SNESMonitorSet(snes,SNESMonitorLGRange,ctx,(PetscErrorCode (*)(void**))PetscViewerDestroy));
1063   }
1064 
1065   flg  = PETSC_FALSE;
1066   PetscCall(PetscOptionsBool("-snes_converged_reason_view_cancel","Remove all converged reason viewers","SNESConvergedReasonViewCancel",flg,&flg,&set));
1067   if (set && flg) PetscCall(SNESConvergedReasonViewCancel(snes));
1068 
1069   flg  = PETSC_FALSE;
1070   PetscCall(PetscOptionsBool("-snes_fd","Use finite differences (slow) to compute Jacobian","SNESComputeJacobianDefault",flg,&flg,NULL));
1071   if (flg) {
1072     void    *functx;
1073     DM      dm;
1074     DMSNES  sdm;
1075     PetscCall(SNESGetDM(snes,&dm));
1076     PetscCall(DMGetDMSNES(dm,&sdm));
1077     sdm->jacobianctx = NULL;
1078     PetscCall(SNESGetFunction(snes,NULL,NULL,&functx));
1079     PetscCall(SNESSetJacobian(snes,snes->jacobian,snes->jacobian_pre,SNESComputeJacobianDefault,functx));
1080     PetscCall(PetscInfo(snes,"Setting default finite difference Jacobian matrix\n"));
1081   }
1082 
1083   flg  = PETSC_FALSE;
1084   PetscCall(PetscOptionsBool("-snes_fd_function","Use finite differences (slow) to compute function from user objective","SNESObjectiveComputeFunctionDefaultFD",flg,&flg,NULL));
1085   if (flg) PetscCall(SNESSetFunction(snes,NULL,SNESObjectiveComputeFunctionDefaultFD,NULL));
1086 
1087   flg  = PETSC_FALSE;
1088   PetscCall(PetscOptionsBool("-snes_fd_color","Use finite differences with coloring to compute Jacobian","SNESComputeJacobianDefaultColor",flg,&flg,NULL));
1089   if (flg) {
1090     DM             dm;
1091     DMSNES         sdm;
1092     PetscCall(SNESGetDM(snes,&dm));
1093     PetscCall(DMGetDMSNES(dm,&sdm));
1094     sdm->jacobianctx = NULL;
1095     PetscCall(SNESSetJacobian(snes,snes->jacobian,snes->jacobian_pre,SNESComputeJacobianDefaultColor,NULL));
1096     PetscCall(PetscInfo(snes,"Setting default finite difference coloring Jacobian matrix\n"));
1097   }
1098 
1099   flg  = PETSC_FALSE;
1100   PetscCall(PetscOptionsBool("-snes_mf_operator","Use a Matrix-Free Jacobian with user-provided preconditioner matrix","SNESSetUseMatrixFree",PETSC_FALSE,&snes->mf_operator,&flg));
1101   if (flg && snes->mf_operator) {
1102     snes->mf_operator = PETSC_TRUE;
1103     snes->mf          = PETSC_TRUE;
1104   }
1105   flg  = PETSC_FALSE;
1106   PetscCall(PetscOptionsBool("-snes_mf","Use a Matrix-Free Jacobian with no preconditioner matrix","SNESSetUseMatrixFree",PETSC_FALSE,&snes->mf,&flg));
1107   if (!flg && snes->mf_operator) snes->mf = PETSC_TRUE;
1108   PetscCall(PetscOptionsInt("-snes_mf_version","Matrix-Free routines version 1 or 2","None",snes->mf_version,&snes->mf_version,NULL));
1109 
1110   flg  = PETSC_FALSE;
1111   PetscCall(SNESGetNPCSide(snes,&pcside));
1112   PetscCall(PetscOptionsEnum("-snes_npc_side","SNES nonlinear preconditioner side","SNESSetNPCSide",PCSides,(PetscEnum)pcside,(PetscEnum*)&pcside,&flg));
1113   if (flg) PetscCall(SNESSetNPCSide(snes,pcside));
1114 
1115 #if defined(PETSC_HAVE_SAWS)
1116   /*
1117     Publish convergence information using SAWs
1118   */
1119   flg  = PETSC_FALSE;
1120   PetscCall(PetscOptionsBool("-snes_monitor_saws","Publish SNES progress using SAWs","SNESMonitorSet",flg,&flg,NULL));
1121   if (flg) {
1122     void *ctx;
1123     PetscCall(SNESMonitorSAWsCreate(snes,&ctx));
1124     PetscCall(SNESMonitorSet(snes,SNESMonitorSAWs,ctx,SNESMonitorSAWsDestroy));
1125   }
1126 #endif
1127 #if defined(PETSC_HAVE_SAWS)
1128   {
1129   PetscBool set;
1130   flg  = PETSC_FALSE;
1131   PetscCall(PetscOptionsBool("-snes_saws_block","Block for SAWs at end of SNESSolve","PetscObjectSAWsBlock",((PetscObject)snes)->amspublishblock,&flg,&set));
1132   if (set) PetscCall(PetscObjectSAWsSetBlock((PetscObject)snes,flg));
1133   }
1134 #endif
1135 
1136   for (i = 0; i < numberofsetfromoptions; i++) {
1137     PetscCall((*othersetfromoptions[i])(snes));
1138   }
1139 
1140   if (snes->ops->setfromoptions) PetscCall((*snes->ops->setfromoptions)(PetscOptionsObject,snes));
1141 
1142   /* process any options handlers added with PetscObjectAddOptionsHandler() */
1143   PetscCall(PetscObjectProcessOptionsHandlers(PetscOptionsObject,(PetscObject)snes));
1144   PetscOptionsEnd();
1145 
1146   if (snes->linesearch) {
1147     PetscCall(SNESGetLineSearch(snes, &snes->linesearch));
1148     PetscCall(SNESLineSearchSetFromOptions(snes->linesearch));
1149   }
1150 
1151   if (snes->usesksp) {
1152     if (!snes->ksp) PetscCall(SNESGetKSP(snes,&snes->ksp));
1153     PetscCall(KSPSetOperators(snes->ksp,snes->jacobian,snes->jacobian_pre));
1154     PetscCall(KSPSetFromOptions(snes->ksp));
1155   }
1156 
1157   /* if user has set the SNES NPC type via options database, create it. */
1158   PetscCall(SNESGetOptionsPrefix(snes, &optionsprefix));
1159   PetscCall(PetscOptionsHasName(((PetscObject)snes)->options,optionsprefix, "-npc_snes_type", &pcset));
1160   if (pcset && (!snes->npc)) {
1161     PetscCall(SNESGetNPC(snes, &snes->npc));
1162   }
1163   if (snes->npc) PetscCall(SNESSetFromOptions(snes->npc));
1164   snes->setfromoptionscalled++;
1165   PetscFunctionReturn(0);
1166 }
1167 
1168 /*@
1169    SNESResetFromOptions - Sets various SNES and KSP parameters from user options ONLY if the SNES was previously set from options
1170 
1171    Collective on SNES
1172 
1173    Input Parameter:
1174 .  snes - the SNES context
1175 
1176    Level: beginner
1177 
1178 .seealso: `SNESSetFromOptions()`, `SNESSetOptionsPrefix()`
1179 @*/
1180 PetscErrorCode SNESResetFromOptions(SNES snes)
1181 {
1182   PetscFunctionBegin;
1183   if (snes->setfromoptionscalled) PetscCall(SNESSetFromOptions(snes));
1184   PetscFunctionReturn(0);
1185 }
1186 
1187 /*@C
1188    SNESSetComputeApplicationContext - Sets an optional function to compute a user-defined context for
1189    the nonlinear solvers.
1190 
1191    Logically Collective on SNES
1192 
1193    Input Parameters:
1194 +  snes - the SNES context
1195 .  compute - function to compute the context
1196 -  destroy - function to destroy the context
1197 
1198    Level: intermediate
1199 
1200    Notes:
1201    This function is currently not available from Fortran.
1202 
1203 .seealso: `SNESGetApplicationContext()`, `SNESSetComputeApplicationContext()`, `SNESGetApplicationContext()`
1204 @*/
1205 PetscErrorCode  SNESSetComputeApplicationContext(SNES snes,PetscErrorCode (*compute)(SNES,void**),PetscErrorCode (*destroy)(void**))
1206 {
1207   PetscFunctionBegin;
1208   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1209   snes->ops->usercompute = compute;
1210   snes->ops->userdestroy = destroy;
1211   PetscFunctionReturn(0);
1212 }
1213 
1214 /*@
1215    SNESSetApplicationContext - Sets the optional user-defined context for
1216    the nonlinear solvers.
1217 
1218    Logically Collective on SNES
1219 
1220    Input Parameters:
1221 +  snes - the SNES context
1222 -  usrP - optional user context
1223 
1224    Level: intermediate
1225 
1226    Fortran Notes:
1227     To use this from Fortran you must write a Fortran interface definition for this
1228     function that tells Fortran the Fortran derived data type that you are passing in as the ctx argument.
1229 
1230 .seealso: `SNESGetApplicationContext()`
1231 @*/
1232 PetscErrorCode  SNESSetApplicationContext(SNES snes,void *usrP)
1233 {
1234   KSP            ksp;
1235 
1236   PetscFunctionBegin;
1237   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1238   PetscCall(SNESGetKSP(snes,&ksp));
1239   PetscCall(KSPSetApplicationContext(ksp,usrP));
1240   snes->user = usrP;
1241   PetscFunctionReturn(0);
1242 }
1243 
1244 /*@
1245    SNESGetApplicationContext - Gets the user-defined context for the
1246    nonlinear solvers.
1247 
1248    Not Collective
1249 
1250    Input Parameter:
1251 .  snes - SNES context
1252 
1253    Output Parameter:
1254 .  usrP - user context
1255 
1256    Fortran Notes:
1257     To use this from Fortran you must write a Fortran interface definition for this
1258     function that tells Fortran the Fortran derived data type that you are passing in as the ctx argument.
1259 
1260    Level: intermediate
1261 
1262 .seealso: `SNESSetApplicationContext()`
1263 @*/
1264 PetscErrorCode  SNESGetApplicationContext(SNES snes,void *usrP)
1265 {
1266   PetscFunctionBegin;
1267   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1268   *(void**)usrP = snes->user;
1269   PetscFunctionReturn(0);
1270 }
1271 
1272 /*@
1273    SNESSetUseMatrixFree - indicates that SNES should use matrix free finite difference matrix vector products internally to apply the Jacobian.
1274 
1275    Collective on SNES
1276 
1277    Input Parameters:
1278 +  snes - SNES context
1279 .  mf_operator - use matrix-free only for the Amat used by SNESSetJacobian(), this means the user provided Pmat will continue to be used
1280 -  mf - use matrix-free for both the Amat and Pmat used by SNESSetJacobian(), both the Amat and Pmat set in SNESSetJacobian() will be ignored
1281 
1282    Options Database:
1283 + -snes_mf - use matrix free for both the mat and pmat operator
1284 . -snes_mf_operator - use matrix free only for the mat operator
1285 . -snes_fd_color - compute the Jacobian via coloring and finite differences.
1286 - -snes_fd - compute the Jacobian via finite differences (slow)
1287 
1288    Level: intermediate
1289 
1290    Notes:
1291       SNES supports three approaches for computing (approximate) Jacobians: user provided via SNESSetJacobian(), matrix free, and computing explicitly with
1292       finite differences and coloring using MatFDColoring. It is also possible to use automatic differentiation and the MatFDColoring object.
1293 
1294 .seealso: `SNESGetUseMatrixFree()`, `MatCreateSNESMF()`, `SNESComputeJacobianDefaultColor()`
1295 @*/
1296 PetscErrorCode  SNESSetUseMatrixFree(SNES snes,PetscBool mf_operator,PetscBool mf)
1297 {
1298   PetscFunctionBegin;
1299   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1300   PetscValidLogicalCollectiveBool(snes,mf_operator,2);
1301   PetscValidLogicalCollectiveBool(snes,mf,3);
1302   snes->mf          = mf_operator ? PETSC_TRUE : mf;
1303   snes->mf_operator = mf_operator;
1304   PetscFunctionReturn(0);
1305 }
1306 
1307 /*@
1308    SNESGetUseMatrixFree - indicates if the SNES uses matrix free finite difference matrix vector products to apply the Jacobian.
1309 
1310    Collective on SNES
1311 
1312    Input Parameter:
1313 .  snes - SNES context
1314 
1315    Output Parameters:
1316 +  mf_operator - use matrix-free only for the Amat used by SNESSetJacobian(), this means the user provided Pmat will continue to be used
1317 -  mf - use matrix-free for both the Amat and Pmat used by SNESSetJacobian(), both the Amat and Pmat set in SNESSetJacobian() will be ignored
1318 
1319    Options Database:
1320 + -snes_mf - use matrix free for both the mat and pmat operator
1321 - -snes_mf_operator - use matrix free only for the mat operator
1322 
1323    Level: intermediate
1324 
1325 .seealso: `SNESSetUseMatrixFree()`, `MatCreateSNESMF()`
1326 @*/
1327 PetscErrorCode  SNESGetUseMatrixFree(SNES snes,PetscBool *mf_operator,PetscBool *mf)
1328 {
1329   PetscFunctionBegin;
1330   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1331   if (mf)          *mf          = snes->mf;
1332   if (mf_operator) *mf_operator = snes->mf_operator;
1333   PetscFunctionReturn(0);
1334 }
1335 
1336 /*@
1337    SNESGetIterationNumber - Gets the number of nonlinear iterations completed
1338    at this time.
1339 
1340    Not Collective
1341 
1342    Input Parameter:
1343 .  snes - SNES context
1344 
1345    Output Parameter:
1346 .  iter - iteration number
1347 
1348    Notes:
1349    For example, during the computation of iteration 2 this would return 1.
1350 
1351    This is useful for using lagged Jacobians (where one does not recompute the
1352    Jacobian at each SNES iteration). For example, the code
1353 .vb
1354       ierr = SNESGetIterationNumber(snes,&it);
1355       if (!(it % 2)) {
1356         [compute Jacobian here]
1357       }
1358 .ve
1359    can be used in your ComputeJacobian() function to cause the Jacobian to be
1360    recomputed every second SNES iteration.
1361 
1362    After the SNES solve is complete this will return the number of nonlinear iterations used.
1363 
1364    Level: intermediate
1365 
1366 .seealso: `SNESGetLinearSolveIterations()`
1367 @*/
1368 PetscErrorCode  SNESGetIterationNumber(SNES snes,PetscInt *iter)
1369 {
1370   PetscFunctionBegin;
1371   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1372   PetscValidIntPointer(iter,2);
1373   *iter = snes->iter;
1374   PetscFunctionReturn(0);
1375 }
1376 
1377 /*@
1378    SNESSetIterationNumber - Sets the current iteration number.
1379 
1380    Not Collective
1381 
1382    Input Parameters:
1383 +  snes - SNES context
1384 -  iter - iteration number
1385 
1386    Level: developer
1387 
1388 .seealso: `SNESGetLinearSolveIterations()`
1389 @*/
1390 PetscErrorCode  SNESSetIterationNumber(SNES snes,PetscInt iter)
1391 {
1392   PetscFunctionBegin;
1393   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1394   PetscCall(PetscObjectSAWsTakeAccess((PetscObject)snes));
1395   snes->iter = iter;
1396   PetscCall(PetscObjectSAWsGrantAccess((PetscObject)snes));
1397   PetscFunctionReturn(0);
1398 }
1399 
1400 /*@
1401    SNESGetNonlinearStepFailures - Gets the number of unsuccessful steps
1402    attempted by the nonlinear solver.
1403 
1404    Not Collective
1405 
1406    Input Parameter:
1407 .  snes - SNES context
1408 
1409    Output Parameter:
1410 .  nfails - number of unsuccessful steps attempted
1411 
1412    Notes:
1413    This counter is reset to zero for each successive call to SNESSolve().
1414 
1415    Level: intermediate
1416 
1417 .seealso: `SNESGetMaxLinearSolveFailures()`, `SNESGetLinearSolveIterations()`, `SNESSetMaxLinearSolveFailures()`, `SNESGetLinearSolveFailures()`,
1418           `SNESSetMaxNonlinearStepFailures()`, `SNESGetMaxNonlinearStepFailures()`
1419 @*/
1420 PetscErrorCode  SNESGetNonlinearStepFailures(SNES snes,PetscInt *nfails)
1421 {
1422   PetscFunctionBegin;
1423   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1424   PetscValidIntPointer(nfails,2);
1425   *nfails = snes->numFailures;
1426   PetscFunctionReturn(0);
1427 }
1428 
1429 /*@
1430    SNESSetMaxNonlinearStepFailures - Sets the maximum number of unsuccessful steps
1431    attempted by the nonlinear solver before it gives up.
1432 
1433    Not Collective
1434 
1435    Input Parameters:
1436 +  snes     - SNES context
1437 -  maxFails - maximum of unsuccessful steps
1438 
1439    Level: intermediate
1440 
1441 .seealso: `SNESGetMaxLinearSolveFailures()`, `SNESGetLinearSolveIterations()`, `SNESSetMaxLinearSolveFailures()`, `SNESGetLinearSolveFailures()`,
1442           `SNESGetMaxNonlinearStepFailures()`, `SNESGetNonlinearStepFailures()`
1443 @*/
1444 PetscErrorCode  SNESSetMaxNonlinearStepFailures(SNES snes, PetscInt maxFails)
1445 {
1446   PetscFunctionBegin;
1447   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1448   snes->maxFailures = maxFails;
1449   PetscFunctionReturn(0);
1450 }
1451 
1452 /*@
1453    SNESGetMaxNonlinearStepFailures - Gets the maximum number of unsuccessful steps
1454    attempted by the nonlinear solver before it gives up.
1455 
1456    Not Collective
1457 
1458    Input Parameter:
1459 .  snes     - SNES context
1460 
1461    Output Parameter:
1462 .  maxFails - maximum of unsuccessful steps
1463 
1464    Level: intermediate
1465 
1466 .seealso: `SNESGetMaxLinearSolveFailures()`, `SNESGetLinearSolveIterations()`, `SNESSetMaxLinearSolveFailures()`, `SNESGetLinearSolveFailures()`,
1467           `SNESSetMaxNonlinearStepFailures()`, `SNESGetNonlinearStepFailures()`
1468 
1469 @*/
1470 PetscErrorCode  SNESGetMaxNonlinearStepFailures(SNES snes, PetscInt *maxFails)
1471 {
1472   PetscFunctionBegin;
1473   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1474   PetscValidIntPointer(maxFails,2);
1475   *maxFails = snes->maxFailures;
1476   PetscFunctionReturn(0);
1477 }
1478 
1479 /*@
1480    SNESGetNumberFunctionEvals - Gets the number of user provided function evaluations
1481      done by SNES.
1482 
1483    Not Collective
1484 
1485    Input Parameter:
1486 .  snes     - SNES context
1487 
1488    Output Parameter:
1489 .  nfuncs - number of evaluations
1490 
1491    Level: intermediate
1492 
1493    Notes:
1494     Reset every time SNESSolve is called unless SNESSetCountersReset() is used.
1495 
1496 .seealso: `SNESGetMaxLinearSolveFailures()`, `SNESGetLinearSolveIterations()`, `SNESSetMaxLinearSolveFailures()`, `SNESGetLinearSolveFailures()`, `SNESSetCountersReset()`
1497 @*/
1498 PetscErrorCode  SNESGetNumberFunctionEvals(SNES snes, PetscInt *nfuncs)
1499 {
1500   PetscFunctionBegin;
1501   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1502   PetscValidIntPointer(nfuncs,2);
1503   *nfuncs = snes->nfuncs;
1504   PetscFunctionReturn(0);
1505 }
1506 
1507 /*@
1508    SNESGetLinearSolveFailures - Gets the number of failed (non-converged)
1509    linear solvers.
1510 
1511    Not Collective
1512 
1513    Input Parameter:
1514 .  snes - SNES context
1515 
1516    Output Parameter:
1517 .  nfails - number of failed solves
1518 
1519    Level: intermediate
1520 
1521    Options Database Keys:
1522 . -snes_max_linear_solve_fail <num> - The number of failures before the solve is terminated
1523 
1524    Notes:
1525    This counter is reset to zero for each successive call to SNESSolve().
1526 
1527 .seealso: `SNESGetMaxLinearSolveFailures()`, `SNESGetLinearSolveIterations()`, `SNESSetMaxLinearSolveFailures()`
1528 @*/
1529 PetscErrorCode  SNESGetLinearSolveFailures(SNES snes,PetscInt *nfails)
1530 {
1531   PetscFunctionBegin;
1532   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1533   PetscValidIntPointer(nfails,2);
1534   *nfails = snes->numLinearSolveFailures;
1535   PetscFunctionReturn(0);
1536 }
1537 
1538 /*@
1539    SNESSetMaxLinearSolveFailures - the number of failed linear solve attempts
1540    allowed before SNES returns with a diverged reason of SNES_DIVERGED_LINEAR_SOLVE
1541 
1542    Logically Collective on SNES
1543 
1544    Input Parameters:
1545 +  snes     - SNES context
1546 -  maxFails - maximum allowed linear solve failures
1547 
1548    Level: intermediate
1549 
1550    Options Database Keys:
1551 . -snes_max_linear_solve_fail <num> - The number of failures before the solve is terminated
1552 
1553    Notes:
1554     By default this is 0; that is SNES returns on the first failed linear solve
1555 
1556 .seealso: `SNESGetLinearSolveFailures()`, `SNESGetMaxLinearSolveFailures()`, `SNESGetLinearSolveIterations()`
1557 @*/
1558 PetscErrorCode  SNESSetMaxLinearSolveFailures(SNES snes, PetscInt maxFails)
1559 {
1560   PetscFunctionBegin;
1561   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1562   PetscValidLogicalCollectiveInt(snes,maxFails,2);
1563   snes->maxLinearSolveFailures = maxFails;
1564   PetscFunctionReturn(0);
1565 }
1566 
1567 /*@
1568    SNESGetMaxLinearSolveFailures - gets the maximum number of linear solve failures that
1569      are allowed before SNES terminates
1570 
1571    Not Collective
1572 
1573    Input Parameter:
1574 .  snes     - SNES context
1575 
1576    Output Parameter:
1577 .  maxFails - maximum of unsuccessful solves allowed
1578 
1579    Level: intermediate
1580 
1581    Notes:
1582     By default this is 1; that is SNES returns on the first failed linear solve
1583 
1584 .seealso: `SNESGetLinearSolveFailures()`, `SNESGetLinearSolveIterations()`, `SNESSetMaxLinearSolveFailures()`,
1585 @*/
1586 PetscErrorCode  SNESGetMaxLinearSolveFailures(SNES snes, PetscInt *maxFails)
1587 {
1588   PetscFunctionBegin;
1589   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1590   PetscValidIntPointer(maxFails,2);
1591   *maxFails = snes->maxLinearSolveFailures;
1592   PetscFunctionReturn(0);
1593 }
1594 
1595 /*@
1596    SNESGetLinearSolveIterations - Gets the total number of linear iterations
1597    used by the nonlinear solver.
1598 
1599    Not Collective
1600 
1601    Input Parameter:
1602 .  snes - SNES context
1603 
1604    Output Parameter:
1605 .  lits - number of linear iterations
1606 
1607    Notes:
1608    This counter is reset to zero for each successive call to SNESSolve() unless SNESSetCountersReset() is used.
1609 
1610    If the linear solver fails inside the SNESSolve() the iterations for that call to the linear solver are not included. If you wish to count them
1611    then call KSPGetIterationNumber() after the failed solve.
1612 
1613    Level: intermediate
1614 
1615 .seealso: `SNESGetIterationNumber()`, `SNESGetLinearSolveFailures()`, `SNESGetMaxLinearSolveFailures()`, `SNESSetCountersReset()`
1616 @*/
1617 PetscErrorCode  SNESGetLinearSolveIterations(SNES snes,PetscInt *lits)
1618 {
1619   PetscFunctionBegin;
1620   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1621   PetscValidIntPointer(lits,2);
1622   *lits = snes->linear_its;
1623   PetscFunctionReturn(0);
1624 }
1625 
1626 /*@
1627    SNESSetCountersReset - Sets whether or not the counters for linear iterations and function evaluations
1628    are reset every time SNESSolve() is called.
1629 
1630    Logically Collective on SNES
1631 
1632    Input Parameters:
1633 +  snes - SNES context
1634 -  reset - whether to reset the counters or not
1635 
1636    Notes:
1637    This defaults to PETSC_TRUE
1638 
1639    Level: developer
1640 
1641 .seealso: `SNESGetNumberFunctionEvals()`, `SNESGetLinearSolveIterations()`, `SNESGetNPC()`
1642 @*/
1643 PetscErrorCode  SNESSetCountersReset(SNES snes,PetscBool reset)
1644 {
1645   PetscFunctionBegin;
1646   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1647   PetscValidLogicalCollectiveBool(snes,reset,2);
1648   snes->counters_reset = reset;
1649   PetscFunctionReturn(0);
1650 }
1651 
1652 /*@
1653    SNESSetKSP - Sets a KSP context for the SNES object to use
1654 
1655    Not Collective, but the SNES and KSP objects must live on the same MPI_Comm
1656 
1657    Input Parameters:
1658 +  snes - the SNES context
1659 -  ksp - the KSP context
1660 
1661    Notes:
1662    The SNES object already has its KSP object, you can obtain with SNESGetKSP()
1663    so this routine is rarely needed.
1664 
1665    The KSP object that is already in the SNES object has its reference count
1666    decreased by one.
1667 
1668    Level: developer
1669 
1670 .seealso: `KSPGetPC()`, `SNESCreate()`, `KSPCreate()`, `SNESSetKSP()`
1671 @*/
1672 PetscErrorCode  SNESSetKSP(SNES snes,KSP ksp)
1673 {
1674   PetscFunctionBegin;
1675   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1676   PetscValidHeaderSpecific(ksp,KSP_CLASSID,2);
1677   PetscCheckSameComm(snes,1,ksp,2);
1678   PetscCall(PetscObjectReference((PetscObject)ksp));
1679   if (snes->ksp) PetscCall(PetscObjectDereference((PetscObject)snes->ksp));
1680   snes->ksp = ksp;
1681   PetscFunctionReturn(0);
1682 }
1683 
1684 /* -----------------------------------------------------------*/
1685 /*@
1686    SNESCreate - Creates a nonlinear solver context.
1687 
1688    Collective
1689 
1690    Input Parameters:
1691 .  comm - MPI communicator
1692 
1693    Output Parameter:
1694 .  outsnes - the new SNES context
1695 
1696    Options Database Keys:
1697 +   -snes_mf - Activates default matrix-free Jacobian-vector products,
1698                and no preconditioning matrix
1699 .   -snes_mf_operator - Activates default matrix-free Jacobian-vector
1700                products, and a user-provided preconditioning matrix
1701                as set by SNESSetJacobian()
1702 -   -snes_fd - Uses (slow!) finite differences to compute Jacobian
1703 
1704    Level: beginner
1705 
1706    Developer Notes:
1707     SNES always creates a KSP object even though many SNES methods do not use it. This is
1708                     unfortunate and should be fixed at some point. The flag snes->usesksp indicates if the
1709                     particular method does use KSP and regulates if the information about the KSP is printed
1710                     in SNESView(). TSSetFromOptions() does call SNESSetFromOptions() which can lead to users being confused
1711                     by help messages about meaningless SNES options.
1712 
1713                     SNES always creates the snes->kspconvctx even though it is used by only one type. This should
1714                     be fixed.
1715 
1716 .seealso: `SNESSolve()`, `SNESDestroy()`, `SNES`, `SNESSetLagPreconditioner()`, `SNESSetLagJacobian()`
1717 
1718 @*/
1719 PetscErrorCode  SNESCreate(MPI_Comm comm,SNES *outsnes)
1720 {
1721   SNES      snes;
1722   SNESKSPEW *kctx;
1723 
1724   PetscFunctionBegin;
1725   PetscValidPointer(outsnes,2);
1726   *outsnes = NULL;
1727   PetscCall(SNESInitializePackage());
1728 
1729   PetscCall(PetscHeaderCreate(snes,SNES_CLASSID,"SNES","Nonlinear solver","SNES",comm,SNESDestroy,SNESView));
1730 
1731   snes->ops->converged    = SNESConvergedDefault;
1732   snes->usesksp           = PETSC_TRUE;
1733   snes->tolerancesset     = PETSC_FALSE;
1734   snes->max_its           = 50;
1735   snes->max_funcs         = 10000;
1736   snes->norm              = 0.0;
1737   snes->xnorm             = 0.0;
1738   snes->ynorm             = 0.0;
1739   snes->normschedule      = SNES_NORM_ALWAYS;
1740   snes->functype          = SNES_FUNCTION_DEFAULT;
1741 #if defined(PETSC_USE_REAL_SINGLE)
1742   snes->rtol              = 1.e-5;
1743 #else
1744   snes->rtol              = 1.e-8;
1745 #endif
1746   snes->ttol              = 0.0;
1747 #if defined(PETSC_USE_REAL_SINGLE)
1748   snes->abstol            = 1.e-25;
1749 #else
1750   snes->abstol            = 1.e-50;
1751 #endif
1752 #if defined(PETSC_USE_REAL_SINGLE)
1753   snes->stol              = 1.e-5;
1754 #else
1755   snes->stol              = 1.e-8;
1756 #endif
1757 #if defined(PETSC_USE_REAL_SINGLE)
1758   snes->deltatol          = 1.e-6;
1759 #else
1760   snes->deltatol          = 1.e-12;
1761 #endif
1762   snes->divtol            = 1.e4;
1763   snes->rnorm0            = 0;
1764   snes->nfuncs            = 0;
1765   snes->numFailures       = 0;
1766   snes->maxFailures       = 1;
1767   snes->linear_its        = 0;
1768   snes->lagjacobian       = 1;
1769   snes->jac_iter          = 0;
1770   snes->lagjac_persist    = PETSC_FALSE;
1771   snes->lagpreconditioner = 1;
1772   snes->pre_iter          = 0;
1773   snes->lagpre_persist    = PETSC_FALSE;
1774   snes->numbermonitors    = 0;
1775   snes->numberreasonviews = 0;
1776   snes->data              = NULL;
1777   snes->setupcalled       = PETSC_FALSE;
1778   snes->ksp_ewconv        = PETSC_FALSE;
1779   snes->nwork             = 0;
1780   snes->work              = NULL;
1781   snes->nvwork            = 0;
1782   snes->vwork             = NULL;
1783   snes->conv_hist_len     = 0;
1784   snes->conv_hist_max     = 0;
1785   snes->conv_hist         = NULL;
1786   snes->conv_hist_its     = NULL;
1787   snes->conv_hist_reset   = PETSC_TRUE;
1788   snes->counters_reset    = PETSC_TRUE;
1789   snes->vec_func_init_set = PETSC_FALSE;
1790   snes->reason            = SNES_CONVERGED_ITERATING;
1791   snes->npcside           = PC_RIGHT;
1792   snes->setfromoptionscalled = 0;
1793 
1794   snes->mf          = PETSC_FALSE;
1795   snes->mf_operator = PETSC_FALSE;
1796   snes->mf_version  = 1;
1797 
1798   snes->numLinearSolveFailures = 0;
1799   snes->maxLinearSolveFailures = 1;
1800 
1801   snes->vizerotolerance = 1.e-8;
1802   snes->checkjacdomainerror = PetscDefined(USE_DEBUG) ? PETSC_TRUE : PETSC_FALSE;
1803 
1804   /* Set this to true if the implementation of SNESSolve_XXX does compute the residual at the final solution. */
1805   snes->alwayscomputesfinalresidual = PETSC_FALSE;
1806 
1807   /* Create context to compute Eisenstat-Walker relative tolerance for KSP */
1808   PetscCall(PetscNewLog(snes,&kctx));
1809 
1810   snes->kspconvctx  = (void*)kctx;
1811   kctx->version     = 2;
1812   kctx->rtol_0      = 0.3; /* Eisenstat and Walker suggest rtol_0=.5, but
1813                              this was too large for some test cases */
1814   kctx->rtol_last   = 0.0;
1815   kctx->rtol_max    = 0.9;
1816   kctx->gamma       = 1.0;
1817   kctx->alpha       = 0.5*(1.0 + PetscSqrtReal(5.0));
1818   kctx->alpha2      = kctx->alpha;
1819   kctx->threshold   = 0.1;
1820   kctx->lresid_last = 0.0;
1821   kctx->norm_last   = 0.0;
1822 
1823   kctx->rk_last     = 0.0;
1824   kctx->rk_last_2   = 0.0;
1825   kctx->rtol_last_2 = 0.0;
1826   kctx->v4_p1       = 0.1;
1827   kctx->v4_p2       = 0.4;
1828   kctx->v4_p3       = 0.7;
1829   kctx->v4_m1       = 0.8;
1830   kctx->v4_m2       = 0.5;
1831   kctx->v4_m3       = 0.1;
1832   kctx->v4_m4       = 0.5;
1833 
1834   *outsnes = snes;
1835   PetscFunctionReturn(0);
1836 }
1837 
1838 /*MC
1839     SNESFunction - Functional form used to convey the nonlinear function to be solved by SNES
1840 
1841      Synopsis:
1842      #include "petscsnes.h"
1843      PetscErrorCode SNESFunction(SNES snes,Vec x,Vec f,void *ctx);
1844 
1845      Collective on snes
1846 
1847      Input Parameters:
1848 +     snes - the SNES context
1849 .     x    - state at which to evaluate residual
1850 -     ctx     - optional user-defined function context, passed in with SNESSetFunction()
1851 
1852      Output Parameter:
1853 .     f  - vector to put residual (function value)
1854 
1855    Level: intermediate
1856 
1857 .seealso: `SNESSetFunction()`, `SNESGetFunction()`
1858 M*/
1859 
1860 /*@C
1861    SNESSetFunction - Sets the function evaluation routine and function
1862    vector for use by the SNES routines in solving systems of nonlinear
1863    equations.
1864 
1865    Logically Collective on SNES
1866 
1867    Input Parameters:
1868 +  snes - the SNES context
1869 .  r - vector to store function values, may be NULL
1870 .  f - function evaluation routine; see SNESFunction for calling sequence details
1871 -  ctx - [optional] user-defined context for private data for the
1872          function evaluation routine (may be NULL)
1873 
1874    Notes:
1875    The Newton-like methods typically solve linear systems of the form
1876 $      f'(x) x = -f(x),
1877    where f'(x) denotes the Jacobian matrix and f(x) is the function.
1878 
1879    Level: beginner
1880 
1881 .seealso: `SNESGetFunction()`, `SNESComputeFunction()`, `SNESSetJacobian()`, `SNESSetPicard()`, `SNESFunction`
1882 @*/
1883 PetscErrorCode  SNESSetFunction(SNES snes,Vec r,PetscErrorCode (*f)(SNES,Vec,Vec,void*),void *ctx)
1884 {
1885   DM             dm;
1886 
1887   PetscFunctionBegin;
1888   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1889   if (r) {
1890     PetscValidHeaderSpecific(r,VEC_CLASSID,2);
1891     PetscCheckSameComm(snes,1,r,2);
1892     PetscCall(PetscObjectReference((PetscObject)r));
1893     PetscCall(VecDestroy(&snes->vec_func));
1894     snes->vec_func = r;
1895   }
1896   PetscCall(SNESGetDM(snes,&dm));
1897   PetscCall(DMSNESSetFunction(dm,f,ctx));
1898   if (f == SNESPicardComputeFunction) {
1899     PetscCall(DMSNESSetMFFunction(dm,SNESPicardComputeMFFunction,ctx));
1900   }
1901   PetscFunctionReturn(0);
1902 }
1903 
1904 /*@C
1905    SNESSetInitialFunction - Sets the function vector to be used as the
1906    function norm at the initialization of the method.  In some
1907    instances, the user has precomputed the function before calling
1908    SNESSolve.  This function allows one to avoid a redundant call
1909    to SNESComputeFunction in that case.
1910 
1911    Logically Collective on SNES
1912 
1913    Input Parameters:
1914 +  snes - the SNES context
1915 -  f - vector to store function value
1916 
1917    Notes:
1918    This should not be modified during the solution procedure.
1919 
1920    This is used extensively in the SNESFAS hierarchy and in nonlinear preconditioning.
1921 
1922    Level: developer
1923 
1924 .seealso: `SNESSetFunction()`, `SNESComputeFunction()`, `SNESSetInitialFunctionNorm()`
1925 @*/
1926 PetscErrorCode  SNESSetInitialFunction(SNES snes, Vec f)
1927 {
1928   Vec            vec_func;
1929 
1930   PetscFunctionBegin;
1931   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1932   PetscValidHeaderSpecific(f,VEC_CLASSID,2);
1933   PetscCheckSameComm(snes,1,f,2);
1934   if (snes->npcside == PC_LEFT && snes->functype == SNES_FUNCTION_PRECONDITIONED) {
1935     snes->vec_func_init_set = PETSC_FALSE;
1936     PetscFunctionReturn(0);
1937   }
1938   PetscCall(SNESGetFunction(snes,&vec_func,NULL,NULL));
1939   PetscCall(VecCopy(f,vec_func));
1940 
1941   snes->vec_func_init_set = PETSC_TRUE;
1942   PetscFunctionReturn(0);
1943 }
1944 
1945 /*@
1946    SNESSetNormSchedule - Sets the SNESNormSchedule used in convergence and monitoring
1947    of the SNES method.
1948 
1949    Logically Collective on SNES
1950 
1951    Input Parameters:
1952 +  snes - the SNES context
1953 -  normschedule - the frequency of norm computation
1954 
1955    Options Database Key:
1956 .  -snes_norm_schedule <none, always, initialonly, finalonly, initialfinalonly> - set the schedule
1957 
1958    Notes:
1959    Only certain SNES methods support certain SNESNormSchedules.  Most require evaluation
1960    of the nonlinear function and the taking of its norm at every iteration to
1961    even ensure convergence at all.  However, methods such as custom Gauss-Seidel methods
1962    (SNESNGS) and the like do not require the norm of the function to be computed, and therefore
1963    may either be monitored for convergence or not.  As these are often used as nonlinear
1964    preconditioners, monitoring the norm of their error is not a useful enterprise within
1965    their solution.
1966 
1967    Level: developer
1968 
1969 .seealso: `SNESGetNormSchedule()`, `SNESComputeFunction()`, `VecNorm()`, `SNESSetFunction()`, `SNESSetInitialFunction()`, `SNESNormSchedule`
1970 @*/
1971 PetscErrorCode  SNESSetNormSchedule(SNES snes, SNESNormSchedule normschedule)
1972 {
1973   PetscFunctionBegin;
1974   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1975   snes->normschedule = normschedule;
1976   PetscFunctionReturn(0);
1977 }
1978 
1979 /*@
1980    SNESGetNormSchedule - Gets the SNESNormSchedule used in convergence and monitoring
1981    of the SNES method.
1982 
1983    Logically Collective on SNES
1984 
1985    Input Parameters:
1986 +  snes - the SNES context
1987 -  normschedule - the type of the norm used
1988 
1989    Level: advanced
1990 
1991 .seealso: `SNESSetNormSchedule()`, `SNESComputeFunction()`, `VecNorm()`, `SNESSetFunction()`, `SNESSetInitialFunction()`, `SNESNormSchedule`
1992 @*/
1993 PetscErrorCode  SNESGetNormSchedule(SNES snes, SNESNormSchedule *normschedule)
1994 {
1995   PetscFunctionBegin;
1996   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1997   *normschedule = snes->normschedule;
1998   PetscFunctionReturn(0);
1999 }
2000 
2001 /*@
2002   SNESSetFunctionNorm - Sets the last computed residual norm.
2003 
2004   Logically Collective on SNES
2005 
2006   Input Parameters:
2007 + snes - the SNES context
2008 
2009 - normschedule - the frequency of norm computation
2010 
2011   Level: developer
2012 
2013 .seealso: `SNESGetNormSchedule()`, `SNESComputeFunction()`, `VecNorm()`, `SNESSetFunction()`, `SNESSetInitialFunction()`, `SNESNormSchedule`
2014 @*/
2015 PetscErrorCode SNESSetFunctionNorm(SNES snes, PetscReal norm)
2016 {
2017   PetscFunctionBegin;
2018   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2019   snes->norm = norm;
2020   PetscFunctionReturn(0);
2021 }
2022 
2023 /*@
2024   SNESGetFunctionNorm - Gets the last computed norm of the residual
2025 
2026   Not Collective
2027 
2028   Input Parameter:
2029 . snes - the SNES context
2030 
2031   Output Parameter:
2032 . norm - the last computed residual norm
2033 
2034   Level: developer
2035 
2036 .seealso: `SNESSetNormSchedule()`, `SNESComputeFunction()`, `VecNorm()`, `SNESSetFunction()`, `SNESSetInitialFunction()`, `SNESNormSchedule`
2037 @*/
2038 PetscErrorCode SNESGetFunctionNorm(SNES snes, PetscReal *norm)
2039 {
2040   PetscFunctionBegin;
2041   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2042   PetscValidRealPointer(norm, 2);
2043   *norm = snes->norm;
2044   PetscFunctionReturn(0);
2045 }
2046 
2047 /*@
2048   SNESGetUpdateNorm - Gets the last computed norm of the Newton update
2049 
2050   Not Collective
2051 
2052   Input Parameter:
2053 . snes - the SNES context
2054 
2055   Output Parameter:
2056 . ynorm - the last computed update norm
2057 
2058   Level: developer
2059 
2060 .seealso: `SNESSetNormSchedule()`, `SNESComputeFunction()`, `SNESGetFunctionNorm()`
2061 @*/
2062 PetscErrorCode SNESGetUpdateNorm(SNES snes, PetscReal *ynorm)
2063 {
2064   PetscFunctionBegin;
2065   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2066   PetscValidRealPointer(ynorm, 2);
2067   *ynorm = snes->ynorm;
2068   PetscFunctionReturn(0);
2069 }
2070 
2071 /*@
2072   SNESGetSolutionNorm - Gets the last computed norm of the solution
2073 
2074   Not Collective
2075 
2076   Input Parameter:
2077 . snes - the SNES context
2078 
2079   Output Parameter:
2080 . xnorm - the last computed solution norm
2081 
2082   Level: developer
2083 
2084 .seealso: `SNESSetNormSchedule()`, `SNESComputeFunction()`, `SNESGetFunctionNorm()`, `SNESGetUpdateNorm()`
2085 @*/
2086 PetscErrorCode SNESGetSolutionNorm(SNES snes, PetscReal *xnorm)
2087 {
2088   PetscFunctionBegin;
2089   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2090   PetscValidRealPointer(xnorm, 2);
2091   *xnorm = snes->xnorm;
2092   PetscFunctionReturn(0);
2093 }
2094 
2095 /*@C
2096    SNESSetFunctionType - Sets the SNESNormSchedule used in convergence and monitoring
2097    of the SNES method.
2098 
2099    Logically Collective on SNES
2100 
2101    Input Parameters:
2102 +  snes - the SNES context
2103 -  normschedule - the frequency of norm computation
2104 
2105    Notes:
2106    Only certain SNES methods support certain SNESNormSchedules.  Most require evaluation
2107    of the nonlinear function and the taking of its norm at every iteration to
2108    even ensure convergence at all.  However, methods such as custom Gauss-Seidel methods
2109    (SNESNGS) and the like do not require the norm of the function to be computed, and therefore
2110    may either be monitored for convergence or not.  As these are often used as nonlinear
2111    preconditioners, monitoring the norm of their error is not a useful enterprise within
2112    their solution.
2113 
2114    Level: developer
2115 
2116 .seealso: `SNESGetNormSchedule()`, `SNESComputeFunction()`, `VecNorm()`, `SNESSetFunction()`, `SNESSetInitialFunction()`, `SNESNormSchedule`
2117 @*/
2118 PetscErrorCode  SNESSetFunctionType(SNES snes, SNESFunctionType type)
2119 {
2120   PetscFunctionBegin;
2121   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2122   snes->functype = type;
2123   PetscFunctionReturn(0);
2124 }
2125 
2126 /*@C
2127    SNESGetFunctionType - Gets the SNESNormSchedule used in convergence and monitoring
2128    of the SNES method.
2129 
2130    Logically Collective on SNES
2131 
2132    Input Parameters:
2133 +  snes - the SNES context
2134 -  normschedule - the type of the norm used
2135 
2136    Level: advanced
2137 
2138 .seealso: `SNESSetNormSchedule()`, `SNESComputeFunction()`, `VecNorm()`, `SNESSetFunction()`, `SNESSetInitialFunction()`, `SNESNormSchedule`
2139 @*/
2140 PetscErrorCode  SNESGetFunctionType(SNES snes, SNESFunctionType *type)
2141 {
2142   PetscFunctionBegin;
2143   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2144   *type = snes->functype;
2145   PetscFunctionReturn(0);
2146 }
2147 
2148 /*MC
2149     SNESNGSFunction - function used to convey a Gauss-Seidel sweep on the nonlinear function
2150 
2151      Synopsis:
2152      #include <petscsnes.h>
2153 $    SNESNGSFunction(SNES snes,Vec x,Vec b,void *ctx);
2154 
2155      Collective on snes
2156 
2157      Input Parameters:
2158 +  X   - solution vector
2159 .  B   - RHS vector
2160 -  ctx - optional user-defined Gauss-Seidel context
2161 
2162      Output Parameter:
2163 .  X   - solution vector
2164 
2165    Level: intermediate
2166 
2167 .seealso: `SNESSetNGS()`, `SNESGetNGS()`
2168 M*/
2169 
2170 /*@C
2171    SNESSetNGS - Sets the user nonlinear Gauss-Seidel routine for
2172    use with composed nonlinear solvers.
2173 
2174    Input Parameters:
2175 +  snes   - the SNES context
2176 .  f - function evaluation routine to apply Gauss-Seidel see SNESNGSFunction
2177 -  ctx    - [optional] user-defined context for private data for the
2178             smoother evaluation routine (may be NULL)
2179 
2180    Notes:
2181    The NGS routines are used by the composed nonlinear solver to generate
2182     a problem appropriate update to the solution, particularly FAS.
2183 
2184    Level: intermediate
2185 
2186 .seealso: `SNESGetFunction()`, `SNESComputeNGS()`
2187 @*/
2188 PetscErrorCode SNESSetNGS(SNES snes,PetscErrorCode (*f)(SNES,Vec,Vec,void*),void *ctx)
2189 {
2190   DM             dm;
2191 
2192   PetscFunctionBegin;
2193   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2194   PetscCall(SNESGetDM(snes,&dm));
2195   PetscCall(DMSNESSetNGS(dm,f,ctx));
2196   PetscFunctionReturn(0);
2197 }
2198 
2199 /*
2200      This is used for -snes_mf_operator; it uses a duplicate of snes->jacobian_pre because snes->jacobian_pre cannot be
2201    changed during the KSPSolve()
2202 */
2203 PetscErrorCode SNESPicardComputeMFFunction(SNES snes,Vec x,Vec f,void *ctx)
2204 {
2205   DM             dm;
2206   DMSNES         sdm;
2207 
2208   PetscFunctionBegin;
2209   PetscCall(SNESGetDM(snes,&dm));
2210   PetscCall(DMGetDMSNES(dm,&sdm));
2211   PetscCheck(sdm->ops->computepjacobian,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE, "Must call SNESSetPicard() to provide Picard Jacobian.");
2212   /*  A(x)*x - b(x) */
2213   if (sdm->ops->computepfunction) {
2214     PetscStackPush("SNES Picard user function");
2215     PetscCall((*sdm->ops->computepfunction)(snes,x,f,sdm->pctx));
2216     PetscStackPop;
2217     PetscCall(VecScale(f,-1.0));
2218     if (!snes->picard) {
2219       /* Cannot share nonzero pattern because of the possible use of SNESComputeJacobianDefault() */
2220       PetscCall(MatDuplicate(snes->jacobian_pre,MAT_DO_NOT_COPY_VALUES,&snes->picard));
2221     }
2222     PetscStackPush("SNES Picard user Jacobian");
2223     PetscCall((*sdm->ops->computepjacobian)(snes,x,snes->picard,snes->picard,sdm->pctx));
2224     PetscStackPop;
2225     PetscCall(MatMultAdd(snes->picard,x,f,f));
2226   } else {
2227     PetscStackPush("SNES Picard user Jacobian");
2228     PetscCall((*sdm->ops->computepjacobian)(snes,x,snes->picard,snes->picard,sdm->pctx));
2229     PetscStackPop;
2230     PetscCall(MatMult(snes->picard,x,f));
2231   }
2232   PetscFunctionReturn(0);
2233 }
2234 
2235 PetscErrorCode SNESPicardComputeFunction(SNES snes,Vec x,Vec f,void *ctx)
2236 {
2237   DM             dm;
2238   DMSNES         sdm;
2239 
2240   PetscFunctionBegin;
2241   PetscCall(SNESGetDM(snes,&dm));
2242   PetscCall(DMGetDMSNES(dm,&sdm));
2243   PetscCheck(sdm->ops->computepjacobian,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE, "Must call SNESSetPicard() to provide Picard Jacobian.");
2244   /*  A(x)*x - b(x) */
2245   if (sdm->ops->computepfunction) {
2246     PetscStackPush("SNES Picard user function");
2247     PetscCall((*sdm->ops->computepfunction)(snes,x,f,sdm->pctx));
2248     PetscStackPop;
2249     PetscCall(VecScale(f,-1.0));
2250     PetscStackPush("SNES Picard user Jacobian");
2251     PetscCall((*sdm->ops->computepjacobian)(snes,x,snes->jacobian,snes->jacobian_pre,sdm->pctx));
2252     PetscStackPop;
2253     PetscCall(MatMultAdd(snes->jacobian_pre,x,f,f));
2254   } else {
2255     PetscStackPush("SNES Picard user Jacobian");
2256     PetscCall((*sdm->ops->computepjacobian)(snes,x,snes->jacobian,snes->jacobian_pre,sdm->pctx));
2257     PetscStackPop;
2258     PetscCall(MatMult(snes->jacobian_pre,x,f));
2259   }
2260   PetscFunctionReturn(0);
2261 }
2262 
2263 PetscErrorCode SNESPicardComputeJacobian(SNES snes,Vec x1,Mat J,Mat B,void *ctx)
2264 {
2265   PetscFunctionBegin;
2266   /* the jacobian matrix should be pre-filled in SNESPicardComputeFunction */
2267   /* must assembly if matrix-free to get the last SNES solution */
2268   PetscCall(MatAssemblyBegin(J,MAT_FINAL_ASSEMBLY));
2269   PetscCall(MatAssemblyEnd(J,MAT_FINAL_ASSEMBLY));
2270   PetscFunctionReturn(0);
2271 }
2272 
2273 /*@C
2274    SNESSetPicard - Use SNES to solve the system A(x) x = bp(x) + b via a Picard type iteration (Picard linearization)
2275 
2276    Logically Collective on SNES
2277 
2278    Input Parameters:
2279 +  snes - the SNES context
2280 .  r - vector to store function values, may be NULL
2281 .  bp - function evaluation routine, may be NULL
2282 .  Amat - matrix with which A(x) x - bp(x) - b is to be computed
2283 .  Pmat - matrix from which preconditioner is computed (usually the same as Amat)
2284 .  J  - function to compute matrix values, see SNESJacobianFunction() for details on its calling sequence
2285 -  ctx - [optional] user-defined context for private data for the function evaluation routine (may be NULL)
2286 
2287    Notes:
2288     It is often better to provide the nonlinear function F() and some approximation to its Jacobian directly and use
2289     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.
2290 
2291     One can call SNESSetPicard() or SNESSetFunction() (and possibly SNESSetJacobian()) but cannot call both
2292 
2293 $     Solves the equation A(x) x = bp(x) - b via the defect correction algorithm A(x^{n}) (x^{n+1} - x^{n}) = bp(x^{n}) + b - A(x^{n})x^{n}
2294 $     Note that when an exact solver is used this corresponds to the "classic" Picard A(x^{n}) x^{n+1} = bp(x^{n}) + b iteration.
2295 
2296      Run with -snes_mf_operator to solve the system with Newton's method using A(x^{n}) to construct the preconditioner.
2297 
2298    We implement the defect correction form of the Picard iteration because it converges much more generally when inexact linear solvers are used then
2299    the direct Picard iteration A(x^n) x^{n+1} = bp(x^n) + b
2300 
2301    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
2302    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
2303    different please contact us at petsc-dev@mcs.anl.gov and we'll have an entirely new argument :-).
2304 
2305    When used with -snes_mf_operator this will run matrix-free Newton's method where the matrix-vector product is of the true Jacobian of A(x)x - bp(x) -b.
2306 
2307    When used with -snes_fd this will compute the true Jacobian (very slowly one column at at time) and thus represent Newton's method.
2308 
2309    When used with -snes_fd_coloring this will compute the Jacobian via coloring and thus represent a faster implementation of Newton's method. But the
2310    the nonzero structure of the Jacobian is, in general larger than that of the Picard matrix A so you must provide in A the needed nonzero structure for the correct
2311    coloring. When using DMDA this may mean creating the matrix A with DMCreateMatrix() using a wider stencil than strictly needed for A or with a DMDA_STENCIL_BOX.
2312    See the commment in src/snes/tutorials/ex15.c.
2313 
2314    Level: intermediate
2315 
2316 .seealso: `SNESGetFunction()`, `SNESSetFunction()`, `SNESComputeFunction()`, `SNESSetJacobian()`, `SNESGetPicard()`, `SNESLineSearchPreCheckPicard()`, `SNESJacobianFunction`
2317 @*/
2318 PetscErrorCode  SNESSetPicard(SNES snes,Vec r,PetscErrorCode (*bp)(SNES,Vec,Vec,void*),Mat Amat, Mat Pmat, PetscErrorCode (*J)(SNES,Vec,Mat,Mat,void*),void *ctx)
2319 {
2320   DM             dm;
2321 
2322   PetscFunctionBegin;
2323   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2324   PetscCall(SNESGetDM(snes, &dm));
2325   PetscCall(DMSNESSetPicard(dm,bp,J,ctx));
2326   PetscCall(DMSNESSetMFFunction(dm,SNESPicardComputeMFFunction,ctx));
2327   PetscCall(SNESSetFunction(snes,r,SNESPicardComputeFunction,ctx));
2328   PetscCall(SNESSetJacobian(snes,Amat,Pmat,SNESPicardComputeJacobian,ctx));
2329   PetscFunctionReturn(0);
2330 }
2331 
2332 /*@C
2333    SNESGetPicard - Returns the context for the Picard iteration
2334 
2335    Not Collective, but Vec is parallel if SNES is parallel. Collective if Vec is requested, but has not been created yet.
2336 
2337    Input Parameter:
2338 .  snes - the SNES context
2339 
2340    Output Parameters:
2341 +  r - the function (or NULL)
2342 .  f - the function (or NULL); see SNESFunction for calling sequence details
2343 .  Amat - the matrix used to defined the operation A(x) x - b(x) (or NULL)
2344 .  Pmat  - the matrix from which the preconditioner will be constructed (or NULL)
2345 .  J - the function for matrix evaluation (or NULL); see SNESJacobianFunction for calling sequence details
2346 -  ctx - the function context (or NULL)
2347 
2348    Level: advanced
2349 
2350 .seealso: `SNESSetPicard()`, `SNESGetFunction()`, `SNESGetJacobian()`, `SNESGetDM()`, `SNESFunction`, `SNESJacobianFunction`
2351 @*/
2352 PetscErrorCode  SNESGetPicard(SNES snes,Vec *r,PetscErrorCode (**f)(SNES,Vec,Vec,void*),Mat *Amat, Mat *Pmat, PetscErrorCode (**J)(SNES,Vec,Mat,Mat,void*),void **ctx)
2353 {
2354   DM             dm;
2355 
2356   PetscFunctionBegin;
2357   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2358   PetscCall(SNESGetFunction(snes,r,NULL,NULL));
2359   PetscCall(SNESGetJacobian(snes,Amat,Pmat,NULL,NULL));
2360   PetscCall(SNESGetDM(snes,&dm));
2361   PetscCall(DMSNESGetPicard(dm,f,J,ctx));
2362   PetscFunctionReturn(0);
2363 }
2364 
2365 /*@C
2366    SNESSetComputeInitialGuess - Sets a routine used to compute an initial guess for the problem
2367 
2368    Logically Collective on SNES
2369 
2370    Input Parameters:
2371 +  snes - the SNES context
2372 .  func - function evaluation routine
2373 -  ctx - [optional] user-defined context for private data for the
2374          function evaluation routine (may be NULL)
2375 
2376    Calling sequence of func:
2377 $    func (SNES snes,Vec x,void *ctx);
2378 
2379 .  f - function vector
2380 -  ctx - optional user-defined function context
2381 
2382    Level: intermediate
2383 
2384 .seealso: `SNESGetFunction()`, `SNESComputeFunction()`, `SNESSetJacobian()`
2385 @*/
2386 PetscErrorCode  SNESSetComputeInitialGuess(SNES snes,PetscErrorCode (*func)(SNES,Vec,void*),void *ctx)
2387 {
2388   PetscFunctionBegin;
2389   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2390   if (func) snes->ops->computeinitialguess = func;
2391   if (ctx)  snes->initialguessP            = ctx;
2392   PetscFunctionReturn(0);
2393 }
2394 
2395 /* --------------------------------------------------------------- */
2396 /*@C
2397    SNESGetRhs - Gets the vector for solving F(x) = rhs. If rhs is not set
2398    it assumes a zero right hand side.
2399 
2400    Logically Collective on SNES
2401 
2402    Input Parameter:
2403 .  snes - the SNES context
2404 
2405    Output Parameter:
2406 .  rhs - the right hand side vector or NULL if the right hand side vector is null
2407 
2408    Level: intermediate
2409 
2410 .seealso: `SNESGetSolution()`, `SNESGetFunction()`, `SNESComputeFunction()`, `SNESSetJacobian()`, `SNESSetFunction()`
2411 @*/
2412 PetscErrorCode  SNESGetRhs(SNES snes,Vec *rhs)
2413 {
2414   PetscFunctionBegin;
2415   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2416   PetscValidPointer(rhs,2);
2417   *rhs = snes->vec_rhs;
2418   PetscFunctionReturn(0);
2419 }
2420 
2421 /*@
2422    SNESComputeFunction - Calls the function that has been set with SNESSetFunction().
2423 
2424    Collective on SNES
2425 
2426    Input Parameters:
2427 +  snes - the SNES context
2428 -  x - input vector
2429 
2430    Output Parameter:
2431 .  y - function vector, as set by SNESSetFunction()
2432 
2433    Notes:
2434    SNESComputeFunction() is typically used within nonlinear solvers
2435    implementations, so users would not generally call this routine themselves.
2436 
2437    Level: developer
2438 
2439 .seealso: `SNESSetFunction()`, `SNESGetFunction()`, `SNESComputeMFFunction()`
2440 @*/
2441 PetscErrorCode  SNESComputeFunction(SNES snes,Vec x,Vec y)
2442 {
2443   DM             dm;
2444   DMSNES         sdm;
2445 
2446   PetscFunctionBegin;
2447   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2448   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
2449   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
2450   PetscCheckSameComm(snes,1,x,2);
2451   PetscCheckSameComm(snes,1,y,3);
2452   PetscCall(VecValidValues(x,2,PETSC_TRUE));
2453 
2454   PetscCall(SNESGetDM(snes,&dm));
2455   PetscCall(DMGetDMSNES(dm,&sdm));
2456   if (sdm->ops->computefunction) {
2457     if (sdm->ops->computefunction != SNESObjectiveComputeFunctionDefaultFD) {
2458       PetscCall(PetscLogEventBegin(SNES_FunctionEval,snes,x,y,0));
2459     }
2460     PetscCall(VecLockReadPush(x));
2461     PetscStackPush("SNES user function");
2462     /* ensure domainerror is false prior to computefunction evaluation (may not have been reset) */
2463     snes->domainerror = PETSC_FALSE;
2464     PetscCall((*sdm->ops->computefunction)(snes,x,y,sdm->functionctx));
2465     PetscStackPop;
2466     PetscCall(VecLockReadPop(x));
2467     if (sdm->ops->computefunction != SNESObjectiveComputeFunctionDefaultFD) {
2468       PetscCall(PetscLogEventEnd(SNES_FunctionEval,snes,x,y,0));
2469     }
2470   } else if (snes->vec_rhs) {
2471     PetscCall(MatMult(snes->jacobian, x, y));
2472   } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE, "Must call SNESSetFunction() or SNESSetDM() before SNESComputeFunction(), likely called from SNESSolve().");
2473   if (snes->vec_rhs) PetscCall(VecAXPY(y,-1.0,snes->vec_rhs));
2474   snes->nfuncs++;
2475   /*
2476      domainerror might not be set on all processes; so we tag vector locally with Inf and the next inner product or norm will
2477      propagate the value to all processes
2478   */
2479   if (snes->domainerror) PetscCall(VecSetInf(y));
2480   PetscFunctionReturn(0);
2481 }
2482 
2483 /*@
2484    SNESComputeMFFunction - Calls the function that has been set with SNESSetMFFunction().
2485 
2486    Collective on SNES
2487 
2488    Input Parameters:
2489 +  snes - the SNES context
2490 -  x - input vector
2491 
2492    Output Parameter:
2493 .  y - function vector, as set by SNESSetMFFunction()
2494 
2495    Notes:
2496        SNESComputeMFFunction() is used within the matrix vector products called by the matrix created with MatCreateSNESMF()
2497    so users would not generally call this routine themselves.
2498 
2499        Since this function is intended for use with finite differencing it does not subtract the right hand side vector provided with SNESSolve()
2500     while SNESComputeFunction() does. As such, this routine cannot be used with  MatMFFDSetBase() with a provided F function value even if it applies the
2501     same function as SNESComputeFunction() if a SNESSolve() right hand side vector is use because the two functions difference would include this right hand side function.
2502 
2503    Level: developer
2504 
2505 .seealso: `SNESSetFunction()`, `SNESGetFunction()`, `SNESComputeFunction()`, `MatCreateSNESMF`
2506 @*/
2507 PetscErrorCode  SNESComputeMFFunction(SNES snes,Vec x,Vec y)
2508 {
2509   DM             dm;
2510   DMSNES         sdm;
2511 
2512   PetscFunctionBegin;
2513   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2514   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
2515   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
2516   PetscCheckSameComm(snes,1,x,2);
2517   PetscCheckSameComm(snes,1,y,3);
2518   PetscCall(VecValidValues(x,2,PETSC_TRUE));
2519 
2520   PetscCall(SNESGetDM(snes,&dm));
2521   PetscCall(DMGetDMSNES(dm,&sdm));
2522   PetscCall(PetscLogEventBegin(SNES_FunctionEval,snes,x,y,0));
2523   PetscCall(VecLockReadPush(x));
2524   PetscStackPush("SNES user function");
2525   /* ensure domainerror is false prior to computefunction evaluation (may not have been reset) */
2526   snes->domainerror = PETSC_FALSE;
2527   PetscCall((*sdm->ops->computemffunction)(snes,x,y,sdm->mffunctionctx));
2528   PetscStackPop;
2529   PetscCall(VecLockReadPop(x));
2530   PetscCall(PetscLogEventEnd(SNES_FunctionEval,snes,x,y,0));
2531   snes->nfuncs++;
2532   /*
2533      domainerror might not be set on all processes; so we tag vector locally with Inf and the next inner product or norm will
2534      propagate the value to all processes
2535   */
2536   if (snes->domainerror) PetscCall(VecSetInf(y));
2537   PetscFunctionReturn(0);
2538 }
2539 
2540 /*@
2541    SNESComputeNGS - Calls the Gauss-Seidel function that has been set with  SNESSetNGS().
2542 
2543    Collective on SNES
2544 
2545    Input Parameters:
2546 +  snes - the SNES context
2547 .  x - input vector
2548 -  b - rhs vector
2549 
2550    Output Parameter:
2551 .  x - new solution vector
2552 
2553    Notes:
2554    SNESComputeNGS() is typically used within composed nonlinear solver
2555    implementations, so most users would not generally call this routine
2556    themselves.
2557 
2558    Level: developer
2559 
2560 .seealso: `SNESSetNGS()`, `SNESComputeFunction()`
2561 @*/
2562 PetscErrorCode  SNESComputeNGS(SNES snes,Vec b,Vec x)
2563 {
2564   DM             dm;
2565   DMSNES         sdm;
2566 
2567   PetscFunctionBegin;
2568   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2569   PetscValidHeaderSpecific(x,VEC_CLASSID,3);
2570   if (b) PetscValidHeaderSpecific(b,VEC_CLASSID,2);
2571   PetscCheckSameComm(snes,1,x,3);
2572   if (b) PetscCheckSameComm(snes,1,b,2);
2573   if (b) PetscCall(VecValidValues(b,2,PETSC_TRUE));
2574   PetscCall(PetscLogEventBegin(SNES_NGSEval,snes,x,b,0));
2575   PetscCall(SNESGetDM(snes,&dm));
2576   PetscCall(DMGetDMSNES(dm,&sdm));
2577   if (sdm->ops->computegs) {
2578     if (b) PetscCall(VecLockReadPush(b));
2579     PetscStackPush("SNES user NGS");
2580     PetscCall((*sdm->ops->computegs)(snes,x,b,sdm->gsctx));
2581     PetscStackPop;
2582     if (b) PetscCall(VecLockReadPop(b));
2583   } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE, "Must call SNESSetNGS() before SNESComputeNGS(), likely called from SNESSolve().");
2584   PetscCall(PetscLogEventEnd(SNES_NGSEval,snes,x,b,0));
2585   PetscFunctionReturn(0);
2586 }
2587 
2588 PetscErrorCode SNESTestJacobian(SNES snes)
2589 {
2590   Mat               A,B,C,D,jacobian;
2591   Vec               x = snes->vec_sol,f = snes->vec_func;
2592   PetscReal         nrm,gnorm;
2593   PetscReal         threshold = 1.e-5;
2594   MatType           mattype;
2595   PetscInt          m,n,M,N;
2596   void              *functx;
2597   PetscBool         complete_print = PETSC_FALSE,threshold_print = PETSC_FALSE,test = PETSC_FALSE,flg,istranspose;
2598   PetscViewer       viewer,mviewer;
2599   MPI_Comm          comm;
2600   PetscInt          tabs;
2601   static PetscBool  directionsprinted = PETSC_FALSE;
2602   PetscViewerFormat format;
2603 
2604   PetscFunctionBegin;
2605   PetscObjectOptionsBegin((PetscObject)snes);
2606   PetscCall(PetscOptionsName("-snes_test_jacobian","Compare hand-coded and finite difference Jacobians","None",&test));
2607   PetscCall(PetscOptionsReal("-snes_test_jacobian", "Threshold for element difference between hand-coded and finite difference being meaningful", "None", threshold, &threshold,NULL));
2608   PetscCall(PetscOptionsViewer("-snes_test_jacobian_view","View difference between hand-coded and finite difference Jacobians element entries","None",&mviewer,&format,&complete_print));
2609   if (!complete_print) {
2610     PetscCall(PetscOptionsDeprecated("-snes_test_jacobian_display","-snes_test_jacobian_view","3.13",NULL));
2611     PetscCall(PetscOptionsViewer("-snes_test_jacobian_display","Display difference between hand-coded and finite difference Jacobians","None",&mviewer,&format,&complete_print));
2612   }
2613   /* for compatibility with PETSc 3.9 and older. */
2614   PetscCall(PetscOptionsDeprecated("-snes_test_jacobian_display_threshold","-snes_test_jacobian","3.13","-snes_test_jacobian accepts an optional threshold (since v3.10)"));
2615   PetscCall(PetscOptionsReal("-snes_test_jacobian_display_threshold", "Display difference between hand-coded and finite difference Jacobians which exceed input threshold", "None", threshold, &threshold, &threshold_print));
2616   PetscOptionsEnd();
2617   if (!test) PetscFunctionReturn(0);
2618 
2619   PetscCall(PetscObjectGetComm((PetscObject)snes,&comm));
2620   PetscCall(PetscViewerASCIIGetStdout(comm,&viewer));
2621   PetscCall(PetscViewerASCIIGetTab(viewer, &tabs));
2622   PetscCall(PetscViewerASCIISetTab(viewer, ((PetscObject)snes)->tablevel));
2623   PetscCall(PetscViewerASCIIPrintf(viewer,"  ---------- Testing Jacobian -------------\n"));
2624   if (!complete_print && !directionsprinted) {
2625     PetscCall(PetscViewerASCIIPrintf(viewer,"  Run with -snes_test_jacobian_view and optionally -snes_test_jacobian <threshold> to show difference\n"));
2626     PetscCall(PetscViewerASCIIPrintf(viewer,"    of hand-coded and finite difference Jacobian entries greater than <threshold>.\n"));
2627   }
2628   if (!directionsprinted) {
2629     PetscCall(PetscViewerASCIIPrintf(viewer,"  Testing hand-coded Jacobian, if (for double precision runs) ||J - Jfd||_F/||J||_F is\n"));
2630     PetscCall(PetscViewerASCIIPrintf(viewer,"    O(1.e-8), the hand-coded Jacobian is probably correct.\n"));
2631     directionsprinted = PETSC_TRUE;
2632   }
2633   if (complete_print) PetscCall(PetscViewerPushFormat(mviewer,format));
2634 
2635   PetscCall(PetscObjectTypeCompare((PetscObject)snes->jacobian,MATMFFD,&flg));
2636   if (!flg) jacobian = snes->jacobian;
2637   else jacobian = snes->jacobian_pre;
2638 
2639   if (!x) {
2640     PetscCall(MatCreateVecs(jacobian, &x, NULL));
2641   } else {
2642     PetscCall(PetscObjectReference((PetscObject) x));
2643   }
2644   if (!f) {
2645     PetscCall(VecDuplicate(x, &f));
2646   } else {
2647     PetscCall(PetscObjectReference((PetscObject) f));
2648   }
2649   /* evaluate the function at this point because SNESComputeJacobianDefault() assumes that the function has been evaluated and put into snes->vec_func */
2650   PetscCall(SNESComputeFunction(snes,x,f));
2651   PetscCall(VecDestroy(&f));
2652   PetscCall(PetscObjectTypeCompare((PetscObject)snes,SNESKSPTRANSPOSEONLY,&istranspose));
2653   while (jacobian) {
2654     Mat JT = NULL, Jsave = NULL;
2655 
2656     if (istranspose) {
2657       PetscCall(MatCreateTranspose(jacobian,&JT));
2658       Jsave = jacobian;
2659       jacobian = JT;
2660     }
2661     PetscCall(PetscObjectBaseTypeCompareAny((PetscObject)jacobian,&flg,MATSEQAIJ,MATMPIAIJ,MATSEQDENSE,MATMPIDENSE,MATSEQBAIJ,MATMPIBAIJ,MATSEQSBAIJ,MATMPISBAIJ,""));
2662     if (flg) {
2663       A    = jacobian;
2664       PetscCall(PetscObjectReference((PetscObject)A));
2665     } else {
2666       PetscCall(MatComputeOperator(jacobian,MATAIJ,&A));
2667     }
2668 
2669     PetscCall(MatGetType(A,&mattype));
2670     PetscCall(MatGetSize(A,&M,&N));
2671     PetscCall(MatGetLocalSize(A,&m,&n));
2672     PetscCall(MatCreate(PetscObjectComm((PetscObject)A),&B));
2673     PetscCall(MatSetType(B,mattype));
2674     PetscCall(MatSetSizes(B,m,n,M,N));
2675     PetscCall(MatSetBlockSizesFromMats(B,A,A));
2676     PetscCall(MatSetUp(B));
2677     PetscCall(MatSetOption(B,MAT_NEW_NONZERO_ALLOCATION_ERR,PETSC_FALSE));
2678 
2679     PetscCall(SNESGetFunction(snes,NULL,NULL,&functx));
2680     PetscCall(SNESComputeJacobianDefault(snes,x,B,B,functx));
2681 
2682     PetscCall(MatDuplicate(B,MAT_COPY_VALUES,&D));
2683     PetscCall(MatAYPX(D,-1.0,A,DIFFERENT_NONZERO_PATTERN));
2684     PetscCall(MatNorm(D,NORM_FROBENIUS,&nrm));
2685     PetscCall(MatNorm(A,NORM_FROBENIUS,&gnorm));
2686     PetscCall(MatDestroy(&D));
2687     if (!gnorm) gnorm = 1; /* just in case */
2688     PetscCall(PetscViewerASCIIPrintf(viewer,"  ||J - Jfd||_F/||J||_F = %g, ||J - Jfd||_F = %g\n",(double)(nrm/gnorm),(double)nrm));
2689 
2690     if (complete_print) {
2691       PetscCall(PetscViewerASCIIPrintf(viewer,"  Hand-coded Jacobian ----------\n"));
2692       PetscCall(MatView(A,mviewer));
2693       PetscCall(PetscViewerASCIIPrintf(viewer,"  Finite difference Jacobian ----------\n"));
2694       PetscCall(MatView(B,mviewer));
2695     }
2696 
2697     if (threshold_print || complete_print) {
2698       PetscInt          Istart, Iend, *ccols, bncols, cncols, j, row;
2699       PetscScalar       *cvals;
2700       const PetscInt    *bcols;
2701       const PetscScalar *bvals;
2702 
2703       PetscCall(MatCreate(PetscObjectComm((PetscObject)A),&C));
2704       PetscCall(MatSetType(C,mattype));
2705       PetscCall(MatSetSizes(C,m,n,M,N));
2706       PetscCall(MatSetBlockSizesFromMats(C,A,A));
2707       PetscCall(MatSetUp(C));
2708       PetscCall(MatSetOption(C,MAT_NEW_NONZERO_ALLOCATION_ERR,PETSC_FALSE));
2709 
2710       PetscCall(MatAYPX(B,-1.0,A,DIFFERENT_NONZERO_PATTERN));
2711       PetscCall(MatGetOwnershipRange(B,&Istart,&Iend));
2712 
2713       for (row = Istart; row < Iend; row++) {
2714         PetscCall(MatGetRow(B,row,&bncols,&bcols,&bvals));
2715         PetscCall(PetscMalloc2(bncols,&ccols,bncols,&cvals));
2716         for (j = 0, cncols = 0; j < bncols; j++) {
2717           if (PetscAbsScalar(bvals[j]) > threshold) {
2718             ccols[cncols] = bcols[j];
2719             cvals[cncols] = bvals[j];
2720             cncols += 1;
2721           }
2722         }
2723         if (cncols) {
2724           PetscCall(MatSetValues(C,1,&row,cncols,ccols,cvals,INSERT_VALUES));
2725         }
2726         PetscCall(MatRestoreRow(B,row,&bncols,&bcols,&bvals));
2727         PetscCall(PetscFree2(ccols,cvals));
2728       }
2729       PetscCall(MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY));
2730       PetscCall(MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY));
2731       PetscCall(PetscViewerASCIIPrintf(viewer,"  Hand-coded minus finite-difference Jacobian with tolerance %g ----------\n",(double)threshold));
2732       PetscCall(MatView(C,complete_print ? mviewer : viewer));
2733       PetscCall(MatDestroy(&C));
2734     }
2735     PetscCall(MatDestroy(&A));
2736     PetscCall(MatDestroy(&B));
2737     PetscCall(MatDestroy(&JT));
2738     if (Jsave) jacobian = Jsave;
2739     if (jacobian != snes->jacobian_pre) {
2740       jacobian = snes->jacobian_pre;
2741       PetscCall(PetscViewerASCIIPrintf(viewer,"  ---------- Testing Jacobian for preconditioner -------------\n"));
2742     }
2743     else jacobian = NULL;
2744   }
2745   PetscCall(VecDestroy(&x));
2746   if (complete_print) PetscCall(PetscViewerPopFormat(mviewer));
2747   if (mviewer) PetscCall(PetscViewerDestroy(&mviewer));
2748   PetscCall(PetscViewerASCIISetTab(viewer,tabs));
2749   PetscFunctionReturn(0);
2750 }
2751 
2752 /*@
2753    SNESComputeJacobian - Computes the Jacobian matrix that has been set with SNESSetJacobian().
2754 
2755    Collective on SNES
2756 
2757    Input Parameters:
2758 +  snes - the SNES context
2759 -  x - input vector
2760 
2761    Output Parameters:
2762 +  A - Jacobian matrix
2763 -  B - optional preconditioning matrix
2764 
2765   Options Database Keys:
2766 +    -snes_lag_preconditioner <lag> - how often to rebuild preconditioner
2767 .    -snes_lag_jacobian <lag> - how often to rebuild Jacobian
2768 .    -snes_test_jacobian <optional threshold> - compare the user provided Jacobian with one compute via finite differences to check for errors.  If a threshold is given, display only those entries whose difference is greater than the threshold.
2769 .    -snes_test_jacobian_view - display the user provided Jacobian, the finite difference Jacobian and the difference between them to help users detect the location of errors in the user provided Jacobian
2770 .    -snes_compare_explicit - Compare the computed Jacobian to the finite difference Jacobian and output the differences
2771 .    -snes_compare_explicit_draw  - Compare the computed Jacobian to the finite difference Jacobian and draw the result
2772 .    -snes_compare_explicit_contour  - Compare the computed Jacobian to the finite difference Jacobian and draw a contour plot with the result
2773 .    -snes_compare_operator  - Make the comparison options above use the operator instead of the preconditioning matrix
2774 .    -snes_compare_coloring - Compute the finite difference Jacobian using coloring and display norms of difference
2775 .    -snes_compare_coloring_display - Compute the finite difference Jacobian using coloring and display verbose differences
2776 .    -snes_compare_coloring_threshold - Display only those matrix entries that differ by more than a given threshold
2777 .    -snes_compare_coloring_threshold_atol - Absolute tolerance for difference in matrix entries to be displayed by -snes_compare_coloring_threshold
2778 .    -snes_compare_coloring_threshold_rtol - Relative tolerance for difference in matrix entries to be displayed by -snes_compare_coloring_threshold
2779 .    -snes_compare_coloring_draw - Compute the finite difference Jacobian using coloring and draw differences
2780 -    -snes_compare_coloring_draw_contour - Compute the finite difference Jacobian using coloring and show contours of matrices and differences
2781 
2782    Notes:
2783    Most users should not need to explicitly call this routine, as it
2784    is used internally within the nonlinear solvers.
2785 
2786    Developer Notes:
2787     This has duplicative ways of checking the accuracy of the user provided Jacobian (see the options above). This is for historical reasons, the routine SNESTestJacobian() use to used
2788       for with the SNESType of test that has been removed.
2789 
2790    Level: developer
2791 
2792 .seealso: `SNESSetJacobian()`, `KSPSetOperators()`, `MatStructure`, `SNESSetLagPreconditioner()`, `SNESSetLagJacobian()`
2793 @*/
2794 PetscErrorCode  SNESComputeJacobian(SNES snes,Vec X,Mat A,Mat B)
2795 {
2796   PetscBool      flag;
2797   DM             dm;
2798   DMSNES         sdm;
2799   KSP            ksp;
2800 
2801   PetscFunctionBegin;
2802   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2803   PetscValidHeaderSpecific(X,VEC_CLASSID,2);
2804   PetscCheckSameComm(snes,1,X,2);
2805   PetscCall(VecValidValues(X,2,PETSC_TRUE));
2806   PetscCall(SNESGetDM(snes,&dm));
2807   PetscCall(DMGetDMSNES(dm,&sdm));
2808 
2809   PetscCheck(sdm->ops->computejacobian,PetscObjectComm((PetscObject)snes),PETSC_ERR_USER,"Must call SNESSetJacobian(), DMSNESSetJacobian(), DMDASNESSetJacobianLocal(), etc");
2810 
2811   /* make sure that MatAssemblyBegin/End() is called on A matrix if it is matrix free */
2812 
2813   if (snes->lagjacobian == -2) {
2814     snes->lagjacobian = -1;
2815 
2816     PetscCall(PetscInfo(snes,"Recomputing Jacobian/preconditioner because lag is -2 (means compute Jacobian, but then never again) \n"));
2817   } else if (snes->lagjacobian == -1) {
2818     PetscCall(PetscInfo(snes,"Reusing Jacobian/preconditioner because lag is -1\n"));
2819     PetscCall(PetscObjectTypeCompare((PetscObject)A,MATMFFD,&flag));
2820     if (flag) {
2821       PetscCall(MatAssemblyBegin(A,MAT_FINAL_ASSEMBLY));
2822       PetscCall(MatAssemblyEnd(A,MAT_FINAL_ASSEMBLY));
2823     }
2824     PetscFunctionReturn(0);
2825   } else if (snes->lagjacobian > 1 && (snes->iter + snes->jac_iter) % snes->lagjacobian) {
2826     PetscCall(PetscInfo(snes,"Reusing Jacobian/preconditioner because lag is %" PetscInt_FMT " and SNES iteration is %" PetscInt_FMT "\n",snes->lagjacobian,snes->iter));
2827     PetscCall(PetscObjectTypeCompare((PetscObject)A,MATMFFD,&flag));
2828     if (flag) {
2829       PetscCall(MatAssemblyBegin(A,MAT_FINAL_ASSEMBLY));
2830       PetscCall(MatAssemblyEnd(A,MAT_FINAL_ASSEMBLY));
2831     }
2832     PetscFunctionReturn(0);
2833   }
2834   if (snes->npc && snes->npcside == PC_LEFT) {
2835     PetscCall(MatAssemblyBegin(A,MAT_FINAL_ASSEMBLY));
2836     PetscCall(MatAssemblyEnd(A,MAT_FINAL_ASSEMBLY));
2837     PetscFunctionReturn(0);
2838   }
2839 
2840   PetscCall(PetscLogEventBegin(SNES_JacobianEval,snes,X,A,B));
2841   PetscCall(VecLockReadPush(X));
2842   PetscStackPush("SNES user Jacobian function");
2843   PetscCall((*sdm->ops->computejacobian)(snes,X,A,B,sdm->jacobianctx));
2844   PetscStackPop;
2845   PetscCall(VecLockReadPop(X));
2846   PetscCall(PetscLogEventEnd(SNES_JacobianEval,snes,X,A,B));
2847 
2848   /* attach latest linearization point to the preconditioning matrix */
2849   PetscCall(PetscObjectCompose((PetscObject)B,"__SNES_latest_X",(PetscObject)X));
2850 
2851   /* the next line ensures that snes->ksp exists */
2852   PetscCall(SNESGetKSP(snes,&ksp));
2853   if (snes->lagpreconditioner == -2) {
2854     PetscCall(PetscInfo(snes,"Rebuilding preconditioner exactly once since lag is -2\n"));
2855     PetscCall(KSPSetReusePreconditioner(snes->ksp,PETSC_FALSE));
2856     snes->lagpreconditioner = -1;
2857   } else if (snes->lagpreconditioner == -1) {
2858     PetscCall(PetscInfo(snes,"Reusing preconditioner because lag is -1\n"));
2859     PetscCall(KSPSetReusePreconditioner(snes->ksp,PETSC_TRUE));
2860   } else if (snes->lagpreconditioner > 1 && (snes->iter + snes->pre_iter) % snes->lagpreconditioner) {
2861     PetscCall(PetscInfo(snes,"Reusing preconditioner because lag is %" PetscInt_FMT " and SNES iteration is %" PetscInt_FMT "\n",snes->lagpreconditioner,snes->iter));
2862     PetscCall(KSPSetReusePreconditioner(snes->ksp,PETSC_TRUE));
2863   } else {
2864     PetscCall(PetscInfo(snes,"Rebuilding preconditioner\n"));
2865     PetscCall(KSPSetReusePreconditioner(snes->ksp,PETSC_FALSE));
2866   }
2867 
2868   PetscCall(SNESTestJacobian(snes));
2869   /* make sure user returned a correct Jacobian and preconditioner */
2870   /* PetscValidHeaderSpecific(A,MAT_CLASSID,3);
2871     PetscValidHeaderSpecific(B,MAT_CLASSID,4);   */
2872   {
2873     PetscBool flag = PETSC_FALSE,flag_draw = PETSC_FALSE,flag_contour = PETSC_FALSE,flag_operator = PETSC_FALSE;
2874     PetscCall(PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes),((PetscObject) snes)->options,((PetscObject)snes)->prefix,"-snes_compare_explicit",NULL,NULL,&flag));
2875     PetscCall(PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes),((PetscObject) snes)->options,((PetscObject)snes)->prefix,"-snes_compare_explicit_draw",NULL,NULL,&flag_draw));
2876     PetscCall(PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes),((PetscObject) snes)->options,((PetscObject)snes)->prefix,"-snes_compare_explicit_draw_contour",NULL,NULL,&flag_contour));
2877     PetscCall(PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes),((PetscObject) snes)->options,((PetscObject)snes)->prefix,"-snes_compare_operator",NULL,NULL,&flag_operator));
2878     if (flag || flag_draw || flag_contour) {
2879       Mat          Bexp_mine = NULL,Bexp,FDexp;
2880       PetscViewer  vdraw,vstdout;
2881       PetscBool    flg;
2882       if (flag_operator) {
2883         PetscCall(MatComputeOperator(A,MATAIJ,&Bexp_mine));
2884         Bexp = Bexp_mine;
2885       } else {
2886         /* See if the preconditioning matrix can be viewed and added directly */
2887         PetscCall(PetscObjectBaseTypeCompareAny((PetscObject)B,&flg,MATSEQAIJ,MATMPIAIJ,MATSEQDENSE,MATMPIDENSE,MATSEQBAIJ,MATMPIBAIJ,MATSEQSBAIJ,MATMPIBAIJ,""));
2888         if (flg) Bexp = B;
2889         else {
2890           /* If the "preconditioning" matrix is itself MATSHELL or some other type without direct support */
2891           PetscCall(MatComputeOperator(B,MATAIJ,&Bexp_mine));
2892           Bexp = Bexp_mine;
2893         }
2894       }
2895       PetscCall(MatConvert(Bexp,MATSAME,MAT_INITIAL_MATRIX,&FDexp));
2896       PetscCall(SNESComputeJacobianDefault(snes,X,FDexp,FDexp,NULL));
2897       PetscCall(PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)snes),&vstdout));
2898       if (flag_draw || flag_contour) {
2899         PetscCall(PetscViewerDrawOpen(PetscObjectComm((PetscObject)snes),NULL,"Explicit Jacobians",PETSC_DECIDE,PETSC_DECIDE,300,300,&vdraw));
2900         if (flag_contour) PetscCall(PetscViewerPushFormat(vdraw,PETSC_VIEWER_DRAW_CONTOUR));
2901       } else vdraw = NULL;
2902       PetscCall(PetscViewerASCIIPrintf(vstdout,"Explicit %s\n",flag_operator ? "Jacobian" : "preconditioning Jacobian"));
2903       if (flag) PetscCall(MatView(Bexp,vstdout));
2904       if (vdraw) PetscCall(MatView(Bexp,vdraw));
2905       PetscCall(PetscViewerASCIIPrintf(vstdout,"Finite difference Jacobian\n"));
2906       if (flag) PetscCall(MatView(FDexp,vstdout));
2907       if (vdraw) PetscCall(MatView(FDexp,vdraw));
2908       PetscCall(MatAYPX(FDexp,-1.0,Bexp,SAME_NONZERO_PATTERN));
2909       PetscCall(PetscViewerASCIIPrintf(vstdout,"User-provided matrix minus finite difference Jacobian\n"));
2910       if (flag) PetscCall(MatView(FDexp,vstdout));
2911       if (vdraw) {              /* Always use contour for the difference */
2912         PetscCall(PetscViewerPushFormat(vdraw,PETSC_VIEWER_DRAW_CONTOUR));
2913         PetscCall(MatView(FDexp,vdraw));
2914         PetscCall(PetscViewerPopFormat(vdraw));
2915       }
2916       if (flag_contour) PetscCall(PetscViewerPopFormat(vdraw));
2917       PetscCall(PetscViewerDestroy(&vdraw));
2918       PetscCall(MatDestroy(&Bexp_mine));
2919       PetscCall(MatDestroy(&FDexp));
2920     }
2921   }
2922   {
2923     PetscBool flag = PETSC_FALSE,flag_display = PETSC_FALSE,flag_draw = PETSC_FALSE,flag_contour = PETSC_FALSE,flag_threshold = PETSC_FALSE;
2924     PetscReal threshold_atol = PETSC_SQRT_MACHINE_EPSILON,threshold_rtol = 10*PETSC_SQRT_MACHINE_EPSILON;
2925     PetscCall(PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes),((PetscObject)snes)->options,((PetscObject)snes)->prefix,"-snes_compare_coloring",NULL,NULL,&flag));
2926     PetscCall(PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes),((PetscObject)snes)->options,((PetscObject)snes)->prefix,"-snes_compare_coloring_display",NULL,NULL,&flag_display));
2927     PetscCall(PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes),((PetscObject)snes)->options,((PetscObject)snes)->prefix,"-snes_compare_coloring_draw",NULL,NULL,&flag_draw));
2928     PetscCall(PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes),((PetscObject)snes)->options,((PetscObject)snes)->prefix,"-snes_compare_coloring_draw_contour",NULL,NULL,&flag_contour));
2929     PetscCall(PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes),((PetscObject)snes)->options,((PetscObject)snes)->prefix,"-snes_compare_coloring_threshold",NULL,NULL,&flag_threshold));
2930     if (flag_threshold) {
2931       PetscCall(PetscOptionsGetReal(((PetscObject)snes)->options,((PetscObject)snes)->prefix,"-snes_compare_coloring_threshold_rtol",&threshold_rtol,NULL));
2932       PetscCall(PetscOptionsGetReal(((PetscObject)snes)->options,((PetscObject)snes)->prefix,"-snes_compare_coloring_threshold_atol",&threshold_atol,NULL));
2933     }
2934     if (flag || flag_display || flag_draw || flag_contour || flag_threshold) {
2935       Mat            Bfd;
2936       PetscViewer    vdraw,vstdout;
2937       MatColoring    coloring;
2938       ISColoring     iscoloring;
2939       MatFDColoring  matfdcoloring;
2940       PetscErrorCode (*func)(SNES,Vec,Vec,void*);
2941       void           *funcctx;
2942       PetscReal      norm1,norm2,normmax;
2943 
2944       PetscCall(MatDuplicate(B,MAT_DO_NOT_COPY_VALUES,&Bfd));
2945       PetscCall(MatColoringCreate(Bfd,&coloring));
2946       PetscCall(MatColoringSetType(coloring,MATCOLORINGSL));
2947       PetscCall(MatColoringSetFromOptions(coloring));
2948       PetscCall(MatColoringApply(coloring,&iscoloring));
2949       PetscCall(MatColoringDestroy(&coloring));
2950       PetscCall(MatFDColoringCreate(Bfd,iscoloring,&matfdcoloring));
2951       PetscCall(MatFDColoringSetFromOptions(matfdcoloring));
2952       PetscCall(MatFDColoringSetUp(Bfd,iscoloring,matfdcoloring));
2953       PetscCall(ISColoringDestroy(&iscoloring));
2954 
2955       /* This method of getting the function is currently unreliable since it doesn't work for DM local functions. */
2956       PetscCall(SNESGetFunction(snes,NULL,&func,&funcctx));
2957       PetscCall(MatFDColoringSetFunction(matfdcoloring,(PetscErrorCode (*)(void))func,funcctx));
2958       PetscCall(PetscObjectSetOptionsPrefix((PetscObject)matfdcoloring,((PetscObject)snes)->prefix));
2959       PetscCall(PetscObjectAppendOptionsPrefix((PetscObject)matfdcoloring,"coloring_"));
2960       PetscCall(MatFDColoringSetFromOptions(matfdcoloring));
2961       PetscCall(MatFDColoringApply(Bfd,matfdcoloring,X,snes));
2962       PetscCall(MatFDColoringDestroy(&matfdcoloring));
2963 
2964       PetscCall(PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)snes),&vstdout));
2965       if (flag_draw || flag_contour) {
2966         PetscCall(PetscViewerDrawOpen(PetscObjectComm((PetscObject)snes),NULL,"Colored Jacobians",PETSC_DECIDE,PETSC_DECIDE,300,300,&vdraw));
2967         if (flag_contour) PetscCall(PetscViewerPushFormat(vdraw,PETSC_VIEWER_DRAW_CONTOUR));
2968       } else vdraw = NULL;
2969       PetscCall(PetscViewerASCIIPrintf(vstdout,"Explicit preconditioning Jacobian\n"));
2970       if (flag_display) PetscCall(MatView(B,vstdout));
2971       if (vdraw) PetscCall(MatView(B,vdraw));
2972       PetscCall(PetscViewerASCIIPrintf(vstdout,"Colored Finite difference Jacobian\n"));
2973       if (flag_display) PetscCall(MatView(Bfd,vstdout));
2974       if (vdraw) PetscCall(MatView(Bfd,vdraw));
2975       PetscCall(MatAYPX(Bfd,-1.0,B,SAME_NONZERO_PATTERN));
2976       PetscCall(MatNorm(Bfd,NORM_1,&norm1));
2977       PetscCall(MatNorm(Bfd,NORM_FROBENIUS,&norm2));
2978       PetscCall(MatNorm(Bfd,NORM_MAX,&normmax));
2979       PetscCall(PetscViewerASCIIPrintf(vstdout,"User-provided matrix minus finite difference Jacobian, norm1=%g normFrob=%g normmax=%g\n",(double)norm1,(double)norm2,(double)normmax));
2980       if (flag_display) PetscCall(MatView(Bfd,vstdout));
2981       if (vdraw) {              /* Always use contour for the difference */
2982         PetscCall(PetscViewerPushFormat(vdraw,PETSC_VIEWER_DRAW_CONTOUR));
2983         PetscCall(MatView(Bfd,vdraw));
2984         PetscCall(PetscViewerPopFormat(vdraw));
2985       }
2986       if (flag_contour) PetscCall(PetscViewerPopFormat(vdraw));
2987 
2988       if (flag_threshold) {
2989         PetscInt bs,rstart,rend,i;
2990         PetscCall(MatGetBlockSize(B,&bs));
2991         PetscCall(MatGetOwnershipRange(B,&rstart,&rend));
2992         for (i=rstart; i<rend; i++) {
2993           const PetscScalar *ba,*ca;
2994           const PetscInt    *bj,*cj;
2995           PetscInt          bn,cn,j,maxentrycol = -1,maxdiffcol = -1,maxrdiffcol = -1;
2996           PetscReal         maxentry = 0,maxdiff = 0,maxrdiff = 0;
2997           PetscCall(MatGetRow(B,i,&bn,&bj,&ba));
2998           PetscCall(MatGetRow(Bfd,i,&cn,&cj,&ca));
2999           PetscCheck(bn == cn,((PetscObject)A)->comm,PETSC_ERR_PLIB,"Unexpected different nonzero pattern in -snes_compare_coloring_threshold");
3000           for (j=0; j<bn; j++) {
3001             PetscReal rdiff = PetscAbsScalar(ca[j]) / (threshold_atol + threshold_rtol*PetscAbsScalar(ba[j]));
3002             if (PetscAbsScalar(ba[j]) > PetscAbs(maxentry)) {
3003               maxentrycol = bj[j];
3004               maxentry    = PetscRealPart(ba[j]);
3005             }
3006             if (PetscAbsScalar(ca[j]) > PetscAbs(maxdiff)) {
3007               maxdiffcol = bj[j];
3008               maxdiff    = PetscRealPart(ca[j]);
3009             }
3010             if (rdiff > maxrdiff) {
3011               maxrdiffcol = bj[j];
3012               maxrdiff    = rdiff;
3013             }
3014           }
3015           if (maxrdiff > 1) {
3016             PetscCall(PetscViewerASCIIPrintf(vstdout,"row %" PetscInt_FMT " (maxentry=%g at %" PetscInt_FMT ", maxdiff=%g at %" PetscInt_FMT ", maxrdiff=%g at %" PetscInt_FMT "):",i,(double)maxentry,maxentrycol,(double)maxdiff,maxdiffcol,(double)maxrdiff,maxrdiffcol));
3017             for (j=0; j<bn; j++) {
3018               PetscReal rdiff;
3019               rdiff = PetscAbsScalar(ca[j]) / (threshold_atol + threshold_rtol*PetscAbsScalar(ba[j]));
3020               if (rdiff > 1) {
3021                 PetscCall(PetscViewerASCIIPrintf(vstdout," (%" PetscInt_FMT ",%g:%g)",bj[j],(double)PetscRealPart(ba[j]),(double)PetscRealPart(ca[j])));
3022               }
3023             }
3024             PetscCall(PetscViewerASCIIPrintf(vstdout,"\n"));
3025           }
3026           PetscCall(MatRestoreRow(B,i,&bn,&bj,&ba));
3027           PetscCall(MatRestoreRow(Bfd,i,&cn,&cj,&ca));
3028         }
3029       }
3030       PetscCall(PetscViewerDestroy(&vdraw));
3031       PetscCall(MatDestroy(&Bfd));
3032     }
3033   }
3034   PetscFunctionReturn(0);
3035 }
3036 
3037 /*MC
3038     SNESJacobianFunction - Function used to convey the nonlinear Jacobian of the function to be solved by SNES
3039 
3040      Synopsis:
3041      #include "petscsnes.h"
3042      PetscErrorCode SNESJacobianFunction(SNES snes,Vec x,Mat Amat,Mat Pmat,void *ctx);
3043 
3044      Collective on snes
3045 
3046     Input Parameters:
3047 +  x - input vector, the Jacobian is to be computed at this value
3048 -  ctx - [optional] user-defined Jacobian context
3049 
3050     Output Parameters:
3051 +  Amat - the matrix that defines the (approximate) Jacobian
3052 -  Pmat - the matrix to be used in constructing the preconditioner, usually the same as Amat.
3053 
3054    Level: intermediate
3055 
3056 .seealso: `SNESSetFunction()`, `SNESGetFunction()`, `SNESSetJacobian()`, `SNESGetJacobian()`
3057 M*/
3058 
3059 /*@C
3060    SNESSetJacobian - Sets the function to compute Jacobian as well as the
3061    location to store the matrix.
3062 
3063    Logically Collective on SNES
3064 
3065    Input Parameters:
3066 +  snes - the SNES context
3067 .  Amat - the matrix that defines the (approximate) Jacobian
3068 .  Pmat - the matrix to be used in constructing the preconditioner, usually the same as Amat.
3069 .  J - Jacobian evaluation routine (if NULL then SNES retains any previously set value), see SNESJacobianFunction for details
3070 -  ctx - [optional] user-defined context for private data for the
3071          Jacobian evaluation routine (may be NULL) (if NULL then SNES retains any previously set value)
3072 
3073    Notes:
3074    If the Amat matrix and Pmat matrix are different you must call MatAssemblyBegin/End() on
3075    each matrix.
3076 
3077    If you know the operator Amat has a null space you can use MatSetNullSpace() and MatSetTransposeNullSpace() to supply the null
3078    space to Amat and the KSP solvers will automatically use that null space as needed during the solution process.
3079 
3080    If using SNESComputeJacobianDefaultColor() to assemble a Jacobian, the ctx argument
3081    must be a MatFDColoring.
3082 
3083    Other defect-correction schemes can be used by computing a different matrix in place of the Jacobian.  One common
3084    example is to use the "Picard linearization" which only differentiates through the highest order parts of each term.
3085 
3086    Level: beginner
3087 
3088 .seealso: `KSPSetOperators()`, `SNESSetFunction()`, `MatMFFDComputeJacobian()`, `SNESComputeJacobianDefaultColor()`, `MatStructure`, `J`,
3089           `SNESSetPicard()`, `SNESJacobianFunction`
3090 @*/
3091 PetscErrorCode  SNESSetJacobian(SNES snes,Mat Amat,Mat Pmat,PetscErrorCode (*J)(SNES,Vec,Mat,Mat,void*),void *ctx)
3092 {
3093   DM             dm;
3094 
3095   PetscFunctionBegin;
3096   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3097   if (Amat) PetscValidHeaderSpecific(Amat,MAT_CLASSID,2);
3098   if (Pmat) PetscValidHeaderSpecific(Pmat,MAT_CLASSID,3);
3099   if (Amat) PetscCheckSameComm(snes,1,Amat,2);
3100   if (Pmat) PetscCheckSameComm(snes,1,Pmat,3);
3101   PetscCall(SNESGetDM(snes,&dm));
3102   PetscCall(DMSNESSetJacobian(dm,J,ctx));
3103   if (Amat) {
3104     PetscCall(PetscObjectReference((PetscObject)Amat));
3105     PetscCall(MatDestroy(&snes->jacobian));
3106 
3107     snes->jacobian = Amat;
3108   }
3109   if (Pmat) {
3110     PetscCall(PetscObjectReference((PetscObject)Pmat));
3111     PetscCall(MatDestroy(&snes->jacobian_pre));
3112 
3113     snes->jacobian_pre = Pmat;
3114   }
3115   PetscFunctionReturn(0);
3116 }
3117 
3118 /*@C
3119    SNESGetJacobian - Returns the Jacobian matrix and optionally the user
3120    provided context for evaluating the Jacobian.
3121 
3122    Not Collective, but Mat object will be parallel if SNES object is
3123 
3124    Input Parameter:
3125 .  snes - the nonlinear solver context
3126 
3127    Output Parameters:
3128 +  Amat - location to stash (approximate) Jacobian matrix (or NULL)
3129 .  Pmat - location to stash matrix used to compute the preconditioner (or NULL)
3130 .  J - location to put Jacobian function (or NULL), see SNESJacobianFunction for details on its calling sequence
3131 -  ctx - location to stash Jacobian ctx (or NULL)
3132 
3133    Level: advanced
3134 
3135 .seealso: `SNESSetJacobian()`, `SNESComputeJacobian()`, `SNESJacobianFunction`, `SNESGetFunction()`
3136 @*/
3137 PetscErrorCode SNESGetJacobian(SNES snes,Mat *Amat,Mat *Pmat,PetscErrorCode (**J)(SNES,Vec,Mat,Mat,void*),void **ctx)
3138 {
3139   DM             dm;
3140   DMSNES         sdm;
3141 
3142   PetscFunctionBegin;
3143   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3144   if (Amat) *Amat = snes->jacobian;
3145   if (Pmat) *Pmat = snes->jacobian_pre;
3146   PetscCall(SNESGetDM(snes,&dm));
3147   PetscCall(DMGetDMSNES(dm,&sdm));
3148   if (J) *J = sdm->ops->computejacobian;
3149   if (ctx) *ctx = sdm->jacobianctx;
3150   PetscFunctionReturn(0);
3151 }
3152 
3153 static PetscErrorCode SNESSetDefaultComputeJacobian(SNES snes)
3154 {
3155   DM             dm;
3156   DMSNES         sdm;
3157 
3158   PetscFunctionBegin;
3159   PetscCall(SNESGetDM(snes,&dm));
3160   PetscCall(DMGetDMSNES(dm,&sdm));
3161   if (!sdm->ops->computejacobian && snes->jacobian_pre) {
3162     DM        dm;
3163     PetscBool isdense,ismf;
3164 
3165     PetscCall(SNESGetDM(snes,&dm));
3166     PetscCall(PetscObjectTypeCompareAny((PetscObject)snes->jacobian_pre,&isdense,MATSEQDENSE,MATMPIDENSE,MATDENSE,NULL));
3167     PetscCall(PetscObjectTypeCompareAny((PetscObject)snes->jacobian_pre,&ismf,MATMFFD,MATSHELL,NULL));
3168     if (isdense) {
3169       PetscCall(DMSNESSetJacobian(dm,SNESComputeJacobianDefault,NULL));
3170     } else if (!ismf) {
3171       PetscCall(DMSNESSetJacobian(dm,SNESComputeJacobianDefaultColor,NULL));
3172     }
3173   }
3174   PetscFunctionReturn(0);
3175 }
3176 
3177 /*@
3178    SNESSetUp - Sets up the internal data structures for the later use
3179    of a nonlinear solver.
3180 
3181    Collective on SNES
3182 
3183    Input Parameters:
3184 .  snes - the SNES context
3185 
3186    Notes:
3187    For basic use of the SNES solvers the user need not explicitly call
3188    SNESSetUp(), since these actions will automatically occur during
3189    the call to SNESSolve().  However, if one wishes to control this
3190    phase separately, SNESSetUp() should be called after SNESCreate()
3191    and optional routines of the form SNESSetXXX(), but before SNESSolve().
3192 
3193    Level: advanced
3194 
3195 .seealso: `SNESCreate()`, `SNESSolve()`, `SNESDestroy()`
3196 @*/
3197 PetscErrorCode  SNESSetUp(SNES snes)
3198 {
3199   DM             dm;
3200   DMSNES         sdm;
3201   SNESLineSearch linesearch, pclinesearch;
3202   void           *lsprectx,*lspostctx;
3203   PetscErrorCode (*precheck)(SNESLineSearch,Vec,Vec,PetscBool*,void*);
3204   PetscErrorCode (*postcheck)(SNESLineSearch,Vec,Vec,Vec,PetscBool*,PetscBool*,void*);
3205   PetscErrorCode (*func)(SNES,Vec,Vec,void*);
3206   Vec            f,fpc;
3207   void           *funcctx;
3208   PetscErrorCode (*jac)(SNES,Vec,Mat,Mat,void*);
3209   void           *jacctx,*appctx;
3210   Mat            j,jpre;
3211 
3212   PetscFunctionBegin;
3213   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3214   if (snes->setupcalled) PetscFunctionReturn(0);
3215   PetscCall(PetscLogEventBegin(SNES_Setup,snes,0,0,0));
3216 
3217   if (!((PetscObject)snes)->type_name) {
3218     PetscCall(SNESSetType(snes,SNESNEWTONLS));
3219   }
3220 
3221   PetscCall(SNESGetFunction(snes,&snes->vec_func,NULL,NULL));
3222 
3223   PetscCall(SNESGetDM(snes,&dm));
3224   PetscCall(DMGetDMSNES(dm,&sdm));
3225   PetscCheck(sdm->ops->computefunction,PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_WRONGSTATE,"Function never provided to SNES object");
3226   PetscCall(SNESSetDefaultComputeJacobian(snes));
3227 
3228   if (!snes->vec_func) {
3229     PetscCall(DMCreateGlobalVector(dm,&snes->vec_func));
3230   }
3231 
3232   if (!snes->ksp) {
3233     PetscCall(SNESGetKSP(snes, &snes->ksp));
3234   }
3235 
3236   if (snes->linesearch) {
3237     PetscCall(SNESGetLineSearch(snes, &snes->linesearch));
3238     PetscCall(SNESLineSearchSetFunction(snes->linesearch,SNESComputeFunction));
3239   }
3240 
3241   if (snes->npc && snes->npcside == PC_LEFT) {
3242     snes->mf          = PETSC_TRUE;
3243     snes->mf_operator = PETSC_FALSE;
3244   }
3245 
3246   if (snes->npc) {
3247     /* copy the DM over */
3248     PetscCall(SNESGetDM(snes,&dm));
3249     PetscCall(SNESSetDM(snes->npc,dm));
3250 
3251     PetscCall(SNESGetFunction(snes,&f,&func,&funcctx));
3252     PetscCall(VecDuplicate(f,&fpc));
3253     PetscCall(SNESSetFunction(snes->npc,fpc,func,funcctx));
3254     PetscCall(SNESGetJacobian(snes,&j,&jpre,&jac,&jacctx));
3255     PetscCall(SNESSetJacobian(snes->npc,j,jpre,jac,jacctx));
3256     PetscCall(SNESGetApplicationContext(snes,&appctx));
3257     PetscCall(SNESSetApplicationContext(snes->npc,appctx));
3258     PetscCall(VecDestroy(&fpc));
3259 
3260     /* copy the function pointers over */
3261     PetscCall(PetscObjectCopyFortranFunctionPointers((PetscObject)snes,(PetscObject)snes->npc));
3262 
3263     /* default to 1 iteration */
3264     PetscCall(SNESSetTolerances(snes->npc,0.0,0.0,0.0,1,snes->npc->max_funcs));
3265     if (snes->npcside == PC_RIGHT) {
3266       PetscCall(SNESSetNormSchedule(snes->npc,SNES_NORM_FINAL_ONLY));
3267     } else {
3268       PetscCall(SNESSetNormSchedule(snes->npc,SNES_NORM_NONE));
3269     }
3270     PetscCall(SNESSetFromOptions(snes->npc));
3271 
3272     /* copy the line search context over */
3273     if (snes->linesearch && snes->npc->linesearch) {
3274       PetscCall(SNESGetLineSearch(snes,&linesearch));
3275       PetscCall(SNESGetLineSearch(snes->npc,&pclinesearch));
3276       PetscCall(SNESLineSearchGetPreCheck(linesearch,&precheck,&lsprectx));
3277       PetscCall(SNESLineSearchGetPostCheck(linesearch,&postcheck,&lspostctx));
3278       PetscCall(SNESLineSearchSetPreCheck(pclinesearch,precheck,lsprectx));
3279       PetscCall(SNESLineSearchSetPostCheck(pclinesearch,postcheck,lspostctx));
3280       PetscCall(PetscObjectCopyFortranFunctionPointers((PetscObject)linesearch, (PetscObject)pclinesearch));
3281     }
3282   }
3283   if (snes->mf) PetscCall(SNESSetUpMatrixFree_Private(snes, snes->mf_operator, snes->mf_version));
3284   if (snes->ops->usercompute && !snes->user) {
3285     PetscCall((*snes->ops->usercompute)(snes,(void**)&snes->user));
3286   }
3287 
3288   snes->jac_iter = 0;
3289   snes->pre_iter = 0;
3290 
3291   if (snes->ops->setup) PetscCall((*snes->ops->setup)(snes));
3292 
3293   PetscCall(SNESSetDefaultComputeJacobian(snes));
3294 
3295   if (snes->npc && snes->npcside == PC_LEFT) {
3296     if (snes->functype == SNES_FUNCTION_PRECONDITIONED) {
3297       if (snes->linesearch) {
3298         PetscCall(SNESGetLineSearch(snes,&linesearch));
3299         PetscCall(SNESLineSearchSetFunction(linesearch,SNESComputeFunctionDefaultNPC));
3300       }
3301     }
3302   }
3303   PetscCall(PetscLogEventEnd(SNES_Setup,snes,0,0,0));
3304   snes->setupcalled = PETSC_TRUE;
3305   PetscFunctionReturn(0);
3306 }
3307 
3308 /*@
3309    SNESReset - Resets a SNES context to the snessetupcalled = 0 state and removes any allocated Vecs and Mats
3310 
3311    Collective on SNES
3312 
3313    Input Parameter:
3314 .  snes - iterative context obtained from SNESCreate()
3315 
3316    Level: intermediate
3317 
3318    Notes:
3319     Also calls the application context destroy routine set with SNESSetComputeApplicationContext()
3320 
3321 .seealso: `SNESCreate()`, `SNESSetUp()`, `SNESSolve()`
3322 @*/
3323 PetscErrorCode  SNESReset(SNES snes)
3324 {
3325   PetscFunctionBegin;
3326   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3327   if (snes->ops->userdestroy && snes->user) {
3328     PetscCall((*snes->ops->userdestroy)((void**)&snes->user));
3329     snes->user = NULL;
3330   }
3331   if (snes->npc) PetscCall(SNESReset(snes->npc));
3332 
3333   if (snes->ops->reset) PetscCall((*snes->ops->reset)(snes));
3334   if (snes->ksp) PetscCall(KSPReset(snes->ksp));
3335 
3336   if (snes->linesearch) PetscCall(SNESLineSearchReset(snes->linesearch));
3337 
3338   PetscCall(VecDestroy(&snes->vec_rhs));
3339   PetscCall(VecDestroy(&snes->vec_sol));
3340   PetscCall(VecDestroy(&snes->vec_sol_update));
3341   PetscCall(VecDestroy(&snes->vec_func));
3342   PetscCall(MatDestroy(&snes->jacobian));
3343   PetscCall(MatDestroy(&snes->jacobian_pre));
3344   PetscCall(MatDestroy(&snes->picard));
3345   PetscCall(VecDestroyVecs(snes->nwork,&snes->work));
3346   PetscCall(VecDestroyVecs(snes->nvwork,&snes->vwork));
3347 
3348   snes->alwayscomputesfinalresidual = PETSC_FALSE;
3349 
3350   snes->nwork       = snes->nvwork = 0;
3351   snes->setupcalled = PETSC_FALSE;
3352   PetscFunctionReturn(0);
3353 }
3354 
3355 /*@
3356    SNESConvergedReasonViewCancel - Clears all the reasonview functions for a SNES object.
3357 
3358    Collective on SNES
3359 
3360    Input Parameter:
3361 .  snes - iterative context obtained from SNESCreate()
3362 
3363    Level: intermediate
3364 
3365 .seealso: `SNESCreate()`, `SNESDestroy()`, `SNESReset()`
3366 @*/
3367 PetscErrorCode  SNESConvergedReasonViewCancel(SNES snes)
3368 {
3369   PetscInt       i;
3370 
3371   PetscFunctionBegin;
3372   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3373   for (i=0; i<snes->numberreasonviews; i++) {
3374     if (snes->reasonviewdestroy[i]) {
3375       PetscCall((*snes->reasonviewdestroy[i])(&snes->reasonviewcontext[i]));
3376     }
3377   }
3378   snes->numberreasonviews = 0;
3379   PetscFunctionReturn(0);
3380 }
3381 
3382 /*@C
3383    SNESDestroy - Destroys the nonlinear solver context that was created
3384    with SNESCreate().
3385 
3386    Collective on SNES
3387 
3388    Input Parameter:
3389 .  snes - the SNES context
3390 
3391    Level: beginner
3392 
3393 .seealso: `SNESCreate()`, `SNESSolve()`
3394 @*/
3395 PetscErrorCode  SNESDestroy(SNES *snes)
3396 {
3397   PetscFunctionBegin;
3398   if (!*snes) PetscFunctionReturn(0);
3399   PetscValidHeaderSpecific((*snes),SNES_CLASSID,1);
3400   if (--((PetscObject)(*snes))->refct > 0) {*snes = NULL; PetscFunctionReturn(0);}
3401 
3402   PetscCall(SNESReset((*snes)));
3403   PetscCall(SNESDestroy(&(*snes)->npc));
3404 
3405   /* if memory was published with SAWs then destroy it */
3406   PetscCall(PetscObjectSAWsViewOff((PetscObject)*snes));
3407   if ((*snes)->ops->destroy) PetscCall((*((*snes))->ops->destroy)((*snes)));
3408 
3409   if ((*snes)->dm) PetscCall(DMCoarsenHookRemove((*snes)->dm,DMCoarsenHook_SNESVecSol,DMRestrictHook_SNESVecSol,*snes));
3410   PetscCall(DMDestroy(&(*snes)->dm));
3411   PetscCall(KSPDestroy(&(*snes)->ksp));
3412   PetscCall(SNESLineSearchDestroy(&(*snes)->linesearch));
3413 
3414   PetscCall(PetscFree((*snes)->kspconvctx));
3415   if ((*snes)->ops->convergeddestroy) {
3416     PetscCall((*(*snes)->ops->convergeddestroy)((*snes)->cnvP));
3417   }
3418   if ((*snes)->conv_hist_alloc) {
3419     PetscCall(PetscFree2((*snes)->conv_hist,(*snes)->conv_hist_its));
3420   }
3421   PetscCall(SNESMonitorCancel((*snes)));
3422   PetscCall(SNESConvergedReasonViewCancel((*snes)));
3423   PetscCall(PetscHeaderDestroy(snes));
3424   PetscFunctionReturn(0);
3425 }
3426 
3427 /* ----------- Routines to set solver parameters ---------- */
3428 
3429 /*@
3430    SNESSetLagPreconditioner - Determines when the preconditioner is rebuilt in the nonlinear solve.
3431 
3432    Logically Collective on SNES
3433 
3434    Input Parameters:
3435 +  snes - the SNES context
3436 -  lag - 1 means rebuild every time the Jacobian is computed within a single nonlinear solve, 2 means every second time
3437          the Jacobian is built etc. -2 indicates rebuild preconditioner at next chance but then never rebuild after that
3438 
3439    Options Database Keys:
3440 +    -snes_lag_jacobian_persists <true,false> - sets the persistence
3441 .    -snes_lag_jacobian <-2,1,2,...> - sets the lag
3442 .    -snes_lag_preconditioner_persists <true,false> - sets the persistence
3443 -    -snes_lag_preconditioner <-2,1,2,...> - sets the lag
3444 
3445    Notes:
3446    The default is 1
3447    The preconditioner is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1 or SNESSetLagPreconditionerPersists() was called
3448 
3449    SNESSetLagPreconditionerPersists() allows using the same uniform lagging (for example every second solve) across multiple solves.
3450 
3451    Level: intermediate
3452 
3453 .seealso: `SNESSetTrustRegionTolerance()`, `SNESGetLagPreconditioner()`, `SNESSetLagJacobian()`, `SNESGetLagJacobian()`, `SNESSetLagPreconditionerPersists()`,
3454           `SNESSetLagJacobianPersists()`
3455 
3456 @*/
3457 PetscErrorCode  SNESSetLagPreconditioner(SNES snes,PetscInt lag)
3458 {
3459   PetscFunctionBegin;
3460   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3461   PetscCheck(lag >= -2,PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag must be -2, -1, 1 or greater");
3462   PetscCheck(lag,PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag cannot be 0");
3463   PetscValidLogicalCollectiveInt(snes,lag,2);
3464   snes->lagpreconditioner = lag;
3465   PetscFunctionReturn(0);
3466 }
3467 
3468 /*@
3469    SNESSetGridSequence - sets the number of steps of grid sequencing that SNES does
3470 
3471    Logically Collective on SNES
3472 
3473    Input Parameters:
3474 +  snes - the SNES context
3475 -  steps - the number of refinements to do, defaults to 0
3476 
3477    Options Database Keys:
3478 .    -snes_grid_sequence <steps> - Use grid sequencing to generate initial guess
3479 
3480    Level: intermediate
3481 
3482    Notes:
3483    Use SNESGetSolution() to extract the fine grid solution after grid sequencing.
3484 
3485 .seealso: `SNESSetTrustRegionTolerance()`, `SNESGetLagPreconditioner()`, `SNESSetLagJacobian()`, `SNESGetLagJacobian()`, `SNESGetGridSequence()`
3486 
3487 @*/
3488 PetscErrorCode  SNESSetGridSequence(SNES snes,PetscInt steps)
3489 {
3490   PetscFunctionBegin;
3491   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3492   PetscValidLogicalCollectiveInt(snes,steps,2);
3493   snes->gridsequence = steps;
3494   PetscFunctionReturn(0);
3495 }
3496 
3497 /*@
3498    SNESGetGridSequence - gets the number of steps of grid sequencing that SNES does
3499 
3500    Logically Collective on SNES
3501 
3502    Input Parameter:
3503 .  snes - the SNES context
3504 
3505    Output Parameter:
3506 .  steps - the number of refinements to do, defaults to 0
3507 
3508    Options Database Keys:
3509 .    -snes_grid_sequence <steps> - set number of refinements
3510 
3511    Level: intermediate
3512 
3513    Notes:
3514    Use SNESGetSolution() to extract the fine grid solution after grid sequencing.
3515 
3516 .seealso: `SNESSetTrustRegionTolerance()`, `SNESGetLagPreconditioner()`, `SNESSetLagJacobian()`, `SNESGetLagJacobian()`, `SNESSetGridSequence()`
3517 
3518 @*/
3519 PetscErrorCode  SNESGetGridSequence(SNES snes,PetscInt *steps)
3520 {
3521   PetscFunctionBegin;
3522   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3523   *steps = snes->gridsequence;
3524   PetscFunctionReturn(0);
3525 }
3526 
3527 /*@
3528    SNESGetLagPreconditioner - Indicates how often the preconditioner is rebuilt
3529 
3530    Not Collective
3531 
3532    Input Parameter:
3533 .  snes - the SNES context
3534 
3535    Output Parameter:
3536 .   lag - -1 indicates NEVER rebuild, 1 means rebuild every time the Jacobian is computed within a single nonlinear solve, 2 means every second time
3537          the Jacobian is built etc. -2 indicates rebuild preconditioner at next chance but then never rebuild after that
3538 
3539    Options Database Keys:
3540 +    -snes_lag_jacobian_persists <true,false> - sets the persistence
3541 .    -snes_lag_jacobian <-2,1,2,...> - sets the lag
3542 .    -snes_lag_preconditioner_persists <true,false> - sets the persistence
3543 -    -snes_lag_preconditioner <-2,1,2,...> - sets the lag
3544 
3545    Notes:
3546    The default is 1
3547    The preconditioner is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1
3548 
3549    Level: intermediate
3550 
3551 .seealso: `SNESSetTrustRegionTolerance()`, `SNESSetLagPreconditioner()`, `SNESSetLagJacobianPersists()`, `SNESSetLagPreconditionerPersists()`
3552 
3553 @*/
3554 PetscErrorCode  SNESGetLagPreconditioner(SNES snes,PetscInt *lag)
3555 {
3556   PetscFunctionBegin;
3557   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3558   *lag = snes->lagpreconditioner;
3559   PetscFunctionReturn(0);
3560 }
3561 
3562 /*@
3563    SNESSetLagJacobian - Determines when the Jacobian is rebuilt in the nonlinear solve. See SNESSetLagPreconditioner() for determining how
3564      often the preconditioner is rebuilt.
3565 
3566    Logically Collective on SNES
3567 
3568    Input Parameters:
3569 +  snes - the SNES context
3570 -  lag - -1 indicates NEVER rebuild, 1 means rebuild every time the Jacobian is computed within a single nonlinear solve, 2 means every second time
3571          the Jacobian is built etc. -2 means rebuild at next chance but then never again
3572 
3573    Options Database Keys:
3574 +    -snes_lag_jacobian_persists <true,false> - sets the persistence
3575 .    -snes_lag_jacobian <-2,1,2,...> - sets the lag
3576 .    -snes_lag_preconditioner_persists <true,false> - sets the persistence
3577 -    -snes_lag_preconditioner <-2,1,2,...> - sets the lag.
3578 
3579    Notes:
3580    The default is 1
3581    The Jacobian is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1
3582    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
3583    at the next Newton step but never again (unless it is reset to another value)
3584 
3585    Level: intermediate
3586 
3587 .seealso: `SNESSetTrustRegionTolerance()`, `SNESGetLagPreconditioner()`, `SNESSetLagPreconditioner()`, `SNESGetLagJacobianPersists()`, `SNESSetLagPreconditionerPersists()`
3588 
3589 @*/
3590 PetscErrorCode  SNESSetLagJacobian(SNES snes,PetscInt lag)
3591 {
3592   PetscFunctionBegin;
3593   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3594   PetscCheck(lag >= -2,PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag must be -2, -1, 1 or greater");
3595   PetscCheck(lag,PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag cannot be 0");
3596   PetscValidLogicalCollectiveInt(snes,lag,2);
3597   snes->lagjacobian = lag;
3598   PetscFunctionReturn(0);
3599 }
3600 
3601 /*@
3602    SNESGetLagJacobian - Indicates how often the Jacobian is rebuilt. See SNESGetLagPreconditioner() to determine when the preconditioner is rebuilt
3603 
3604    Not Collective
3605 
3606    Input Parameter:
3607 .  snes - the SNES context
3608 
3609    Output Parameter:
3610 .   lag - -1 indicates NEVER rebuild, 1 means rebuild every time the Jacobian is computed within a single nonlinear solve, 2 means every second time
3611          the Jacobian is built etc.
3612 
3613    Notes:
3614    The default is 1
3615    The jacobian is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1 or SNESSetLagJacobianPersists() was called.
3616 
3617    Level: intermediate
3618 
3619 .seealso: `SNESSetTrustRegionTolerance()`, `SNESSetLagJacobian()`, `SNESSetLagPreconditioner()`, `SNESGetLagPreconditioner()`, `SNESSetLagJacobianPersists()`, `SNESSetLagPreconditionerPersists()`
3620 
3621 @*/
3622 PetscErrorCode  SNESGetLagJacobian(SNES snes,PetscInt *lag)
3623 {
3624   PetscFunctionBegin;
3625   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3626   *lag = snes->lagjacobian;
3627   PetscFunctionReturn(0);
3628 }
3629 
3630 /*@
3631    SNESSetLagJacobianPersists - Set whether or not the Jacobian lagging persists through multiple solves
3632 
3633    Logically collective on SNES
3634 
3635    Input Parameters:
3636 +  snes - the SNES context
3637 -   flg - jacobian lagging persists if true
3638 
3639    Options Database Keys:
3640 +    -snes_lag_jacobian_persists <true,false> - sets the persistence
3641 .    -snes_lag_jacobian <-2,1,2,...> - sets the lag
3642 .    -snes_lag_preconditioner_persists <true,false> - sets the persistence
3643 -    -snes_lag_preconditioner <-2,1,2,...> - sets the lag
3644 
3645    Notes:
3646     This is useful both for nonlinear preconditioning, where it's appropriate to have the Jacobian be stale by
3647    several solves, and for implicit time-stepping, where Jacobian lagging in the inner nonlinear solve over several
3648    timesteps may present huge efficiency gains.
3649 
3650    Level: developer
3651 
3652 .seealso: `SNESSetLagPreconditionerPersists()`, `SNESSetLagJacobian()`, `SNESGetLagJacobian()`, `SNESGetNPC()`, `SNESSetLagJacobianPersists()`
3653 
3654 @*/
3655 PetscErrorCode  SNESSetLagJacobianPersists(SNES snes,PetscBool flg)
3656 {
3657   PetscFunctionBegin;
3658   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3659   PetscValidLogicalCollectiveBool(snes,flg,2);
3660   snes->lagjac_persist = flg;
3661   PetscFunctionReturn(0);
3662 }
3663 
3664 /*@
3665    SNESSetLagPreconditionerPersists - Set whether or not the preconditioner lagging persists through multiple nonlinear solves
3666 
3667    Logically Collective on SNES
3668 
3669    Input Parameters:
3670 +  snes - the SNES context
3671 -   flg - preconditioner lagging persists if true
3672 
3673    Options Database Keys:
3674 +    -snes_lag_jacobian_persists <true,false> - sets the persistence
3675 .    -snes_lag_jacobian <-2,1,2,...> - sets the lag
3676 .    -snes_lag_preconditioner_persists <true,false> - sets the persistence
3677 -    -snes_lag_preconditioner <-2,1,2,...> - sets the lag
3678 
3679    Notes:
3680     This is useful both for nonlinear preconditioning, where it's appropriate to have the preconditioner be stale
3681    by several solves, and for implicit time-stepping, where preconditioner lagging in the inner nonlinear solve over
3682    several timesteps may present huge efficiency gains.
3683 
3684    Level: developer
3685 
3686 .seealso: `SNESSetLagJacobianPersists()`, `SNESSetLagJacobian()`, `SNESGetLagJacobian()`, `SNESGetNPC()`, `SNESSetLagPreconditioner()`
3687 
3688 @*/
3689 PetscErrorCode  SNESSetLagPreconditionerPersists(SNES snes,PetscBool flg)
3690 {
3691   PetscFunctionBegin;
3692   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3693   PetscValidLogicalCollectiveBool(snes,flg,2);
3694   snes->lagpre_persist = flg;
3695   PetscFunctionReturn(0);
3696 }
3697 
3698 /*@
3699    SNESSetForceIteration - force SNESSolve() to take at least one iteration regardless of the initial residual norm
3700 
3701    Logically Collective on SNES
3702 
3703    Input Parameters:
3704 +  snes - the SNES context
3705 -  force - PETSC_TRUE require at least one iteration
3706 
3707    Options Database Keys:
3708 .    -snes_force_iteration <force> - Sets forcing an iteration
3709 
3710    Notes:
3711    This is used sometimes with TS to prevent TS from detecting a false steady state solution
3712 
3713    Level: intermediate
3714 
3715 .seealso: `SNESSetTrustRegionTolerance()`, `SNESSetDivergenceTolerance()`
3716 @*/
3717 PetscErrorCode  SNESSetForceIteration(SNES snes,PetscBool force)
3718 {
3719   PetscFunctionBegin;
3720   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3721   snes->forceiteration = force;
3722   PetscFunctionReturn(0);
3723 }
3724 
3725 /*@
3726    SNESGetForceIteration - Whether or not to force SNESSolve() take at least one iteration regardless of the initial residual norm
3727 
3728    Logically Collective on SNES
3729 
3730    Input Parameters:
3731 .  snes - the SNES context
3732 
3733    Output Parameter:
3734 .  force - PETSC_TRUE requires at least one iteration.
3735 
3736    Level: intermediate
3737 
3738 .seealso: `SNESSetForceIteration()`, `SNESSetTrustRegionTolerance()`, `SNESSetDivergenceTolerance()`
3739 @*/
3740 PetscErrorCode  SNESGetForceIteration(SNES snes,PetscBool *force)
3741 {
3742   PetscFunctionBegin;
3743   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3744   *force = snes->forceiteration;
3745   PetscFunctionReturn(0);
3746 }
3747 
3748 /*@
3749    SNESSetTolerances - Sets various parameters used in convergence tests.
3750 
3751    Logically Collective on SNES
3752 
3753    Input Parameters:
3754 +  snes - the SNES context
3755 .  abstol - absolute convergence tolerance
3756 .  rtol - relative convergence tolerance
3757 .  stol -  convergence tolerance in terms of the norm of the change in the solution between steps,  || delta x || < stol*|| x ||
3758 .  maxit - maximum number of iterations
3759 -  maxf - maximum number of function evaluations (-1 indicates no limit)
3760 
3761    Options Database Keys:
3762 +    -snes_atol <abstol> - Sets abstol
3763 .    -snes_rtol <rtol> - Sets rtol
3764 .    -snes_stol <stol> - Sets stol
3765 .    -snes_max_it <maxit> - Sets maxit
3766 -    -snes_max_funcs <maxf> - Sets maxf
3767 
3768    Notes:
3769    The default maximum number of iterations is 50.
3770    The default maximum number of function evaluations is 1000.
3771 
3772    Level: intermediate
3773 
3774 .seealso: `SNESSetTrustRegionTolerance()`, `SNESSetDivergenceTolerance()`, `SNESSetForceIteration()`
3775 @*/
3776 PetscErrorCode  SNESSetTolerances(SNES snes,PetscReal abstol,PetscReal rtol,PetscReal stol,PetscInt maxit,PetscInt maxf)
3777 {
3778   PetscFunctionBegin;
3779   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3780   PetscValidLogicalCollectiveReal(snes,abstol,2);
3781   PetscValidLogicalCollectiveReal(snes,rtol,3);
3782   PetscValidLogicalCollectiveReal(snes,stol,4);
3783   PetscValidLogicalCollectiveInt(snes,maxit,5);
3784   PetscValidLogicalCollectiveInt(snes,maxf,6);
3785 
3786   if (abstol != PETSC_DEFAULT) {
3787     PetscCheck(abstol >= 0.0,PetscObjectComm((PetscObject)snes),PETSC_ERR_ARG_OUTOFRANGE,"Absolute tolerance %g must be non-negative",(double)abstol);
3788     snes->abstol = abstol;
3789   }
3790   if (rtol != PETSC_DEFAULT) {
3791     PetscCheck(rtol >= 0.0 && 1.0 > rtol,PetscObjectComm((PetscObject)snes),PETSC_ERR_ARG_OUTOFRANGE,"Relative tolerance %g must be non-negative and less than 1.0",(double)rtol);
3792     snes->rtol = rtol;
3793   }
3794   if (stol != PETSC_DEFAULT) {
3795     PetscCheck(stol >= 0.0,PetscObjectComm((PetscObject)snes),PETSC_ERR_ARG_OUTOFRANGE,"Step tolerance %g must be non-negative",(double)stol);
3796     snes->stol = stol;
3797   }
3798   if (maxit != PETSC_DEFAULT) {
3799     PetscCheck(maxit >= 0,PetscObjectComm((PetscObject)snes),PETSC_ERR_ARG_OUTOFRANGE,"Maximum number of iterations %" PetscInt_FMT " must be non-negative",maxit);
3800     snes->max_its = maxit;
3801   }
3802   if (maxf != PETSC_DEFAULT) {
3803     PetscCheck(maxf >= -1,PetscObjectComm((PetscObject)snes),PETSC_ERR_ARG_OUTOFRANGE,"Maximum number of function evaluations %" PetscInt_FMT " must be -1 or nonnegative",maxf);
3804     snes->max_funcs = maxf;
3805   }
3806   snes->tolerancesset = PETSC_TRUE;
3807   PetscFunctionReturn(0);
3808 }
3809 
3810 /*@
3811    SNESSetDivergenceTolerance - Sets the divergence tolerance used for the SNES divergence test.
3812 
3813    Logically Collective on SNES
3814 
3815    Input Parameters:
3816 +  snes - the SNES context
3817 -  divtol - the divergence tolerance. Use -1 to deactivate the test.
3818 
3819    Options Database Keys:
3820 .    -snes_divergence_tolerance <divtol> - Sets divtol
3821 
3822    Notes:
3823    The default divergence tolerance is 1e4.
3824 
3825    Level: intermediate
3826 
3827 .seealso: `SNESSetTolerances()`, `SNESGetDivergenceTolerance`
3828 @*/
3829 PetscErrorCode  SNESSetDivergenceTolerance(SNES snes,PetscReal divtol)
3830 {
3831   PetscFunctionBegin;
3832   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3833   PetscValidLogicalCollectiveReal(snes,divtol,2);
3834 
3835   if (divtol != PETSC_DEFAULT) {
3836     snes->divtol = divtol;
3837   }
3838   else {
3839     snes->divtol = 1.0e4;
3840   }
3841   PetscFunctionReturn(0);
3842 }
3843 
3844 /*@
3845    SNESGetTolerances - Gets various parameters used in convergence tests.
3846 
3847    Not Collective
3848 
3849    Input Parameters:
3850 +  snes - the SNES context
3851 .  atol - absolute convergence tolerance
3852 .  rtol - relative convergence tolerance
3853 .  stol -  convergence tolerance in terms of the norm
3854            of the change in the solution between steps
3855 .  maxit - maximum number of iterations
3856 -  maxf - maximum number of function evaluations
3857 
3858    Notes:
3859    The user can specify NULL for any parameter that is not needed.
3860 
3861    Level: intermediate
3862 
3863 .seealso: `SNESSetTolerances()`
3864 @*/
3865 PetscErrorCode  SNESGetTolerances(SNES snes,PetscReal *atol,PetscReal *rtol,PetscReal *stol,PetscInt *maxit,PetscInt *maxf)
3866 {
3867   PetscFunctionBegin;
3868   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3869   if (atol)  *atol  = snes->abstol;
3870   if (rtol)  *rtol  = snes->rtol;
3871   if (stol)  *stol  = snes->stol;
3872   if (maxit) *maxit = snes->max_its;
3873   if (maxf)  *maxf  = snes->max_funcs;
3874   PetscFunctionReturn(0);
3875 }
3876 
3877 /*@
3878    SNESGetDivergenceTolerance - Gets divergence tolerance used in divergence test.
3879 
3880    Not Collective
3881 
3882    Input Parameters:
3883 +  snes - the SNES context
3884 -  divtol - divergence tolerance
3885 
3886    Level: intermediate
3887 
3888 .seealso: `SNESSetDivergenceTolerance()`
3889 @*/
3890 PetscErrorCode  SNESGetDivergenceTolerance(SNES snes,PetscReal *divtol)
3891 {
3892   PetscFunctionBegin;
3893   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3894   if (divtol) *divtol = snes->divtol;
3895   PetscFunctionReturn(0);
3896 }
3897 
3898 /*@
3899    SNESSetTrustRegionTolerance - Sets the trust region parameter tolerance.
3900 
3901    Logically Collective on SNES
3902 
3903    Input Parameters:
3904 +  snes - the SNES context
3905 -  tol - tolerance
3906 
3907    Options Database Key:
3908 .  -snes_trtol <tol> - Sets tol
3909 
3910    Level: intermediate
3911 
3912 .seealso: `SNESSetTolerances()`
3913 @*/
3914 PetscErrorCode  SNESSetTrustRegionTolerance(SNES snes,PetscReal tol)
3915 {
3916   PetscFunctionBegin;
3917   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3918   PetscValidLogicalCollectiveReal(snes,tol,2);
3919   snes->deltatol = tol;
3920   PetscFunctionReturn(0);
3921 }
3922 
3923 PETSC_INTERN PetscErrorCode  SNESMonitorRange_Private(SNES,PetscInt,PetscReal*);
3924 
3925 PetscErrorCode  SNESMonitorLGRange(SNES snes,PetscInt n,PetscReal rnorm,void *monctx)
3926 {
3927   PetscDrawLG      lg;
3928   PetscReal        x,y,per;
3929   PetscViewer      v = (PetscViewer)monctx;
3930   static PetscReal prev; /* should be in the context */
3931   PetscDraw        draw;
3932 
3933   PetscFunctionBegin;
3934   PetscValidHeaderSpecific(v,PETSC_VIEWER_CLASSID,4);
3935   PetscCall(PetscViewerDrawGetDrawLG(v,0,&lg));
3936   if (!n) PetscCall(PetscDrawLGReset(lg));
3937   PetscCall(PetscDrawLGGetDraw(lg,&draw));
3938   PetscCall(PetscDrawSetTitle(draw,"Residual norm"));
3939   x    = (PetscReal)n;
3940   if (rnorm > 0.0) y = PetscLog10Real(rnorm);
3941   else y = -15.0;
3942   PetscCall(PetscDrawLGAddPoint(lg,&x,&y));
3943   if (n < 20 || !(n % 5) || snes->reason) {
3944     PetscCall(PetscDrawLGDraw(lg));
3945     PetscCall(PetscDrawLGSave(lg));
3946   }
3947 
3948   PetscCall(PetscViewerDrawGetDrawLG(v,1,&lg));
3949   if (!n) PetscCall(PetscDrawLGReset(lg));
3950   PetscCall(PetscDrawLGGetDraw(lg,&draw));
3951   PetscCall(PetscDrawSetTitle(draw,"% elemts > .2*max elemt"));
3952   PetscCall(SNESMonitorRange_Private(snes,n,&per));
3953   x    = (PetscReal)n;
3954   y    = 100.0*per;
3955   PetscCall(PetscDrawLGAddPoint(lg,&x,&y));
3956   if (n < 20 || !(n % 5) || snes->reason) {
3957     PetscCall(PetscDrawLGDraw(lg));
3958     PetscCall(PetscDrawLGSave(lg));
3959   }
3960 
3961   PetscCall(PetscViewerDrawGetDrawLG(v,2,&lg));
3962   if (!n) {prev = rnorm;PetscCall(PetscDrawLGReset(lg));}
3963   PetscCall(PetscDrawLGGetDraw(lg,&draw));
3964   PetscCall(PetscDrawSetTitle(draw,"(norm -oldnorm)/oldnorm"));
3965   x    = (PetscReal)n;
3966   y    = (prev - rnorm)/prev;
3967   PetscCall(PetscDrawLGAddPoint(lg,&x,&y));
3968   if (n < 20 || !(n % 5) || snes->reason) {
3969     PetscCall(PetscDrawLGDraw(lg));
3970     PetscCall(PetscDrawLGSave(lg));
3971   }
3972 
3973   PetscCall(PetscViewerDrawGetDrawLG(v,3,&lg));
3974   if (!n) PetscCall(PetscDrawLGReset(lg));
3975   PetscCall(PetscDrawLGGetDraw(lg,&draw));
3976   PetscCall(PetscDrawSetTitle(draw,"(norm -oldnorm)/oldnorm*(% > .2 max)"));
3977   x    = (PetscReal)n;
3978   y    = (prev - rnorm)/(prev*per);
3979   if (n > 2) { /*skip initial crazy value */
3980     PetscCall(PetscDrawLGAddPoint(lg,&x,&y));
3981   }
3982   if (n < 20 || !(n % 5) || snes->reason) {
3983     PetscCall(PetscDrawLGDraw(lg));
3984     PetscCall(PetscDrawLGSave(lg));
3985   }
3986   prev = rnorm;
3987   PetscFunctionReturn(0);
3988 }
3989 
3990 /*@
3991    SNESMonitor - runs the user provided monitor routines, if they exist
3992 
3993    Collective on SNES
3994 
3995    Input Parameters:
3996 +  snes - nonlinear solver context obtained from SNESCreate()
3997 .  iter - iteration number
3998 -  rnorm - relative norm of the residual
3999 
4000    Notes:
4001    This routine is called by the SNES implementations.
4002    It does not typically need to be called by the user.
4003 
4004    Level: developer
4005 
4006 .seealso: `SNESMonitorSet()`
4007 @*/
4008 PetscErrorCode  SNESMonitor(SNES snes,PetscInt iter,PetscReal rnorm)
4009 {
4010   PetscInt       i,n = snes->numbermonitors;
4011 
4012   PetscFunctionBegin;
4013   PetscCall(VecLockReadPush(snes->vec_sol));
4014   for (i=0; i<n; i++) {
4015     PetscCall((*snes->monitor[i])(snes,iter,rnorm,snes->monitorcontext[i]));
4016   }
4017   PetscCall(VecLockReadPop(snes->vec_sol));
4018   PetscFunctionReturn(0);
4019 }
4020 
4021 /* ------------ Routines to set performance monitoring options ----------- */
4022 
4023 /*MC
4024     SNESMonitorFunction - functional form passed to SNESMonitorSet() to monitor convergence of nonlinear solver
4025 
4026      Synopsis:
4027      #include <petscsnes.h>
4028 $    PetscErrorCode SNESMonitorFunction(SNES snes,PetscInt its, PetscReal norm,void *mctx)
4029 
4030      Collective on snes
4031 
4032     Input Parameters:
4033 +    snes - the SNES context
4034 .    its - iteration number
4035 .    norm - 2-norm function value (may be estimated)
4036 -    mctx - [optional] monitoring context
4037 
4038    Level: advanced
4039 
4040 .seealso: `SNESMonitorSet()`, `SNESMonitorGet()`
4041 M*/
4042 
4043 /*@C
4044    SNESMonitorSet - Sets an ADDITIONAL function that is to be used at every
4045    iteration of the nonlinear solver to display the iteration's
4046    progress.
4047 
4048    Logically Collective on SNES
4049 
4050    Input Parameters:
4051 +  snes - the SNES context
4052 .  f - the monitor function, see SNESMonitorFunction for the calling sequence
4053 .  mctx - [optional] user-defined context for private data for the
4054           monitor routine (use NULL if no context is desired)
4055 -  monitordestroy - [optional] routine that frees monitor context
4056           (may be NULL)
4057 
4058    Options Database Keys:
4059 +    -snes_monitor        - sets SNESMonitorDefault()
4060 .    -snes_monitor draw::draw_lg - sets line graph monitor,
4061 -    -snes_monitor_cancel - cancels all monitors that have
4062                             been hardwired into a code by
4063                             calls to SNESMonitorSet(), but
4064                             does not cancel those set via
4065                             the options database.
4066 
4067    Notes:
4068    Several different monitoring routines may be set by calling
4069    SNESMonitorSet() multiple times; all will be called in the
4070    order in which they were set.
4071 
4072    Fortran Notes:
4073     Only a single monitor function can be set for each SNES object
4074 
4075    Level: intermediate
4076 
4077 .seealso: `SNESMonitorDefault()`, `SNESMonitorCancel()`, `SNESMonitorFunction`
4078 @*/
4079 PetscErrorCode  SNESMonitorSet(SNES snes,PetscErrorCode (*f)(SNES,PetscInt,PetscReal,void*),void *mctx,PetscErrorCode (*monitordestroy)(void**))
4080 {
4081   PetscInt       i;
4082   PetscBool      identical;
4083 
4084   PetscFunctionBegin;
4085   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
4086   for (i=0; i<snes->numbermonitors;i++) {
4087     PetscCall(PetscMonitorCompare((PetscErrorCode (*)(void))f,mctx,monitordestroy,(PetscErrorCode (*)(void))snes->monitor[i],snes->monitorcontext[i],snes->monitordestroy[i],&identical));
4088     if (identical) PetscFunctionReturn(0);
4089   }
4090   PetscCheck(snes->numbermonitors < MAXSNESMONITORS,PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Too many monitors set");
4091   snes->monitor[snes->numbermonitors]          = f;
4092   snes->monitordestroy[snes->numbermonitors]   = monitordestroy;
4093   snes->monitorcontext[snes->numbermonitors++] = (void*)mctx;
4094   PetscFunctionReturn(0);
4095 }
4096 
4097 /*@
4098    SNESMonitorCancel - Clears all the monitor functions for a SNES object.
4099 
4100    Logically Collective on SNES
4101 
4102    Input Parameters:
4103 .  snes - the SNES context
4104 
4105    Options Database Key:
4106 .  -snes_monitor_cancel - cancels all monitors that have been hardwired
4107     into a code by calls to SNESMonitorSet(), but does not cancel those
4108     set via the options database
4109 
4110    Notes:
4111    There is no way to clear one specific monitor from a SNES object.
4112 
4113    Level: intermediate
4114 
4115 .seealso: `SNESMonitorDefault()`, `SNESMonitorSet()`
4116 @*/
4117 PetscErrorCode  SNESMonitorCancel(SNES snes)
4118 {
4119   PetscInt       i;
4120 
4121   PetscFunctionBegin;
4122   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
4123   for (i=0; i<snes->numbermonitors; i++) {
4124     if (snes->monitordestroy[i]) {
4125       PetscCall((*snes->monitordestroy[i])(&snes->monitorcontext[i]));
4126     }
4127   }
4128   snes->numbermonitors = 0;
4129   PetscFunctionReturn(0);
4130 }
4131 
4132 /*MC
4133     SNESConvergenceTestFunction - functional form used for testing of convergence of nonlinear solver
4134 
4135      Synopsis:
4136      #include <petscsnes.h>
4137 $     PetscErrorCode SNESConvergenceTest(SNES snes,PetscInt it,PetscReal xnorm,PetscReal gnorm,PetscReal f,SNESConvergedReason *reason,void *cctx)
4138 
4139      Collective on snes
4140 
4141     Input Parameters:
4142 +    snes - the SNES context
4143 .    it - current iteration (0 is the first and is before any Newton step)
4144 .    xnorm - 2-norm of current iterate
4145 .    gnorm - 2-norm of current step
4146 .    f - 2-norm of function
4147 -    cctx - [optional] convergence context
4148 
4149     Output Parameter:
4150 .    reason - reason for convergence/divergence, only needs to be set when convergence or divergence is detected
4151 
4152    Level: intermediate
4153 
4154 .seealso: `SNESSetConvergenceTest()`, `SNESGetConvergenceTest()`
4155 M*/
4156 
4157 /*@C
4158    SNESSetConvergenceTest - Sets the function that is to be used
4159    to test for convergence of the nonlinear iterative solution.
4160 
4161    Logically Collective on SNES
4162 
4163    Input Parameters:
4164 +  snes - the SNES context
4165 .  SNESConvergenceTestFunction - routine to test for convergence
4166 .  cctx - [optional] context for private data for the convergence routine  (may be NULL)
4167 -  destroy - [optional] destructor for the context (may be NULL; PETSC_NULL_FUNCTION in Fortran)
4168 
4169    Level: advanced
4170 
4171 .seealso: `SNESConvergedDefault()`, `SNESConvergedSkip()`, `SNESConvergenceTestFunction`
4172 @*/
4173 PetscErrorCode  SNESSetConvergenceTest(SNES snes,PetscErrorCode (*SNESConvergenceTestFunction)(SNES,PetscInt,PetscReal,PetscReal,PetscReal,SNESConvergedReason*,void*),void *cctx,PetscErrorCode (*destroy)(void*))
4174 {
4175   PetscFunctionBegin;
4176   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
4177   if (!SNESConvergenceTestFunction) SNESConvergenceTestFunction = SNESConvergedSkip;
4178   if (snes->ops->convergeddestroy) PetscCall((*snes->ops->convergeddestroy)(snes->cnvP));
4179   snes->ops->converged        = SNESConvergenceTestFunction;
4180   snes->ops->convergeddestroy = destroy;
4181   snes->cnvP                  = cctx;
4182   PetscFunctionReturn(0);
4183 }
4184 
4185 /*@
4186    SNESGetConvergedReason - Gets the reason the SNES iteration was stopped.
4187 
4188    Not Collective
4189 
4190    Input Parameter:
4191 .  snes - the SNES context
4192 
4193    Output Parameter:
4194 .  reason - negative value indicates diverged, positive value converged, see SNESConvergedReason or the
4195             manual pages for the individual convergence tests for complete lists
4196 
4197    Options Database:
4198 .   -snes_converged_reason - prints the reason to standard out
4199 
4200    Level: intermediate
4201 
4202    Notes:
4203     Should only be called after the call the SNESSolve() is complete, if it is called earlier it returns the value SNES__CONVERGED_ITERATING.
4204 
4205 .seealso: `SNESSetConvergenceTest()`, `SNESSetConvergedReason()`, `SNESConvergedReason`
4206 @*/
4207 PetscErrorCode SNESGetConvergedReason(SNES snes,SNESConvergedReason *reason)
4208 {
4209   PetscFunctionBegin;
4210   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
4211   PetscValidPointer(reason,2);
4212   *reason = snes->reason;
4213   PetscFunctionReturn(0);
4214 }
4215 
4216 /*@C
4217    SNESGetConvergedReasonString - Return a human readable string for snes converged reason
4218 
4219    Not Collective
4220 
4221    Input Parameter:
4222 .  snes - the SNES context
4223 
4224    Output Parameter:
4225 .  strreason - a human readable string that describes SNES converged reason
4226 
4227    Level: beginner
4228 
4229 .seealso: `SNESGetConvergedReason()`
4230 @*/
4231 PetscErrorCode SNESGetConvergedReasonString(SNES snes, const char** strreason)
4232 {
4233   PetscFunctionBegin;
4234   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
4235   PetscValidPointer(strreason,2);
4236   *strreason = SNESConvergedReasons[snes->reason];
4237   PetscFunctionReturn(0);
4238 }
4239 
4240 /*@
4241    SNESSetConvergedReason - Sets the reason the SNES iteration was stopped.
4242 
4243    Not Collective
4244 
4245    Input Parameters:
4246 +  snes - the SNES context
4247 -  reason - negative value indicates diverged, positive value converged, see SNESConvergedReason or the
4248             manual pages for the individual convergence tests for complete lists
4249 
4250    Level: intermediate
4251 
4252 .seealso: `SNESGetConvergedReason()`, `SNESSetConvergenceTest()`, `SNESConvergedReason`
4253 @*/
4254 PetscErrorCode SNESSetConvergedReason(SNES snes,SNESConvergedReason reason)
4255 {
4256   PetscFunctionBegin;
4257   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
4258   snes->reason = reason;
4259   PetscFunctionReturn(0);
4260 }
4261 
4262 /*@
4263    SNESSetConvergenceHistory - Sets the array used to hold the convergence history.
4264 
4265    Logically Collective on SNES
4266 
4267    Input Parameters:
4268 +  snes - iterative context obtained from SNESCreate()
4269 .  a   - array to hold history, this array will contain the function norms computed at each step
4270 .  its - integer array holds the number of linear iterations for each solve.
4271 .  na  - size of a and its
4272 -  reset - PETSC_TRUE indicates each new nonlinear solve resets the history counter to zero,
4273            else it continues storing new values for new nonlinear solves after the old ones
4274 
4275    Notes:
4276    If 'a' and 'its' are NULL then space is allocated for the history. If 'na' PETSC_DECIDE or PETSC_DEFAULT then a
4277    default array of length 10000 is allocated.
4278 
4279    This routine is useful, e.g., when running a code for purposes
4280    of accurate performance monitoring, when no I/O should be done
4281    during the section of code that is being timed.
4282 
4283    Level: intermediate
4284 
4285 .seealso: `SNESGetConvergenceHistory()`
4286 
4287 @*/
4288 PetscErrorCode  SNESSetConvergenceHistory(SNES snes,PetscReal a[],PetscInt its[],PetscInt na,PetscBool reset)
4289 {
4290   PetscFunctionBegin;
4291   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
4292   if (a) PetscValidRealPointer(a,2);
4293   if (its) PetscValidIntPointer(its,3);
4294   if (!a) {
4295     if (na == PETSC_DECIDE || na == PETSC_DEFAULT) na = 1000;
4296     PetscCall(PetscCalloc2(na,&a,na,&its));
4297     snes->conv_hist_alloc = PETSC_TRUE;
4298   }
4299   snes->conv_hist       = a;
4300   snes->conv_hist_its   = its;
4301   snes->conv_hist_max   = (size_t)na;
4302   snes->conv_hist_len   = 0;
4303   snes->conv_hist_reset = reset;
4304   PetscFunctionReturn(0);
4305 }
4306 
4307 #if defined(PETSC_HAVE_MATLAB_ENGINE)
4308 #include <engine.h>   /* MATLAB include file */
4309 #include <mex.h>      /* MATLAB include file */
4310 
4311 PETSC_EXTERN mxArray *SNESGetConvergenceHistoryMatlab(SNES snes)
4312 {
4313   mxArray   *mat;
4314   PetscInt  i;
4315   PetscReal *ar;
4316 
4317   PetscFunctionBegin;
4318   mat = mxCreateDoubleMatrix(snes->conv_hist_len,1,mxREAL);
4319   ar  = (PetscReal*) mxGetData(mat);
4320   for (i=0; i<snes->conv_hist_len; i++) ar[i] = snes->conv_hist[i];
4321   PetscFunctionReturn(mat);
4322 }
4323 #endif
4324 
4325 /*@C
4326    SNESGetConvergenceHistory - Gets the array used to hold the convergence history.
4327 
4328    Not Collective
4329 
4330    Input Parameter:
4331 .  snes - iterative context obtained from SNESCreate()
4332 
4333    Output Parameters:
4334 +  a   - array to hold history
4335 .  its - integer array holds the number of linear iterations (or
4336          negative if not converged) for each solve.
4337 -  na  - size of a and its
4338 
4339    Notes:
4340     The calling sequence for this routine in Fortran is
4341 $   call SNESGetConvergenceHistory(SNES snes, integer na, integer ierr)
4342 
4343    This routine is useful, e.g., when running a code for purposes
4344    of accurate performance monitoring, when no I/O should be done
4345    during the section of code that is being timed.
4346 
4347    Level: intermediate
4348 
4349 .seealso: `SNESSetConvergenceHistory()`
4350 
4351 @*/
4352 PetscErrorCode  SNESGetConvergenceHistory(SNES snes,PetscReal *a[],PetscInt *its[],PetscInt *na)
4353 {
4354   PetscFunctionBegin;
4355   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
4356   if (a)   *a   = snes->conv_hist;
4357   if (its) *its = snes->conv_hist_its;
4358   if (na)  *na  = (PetscInt) snes->conv_hist_len;
4359   PetscFunctionReturn(0);
4360 }
4361 
4362 /*@C
4363   SNESSetUpdate - Sets the general-purpose update function called
4364   at the beginning of every iteration of the nonlinear solve. Specifically
4365   it is called just before the Jacobian is "evaluated".
4366 
4367   Logically Collective on SNES
4368 
4369   Input Parameters:
4370 + snes - The nonlinear solver context
4371 - func - The function
4372 
4373   Calling sequence of func:
4374 $ func (SNES snes, PetscInt step);
4375 
4376 . step - The current step of the iteration
4377 
4378   Level: advanced
4379 
4380   Note:
4381      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()
4382      This is not used by most users.
4383 
4384      There are a varity of function hooks one many set that are called at different stages of the nonlinear solution process, see the functions listed below.
4385 
4386 .seealso `SNESSetJacobian()`, `SNESSolve()`, `SNESLineSearchSetPreCheck()`, `SNESLineSearchSetPostCheck()`, `SNESNewtonTRSetPreCheck()`, `SNESNewtonTRSetPostCheck()`,
4387          `SNESMonitorSet()`, `SNESSetDivergenceTest()`
4388 @*/
4389 PetscErrorCode  SNESSetUpdate(SNES snes, PetscErrorCode (*func)(SNES, PetscInt))
4390 {
4391   PetscFunctionBegin;
4392   PetscValidHeaderSpecific(snes, SNES_CLASSID,1);
4393   snes->ops->update = func;
4394   PetscFunctionReturn(0);
4395 }
4396 
4397 /*
4398    SNESScaleStep_Private - Scales a step so that its length is less than the
4399    positive parameter delta.
4400 
4401     Input Parameters:
4402 +   snes - the SNES context
4403 .   y - approximate solution of linear system
4404 .   fnorm - 2-norm of current function
4405 -   delta - trust region size
4406 
4407     Output Parameters:
4408 +   gpnorm - predicted function norm at the new point, assuming local
4409     linearization.  The value is zero if the step lies within the trust
4410     region, and exceeds zero otherwise.
4411 -   ynorm - 2-norm of the step
4412 
4413     Note:
4414     For non-trust region methods such as SNESNEWTONLS, the parameter delta
4415     is set to be the maximum allowable step size.
4416 
4417 */
4418 PetscErrorCode SNESScaleStep_Private(SNES snes,Vec y,PetscReal *fnorm,PetscReal *delta,PetscReal *gpnorm,PetscReal *ynorm)
4419 {
4420   PetscReal      nrm;
4421   PetscScalar    cnorm;
4422 
4423   PetscFunctionBegin;
4424   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
4425   PetscValidHeaderSpecific(y,VEC_CLASSID,2);
4426   PetscCheckSameComm(snes,1,y,2);
4427 
4428   PetscCall(VecNorm(y,NORM_2,&nrm));
4429   if (nrm > *delta) {
4430     nrm     = *delta/nrm;
4431     *gpnorm = (1.0 - nrm)*(*fnorm);
4432     cnorm   = nrm;
4433     PetscCall(VecScale(y,cnorm));
4434     *ynorm  = *delta;
4435   } else {
4436     *gpnorm = 0.0;
4437     *ynorm  = nrm;
4438   }
4439   PetscFunctionReturn(0);
4440 }
4441 
4442 /*@C
4443    SNESConvergedReasonView - Displays the reason a SNES solve converged or diverged to a viewer
4444 
4445    Collective on SNES
4446 
4447    Parameter:
4448 +  snes - iterative context obtained from SNESCreate()
4449 -  viewer - the viewer to display the reason
4450 
4451    Options Database Keys:
4452 +  -snes_converged_reason - print reason for converged or diverged, also prints number of iterations
4453 -  -snes_converged_reason ::failed - only print reason and number of iterations when diverged
4454 
4455   Notes:
4456      To change the format of the output call PetscViewerPushFormat(viewer,format) before this call. Use PETSC_VIEWER_DEFAULT for the default,
4457      use PETSC_VIEWER_FAILED to only display a reason if it fails.
4458 
4459    Level: beginner
4460 
4461 .seealso: `SNESCreate()`, `SNESSetUp()`, `SNESDestroy()`, `SNESSetTolerances()`, `SNESConvergedDefault()`, `SNESGetConvergedReason()`, `SNESConvergedReasonViewFromOptions()`,
4462           `PetscViewerPushFormat()`, `PetscViewerPopFormat()`
4463 
4464 @*/
4465 PetscErrorCode  SNESConvergedReasonView(SNES snes,PetscViewer viewer)
4466 {
4467   PetscViewerFormat format;
4468   PetscBool         isAscii;
4469 
4470   PetscFunctionBegin;
4471   if (!viewer) viewer = PETSC_VIEWER_STDOUT_(PetscObjectComm((PetscObject)snes));
4472   PetscCall(PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&isAscii));
4473   if (isAscii) {
4474     PetscCall(PetscViewerGetFormat(viewer, &format));
4475     PetscCall(PetscViewerASCIIAddTab(viewer,((PetscObject)snes)->tablevel));
4476     if (format == PETSC_VIEWER_ASCII_INFO_DETAIL) {
4477       DM              dm;
4478       Vec             u;
4479       PetscDS         prob;
4480       PetscInt        Nf, f;
4481       PetscErrorCode (**exactSol)(PetscInt, PetscReal, const PetscReal[], PetscInt, PetscScalar[], void *);
4482       void            **exactCtx;
4483       PetscReal       error;
4484 
4485       PetscCall(SNESGetDM(snes, &dm));
4486       PetscCall(SNESGetSolution(snes, &u));
4487       PetscCall(DMGetDS(dm, &prob));
4488       PetscCall(PetscDSGetNumFields(prob, &Nf));
4489       PetscCall(PetscMalloc2(Nf, &exactSol, Nf, &exactCtx));
4490       for (f = 0; f < Nf; ++f) PetscCall(PetscDSGetExactSolution(prob, f, &exactSol[f], &exactCtx[f]));
4491       PetscCall(DMComputeL2Diff(dm, 0.0, exactSol, exactCtx, u, &error));
4492       PetscCall(PetscFree2(exactSol, exactCtx));
4493       if (error < 1.0e-11) PetscCall(PetscViewerASCIIPrintf(viewer, "L_2 Error: < 1.0e-11\n"));
4494       else                 PetscCall(PetscViewerASCIIPrintf(viewer, "L_2 Error: %g\n", (double)error));
4495     }
4496     if (snes->reason > 0 && format != PETSC_VIEWER_FAILED) {
4497       if (((PetscObject) snes)->prefix) {
4498         PetscCall(PetscViewerASCIIPrintf(viewer,"Nonlinear %s solve converged due to %s iterations %" PetscInt_FMT "\n",((PetscObject) snes)->prefix,SNESConvergedReasons[snes->reason],snes->iter));
4499       } else {
4500         PetscCall(PetscViewerASCIIPrintf(viewer,"Nonlinear solve converged due to %s iterations %" PetscInt_FMT "\n",SNESConvergedReasons[snes->reason],snes->iter));
4501       }
4502     } else if (snes->reason <= 0) {
4503       if (((PetscObject) snes)->prefix) {
4504         PetscCall(PetscViewerASCIIPrintf(viewer,"Nonlinear %s solve did not converge due to %s iterations %" PetscInt_FMT "\n",((PetscObject) snes)->prefix,SNESConvergedReasons[snes->reason],snes->iter));
4505       } else {
4506         PetscCall(PetscViewerASCIIPrintf(viewer,"Nonlinear solve did not converge due to %s iterations %" PetscInt_FMT "\n",SNESConvergedReasons[snes->reason],snes->iter));
4507       }
4508     }
4509     PetscCall(PetscViewerASCIISubtractTab(viewer,((PetscObject)snes)->tablevel));
4510   }
4511   PetscFunctionReturn(0);
4512 }
4513 
4514 /*@C
4515    SNESConvergedReasonViewSet - Sets an ADDITIONAL function that is to be used at the
4516     end of the nonlinear solver to display the conver reason of the nonlinear solver.
4517 
4518    Logically Collective on SNES
4519 
4520    Input Parameters:
4521 +  snes - the SNES context
4522 .  f - the snes converged reason view function
4523 .  vctx - [optional] user-defined context for private data for the
4524           snes converged reason view routine (use NULL if no context is desired)
4525 -  reasonviewdestroy - [optional] routine that frees reasonview context
4526           (may be NULL)
4527 
4528    Options Database Keys:
4529 +    -snes_converged_reason        - sets a default SNESConvergedReasonView()
4530 -    -snes_converged_reason_view_cancel - cancels all converged reason viewers that have
4531                             been hardwired into a code by
4532                             calls to SNESConvergedReasonViewSet(), but
4533                             does not cancel those set via
4534                             the options database.
4535 
4536    Notes:
4537    Several different converged reason view routines may be set by calling
4538    SNESConvergedReasonViewSet() multiple times; all will be called in the
4539    order in which they were set.
4540 
4541    Level: intermediate
4542 
4543 .seealso: `SNESConvergedReasonView()`, `SNESConvergedReasonViewCancel()`
4544 @*/
4545 PetscErrorCode  SNESConvergedReasonViewSet(SNES snes,PetscErrorCode (*f)(SNES,void*),void *vctx,PetscErrorCode (*reasonviewdestroy)(void**))
4546 {
4547   PetscInt       i;
4548   PetscBool      identical;
4549 
4550   PetscFunctionBegin;
4551   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
4552   for (i=0; i<snes->numberreasonviews;i++) {
4553     PetscCall(PetscMonitorCompare((PetscErrorCode (*)(void))f,vctx,reasonviewdestroy,(PetscErrorCode (*)(void))snes->reasonview[i],snes->reasonviewcontext[i],snes->reasonviewdestroy[i],&identical));
4554     if (identical) PetscFunctionReturn(0);
4555   }
4556   PetscCheck(snes->numberreasonviews < MAXSNESREASONVIEWS,PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Too many SNES reasonview set");
4557   snes->reasonview[snes->numberreasonviews]          = f;
4558   snes->reasonviewdestroy[snes->numberreasonviews]   = reasonviewdestroy;
4559   snes->reasonviewcontext[snes->numberreasonviews++] = (void*)vctx;
4560   PetscFunctionReturn(0);
4561 }
4562 
4563 /*@
4564   SNESConvergedReasonViewFromOptions - Processes command line options to determine if/how a SNESReason is to be viewed.
4565                                        All the user-provided convergedReasonView routines will be involved as well, if they exist.
4566 
4567   Collective on SNES
4568 
4569   Input Parameters:
4570 . snes   - the SNES object
4571 
4572   Level: intermediate
4573 
4574 .seealso: `SNESCreate()`, `SNESSetUp()`, `SNESDestroy()`, `SNESSetTolerances()`, `SNESConvergedDefault()`, `SNESGetConvergedReason()`, `SNESConvergedReasonView()`
4575 
4576 @*/
4577 PetscErrorCode SNESConvergedReasonViewFromOptions(SNES snes)
4578 {
4579   PetscViewer       viewer;
4580   PetscBool         flg;
4581   static PetscBool  incall = PETSC_FALSE;
4582   PetscViewerFormat format;
4583   PetscInt          i;
4584 
4585   PetscFunctionBegin;
4586   if (incall) PetscFunctionReturn(0);
4587   incall = PETSC_TRUE;
4588 
4589   /* All user-provided viewers are called first, if they exist. */
4590   for (i=0; i<snes->numberreasonviews; i++) {
4591     PetscCall((*snes->reasonview[i])(snes,snes->reasonviewcontext[i]));
4592   }
4593 
4594   /* Call PETSc default routine if users ask for it */
4595   PetscCall(PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes),((PetscObject)snes)->options,((PetscObject)snes)->prefix,"-snes_converged_reason",&viewer,&format,&flg));
4596   if (flg) {
4597     PetscCall(PetscViewerPushFormat(viewer,format));
4598     PetscCall(SNESConvergedReasonView(snes,viewer));
4599     PetscCall(PetscViewerPopFormat(viewer));
4600     PetscCall(PetscViewerDestroy(&viewer));
4601   }
4602   incall = PETSC_FALSE;
4603   PetscFunctionReturn(0);
4604 }
4605 
4606 /*@
4607    SNESSolve - Solves a nonlinear system F(x) = b.
4608    Call SNESSolve() after calling SNESCreate() and optional routines of the form SNESSetXXX().
4609 
4610    Collective on SNES
4611 
4612    Input Parameters:
4613 +  snes - the SNES context
4614 .  b - the constant part of the equation F(x) = b, or NULL to use zero.
4615 -  x - the solution vector.
4616 
4617    Notes:
4618    The user should initialize the vector,x, with the initial guess
4619    for the nonlinear solve prior to calling SNESSolve().  In particular,
4620    to employ an initial guess of zero, the user should explicitly set
4621    this vector to zero by calling VecSet().
4622 
4623    Level: beginner
4624 
4625 .seealso: `SNESCreate()`, `SNESDestroy()`, `SNESSetFunction()`, `SNESSetJacobian()`, `SNESSetGridSequence()`, `SNESGetSolution()`,
4626           `SNESNewtonTRSetPreCheck()`, `SNESNewtonTRGetPreCheck()`, `SNESNewtonTRSetPostCheck()`, `SNESNewtonTRGetPostCheck()`,
4627           `SNESLineSearchSetPostCheck()`, `SNESLineSearchGetPostCheck()`, `SNESLineSearchSetPreCheck()`, `SNESLineSearchGetPreCheck()`
4628 @*/
4629 PetscErrorCode  SNESSolve(SNES snes,Vec b,Vec x)
4630 {
4631   PetscBool         flg;
4632   PetscInt          grid;
4633   Vec               xcreated = NULL;
4634   DM                dm;
4635 
4636   PetscFunctionBegin;
4637   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
4638   if (x) PetscValidHeaderSpecific(x,VEC_CLASSID,3);
4639   if (x) PetscCheckSameComm(snes,1,x,3);
4640   if (b) PetscValidHeaderSpecific(b,VEC_CLASSID,2);
4641   if (b) PetscCheckSameComm(snes,1,b,2);
4642 
4643   /* High level operations using the nonlinear solver */
4644   {
4645     PetscViewer       viewer;
4646     PetscViewerFormat format;
4647     PetscInt          num;
4648     PetscBool         flg;
4649     static PetscBool  incall = PETSC_FALSE;
4650 
4651     if (!incall) {
4652       /* Estimate the convergence rate of the discretization */
4653       PetscCall(PetscOptionsGetViewer(PetscObjectComm((PetscObject) snes),((PetscObject)snes)->options, ((PetscObject) snes)->prefix, "-snes_convergence_estimate", &viewer, &format, &flg));
4654       if (flg) {
4655         PetscConvEst conv;
4656         DM           dm;
4657         PetscReal   *alpha; /* Convergence rate of the solution error for each field in the L_2 norm */
4658         PetscInt     Nf;
4659 
4660         incall = PETSC_TRUE;
4661         PetscCall(SNESGetDM(snes, &dm));
4662         PetscCall(DMGetNumFields(dm, &Nf));
4663         PetscCall(PetscCalloc1(Nf, &alpha));
4664         PetscCall(PetscConvEstCreate(PetscObjectComm((PetscObject) snes), &conv));
4665         PetscCall(PetscConvEstSetSolver(conv, (PetscObject) snes));
4666         PetscCall(PetscConvEstSetFromOptions(conv));
4667         PetscCall(PetscConvEstSetUp(conv));
4668         PetscCall(PetscConvEstGetConvRate(conv, alpha));
4669         PetscCall(PetscViewerPushFormat(viewer, format));
4670         PetscCall(PetscConvEstRateView(conv, alpha, viewer));
4671         PetscCall(PetscViewerPopFormat(viewer));
4672         PetscCall(PetscViewerDestroy(&viewer));
4673         PetscCall(PetscConvEstDestroy(&conv));
4674         PetscCall(PetscFree(alpha));
4675         incall = PETSC_FALSE;
4676       }
4677       /* Adaptively refine the initial grid */
4678       num  = 1;
4679       PetscCall(PetscOptionsGetInt(NULL, ((PetscObject) snes)->prefix, "-snes_adapt_initial", &num, &flg));
4680       if (flg) {
4681         DMAdaptor adaptor;
4682 
4683         incall = PETSC_TRUE;
4684         PetscCall(DMAdaptorCreate(PetscObjectComm((PetscObject)snes), &adaptor));
4685         PetscCall(DMAdaptorSetSolver(adaptor, snes));
4686         PetscCall(DMAdaptorSetSequenceLength(adaptor, num));
4687         PetscCall(DMAdaptorSetFromOptions(adaptor));
4688         PetscCall(DMAdaptorSetUp(adaptor));
4689         PetscCall(DMAdaptorAdapt(adaptor, x, DM_ADAPTATION_INITIAL, &dm, &x));
4690         PetscCall(DMAdaptorDestroy(&adaptor));
4691         incall = PETSC_FALSE;
4692       }
4693       /* Use grid sequencing to adapt */
4694       num  = 0;
4695       PetscCall(PetscOptionsGetInt(NULL, ((PetscObject) snes)->prefix, "-snes_adapt_sequence", &num, NULL));
4696       if (num) {
4697         DMAdaptor adaptor;
4698 
4699         incall = PETSC_TRUE;
4700         PetscCall(DMAdaptorCreate(PetscObjectComm((PetscObject)snes), &adaptor));
4701         PetscCall(DMAdaptorSetSolver(adaptor, snes));
4702         PetscCall(DMAdaptorSetSequenceLength(adaptor, num));
4703         PetscCall(DMAdaptorSetFromOptions(adaptor));
4704         PetscCall(DMAdaptorSetUp(adaptor));
4705         PetscCall(DMAdaptorAdapt(adaptor, x, DM_ADAPTATION_SEQUENTIAL, &dm, &x));
4706         PetscCall(DMAdaptorDestroy(&adaptor));
4707         incall = PETSC_FALSE;
4708       }
4709     }
4710   }
4711   if (!x) { x = snes->vec_sol; }
4712   if (!x) {
4713     PetscCall(SNESGetDM(snes,&dm));
4714     PetscCall(DMCreateGlobalVector(dm,&xcreated));
4715     x    = xcreated;
4716   }
4717   PetscCall(SNESViewFromOptions(snes,NULL,"-snes_view_pre"));
4718 
4719   for (grid=0; grid<snes->gridsequence; grid++) PetscCall(PetscViewerASCIIPushTab(PETSC_VIEWER_STDOUT_(PetscObjectComm((PetscObject)snes))));
4720   for (grid=0; grid<snes->gridsequence+1; grid++) {
4721 
4722     /* set solution vector */
4723     if (!grid) PetscCall(PetscObjectReference((PetscObject)x));
4724     PetscCall(VecDestroy(&snes->vec_sol));
4725     snes->vec_sol = x;
4726     PetscCall(SNESGetDM(snes,&dm));
4727 
4728     /* set affine vector if provided */
4729     if (b) PetscCall(PetscObjectReference((PetscObject)b));
4730     PetscCall(VecDestroy(&snes->vec_rhs));
4731     snes->vec_rhs = b;
4732 
4733     if (snes->vec_rhs) PetscCheck(snes->vec_func != snes->vec_rhs,PETSC_COMM_SELF,PETSC_ERR_ARG_IDN,"Right hand side vector cannot be function vector");
4734     PetscCheck(snes->vec_func != snes->vec_sol,PETSC_COMM_SELF,PETSC_ERR_ARG_IDN,"Solution vector cannot be function vector");
4735     PetscCheck(snes->vec_rhs  != snes->vec_sol,PETSC_COMM_SELF,PETSC_ERR_ARG_IDN,"Solution vector cannot be right hand side vector");
4736     if (!snes->vec_sol_update /* && snes->vec_sol */) {
4737       PetscCall(VecDuplicate(snes->vec_sol,&snes->vec_sol_update));
4738       PetscCall(PetscLogObjectParent((PetscObject)snes,(PetscObject)snes->vec_sol_update));
4739     }
4740     PetscCall(DMShellSetGlobalVector(dm,snes->vec_sol));
4741     PetscCall(SNESSetUp(snes));
4742 
4743     if (!grid) {
4744       if (snes->ops->computeinitialguess) PetscCall((*snes->ops->computeinitialguess)(snes,snes->vec_sol,snes->initialguessP));
4745     }
4746 
4747     if (snes->conv_hist_reset) snes->conv_hist_len = 0;
4748     if (snes->counters_reset) {snes->nfuncs = 0; snes->linear_its = 0; snes->numFailures = 0;}
4749 
4750     PetscCall(PetscLogEventBegin(SNES_Solve,snes,0,0,0));
4751     PetscCall((*snes->ops->solve)(snes));
4752     PetscCall(PetscLogEventEnd(SNES_Solve,snes,0,0,0));
4753     PetscCheck(snes->reason,PETSC_COMM_SELF,PETSC_ERR_PLIB,"Internal error, solver returned without setting converged reason");
4754     snes->domainerror = PETSC_FALSE; /* clear the flag if it has been set */
4755 
4756     if (snes->lagjac_persist) snes->jac_iter += snes->iter;
4757     if (snes->lagpre_persist) snes->pre_iter += snes->iter;
4758 
4759     PetscCall(PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes),((PetscObject)snes)->options,((PetscObject)snes)->prefix,"-snes_test_local_min",NULL,NULL,&flg));
4760     if (flg && !PetscPreLoadingOn) PetscCall(SNESTestLocalMin(snes));
4761     /* Call converged reason views. This may involve user-provided viewers as well */
4762     PetscCall(SNESConvergedReasonViewFromOptions(snes));
4763 
4764     if (snes->errorifnotconverged) PetscCheck(snes->reason >= 0,PetscObjectComm((PetscObject)snes),PETSC_ERR_NOT_CONVERGED,"SNESSolve has not converged");
4765     if (snes->reason < 0) break;
4766     if (grid < snes->gridsequence) {
4767       DM  fine;
4768       Vec xnew;
4769       Mat interp;
4770 
4771       PetscCall(DMRefine(snes->dm,PetscObjectComm((PetscObject)snes),&fine));
4772       PetscCheck(fine,PetscObjectComm((PetscObject)snes),PETSC_ERR_ARG_INCOMP,"DMRefine() did not perform any refinement, cannot continue grid sequencing");
4773       PetscCall(DMCreateInterpolation(snes->dm,fine,&interp,NULL));
4774       PetscCall(DMCreateGlobalVector(fine,&xnew));
4775       PetscCall(MatInterpolate(interp,x,xnew));
4776       PetscCall(DMInterpolate(snes->dm,interp,fine));
4777       PetscCall(MatDestroy(&interp));
4778       x    = xnew;
4779 
4780       PetscCall(SNESReset(snes));
4781       PetscCall(SNESSetDM(snes,fine));
4782       PetscCall(SNESResetFromOptions(snes));
4783       PetscCall(DMDestroy(&fine));
4784       PetscCall(PetscViewerASCIIPopTab(PETSC_VIEWER_STDOUT_(PetscObjectComm((PetscObject)snes))));
4785     }
4786   }
4787   PetscCall(SNESViewFromOptions(snes,NULL,"-snes_view"));
4788   PetscCall(VecViewFromOptions(snes->vec_sol,(PetscObject)snes,"-snes_view_solution"));
4789   PetscCall(DMMonitor(snes->dm));
4790   PetscCall(SNESMonitorPauseFinal_Internal(snes));
4791 
4792   PetscCall(VecDestroy(&xcreated));
4793   PetscCall(PetscObjectSAWsBlock((PetscObject)snes));
4794   PetscFunctionReturn(0);
4795 }
4796 
4797 /* --------- Internal routines for SNES Package --------- */
4798 
4799 /*@C
4800    SNESSetType - Sets the method for the nonlinear solver.
4801 
4802    Collective on SNES
4803 
4804    Input Parameters:
4805 +  snes - the SNES context
4806 -  type - a known method
4807 
4808    Options Database Key:
4809 .  -snes_type <type> - Sets the method; use -help for a list
4810    of available methods (for instance, newtonls or newtontr)
4811 
4812    Notes:
4813    See "petsc/include/petscsnes.h" for available methods (for instance)
4814 +    SNESNEWTONLS - Newton's method with line search
4815      (systems of nonlinear equations)
4816 -    SNESNEWTONTR - Newton's method with trust region
4817      (systems of nonlinear equations)
4818 
4819   Normally, it is best to use the SNESSetFromOptions() command and then
4820   set the SNES solver type from the options database rather than by using
4821   this routine.  Using the options database provides the user with
4822   maximum flexibility in evaluating the many nonlinear solvers.
4823   The SNESSetType() routine is provided for those situations where it
4824   is necessary to set the nonlinear solver independently of the command
4825   line or options database.  This might be the case, for example, when
4826   the choice of solver changes during the execution of the program,
4827   and the user's application is taking responsibility for choosing the
4828   appropriate method.
4829 
4830     Developer Notes:
4831     SNESRegister() adds a constructor for a new SNESType to SNESList, SNESSetType() locates
4832     the constructor in that list and calls it to create the spexific object.
4833 
4834   Level: intermediate
4835 
4836 .seealso: `SNESType`, `SNESCreate()`, `SNESDestroy()`, `SNESGetType()`, `SNESSetFromOptions()`
4837 
4838 @*/
4839 PetscErrorCode  SNESSetType(SNES snes,SNESType type)
4840 {
4841   PetscBool      match;
4842   PetscErrorCode (*r)(SNES);
4843 
4844   PetscFunctionBegin;
4845   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
4846   PetscValidCharPointer(type,2);
4847 
4848   PetscCall(PetscObjectTypeCompare((PetscObject)snes,type,&match));
4849   if (match) PetscFunctionReturn(0);
4850 
4851   PetscCall(PetscFunctionListFind(SNESList,type,&r));
4852   PetscCheck(r,PETSC_COMM_SELF,PETSC_ERR_ARG_UNKNOWN_TYPE,"Unable to find requested SNES type %s",type);
4853   /* Destroy the previous private SNES context */
4854   if (snes->ops->destroy) PetscCall((*snes->ops->destroy)(snes));
4855   /* Reinitialize function pointers in SNESOps structure */
4856   snes->ops->setup          = NULL;
4857   snes->ops->solve          = NULL;
4858   snes->ops->view           = NULL;
4859   snes->ops->setfromoptions = NULL;
4860   snes->ops->destroy        = NULL;
4861 
4862   /* It may happen the user has customized the line search before calling SNESSetType */
4863   if (((PetscObject)snes)->type_name) PetscCall(SNESLineSearchDestroy(&snes->linesearch));
4864 
4865   /* Call the SNESCreate_XXX routine for this particular Nonlinear solver */
4866   snes->setupcalled = PETSC_FALSE;
4867 
4868   PetscCall(PetscObjectChangeTypeName((PetscObject)snes,type));
4869   PetscCall((*r)(snes));
4870   PetscFunctionReturn(0);
4871 }
4872 
4873 /*@C
4874    SNESGetType - Gets the SNES method type and name (as a string).
4875 
4876    Not Collective
4877 
4878    Input Parameter:
4879 .  snes - nonlinear solver context
4880 
4881    Output Parameter:
4882 .  type - SNES method (a character string)
4883 
4884    Level: intermediate
4885 
4886 @*/
4887 PetscErrorCode  SNESGetType(SNES snes,SNESType *type)
4888 {
4889   PetscFunctionBegin;
4890   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
4891   PetscValidPointer(type,2);
4892   *type = ((PetscObject)snes)->type_name;
4893   PetscFunctionReturn(0);
4894 }
4895 
4896 /*@
4897   SNESSetSolution - Sets the solution vector for use by the SNES routines.
4898 
4899   Logically Collective on SNES
4900 
4901   Input Parameters:
4902 + snes - the SNES context obtained from SNESCreate()
4903 - u    - the solution vector
4904 
4905   Level: beginner
4906 
4907 @*/
4908 PetscErrorCode SNESSetSolution(SNES snes, Vec u)
4909 {
4910   DM             dm;
4911 
4912   PetscFunctionBegin;
4913   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
4914   PetscValidHeaderSpecific(u, VEC_CLASSID, 2);
4915   PetscCall(PetscObjectReference((PetscObject) u));
4916   PetscCall(VecDestroy(&snes->vec_sol));
4917 
4918   snes->vec_sol = u;
4919 
4920   PetscCall(SNESGetDM(snes, &dm));
4921   PetscCall(DMShellSetGlobalVector(dm, u));
4922   PetscFunctionReturn(0);
4923 }
4924 
4925 /*@
4926    SNESGetSolution - Returns the vector where the approximate solution is
4927    stored. This is the fine grid solution when using SNESSetGridSequence().
4928 
4929    Not Collective, but Vec is parallel if SNES is parallel
4930 
4931    Input Parameter:
4932 .  snes - the SNES context
4933 
4934    Output Parameter:
4935 .  x - the solution
4936 
4937    Level: intermediate
4938 
4939 .seealso: `SNESGetSolutionUpdate()`, `SNESGetFunction()`
4940 @*/
4941 PetscErrorCode  SNESGetSolution(SNES snes,Vec *x)
4942 {
4943   PetscFunctionBegin;
4944   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
4945   PetscValidPointer(x,2);
4946   *x = snes->vec_sol;
4947   PetscFunctionReturn(0);
4948 }
4949 
4950 /*@
4951    SNESGetSolutionUpdate - Returns the vector where the solution update is
4952    stored.
4953 
4954    Not Collective, but Vec is parallel if SNES is parallel
4955 
4956    Input Parameter:
4957 .  snes - the SNES context
4958 
4959    Output Parameter:
4960 .  x - the solution update
4961 
4962    Level: advanced
4963 
4964 .seealso: `SNESGetSolution()`, `SNESGetFunction()`
4965 @*/
4966 PetscErrorCode  SNESGetSolutionUpdate(SNES snes,Vec *x)
4967 {
4968   PetscFunctionBegin;
4969   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
4970   PetscValidPointer(x,2);
4971   *x = snes->vec_sol_update;
4972   PetscFunctionReturn(0);
4973 }
4974 
4975 /*@C
4976    SNESGetFunction - Returns the vector where the function is stored.
4977 
4978    Not Collective, but Vec is parallel if SNES is parallel. Collective if Vec is requested, but has not been created yet.
4979 
4980    Input Parameter:
4981 .  snes - the SNES context
4982 
4983    Output Parameters:
4984 +  r - the vector that is used to store residuals (or NULL if you don't want it)
4985 .  f - the function (or NULL if you don't want it); see SNESFunction for calling sequence details
4986 -  ctx - the function context (or NULL if you don't want it)
4987 
4988    Level: advanced
4989 
4990     Notes: The vector r DOES NOT, in general contain the current value of the SNES nonlinear function
4991 
4992 .seealso: `SNESSetFunction()`, `SNESGetSolution()`, `SNESFunction`
4993 @*/
4994 PetscErrorCode  SNESGetFunction(SNES snes,Vec *r,PetscErrorCode (**f)(SNES,Vec,Vec,void*),void **ctx)
4995 {
4996   DM             dm;
4997 
4998   PetscFunctionBegin;
4999   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
5000   if (r) {
5001     if (!snes->vec_func) {
5002       if (snes->vec_rhs) {
5003         PetscCall(VecDuplicate(snes->vec_rhs,&snes->vec_func));
5004       } else if (snes->vec_sol) {
5005         PetscCall(VecDuplicate(snes->vec_sol,&snes->vec_func));
5006       } else if (snes->dm) {
5007         PetscCall(DMCreateGlobalVector(snes->dm,&snes->vec_func));
5008       }
5009     }
5010     *r = snes->vec_func;
5011   }
5012   PetscCall(SNESGetDM(snes,&dm));
5013   PetscCall(DMSNESGetFunction(dm,f,ctx));
5014   PetscFunctionReturn(0);
5015 }
5016 
5017 /*@C
5018    SNESGetNGS - Returns the NGS function and context.
5019 
5020    Input Parameter:
5021 .  snes - the SNES context
5022 
5023    Output Parameters:
5024 +  f - the function (or NULL) see SNESNGSFunction for details
5025 -  ctx    - the function context (or NULL)
5026 
5027    Level: advanced
5028 
5029 .seealso: `SNESSetNGS()`, `SNESGetFunction()`
5030 @*/
5031 
5032 PetscErrorCode SNESGetNGS (SNES snes, PetscErrorCode (**f)(SNES, Vec, Vec, void*), void ** ctx)
5033 {
5034   DM             dm;
5035 
5036   PetscFunctionBegin;
5037   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
5038   PetscCall(SNESGetDM(snes,&dm));
5039   PetscCall(DMSNESGetNGS(dm,f,ctx));
5040   PetscFunctionReturn(0);
5041 }
5042 
5043 /*@C
5044    SNESSetOptionsPrefix - Sets the prefix used for searching for all
5045    SNES options in the database.
5046 
5047    Logically Collective on SNES
5048 
5049    Input Parameters:
5050 +  snes - the SNES context
5051 -  prefix - the prefix to prepend to all option names
5052 
5053    Notes:
5054    A hyphen (-) must NOT be given at the beginning of the prefix name.
5055    The first character of all runtime options is AUTOMATICALLY the hyphen.
5056 
5057    Level: advanced
5058 
5059 .seealso: `SNESSetFromOptions()`
5060 @*/
5061 PetscErrorCode  SNESSetOptionsPrefix(SNES snes,const char prefix[])
5062 {
5063   PetscFunctionBegin;
5064   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
5065   PetscCall(PetscObjectSetOptionsPrefix((PetscObject)snes,prefix));
5066   if (!snes->ksp) PetscCall(SNESGetKSP(snes,&snes->ksp));
5067   if (snes->linesearch) {
5068     PetscCall(SNESGetLineSearch(snes,&snes->linesearch));
5069     PetscCall(PetscObjectSetOptionsPrefix((PetscObject)snes->linesearch,prefix));
5070   }
5071   PetscCall(KSPSetOptionsPrefix(snes->ksp,prefix));
5072   PetscFunctionReturn(0);
5073 }
5074 
5075 /*@C
5076    SNESAppendOptionsPrefix - Appends to the prefix used for searching for all
5077    SNES options in the database.
5078 
5079    Logically Collective on SNES
5080 
5081    Input Parameters:
5082 +  snes - the SNES context
5083 -  prefix - the prefix to prepend to all option names
5084 
5085    Notes:
5086    A hyphen (-) must NOT be given at the beginning of the prefix name.
5087    The first character of all runtime options is AUTOMATICALLY the hyphen.
5088 
5089    Level: advanced
5090 
5091 .seealso: `SNESGetOptionsPrefix()`
5092 @*/
5093 PetscErrorCode  SNESAppendOptionsPrefix(SNES snes,const char prefix[])
5094 {
5095   PetscFunctionBegin;
5096   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
5097   PetscCall(PetscObjectAppendOptionsPrefix((PetscObject)snes,prefix));
5098   if (!snes->ksp) PetscCall(SNESGetKSP(snes,&snes->ksp));
5099   if (snes->linesearch) {
5100     PetscCall(SNESGetLineSearch(snes,&snes->linesearch));
5101     PetscCall(PetscObjectAppendOptionsPrefix((PetscObject)snes->linesearch,prefix));
5102   }
5103   PetscCall(KSPAppendOptionsPrefix(snes->ksp,prefix));
5104   PetscFunctionReturn(0);
5105 }
5106 
5107 /*@C
5108    SNESGetOptionsPrefix - Sets the prefix used for searching for all
5109    SNES options in the database.
5110 
5111    Not Collective
5112 
5113    Input Parameter:
5114 .  snes - the SNES context
5115 
5116    Output Parameter:
5117 .  prefix - pointer to the prefix string used
5118 
5119    Notes:
5120     On the fortran side, the user should pass in a string 'prefix' of
5121    sufficient length to hold the prefix.
5122 
5123    Level: advanced
5124 
5125 .seealso: `SNESAppendOptionsPrefix()`
5126 @*/
5127 PetscErrorCode  SNESGetOptionsPrefix(SNES snes,const char *prefix[])
5128 {
5129   PetscFunctionBegin;
5130   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
5131   PetscCall(PetscObjectGetOptionsPrefix((PetscObject)snes,prefix));
5132   PetscFunctionReturn(0);
5133 }
5134 
5135 /*@C
5136   SNESRegister - Adds a method to the nonlinear solver package.
5137 
5138    Not collective
5139 
5140    Input Parameters:
5141 +  name_solver - name of a new user-defined solver
5142 -  routine_create - routine to create method context
5143 
5144    Notes:
5145    SNESRegister() may be called multiple times to add several user-defined solvers.
5146 
5147    Sample usage:
5148 .vb
5149    SNESRegister("my_solver",MySolverCreate);
5150 .ve
5151 
5152    Then, your solver can be chosen with the procedural interface via
5153 $     SNESSetType(snes,"my_solver")
5154    or at runtime via the option
5155 $     -snes_type my_solver
5156 
5157    Level: advanced
5158 
5159     Note: If your function is not being put into a shared library then use SNESRegister() instead
5160 
5161 .seealso: `SNESRegisterAll()`, `SNESRegisterDestroy()`
5162 
5163   Level: advanced
5164 @*/
5165 PetscErrorCode  SNESRegister(const char sname[],PetscErrorCode (*function)(SNES))
5166 {
5167   PetscFunctionBegin;
5168   PetscCall(SNESInitializePackage());
5169   PetscCall(PetscFunctionListAdd(&SNESList,sname,function));
5170   PetscFunctionReturn(0);
5171 }
5172 
5173 PetscErrorCode  SNESTestLocalMin(SNES snes)
5174 {
5175   PetscInt       N,i,j;
5176   Vec            u,uh,fh;
5177   PetscScalar    value;
5178   PetscReal      norm;
5179 
5180   PetscFunctionBegin;
5181   PetscCall(SNESGetSolution(snes,&u));
5182   PetscCall(VecDuplicate(u,&uh));
5183   PetscCall(VecDuplicate(u,&fh));
5184 
5185   /* currently only works for sequential */
5186   PetscCall(PetscPrintf(PetscObjectComm((PetscObject)snes),"Testing FormFunction() for local min\n"));
5187   PetscCall(VecGetSize(u,&N));
5188   for (i=0; i<N; i++) {
5189     PetscCall(VecCopy(u,uh));
5190     PetscCall(PetscPrintf(PetscObjectComm((PetscObject)snes),"i = %" PetscInt_FMT "\n",i));
5191     for (j=-10; j<11; j++) {
5192       value = PetscSign(j)*PetscExpReal(PetscAbs(j)-10.0);
5193       PetscCall(VecSetValue(uh,i,value,ADD_VALUES));
5194       PetscCall(SNESComputeFunction(snes,uh,fh));
5195       PetscCall(VecNorm(fh,NORM_2,&norm));
5196       PetscCall(PetscPrintf(PetscObjectComm((PetscObject)snes),"       j norm %" PetscInt_FMT " %18.16e\n",j,(double)norm));
5197       value = -value;
5198       PetscCall(VecSetValue(uh,i,value,ADD_VALUES));
5199     }
5200   }
5201   PetscCall(VecDestroy(&uh));
5202   PetscCall(VecDestroy(&fh));
5203   PetscFunctionReturn(0);
5204 }
5205 
5206 /*@
5207    SNESKSPSetUseEW - Sets SNES use Eisenstat-Walker method for
5208    computing relative tolerance for linear solvers within an inexact
5209    Newton method.
5210 
5211    Logically Collective on SNES
5212 
5213    Input Parameters:
5214 +  snes - SNES context
5215 -  flag - PETSC_TRUE or PETSC_FALSE
5216 
5217     Options Database:
5218 +  -snes_ksp_ew - use Eisenstat-Walker method for determining linear system convergence
5219 .  -snes_ksp_ew_version ver - version of  Eisenstat-Walker method
5220 .  -snes_ksp_ew_rtol0 <rtol0> - Sets rtol0
5221 .  -snes_ksp_ew_rtolmax <rtolmax> - Sets rtolmax
5222 .  -snes_ksp_ew_gamma <gamma> - Sets gamma
5223 .  -snes_ksp_ew_alpha <alpha> - Sets alpha
5224 .  -snes_ksp_ew_alpha2 <alpha2> - Sets alpha2
5225 -  -snes_ksp_ew_threshold <threshold> - Sets threshold
5226 
5227    Notes:
5228    Currently, the default is to use a constant relative tolerance for
5229    the inner linear solvers.  Alternatively, one can use the
5230    Eisenstat-Walker method, where the relative convergence tolerance
5231    is reset at each Newton iteration according progress of the nonlinear
5232    solver.
5233 
5234    Level: advanced
5235 
5236    Reference:
5237    S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an
5238    inexact Newton method", SISC 17 (1), pp.16-32, 1996.
5239 
5240 .seealso: `SNESKSPGetUseEW()`, `SNESKSPGetParametersEW()`, `SNESKSPSetParametersEW()`
5241 @*/
5242 PetscErrorCode  SNESKSPSetUseEW(SNES snes,PetscBool flag)
5243 {
5244   PetscFunctionBegin;
5245   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
5246   PetscValidLogicalCollectiveBool(snes,flag,2);
5247   snes->ksp_ewconv = flag;
5248   PetscFunctionReturn(0);
5249 }
5250 
5251 /*@
5252    SNESKSPGetUseEW - Gets if SNES is using Eisenstat-Walker method
5253    for computing relative tolerance for linear solvers within an
5254    inexact Newton method.
5255 
5256    Not Collective
5257 
5258    Input Parameter:
5259 .  snes - SNES context
5260 
5261    Output Parameter:
5262 .  flag - PETSC_TRUE or PETSC_FALSE
5263 
5264    Notes:
5265    Currently, the default is to use a constant relative tolerance for
5266    the inner linear solvers.  Alternatively, one can use the
5267    Eisenstat-Walker method, where the relative convergence tolerance
5268    is reset at each Newton iteration according progress of the nonlinear
5269    solver.
5270 
5271    Level: advanced
5272 
5273    Reference:
5274    S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an
5275    inexact Newton method", SISC 17 (1), pp.16-32, 1996.
5276 
5277 .seealso: `SNESKSPSetUseEW()`, `SNESKSPGetParametersEW()`, `SNESKSPSetParametersEW()`
5278 @*/
5279 PetscErrorCode  SNESKSPGetUseEW(SNES snes, PetscBool  *flag)
5280 {
5281   PetscFunctionBegin;
5282   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
5283   PetscValidBoolPointer(flag,2);
5284   *flag = snes->ksp_ewconv;
5285   PetscFunctionReturn(0);
5286 }
5287 
5288 /*@
5289    SNESKSPSetParametersEW - Sets parameters for Eisenstat-Walker
5290    convergence criteria for the linear solvers within an inexact
5291    Newton method.
5292 
5293    Logically Collective on SNES
5294 
5295    Input Parameters:
5296 +    snes - SNES context
5297 .    version - version 1, 2 (default is 2), 3 or 4
5298 .    rtol_0 - initial relative tolerance (0 <= rtol_0 < 1)
5299 .    rtol_max - maximum relative tolerance (0 <= rtol_max < 1)
5300 .    gamma - multiplicative factor for version 2 rtol computation
5301              (0 <= gamma2 <= 1)
5302 .    alpha - power for version 2 rtol computation (1 < alpha <= 2)
5303 .    alpha2 - power for safeguard
5304 -    threshold - threshold for imposing safeguard (0 < threshold < 1)
5305 
5306    Note:
5307    Version 3 was contributed by Luis Chacon, June 2006.
5308 
5309    Use PETSC_DEFAULT to retain the default for any of the parameters.
5310 
5311    Level: advanced
5312 
5313    Reference:
5314    S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an
5315    inexact Newton method", Utah State University Math. Stat. Dept. Res.
5316    Report 6/94/75, June, 1994, to appear in SIAM J. Sci. Comput.
5317 
5318 .seealso: `SNESKSPSetUseEW()`, `SNESKSPGetUseEW()`, `SNESKSPGetParametersEW()`
5319 @*/
5320 PetscErrorCode  SNESKSPSetParametersEW(SNES snes,PetscInt version,PetscReal rtol_0,PetscReal rtol_max,PetscReal gamma,PetscReal alpha,PetscReal alpha2,PetscReal threshold)
5321 {
5322   SNESKSPEW *kctx;
5323 
5324   PetscFunctionBegin;
5325   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
5326   kctx = (SNESKSPEW*)snes->kspconvctx;
5327   PetscCheck(kctx,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context existing");
5328   PetscValidLogicalCollectiveInt(snes,version,2);
5329   PetscValidLogicalCollectiveReal(snes,rtol_0,3);
5330   PetscValidLogicalCollectiveReal(snes,rtol_max,4);
5331   PetscValidLogicalCollectiveReal(snes,gamma,5);
5332   PetscValidLogicalCollectiveReal(snes,alpha,6);
5333   PetscValidLogicalCollectiveReal(snes,alpha2,7);
5334   PetscValidLogicalCollectiveReal(snes,threshold,8);
5335 
5336   if (version != PETSC_DEFAULT)   kctx->version   = version;
5337   if (rtol_0 != PETSC_DEFAULT)    kctx->rtol_0    = rtol_0;
5338   if (rtol_max != PETSC_DEFAULT)  kctx->rtol_max  = rtol_max;
5339   if (gamma != PETSC_DEFAULT)     kctx->gamma     = gamma;
5340   if (alpha != PETSC_DEFAULT)     kctx->alpha     = alpha;
5341   if (alpha2 != PETSC_DEFAULT)    kctx->alpha2    = alpha2;
5342   if (threshold != PETSC_DEFAULT) kctx->threshold = threshold;
5343 
5344   PetscCheck(kctx->version >= 1 && kctx->version <= 4,PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Only versions 1 to 4 are supported: %" PetscInt_FMT,kctx->version);
5345   PetscCheck(kctx->rtol_0 >= 0.0 && kctx->rtol_0 < 1.0,PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"0.0 <= rtol_0 < 1.0: %g",(double)kctx->rtol_0);
5346   PetscCheck(kctx->rtol_max >= 0.0 && kctx->rtol_max < 1.0,PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"0.0 <= rtol_max (%g) < 1.0",(double)kctx->rtol_max);
5347   PetscCheck(kctx->gamma >= 0.0 && kctx->gamma <= 1.0,PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"0.0 <= gamma (%g) <= 1.0",(double)kctx->gamma);
5348   PetscCheck(kctx->alpha > 1.0 && kctx->alpha <= 2.0,PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"1.0 < alpha (%g) <= 2.0",(double)kctx->alpha);
5349   PetscCheck(kctx->threshold > 0.0 && kctx->threshold < 1.0,PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"0.0 < threshold (%g) < 1.0",(double)kctx->threshold);
5350   PetscFunctionReturn(0);
5351 }
5352 
5353 /*@
5354    SNESKSPGetParametersEW - Gets parameters for Eisenstat-Walker
5355    convergence criteria for the linear solvers within an inexact
5356    Newton method.
5357 
5358    Not Collective
5359 
5360    Input Parameter:
5361 .    snes - SNES context
5362 
5363    Output Parameters:
5364 +    version - version 1, 2 (default is 2), 3 or 4
5365 .    rtol_0 - initial relative tolerance (0 <= rtol_0 < 1)
5366 .    rtol_max - maximum relative tolerance (0 <= rtol_max < 1)
5367 .    gamma - multiplicative factor for version 2 rtol computation (0 <= gamma2 <= 1)
5368 .    alpha - power for version 2 rtol computation (1 < alpha <= 2)
5369 .    alpha2 - power for safeguard
5370 -    threshold - threshold for imposing safeguard (0 < threshold < 1)
5371 
5372    Level: advanced
5373 
5374 .seealso: `SNESKSPSetUseEW()`, `SNESKSPGetUseEW()`, `SNESKSPSetParametersEW()`
5375 @*/
5376 PetscErrorCode  SNESKSPGetParametersEW(SNES snes,PetscInt *version,PetscReal *rtol_0,PetscReal *rtol_max,PetscReal *gamma,PetscReal *alpha,PetscReal *alpha2,PetscReal *threshold)
5377 {
5378   SNESKSPEW *kctx;
5379 
5380   PetscFunctionBegin;
5381   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
5382   kctx = (SNESKSPEW*)snes->kspconvctx;
5383   PetscCheck(kctx,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context existing");
5384   if (version)   *version   = kctx->version;
5385   if (rtol_0)    *rtol_0    = kctx->rtol_0;
5386   if (rtol_max)  *rtol_max  = kctx->rtol_max;
5387   if (gamma)     *gamma     = kctx->gamma;
5388   if (alpha)     *alpha     = kctx->alpha;
5389   if (alpha2)    *alpha2    = kctx->alpha2;
5390   if (threshold) *threshold = kctx->threshold;
5391   PetscFunctionReturn(0);
5392 }
5393 
5394 PetscErrorCode KSPPreSolve_SNESEW(KSP ksp, Vec b, Vec x, SNES snes)
5395 {
5396   SNESKSPEW *kctx = (SNESKSPEW*)snes->kspconvctx;
5397   PetscReal rtol  = PETSC_DEFAULT,stol;
5398 
5399   PetscFunctionBegin;
5400   if (!snes->ksp_ewconv) PetscFunctionReturn(0);
5401   if (!snes->iter) {
5402     rtol = kctx->rtol_0; /* first time in, so use the original user rtol */
5403     PetscCall(VecNorm(snes->vec_func,NORM_2,&kctx->norm_first));
5404   } else {
5405     if (kctx->version == 1) {
5406       rtol = PetscAbsReal(snes->norm - kctx->lresid_last)/kctx->norm_last;
5407       stol = PetscPowReal(kctx->rtol_last,kctx->alpha2);
5408       if (stol > kctx->threshold) rtol = PetscMax(rtol,stol);
5409     } else if (kctx->version == 2) {
5410       rtol = kctx->gamma * PetscPowReal(snes->norm/kctx->norm_last,kctx->alpha);
5411       stol = kctx->gamma * PetscPowReal(kctx->rtol_last,kctx->alpha);
5412       if (stol > kctx->threshold) rtol = PetscMax(rtol,stol);
5413     } else if (kctx->version == 3) { /* contributed by Luis Chacon, June 2006. */
5414       rtol = kctx->gamma * PetscPowReal(snes->norm/kctx->norm_last,kctx->alpha);
5415       /* safeguard: avoid sharp decrease of rtol */
5416       stol = kctx->gamma*PetscPowReal(kctx->rtol_last,kctx->alpha);
5417       stol = PetscMax(rtol,stol);
5418       rtol = PetscMin(kctx->rtol_0,stol);
5419       /* safeguard: avoid oversolving */
5420       stol = kctx->gamma*(kctx->norm_first*snes->rtol)/snes->norm;
5421       stol = PetscMax(rtol,stol);
5422       rtol = PetscMin(kctx->rtol_0,stol);
5423     } else if (kctx->version == 4) { /* H.-B. An et al. Journal of Computational and Applied Mathematics 200 (2007) 47-60 */
5424       PetscReal ared = PetscAbsReal(kctx->norm_last - snes->norm);
5425       PetscReal pred = PetscAbsReal(kctx->norm_last - kctx->lresid_last);
5426       PetscReal rk = ared / pred;
5427       if (rk < kctx->v4_p1) rtol = 1. - 2.*kctx->v4_p1;
5428       else if (rk < kctx->v4_p2) rtol = kctx->rtol_last;
5429       else if (rk < kctx->v4_p3) rtol = kctx->v4_m1 * kctx->rtol_last;
5430       else rtol = kctx->v4_m2 * kctx->rtol_last;
5431 
5432       if (kctx->rtol_last_2 > kctx->v4_m3 && kctx->rtol_last > kctx->v4_m3 &&
5433           kctx->rk_last_2 < kctx->v4_p1 && kctx->rk_last < kctx->v4_p1) {
5434         rtol = kctx->v4_m4 * kctx->rtol_last;
5435         //printf("iter %" PetscInt_FMT ", Eisenstat-Walker (version %" PetscInt_FMT ") KSP rtol=%g (rk %g ps %g %g %g) (AD)\n",snes->iter,kctx->version,(double)rtol,rk,kctx->v4_p1,kctx->v4_p2,kctx->v4_p3);
5436       } else {
5437         //printf("iter %" PetscInt_FMT ", Eisenstat-Walker (version %" PetscInt_FMT ") KSP rtol=%g (rk %g ps %g %g %g)\n",snes->iter,kctx->version,(double)rtol,rk,kctx->v4_p1,kctx->v4_p2,kctx->v4_p3);
5438       }
5439       kctx->rtol_last_2 = kctx->rtol_last;
5440       kctx->rk_last_2 = kctx->rk_last;
5441       kctx->rk_last = rk;
5442     } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Only versions 1-4 are supported: %" PetscInt_FMT,kctx->version);
5443   }
5444   /* safeguard: avoid rtol greater than rtol_max */
5445   rtol = PetscMin(rtol,kctx->rtol_max);
5446   PetscCall(KSPSetTolerances(ksp,rtol,PETSC_DEFAULT,PETSC_DEFAULT,PETSC_DEFAULT));
5447   PetscCall(PetscInfo(snes,"iter %" PetscInt_FMT ", Eisenstat-Walker (version %" PetscInt_FMT ") KSP rtol=%g\n",snes->iter,kctx->version,(double)rtol));
5448   PetscFunctionReturn(0);
5449 }
5450 
5451 PetscErrorCode KSPPostSolve_SNESEW(KSP ksp, Vec b, Vec x, SNES snes)
5452 {
5453   SNESKSPEW *kctx = (SNESKSPEW*)snes->kspconvctx;
5454   PCSide    pcside;
5455   Vec       lres;
5456 
5457   PetscFunctionBegin;
5458   if (!snes->ksp_ewconv) PetscFunctionReturn(0);
5459   PetscCall(KSPGetTolerances(ksp,&kctx->rtol_last,NULL,NULL,NULL));
5460   kctx->norm_last = snes->norm;
5461   if (kctx->version == 1 || kctx->version == 4) {
5462     PC        pc;
5463     PetscBool getRes;
5464 
5465     PetscCall(KSPGetPC(ksp,&pc));
5466     PetscCall(PetscObjectTypeCompare((PetscObject)pc,PCNONE,&getRes));
5467     if (!getRes) {
5468       KSPNormType normtype;
5469 
5470       PetscCall(KSPGetNormType(ksp,&normtype));
5471       getRes = (PetscBool)(normtype == KSP_NORM_UNPRECONDITIONED);
5472     }
5473     PetscCall(KSPGetPCSide(ksp,&pcside));
5474     if (pcside == PC_RIGHT || getRes) { /* KSP residual is true linear residual */
5475       PetscCall(KSPGetResidualNorm(ksp,&kctx->lresid_last));
5476     } else {
5477       /* KSP residual is preconditioned residual */
5478       /* compute true linear residual norm */
5479       Mat J;
5480       PetscCall(KSPGetOperators(ksp,&J,NULL));
5481       PetscCall(VecDuplicate(b,&lres));
5482       PetscCall(MatMult(J,x,lres));
5483       PetscCall(VecAYPX(lres,-1.0,b));
5484       PetscCall(VecNorm(lres,NORM_2,&kctx->lresid_last));
5485       PetscCall(VecDestroy(&lres));
5486     }
5487   }
5488   PetscFunctionReturn(0);
5489 }
5490 
5491 /*@
5492    SNESGetKSP - Returns the KSP context for a SNES solver.
5493 
5494    Not Collective, but if SNES object is parallel, then KSP object is parallel
5495 
5496    Input Parameter:
5497 .  snes - the SNES context
5498 
5499    Output Parameter:
5500 .  ksp - the KSP context
5501 
5502    Notes:
5503    The user can then directly manipulate the KSP context to set various
5504    options, etc.  Likewise, the user can then extract and manipulate the
5505    PC contexts as well.
5506 
5507    Level: beginner
5508 
5509 .seealso: `KSPGetPC()`, `SNESCreate()`, `KSPCreate()`, `SNESSetKSP()`
5510 @*/
5511 PetscErrorCode  SNESGetKSP(SNES snes,KSP *ksp)
5512 {
5513   PetscFunctionBegin;
5514   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
5515   PetscValidPointer(ksp,2);
5516 
5517   if (!snes->ksp) {
5518     PetscCall(KSPCreate(PetscObjectComm((PetscObject)snes),&snes->ksp));
5519     PetscCall(PetscObjectIncrementTabLevel((PetscObject)snes->ksp,(PetscObject)snes,1));
5520     PetscCall(PetscLogObjectParent((PetscObject)snes,(PetscObject)snes->ksp));
5521 
5522     PetscCall(KSPSetPreSolve(snes->ksp,(PetscErrorCode (*)(KSP,Vec,Vec,void*))KSPPreSolve_SNESEW,snes));
5523     PetscCall(KSPSetPostSolve(snes->ksp,(PetscErrorCode (*)(KSP,Vec,Vec,void*))KSPPostSolve_SNESEW,snes));
5524 
5525     PetscCall(KSPMonitorSetFromOptions(snes->ksp, "-snes_monitor_ksp", "snes_preconditioned_residual", snes));
5526     PetscCall(PetscObjectSetOptions((PetscObject)snes->ksp,((PetscObject)snes)->options));
5527   }
5528   *ksp = snes->ksp;
5529   PetscFunctionReturn(0);
5530 }
5531 
5532 #include <petsc/private/dmimpl.h>
5533 /*@
5534    SNESSetDM - Sets the DM that may be used by some nonlinear solvers or their underlying preconditioners
5535 
5536    Logically Collective on SNES
5537 
5538    Input Parameters:
5539 +  snes - the nonlinear solver context
5540 -  dm - the dm, cannot be NULL
5541 
5542    Notes:
5543    A DM can only be used for solving one problem at a time because information about the problem is stored on the DM,
5544    even when not using interfaces like DMSNESSetFunction().  Use DMClone() to get a distinct DM when solving different
5545    problems using the same function space.
5546 
5547    Level: intermediate
5548 
5549 .seealso: `SNESGetDM()`, `KSPSetDM()`, `KSPGetDM()`
5550 @*/
5551 PetscErrorCode  SNESSetDM(SNES snes,DM dm)
5552 {
5553   KSP            ksp;
5554   DMSNES         sdm;
5555 
5556   PetscFunctionBegin;
5557   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
5558   PetscValidHeaderSpecific(dm,DM_CLASSID,2);
5559   PetscCall(PetscObjectReference((PetscObject)dm));
5560   if (snes->dm) {               /* Move the DMSNES context over to the new DM unless the new DM already has one */
5561     if (snes->dm->dmsnes && !dm->dmsnes) {
5562       PetscCall(DMCopyDMSNES(snes->dm,dm));
5563       PetscCall(DMGetDMSNES(snes->dm,&sdm));
5564       if (sdm->originaldm == snes->dm) sdm->originaldm = dm; /* Grant write privileges to the replacement DM */
5565     }
5566     PetscCall(DMCoarsenHookRemove(snes->dm,DMCoarsenHook_SNESVecSol,DMRestrictHook_SNESVecSol,snes));
5567     PetscCall(DMDestroy(&snes->dm));
5568   }
5569   snes->dm     = dm;
5570   snes->dmAuto = PETSC_FALSE;
5571 
5572   PetscCall(SNESGetKSP(snes,&ksp));
5573   PetscCall(KSPSetDM(ksp,dm));
5574   PetscCall(KSPSetDMActive(ksp,PETSC_FALSE));
5575   if (snes->npc) {
5576     PetscCall(SNESSetDM(snes->npc,snes->dm));
5577     PetscCall(SNESSetNPCSide(snes,snes->npcside));
5578   }
5579   PetscFunctionReturn(0);
5580 }
5581 
5582 /*@
5583    SNESGetDM - Gets the DM that may be used by some preconditioners
5584 
5585    Not Collective but DM obtained is parallel on SNES
5586 
5587    Input Parameter:
5588 . snes - the preconditioner context
5589 
5590    Output Parameter:
5591 .  dm - the dm
5592 
5593    Level: intermediate
5594 
5595 .seealso: `SNESSetDM()`, `KSPSetDM()`, `KSPGetDM()`
5596 @*/
5597 PetscErrorCode  SNESGetDM(SNES snes,DM *dm)
5598 {
5599   PetscFunctionBegin;
5600   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
5601   if (!snes->dm) {
5602     PetscCall(DMShellCreate(PetscObjectComm((PetscObject)snes),&snes->dm));
5603     snes->dmAuto = PETSC_TRUE;
5604   }
5605   *dm = snes->dm;
5606   PetscFunctionReturn(0);
5607 }
5608 
5609 /*@
5610   SNESSetNPC - Sets the nonlinear preconditioner to be used.
5611 
5612   Collective on SNES
5613 
5614   Input Parameters:
5615 + snes - iterative context obtained from SNESCreate()
5616 - pc   - the preconditioner object
5617 
5618   Notes:
5619   Use SNESGetNPC() to retrieve the preconditioner context (for example,
5620   to configure it using the API).
5621 
5622   Level: developer
5623 
5624 .seealso: `SNESGetNPC()`, `SNESHasNPC()`
5625 @*/
5626 PetscErrorCode SNESSetNPC(SNES snes, SNES pc)
5627 {
5628   PetscFunctionBegin;
5629   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
5630   PetscValidHeaderSpecific(pc, SNES_CLASSID, 2);
5631   PetscCheckSameComm(snes, 1, pc, 2);
5632   PetscCall(PetscObjectReference((PetscObject) pc));
5633   PetscCall(SNESDestroy(&snes->npc));
5634   snes->npc = pc;
5635   PetscCall(PetscLogObjectParent((PetscObject)snes, (PetscObject)snes->npc));
5636   PetscFunctionReturn(0);
5637 }
5638 
5639 /*@
5640   SNESGetNPC - Creates a nonlinear preconditioning solver (SNES) to be used to precondition the nonlinear solver.
5641 
5642   Not Collective; but any changes to the obtained SNES object must be applied collectively
5643 
5644   Input Parameter:
5645 . snes - iterative context obtained from SNESCreate()
5646 
5647   Output Parameter:
5648 . pc - preconditioner context
5649 
5650   Options Database:
5651 . -npc_snes_type <type> - set the type of the SNES to use as the nonlinear preconditioner
5652 
5653   Notes:
5654     If a SNES was previously set with SNESSetNPC() then that SNES is returned, otherwise a new SNES object is created.
5655 
5656     The (preconditioner) SNES returned automatically inherits the same nonlinear function and Jacobian supplied to the original
5657     SNES during SNESSetUp()
5658 
5659   Level: developer
5660 
5661 .seealso: `SNESSetNPC()`, `SNESHasNPC()`, `SNES`, `SNESCreate()`
5662 @*/
5663 PetscErrorCode SNESGetNPC(SNES snes, SNES *pc)
5664 {
5665   const char     *optionsprefix;
5666 
5667   PetscFunctionBegin;
5668   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
5669   PetscValidPointer(pc, 2);
5670   if (!snes->npc) {
5671     PetscCall(SNESCreate(PetscObjectComm((PetscObject)snes),&snes->npc));
5672     PetscCall(PetscObjectIncrementTabLevel((PetscObject)snes->npc,(PetscObject)snes,1));
5673     PetscCall(PetscLogObjectParent((PetscObject)snes,(PetscObject)snes->npc));
5674     PetscCall(SNESGetOptionsPrefix(snes,&optionsprefix));
5675     PetscCall(SNESSetOptionsPrefix(snes->npc,optionsprefix));
5676     PetscCall(SNESAppendOptionsPrefix(snes->npc,"npc_"));
5677     PetscCall(SNESSetCountersReset(snes->npc,PETSC_FALSE));
5678   }
5679   *pc = snes->npc;
5680   PetscFunctionReturn(0);
5681 }
5682 
5683 /*@
5684   SNESHasNPC - Returns whether a nonlinear preconditioner exists
5685 
5686   Not Collective
5687 
5688   Input Parameter:
5689 . snes - iterative context obtained from SNESCreate()
5690 
5691   Output Parameter:
5692 . has_npc - whether the SNES has an NPC or not
5693 
5694   Level: developer
5695 
5696 .seealso: `SNESSetNPC()`, `SNESGetNPC()`
5697 @*/
5698 PetscErrorCode SNESHasNPC(SNES snes, PetscBool *has_npc)
5699 {
5700   PetscFunctionBegin;
5701   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
5702   *has_npc = (PetscBool) (snes->npc ? PETSC_TRUE : PETSC_FALSE);
5703   PetscFunctionReturn(0);
5704 }
5705 
5706 /*@
5707     SNESSetNPCSide - Sets the preconditioning side.
5708 
5709     Logically Collective on SNES
5710 
5711     Input Parameter:
5712 .   snes - iterative context obtained from SNESCreate()
5713 
5714     Output Parameter:
5715 .   side - the preconditioning side, where side is one of
5716 .vb
5717       PC_LEFT - left preconditioning
5718       PC_RIGHT - right preconditioning (default for most nonlinear solvers)
5719 .ve
5720 
5721     Options Database Keys:
5722 .   -snes_npc_side <right,left> - nonlinear preconditioner side
5723 
5724     Notes:
5725     SNESNRICHARDSON and SNESNCG only support left preconditioning.
5726 
5727     Level: intermediate
5728 
5729 .seealso: `SNESGetNPCSide()`, `KSPSetPCSide()`
5730 @*/
5731 PetscErrorCode  SNESSetNPCSide(SNES snes,PCSide side)
5732 {
5733   PetscFunctionBegin;
5734   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
5735   PetscValidLogicalCollectiveEnum(snes,side,2);
5736   if (side == PC_SIDE_DEFAULT) side = PC_RIGHT;
5737   PetscCheck((side == PC_LEFT) || (side == PC_RIGHT),PetscObjectComm((PetscObject)snes),PETSC_ERR_ARG_WRONG,"Only PC_LEFT and PC_RIGHT are supported");
5738   snes->npcside = side;
5739   PetscFunctionReturn(0);
5740 }
5741 
5742 /*@
5743     SNESGetNPCSide - Gets the preconditioning side.
5744 
5745     Not Collective
5746 
5747     Input Parameter:
5748 .   snes - iterative context obtained from SNESCreate()
5749 
5750     Output Parameter:
5751 .   side - the preconditioning side, where side is one of
5752 .vb
5753       PC_LEFT - left preconditioning
5754       PC_RIGHT - right preconditioning (default for most nonlinear solvers)
5755 .ve
5756 
5757     Level: intermediate
5758 
5759 .seealso: `SNESSetNPCSide()`, `KSPGetPCSide()`
5760 @*/
5761 PetscErrorCode  SNESGetNPCSide(SNES snes,PCSide *side)
5762 {
5763   PetscFunctionBegin;
5764   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
5765   PetscValidPointer(side,2);
5766   *side = snes->npcside;
5767   PetscFunctionReturn(0);
5768 }
5769 
5770 /*@
5771   SNESSetLineSearch - Sets the linesearch on the SNES instance.
5772 
5773   Collective on SNES
5774 
5775   Input Parameters:
5776 + snes - iterative context obtained from SNESCreate()
5777 - linesearch   - the linesearch object
5778 
5779   Notes:
5780   Use SNESGetLineSearch() to retrieve the preconditioner context (for example,
5781   to configure it using the API).
5782 
5783   Level: developer
5784 
5785 .seealso: `SNESGetLineSearch()`
5786 @*/
5787 PetscErrorCode SNESSetLineSearch(SNES snes, SNESLineSearch linesearch)
5788 {
5789   PetscFunctionBegin;
5790   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
5791   PetscValidHeaderSpecific(linesearch, SNESLINESEARCH_CLASSID, 2);
5792   PetscCheckSameComm(snes, 1, linesearch, 2);
5793   PetscCall(PetscObjectReference((PetscObject) linesearch));
5794   PetscCall(SNESLineSearchDestroy(&snes->linesearch));
5795 
5796   snes->linesearch = linesearch;
5797 
5798   PetscCall(PetscLogObjectParent((PetscObject)snes, (PetscObject)snes->linesearch));
5799   PetscFunctionReturn(0);
5800 }
5801 
5802 /*@
5803   SNESGetLineSearch - Returns a pointer to the line search context set with SNESSetLineSearch()
5804   or creates a default line search instance associated with the SNES and returns it.
5805 
5806   Not Collective
5807 
5808   Input Parameter:
5809 . snes - iterative context obtained from SNESCreate()
5810 
5811   Output Parameter:
5812 . linesearch - linesearch context
5813 
5814   Level: beginner
5815 
5816 .seealso: `SNESSetLineSearch()`, `SNESLineSearchCreate()`
5817 @*/
5818 PetscErrorCode SNESGetLineSearch(SNES snes, SNESLineSearch *linesearch)
5819 {
5820   const char     *optionsprefix;
5821 
5822   PetscFunctionBegin;
5823   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
5824   PetscValidPointer(linesearch, 2);
5825   if (!snes->linesearch) {
5826     PetscCall(SNESGetOptionsPrefix(snes, &optionsprefix));
5827     PetscCall(SNESLineSearchCreate(PetscObjectComm((PetscObject)snes), &snes->linesearch));
5828     PetscCall(SNESLineSearchSetSNES(snes->linesearch, snes));
5829     PetscCall(SNESLineSearchAppendOptionsPrefix(snes->linesearch, optionsprefix));
5830     PetscCall(PetscObjectIncrementTabLevel((PetscObject) snes->linesearch, (PetscObject) snes, 1));
5831     PetscCall(PetscLogObjectParent((PetscObject)snes, (PetscObject)snes->linesearch));
5832   }
5833   *linesearch = snes->linesearch;
5834   PetscFunctionReturn(0);
5835 }
5836