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