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