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