xref: /petsc/src/snes/interface/snes.c (revision 14e7b07eeb9e40f6f4410f12e254190850606b19)
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.
3830 
3831   Options Database Key:
3832 . -snes_divergence_tolerance <divtol> - Sets `divtol`
3833 
3834   Level: intermediate
3835 
3836   Note:
3837   Non-positive values of `divtol` different from `PETSC_DEFAULT` will deactivate the test.
3838 
3839 .seealso: [](ch_snes), `SNES`, `SNESSolve()`, `SNESSetTolerances()`, `SNESGetDivergenceTolerance`
3840 @*/
3841 PetscErrorCode SNESSetDivergenceTolerance(SNES snes, PetscReal divtol)
3842 {
3843   PetscFunctionBegin;
3844   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
3845   PetscValidLogicalCollectiveReal(snes, divtol, 2);
3846   if (divtol != (PetscReal)PETSC_DEFAULT) snes->divtol = divtol;
3847   PetscFunctionReturn(PETSC_SUCCESS);
3848 }
3849 
3850 /*@
3851   SNESGetTolerances - Gets various parameters used in convergence tests.
3852 
3853   Not Collective
3854 
3855   Input Parameters:
3856 + snes  - the `SNES` context
3857 . atol  - absolute convergence tolerance
3858 . rtol  - relative convergence tolerance
3859 . stol  - convergence tolerance in terms of the norm
3860           of the change in the solution between steps
3861 . maxit - maximum number of iterations
3862 - maxf  - maximum number of function evaluations
3863 
3864   Level: intermediate
3865 
3866   Note:
3867   The user can specify `NULL` for any parameter that is not needed.
3868 
3869 .seealso: [](ch_snes), `SNES`, `SNESSetTolerances()`
3870 @*/
3871 PetscErrorCode SNESGetTolerances(SNES snes, PetscReal *atol, PetscReal *rtol, PetscReal *stol, PetscInt *maxit, PetscInt *maxf)
3872 {
3873   PetscFunctionBegin;
3874   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
3875   if (atol) *atol = snes->abstol;
3876   if (rtol) *rtol = snes->rtol;
3877   if (stol) *stol = snes->stol;
3878   if (maxit) *maxit = snes->max_its;
3879   if (maxf) *maxf = snes->max_funcs;
3880   PetscFunctionReturn(PETSC_SUCCESS);
3881 }
3882 
3883 /*@
3884   SNESGetDivergenceTolerance - Gets divergence tolerance used in divergence test.
3885 
3886   Not Collective
3887 
3888   Input Parameters:
3889 + snes   - the `SNES` context
3890 - divtol - divergence tolerance
3891 
3892   Level: intermediate
3893 
3894 .seealso: [](ch_snes), `SNES`, `SNESSetDivergenceTolerance()`
3895 @*/
3896 PetscErrorCode SNESGetDivergenceTolerance(SNES snes, PetscReal *divtol)
3897 {
3898   PetscFunctionBegin;
3899   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
3900   if (divtol) *divtol = snes->divtol;
3901   PetscFunctionReturn(PETSC_SUCCESS);
3902 }
3903 
3904 /*@
3905   SNESSetTrustRegionTolerance - Sets the trust region parameter tolerance.
3906 
3907   Logically Collective
3908 
3909   Input Parameters:
3910 + snes - the `SNES` context
3911 - tol  - tolerance
3912 
3913   Options Database Key:
3914 . -snes_tr_tol <tol> - Sets tol
3915 
3916   Level: intermediate
3917 
3918   Developer Note:
3919   Should be SNESTrustRegionSetTolerance()
3920 
3921 .seealso: [](ch_snes), `SNES`, `SNESNEWTONTR`, `SNESSetTolerances()`
3922 @*/
3923 PetscErrorCode SNESSetTrustRegionTolerance(SNES snes, PetscReal tol)
3924 {
3925   PetscFunctionBegin;
3926   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
3927   PetscValidLogicalCollectiveReal(snes, tol, 2);
3928   snes->deltatol = tol;
3929   PetscFunctionReturn(PETSC_SUCCESS);
3930 }
3931 
3932 PETSC_INTERN PetscErrorCode SNESMonitorRange_Private(SNES, PetscInt, PetscReal *);
3933 
3934 PetscErrorCode SNESMonitorLGRange(SNES snes, PetscInt n, PetscReal rnorm, void *monctx)
3935 {
3936   PetscDrawLG      lg;
3937   PetscReal        x, y, per;
3938   PetscViewer      v = (PetscViewer)monctx;
3939   static PetscReal prev; /* should be in the context */
3940   PetscDraw        draw;
3941 
3942   PetscFunctionBegin;
3943   PetscValidHeaderSpecific(v, PETSC_VIEWER_CLASSID, 4);
3944   PetscCall(PetscViewerDrawGetDrawLG(v, 0, &lg));
3945   if (!n) PetscCall(PetscDrawLGReset(lg));
3946   PetscCall(PetscDrawLGGetDraw(lg, &draw));
3947   PetscCall(PetscDrawSetTitle(draw, "Residual norm"));
3948   x = (PetscReal)n;
3949   if (rnorm > 0.0) y = PetscLog10Real(rnorm);
3950   else y = -15.0;
3951   PetscCall(PetscDrawLGAddPoint(lg, &x, &y));
3952   if (n < 20 || !(n % 5) || snes->reason) {
3953     PetscCall(PetscDrawLGDraw(lg));
3954     PetscCall(PetscDrawLGSave(lg));
3955   }
3956 
3957   PetscCall(PetscViewerDrawGetDrawLG(v, 1, &lg));
3958   if (!n) PetscCall(PetscDrawLGReset(lg));
3959   PetscCall(PetscDrawLGGetDraw(lg, &draw));
3960   PetscCall(PetscDrawSetTitle(draw, "% elements > .2*max element"));
3961   PetscCall(SNESMonitorRange_Private(snes, n, &per));
3962   x = (PetscReal)n;
3963   y = 100.0 * per;
3964   PetscCall(PetscDrawLGAddPoint(lg, &x, &y));
3965   if (n < 20 || !(n % 5) || snes->reason) {
3966     PetscCall(PetscDrawLGDraw(lg));
3967     PetscCall(PetscDrawLGSave(lg));
3968   }
3969 
3970   PetscCall(PetscViewerDrawGetDrawLG(v, 2, &lg));
3971   if (!n) {
3972     prev = rnorm;
3973     PetscCall(PetscDrawLGReset(lg));
3974   }
3975   PetscCall(PetscDrawLGGetDraw(lg, &draw));
3976   PetscCall(PetscDrawSetTitle(draw, "(norm -oldnorm)/oldnorm"));
3977   x = (PetscReal)n;
3978   y = (prev - rnorm) / prev;
3979   PetscCall(PetscDrawLGAddPoint(lg, &x, &y));
3980   if (n < 20 || !(n % 5) || snes->reason) {
3981     PetscCall(PetscDrawLGDraw(lg));
3982     PetscCall(PetscDrawLGSave(lg));
3983   }
3984 
3985   PetscCall(PetscViewerDrawGetDrawLG(v, 3, &lg));
3986   if (!n) PetscCall(PetscDrawLGReset(lg));
3987   PetscCall(PetscDrawLGGetDraw(lg, &draw));
3988   PetscCall(PetscDrawSetTitle(draw, "(norm -oldnorm)/oldnorm*(% > .2 max)"));
3989   x = (PetscReal)n;
3990   y = (prev - rnorm) / (prev * per);
3991   if (n > 2) { /*skip initial crazy value */
3992     PetscCall(PetscDrawLGAddPoint(lg, &x, &y));
3993   }
3994   if (n < 20 || !(n % 5) || snes->reason) {
3995     PetscCall(PetscDrawLGDraw(lg));
3996     PetscCall(PetscDrawLGSave(lg));
3997   }
3998   prev = rnorm;
3999   PetscFunctionReturn(PETSC_SUCCESS);
4000 }
4001 
4002 /*@
4003   SNESConverged - Run the convergence test and update the `SNESConvergedReason`.
4004 
4005   Collective
4006 
4007   Input Parameters:
4008 + snes  - the `SNES` context
4009 . it    - current iteration
4010 . xnorm - 2-norm of current iterate
4011 . snorm - 2-norm of current step
4012 - fnorm - 2-norm of function
4013 
4014   Level: developer
4015 
4016   Note:
4017   This routine is called by the `SNESSolve()` implementations.
4018   It does not typically need to be called by the user.
4019 
4020 .seealso: [](ch_snes), `SNES`, `SNESSolve`, `SNESSetConvergenceTest()`, `SNESGetConvergenceTest()`
4021 @*/
4022 PetscErrorCode SNESConverged(SNES snes, PetscInt it, PetscReal xnorm, PetscReal snorm, PetscReal fnorm)
4023 {
4024   PetscFunctionBegin;
4025   if (!snes->reason) {
4026     if (snes->normschedule == SNES_NORM_ALWAYS) PetscUseTypeMethod(snes, converged, it, xnorm, snorm, fnorm, &snes->reason, snes->cnvP);
4027     if (it == snes->max_its && !snes->reason) {
4028       if (snes->normschedule == SNES_NORM_ALWAYS) {
4029         PetscCall(PetscInfo(snes, "Maximum number of iterations has been reached: %" PetscInt_FMT "\n", snes->max_its));
4030         snes->reason = SNES_DIVERGED_MAX_IT;
4031       } else snes->reason = SNES_CONVERGED_ITS;
4032     }
4033   }
4034   PetscFunctionReturn(PETSC_SUCCESS);
4035 }
4036 
4037 /*@
4038   SNESMonitor - runs the user provided monitor routines, if they exist
4039 
4040   Collective
4041 
4042   Input Parameters:
4043 + snes  - nonlinear solver context obtained from `SNESCreate()`
4044 . iter  - iteration number
4045 - rnorm - relative norm of the residual
4046 
4047   Level: developer
4048 
4049   Note:
4050   This routine is called by the `SNESSolve()` implementations.
4051   It does not typically need to be called by the user.
4052 
4053 .seealso: [](ch_snes), `SNES`, `SNESMonitorSet()`
4054 @*/
4055 PetscErrorCode SNESMonitor(SNES snes, PetscInt iter, PetscReal rnorm)
4056 {
4057   PetscInt i, n = snes->numbermonitors;
4058 
4059   PetscFunctionBegin;
4060   if (n > 0) SNESCheckFunctionNorm(snes, rnorm);
4061   PetscCall(VecLockReadPush(snes->vec_sol));
4062   for (i = 0; i < n; i++) PetscCall((*snes->monitor[i])(snes, iter, rnorm, snes->monitorcontext[i]));
4063   PetscCall(VecLockReadPop(snes->vec_sol));
4064   PetscFunctionReturn(PETSC_SUCCESS);
4065 }
4066 
4067 /* ------------ Routines to set performance monitoring options ----------- */
4068 
4069 /*MC
4070     SNESMonitorFunction - functional form passed to `SNESMonitorSet()` to monitor convergence of nonlinear solver
4071 
4072      Synopsis:
4073      #include <petscsnes.h>
4074     PetscErrorCode SNESMonitorFunction(SNES snes, PetscInt its, PetscReal norm, void *mctx)
4075 
4076      Collective
4077 
4078     Input Parameters:
4079 +    snes - the `SNES` context
4080 .    its - iteration number
4081 .    norm - 2-norm function value (may be estimated)
4082 -    mctx - [optional] monitoring context
4083 
4084    Level: advanced
4085 
4086 .seealso: [](ch_snes), `SNESMonitorSet()`, `SNESMonitorSet()`, `SNESMonitorGet()`
4087 M*/
4088 
4089 /*@C
4090   SNESMonitorSet - Sets an ADDITIONAL function that is to be used at every
4091   iteration of the nonlinear solver to display the iteration's
4092   progress.
4093 
4094   Logically Collective
4095 
4096   Input Parameters:
4097 + snes           - the `SNES` context
4098 . f              - the monitor function,  for the calling sequence see `SNESMonitorFunction`
4099 . mctx           - [optional] user-defined context for private data for the monitor routine (use `NULL` if no context is desired)
4100 - monitordestroy - [optional] routine that frees monitor context (may be `NULL`)
4101 
4102   Options Database Keys:
4103 + -snes_monitor               - sets `SNESMonitorDefault()`
4104 . -snes_monitor draw::draw_lg - sets line graph monitor,
4105 - -snes_monitor_cancel        - cancels all monitors that have been hardwired into a code by calls to `SNESMonitorSet()`, but does not cancel those set via
4106                                 the options database.
4107 
4108   Level: intermediate
4109 
4110   Note:
4111   Several different monitoring routines may be set by calling
4112   `SNESMonitorSet()` multiple times; all will be called in the
4113   order in which they were set.
4114 
4115   Fortran Note:
4116   Only a single monitor function can be set for each `SNES` object
4117 
4118 .seealso: [](ch_snes), `SNES`, `SNESSolve()`, `SNESMonitorDefault()`, `SNESMonitorCancel()`, `SNESMonitorFunction`
4119 @*/
4120 PetscErrorCode SNESMonitorSet(SNES snes, PetscErrorCode (*f)(SNES, PetscInt, PetscReal, void *), void *mctx, PetscErrorCode (*monitordestroy)(void **))
4121 {
4122   PetscInt  i;
4123   PetscBool identical;
4124 
4125   PetscFunctionBegin;
4126   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
4127   for (i = 0; i < snes->numbermonitors; i++) {
4128     PetscCall(PetscMonitorCompare((PetscErrorCode(*)(void))f, mctx, monitordestroy, (PetscErrorCode(*)(void))snes->monitor[i], snes->monitorcontext[i], snes->monitordestroy[i], &identical));
4129     if (identical) PetscFunctionReturn(PETSC_SUCCESS);
4130   }
4131   PetscCheck(snes->numbermonitors < MAXSNESMONITORS, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Too many monitors set");
4132   snes->monitor[snes->numbermonitors]          = f;
4133   snes->monitordestroy[snes->numbermonitors]   = monitordestroy;
4134   snes->monitorcontext[snes->numbermonitors++] = (void *)mctx;
4135   PetscFunctionReturn(PETSC_SUCCESS);
4136 }
4137 
4138 /*@
4139   SNESMonitorCancel - Clears all the monitor functions for a `SNES` object.
4140 
4141   Logically Collective
4142 
4143   Input Parameter:
4144 . snes - the `SNES` context
4145 
4146   Options Database Key:
4147 . -snes_monitor_cancel - cancels all monitors that have been hardwired
4148     into a code by calls to `SNESMonitorSet()`, but does not cancel those
4149     set via the options database
4150 
4151   Level: intermediate
4152 
4153   Note:
4154   There is no way to clear one specific monitor from a `SNES` object.
4155 
4156 .seealso: [](ch_snes), `SNES`, `SNESMonitorGet()`, `SNESMonitorDefault()`, `SNESMonitorSet()`
4157 @*/
4158 PetscErrorCode SNESMonitorCancel(SNES snes)
4159 {
4160   PetscInt i;
4161 
4162   PetscFunctionBegin;
4163   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
4164   for (i = 0; i < snes->numbermonitors; i++) {
4165     if (snes->monitordestroy[i]) PetscCall((*snes->monitordestroy[i])(&snes->monitorcontext[i]));
4166   }
4167   snes->numbermonitors = 0;
4168   PetscFunctionReturn(PETSC_SUCCESS);
4169 }
4170 
4171 /*MC
4172     SNESConvergenceTestFunction - functional form used for testing of convergence of nonlinear solver
4173 
4174      Synopsis:
4175      #include <petscsnes.h>
4176      PetscErrorCode SNESConvergenceTest(SNES snes, PetscInt it, PetscReal xnorm, PetscReal gnorm, PetscReal f, SNESConvergedReason *reason, void *cctx)
4177 
4178      Collective
4179 
4180     Input Parameters:
4181 +    snes - the `SNES` context
4182 .    it - current iteration (0 is the first and is before any Newton step)
4183 .    xnorm - 2-norm of current iterate
4184 .    gnorm - 2-norm of current step
4185 .    f - 2-norm of function
4186 -    cctx - [optional] convergence context
4187 
4188     Output Parameter:
4189 .    reason - reason for convergence/divergence, only needs to be set when convergence or divergence is detected
4190 
4191    Level: intermediate
4192 
4193 .seealso: [](ch_snes), `SNES`, `SNESSolve`, `SNESSetConvergenceTest()`, `SNESGetConvergenceTest()`
4194 M*/
4195 
4196 /*@C
4197   SNESSetConvergenceTest - Sets the function that is to be used
4198   to test for convergence of the nonlinear iterative solution.
4199 
4200   Logically Collective
4201 
4202   Input Parameters:
4203 + snes                        - the `SNES` context
4204 . SNESConvergenceTestFunction - routine to test for convergence
4205 . cctx                        - [optional] context for private data for the convergence routine  (may be `NULL`)
4206 - destroy                     - [optional] destructor for the context (may be `NULL`; `PETSC_NULL_FUNCTION` in Fortran)
4207 
4208   Level: advanced
4209 
4210 .seealso: [](ch_snes), `SNES`, `SNESConvergedDefault()`, `SNESConvergedSkip()`, `SNESConvergenceTestFunction`
4211 @*/
4212 PetscErrorCode SNESSetConvergenceTest(SNES snes, PetscErrorCode (*SNESConvergenceTestFunction)(SNES, PetscInt, PetscReal, PetscReal, PetscReal, SNESConvergedReason *, void *), void *cctx, PetscErrorCode (*destroy)(void *))
4213 {
4214   PetscFunctionBegin;
4215   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
4216   if (!SNESConvergenceTestFunction) SNESConvergenceTestFunction = SNESConvergedSkip;
4217   if (snes->ops->convergeddestroy) PetscCall((*snes->ops->convergeddestroy)(snes->cnvP));
4218   snes->ops->converged        = SNESConvergenceTestFunction;
4219   snes->ops->convergeddestroy = destroy;
4220   snes->cnvP                  = cctx;
4221   PetscFunctionReturn(PETSC_SUCCESS);
4222 }
4223 
4224 /*@
4225   SNESGetConvergedReason - Gets the reason the `SNES` iteration was stopped.
4226 
4227   Not Collective
4228 
4229   Input Parameter:
4230 . snes - the `SNES` context
4231 
4232   Output Parameter:
4233 . reason - negative value indicates diverged, positive value converged, see `SNESConvergedReason` for the individual convergence tests for complete lists
4234 
4235   Options Database Key:
4236 . -snes_converged_reason - prints the reason to standard out
4237 
4238   Level: intermediate
4239 
4240   Note:
4241   Should only be called after the call the `SNESSolve()` is complete, if it is called earlier it returns the value `SNES__CONVERGED_ITERATING`.
4242 
4243 .seealso: [](ch_snes), `SNESSolve()`, `SNESSetConvergenceTest()`, `SNESSetConvergedReason()`, `SNESConvergedReason`, `SNESGetConvergedReasonString()`
4244 @*/
4245 PetscErrorCode SNESGetConvergedReason(SNES snes, SNESConvergedReason *reason)
4246 {
4247   PetscFunctionBegin;
4248   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
4249   PetscAssertPointer(reason, 2);
4250   *reason = snes->reason;
4251   PetscFunctionReturn(PETSC_SUCCESS);
4252 }
4253 
4254 /*@C
4255   SNESGetConvergedReasonString - Return a human readable string for `SNESConvergedReason`
4256 
4257   Not Collective
4258 
4259   Input Parameter:
4260 . snes - the `SNES` context
4261 
4262   Output Parameter:
4263 . strreason - a human readable string that describes `SNES` converged reason
4264 
4265   Level: beginner
4266 
4267 .seealso: [](ch_snes), `SNES`, `SNESGetConvergedReason()`
4268 @*/
4269 PetscErrorCode SNESGetConvergedReasonString(SNES snes, const char **strreason)
4270 {
4271   PetscFunctionBegin;
4272   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
4273   PetscAssertPointer(strreason, 2);
4274   *strreason = SNESConvergedReasons[snes->reason];
4275   PetscFunctionReturn(PETSC_SUCCESS);
4276 }
4277 
4278 /*@
4279   SNESSetConvergedReason - Sets the reason the `SNES` iteration was stopped.
4280 
4281   Not Collective
4282 
4283   Input Parameters:
4284 + snes   - the `SNES` context
4285 - reason - negative value indicates diverged, positive value converged, see `SNESConvergedReason` or the
4286             manual pages for the individual convergence tests for complete lists
4287 
4288   Level: developer
4289 
4290   Developer Note:
4291   Called inside the various `SNESSolve()` implementations
4292 
4293 .seealso: [](ch_snes), `SNESGetConvergedReason()`, `SNESSetConvergenceTest()`, `SNESConvergedReason`
4294 @*/
4295 PetscErrorCode SNESSetConvergedReason(SNES snes, SNESConvergedReason reason)
4296 {
4297   PetscFunctionBegin;
4298   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
4299   PetscCheck(!snes->errorifnotconverged || reason > 0, PetscObjectComm((PetscObject)snes), PETSC_ERR_PLIB, "SNES code should have previously errored due to negative reason");
4300   snes->reason = reason;
4301   PetscFunctionReturn(PETSC_SUCCESS);
4302 }
4303 
4304 /*@
4305   SNESSetConvergenceHistory - Sets the arrays used to hold the convergence history.
4306 
4307   Logically Collective
4308 
4309   Input Parameters:
4310 + snes  - iterative context obtained from `SNESCreate()`
4311 . a     - array to hold history, this array will contain the function norms computed at each step
4312 . its   - integer array holds the number of linear iterations for each solve.
4313 . na    - size of `a` and `its`
4314 - reset - `PETSC_TRUE` indicates each new nonlinear solve resets the history counter to zero,
4315            else it continues storing new values for new nonlinear solves after the old ones
4316 
4317   Level: intermediate
4318 
4319   Notes:
4320   If 'a' and 'its' are `NULL` then space is allocated for the history. If 'na' `PETSC_DECIDE` or `PETSC_DEFAULT` then a
4321   default array of length 10000 is allocated.
4322 
4323   This routine is useful, e.g., when running a code for purposes
4324   of accurate performance monitoring, when no I/O should be done
4325   during the section of code that is being timed.
4326 
4327   If the arrays run out of space after a number of iterations then the later values are not saved in the history
4328 
4329 .seealso: [](ch_snes), `SNES`, `SNESSolve()`, `SNESGetConvergenceHistory()`
4330 @*/
4331 PetscErrorCode SNESSetConvergenceHistory(SNES snes, PetscReal a[], PetscInt its[], PetscInt na, PetscBool reset)
4332 {
4333   PetscFunctionBegin;
4334   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
4335   if (a) PetscAssertPointer(a, 2);
4336   if (its) PetscAssertPointer(its, 3);
4337   if (!a) {
4338     if (na == PETSC_DECIDE || na == PETSC_DEFAULT) na = 1000;
4339     PetscCall(PetscCalloc2(na, &a, na, &its));
4340     snes->conv_hist_alloc = PETSC_TRUE;
4341   }
4342   snes->conv_hist       = a;
4343   snes->conv_hist_its   = its;
4344   snes->conv_hist_max   = (size_t)na;
4345   snes->conv_hist_len   = 0;
4346   snes->conv_hist_reset = reset;
4347   PetscFunctionReturn(PETSC_SUCCESS);
4348 }
4349 
4350 #if defined(PETSC_HAVE_MATLAB)
4351   #include <engine.h> /* MATLAB include file */
4352   #include <mex.h>    /* MATLAB include file */
4353 
4354 PETSC_EXTERN mxArray *SNESGetConvergenceHistoryMatlab(SNES snes)
4355 {
4356   mxArray   *mat;
4357   PetscInt   i;
4358   PetscReal *ar;
4359 
4360   mat = mxCreateDoubleMatrix(snes->conv_hist_len, 1, mxREAL);
4361   ar  = (PetscReal *)mxGetData(mat);
4362   for (i = 0; i < snes->conv_hist_len; i++) ar[i] = snes->conv_hist[i];
4363   return mat;
4364 }
4365 #endif
4366 
4367 /*@C
4368   SNESGetConvergenceHistory - Gets the arrays used to hold the convergence history.
4369 
4370   Not Collective
4371 
4372   Input Parameter:
4373 . snes - iterative context obtained from `SNESCreate()`
4374 
4375   Output Parameters:
4376 + a   - array to hold history, usually was set with `SNESSetConvergenceHistory()`
4377 . its - integer array holds the number of linear iterations (or
4378          negative if not converged) for each solve.
4379 - na  - size of `a` and `its`
4380 
4381   Level: intermediate
4382 
4383   Note:
4384   This routine is useful, e.g., when running a code for purposes
4385   of accurate performance monitoring, when no I/O should be done
4386   during the section of code that is being timed.
4387 
4388   Fortran Note:
4389   The calling sequence for this routine in Fortran is
4390 .vb
4391     call SNESGetConvergenceHistory(SNES snes, integer na, integer ierr)
4392 .ve
4393 
4394 .seealso: [](ch_snes), `SNES`, `SNESSolve()`, `SNESSetConvergenceHistory()`
4395 @*/
4396 PetscErrorCode SNESGetConvergenceHistory(SNES snes, PetscReal *a[], PetscInt *its[], PetscInt *na)
4397 {
4398   PetscFunctionBegin;
4399   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
4400   if (a) *a = snes->conv_hist;
4401   if (its) *its = snes->conv_hist_its;
4402   if (na) *na = (PetscInt)snes->conv_hist_len;
4403   PetscFunctionReturn(PETSC_SUCCESS);
4404 }
4405 
4406 /*@C
4407   SNESSetUpdate - Sets the general-purpose update function called
4408   at the beginning of every iteration of the nonlinear solve. Specifically
4409   it is called just before the Jacobian is "evaluated" and after the function
4410   evaluation.
4411 
4412   Logically Collective
4413 
4414   Input Parameters:
4415 + snes - The nonlinear solver context
4416 - func - The update function; for calling sequence see `SNESUpdateFn`
4417 
4418   Level: advanced
4419 
4420   Notes:
4421   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
4422   to `SNESSetFunction()`, or `SNESSetPicard()`
4423   This is not used by most users, and it is intended to provide a general hook that is run
4424   right before the direction step is computed.
4425   Users are free to modify the current residual vector,
4426   the current linearization point, or any other vector associated to the specific solver used.
4427   If such modifications take place, it is the user responsibility to update all the relevant
4428   vectors.
4429 
4430   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.
4431 
4432 .seealso: [](ch_snes), `SNES`, `SNESSolve()`, `SNESSetJacobian()`, `SNESLineSearchSetPreCheck()`, `SNESLineSearchSetPostCheck()`, `SNESNewtonTRSetPreCheck()`, `SNESNewtonTRSetPostCheck()`,
4433          `SNESMonitorSet()`
4434 @*/
4435 PetscErrorCode SNESSetUpdate(SNES snes, SNESUpdateFn *func)
4436 {
4437   PetscFunctionBegin;
4438   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
4439   snes->ops->update = func;
4440   PetscFunctionReturn(PETSC_SUCCESS);
4441 }
4442 
4443 /*@
4444   SNESConvergedReasonView - Displays the reason a `SNES` solve converged or diverged to a viewer
4445 
4446   Collective
4447 
4448   Input Parameters:
4449 + snes   - iterative context obtained from `SNESCreate()`
4450 - viewer - the viewer to display the reason
4451 
4452   Options Database Keys:
4453 + -snes_converged_reason          - print reason for converged or diverged, also prints number of iterations
4454 - -snes_converged_reason ::failed - only print reason and number of iterations when diverged
4455 
4456   Level: beginner
4457 
4458   Note:
4459   To change the format of the output call `PetscViewerPushFormat`(viewer,format) before this call. Use `PETSC_VIEWER_DEFAULT` for the default,
4460   use `PETSC_VIEWER_FAILED` to only display a reason if it fails.
4461 
4462 .seealso: [](ch_snes), `SNESConvergedReason`, `PetscViewer`, `SNES`,
4463           `SNESCreate()`, `SNESSetUp()`, `SNESDestroy()`, `SNESSetTolerances()`, `SNESConvergedDefault()`, `SNESGetConvergedReason()`,
4464           `SNESConvergedReasonViewFromOptions()`,
4465           `PetscViewerPushFormat()`, `PetscViewerPopFormat()`
4466 @*/
4467 PetscErrorCode SNESConvergedReasonView(SNES snes, PetscViewer viewer)
4468 {
4469   PetscViewerFormat format;
4470   PetscBool         isAscii;
4471 
4472   PetscFunctionBegin;
4473   if (!viewer) viewer = PETSC_VIEWER_STDOUT_(PetscObjectComm((PetscObject)snes));
4474   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &isAscii));
4475   if (isAscii) {
4476     PetscCall(PetscViewerGetFormat(viewer, &format));
4477     PetscCall(PetscViewerASCIIAddTab(viewer, ((PetscObject)snes)->tablevel + 1));
4478     if (format == PETSC_VIEWER_ASCII_INFO_DETAIL) {
4479       DM       dm;
4480       Vec      u;
4481       PetscDS  prob;
4482       PetscInt Nf, f;
4483       PetscErrorCode (**exactSol)(PetscInt, PetscReal, const PetscReal[], PetscInt, PetscScalar[], void *);
4484       void    **exactCtx;
4485       PetscReal error;
4486 
4487       PetscCall(SNESGetDM(snes, &dm));
4488       PetscCall(SNESGetSolution(snes, &u));
4489       PetscCall(DMGetDS(dm, &prob));
4490       PetscCall(PetscDSGetNumFields(prob, &Nf));
4491       PetscCall(PetscMalloc2(Nf, &exactSol, Nf, &exactCtx));
4492       for (f = 0; f < Nf; ++f) PetscCall(PetscDSGetExactSolution(prob, f, &exactSol[f], &exactCtx[f]));
4493       PetscCall(DMComputeL2Diff(dm, 0.0, exactSol, exactCtx, u, &error));
4494       PetscCall(PetscFree2(exactSol, exactCtx));
4495       if (error < 1.0e-11) PetscCall(PetscViewerASCIIPrintf(viewer, "L_2 Error: < 1.0e-11\n"));
4496       else PetscCall(PetscViewerASCIIPrintf(viewer, "L_2 Error: %g\n", (double)error));
4497     }
4498     if (snes->reason > 0 && format != PETSC_VIEWER_FAILED) {
4499       if (((PetscObject)snes)->prefix) {
4500         PetscCall(PetscViewerASCIIPrintf(viewer, "Nonlinear %s solve converged due to %s iterations %" PetscInt_FMT "\n", ((PetscObject)snes)->prefix, SNESConvergedReasons[snes->reason], snes->iter));
4501       } else {
4502         PetscCall(PetscViewerASCIIPrintf(viewer, "Nonlinear solve converged due to %s iterations %" PetscInt_FMT "\n", SNESConvergedReasons[snes->reason], snes->iter));
4503       }
4504     } else if (snes->reason <= 0) {
4505       if (((PetscObject)snes)->prefix) {
4506         PetscCall(PetscViewerASCIIPrintf(viewer, "Nonlinear %s solve did not converge due to %s iterations %" PetscInt_FMT "\n", ((PetscObject)snes)->prefix, SNESConvergedReasons[snes->reason], snes->iter));
4507       } else {
4508         PetscCall(PetscViewerASCIIPrintf(viewer, "Nonlinear solve did not converge due to %s iterations %" PetscInt_FMT "\n", SNESConvergedReasons[snes->reason], snes->iter));
4509       }
4510     }
4511     PetscCall(PetscViewerASCIISubtractTab(viewer, ((PetscObject)snes)->tablevel + 1));
4512   }
4513   PetscFunctionReturn(PETSC_SUCCESS);
4514 }
4515 
4516 /*@C
4517   SNESConvergedReasonViewSet - Sets an ADDITIONAL function that is to be used at the
4518   end of the nonlinear solver to display the convergence reason of the nonlinear solver.
4519 
4520   Logically Collective
4521 
4522   Input Parameters:
4523 + snes              - the `SNES` context
4524 . f                 - the `SNESConvergedReason` view function
4525 . vctx              - [optional] user-defined context for private data for the `SNESConvergedReason` view function (use `NULL` if no context is desired)
4526 - reasonviewdestroy - [optional] routine that frees the context (may be `NULL`)
4527 
4528   Calling sequence of `f`:
4529 + snes - the `SNES` context
4530 - vctx - [optional] user-defined context for private data for the function
4531 
4532   Calling sequence of `reasonviewerdestroy`:
4533 . vctx - [optional] user-defined context for private data for the function
4534 
4535   Options Database Keys:
4536 + -snes_converged_reason             - sets a default `SNESConvergedReasonView()`
4537 - -snes_converged_reason_view_cancel - cancels all converged reason viewers that have been hardwired into a code by
4538                                        calls to `SNESConvergedReasonViewSet()`, but does not cancel those set via the options database.
4539 
4540   Level: intermediate
4541 
4542   Note:
4543   Several different converged reason view routines may be set by calling
4544   `SNESConvergedReasonViewSet()` multiple times; all will be called in the
4545   order in which they were set.
4546 
4547 .seealso: [](ch_snes), `SNES`, `SNESSolve()`, `SNESConvergedReason`, `SNESGetConvergedReason()`, `SNESConvergedReasonView()`, `SNESConvergedReasonViewCancel()`
4548 @*/
4549 PetscErrorCode SNESConvergedReasonViewSet(SNES snes, PetscErrorCode (*f)(SNES snes, void *vctx), void *vctx, PetscErrorCode (*reasonviewdestroy)(void **vctx))
4550 {
4551   PetscInt  i;
4552   PetscBool identical;
4553 
4554   PetscFunctionBegin;
4555   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
4556   for (i = 0; i < snes->numberreasonviews; i++) {
4557     PetscCall(PetscMonitorCompare((PetscErrorCode(*)(void))f, vctx, reasonviewdestroy, (PetscErrorCode(*)(void))snes->reasonview[i], snes->reasonviewcontext[i], snes->reasonviewdestroy[i], &identical));
4558     if (identical) PetscFunctionReturn(PETSC_SUCCESS);
4559   }
4560   PetscCheck(snes->numberreasonviews < MAXSNESREASONVIEWS, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Too many SNES reasonview set");
4561   snes->reasonview[snes->numberreasonviews]          = f;
4562   snes->reasonviewdestroy[snes->numberreasonviews]   = reasonviewdestroy;
4563   snes->reasonviewcontext[snes->numberreasonviews++] = (void *)vctx;
4564   PetscFunctionReturn(PETSC_SUCCESS);
4565 }
4566 
4567 /*@
4568   SNESConvergedReasonViewFromOptions - Processes command line options to determine if/how a `SNESConvergedReason` is to be viewed at the end of `SNESSolve()`
4569   All the user-provided convergedReasonView routines will be involved as well, if they exist.
4570 
4571   Collective
4572 
4573   Input Parameter:
4574 . snes - the `SNES` object
4575 
4576   Level: advanced
4577 
4578 .seealso: [](ch_snes), `SNES`, `SNESConvergedReason`, `SNESConvergedReasonViewSet()`, `SNESCreate()`, `SNESSetUp()`, `SNESDestroy()`,
4579           `SNESSetTolerances()`, `SNESConvergedDefault()`, `SNESGetConvergedReason()`, `SNESConvergedReasonView()`
4580 @*/
4581 PetscErrorCode SNESConvergedReasonViewFromOptions(SNES snes)
4582 {
4583   PetscViewer       viewer;
4584   PetscBool         flg;
4585   static PetscBool  incall = PETSC_FALSE;
4586   PetscViewerFormat format;
4587   PetscInt          i;
4588 
4589   PetscFunctionBegin;
4590   if (incall) PetscFunctionReturn(PETSC_SUCCESS);
4591   incall = PETSC_TRUE;
4592 
4593   /* All user-provided viewers are called first, if they exist. */
4594   for (i = 0; i < snes->numberreasonviews; i++) PetscCall((*snes->reasonview[i])(snes, snes->reasonviewcontext[i]));
4595 
4596   /* Call PETSc default routine if users ask for it */
4597   PetscCall(PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes), ((PetscObject)snes)->options, ((PetscObject)snes)->prefix, "-snes_converged_reason", &viewer, &format, &flg));
4598   if (flg) {
4599     PetscCall(PetscViewerPushFormat(viewer, format));
4600     PetscCall(SNESConvergedReasonView(snes, viewer));
4601     PetscCall(PetscViewerPopFormat(viewer));
4602     PetscCall(PetscOptionsRestoreViewer(&viewer));
4603   }
4604   incall = PETSC_FALSE;
4605   PetscFunctionReturn(PETSC_SUCCESS);
4606 }
4607 
4608 /*@
4609   SNESSolve - Solves a nonlinear system F(x) = b.
4610 
4611   Collective
4612 
4613   Input Parameters:
4614 + snes - the `SNES` context
4615 . b    - the constant part of the equation F(x) = b, or `NULL` to use zero.
4616 - x    - the solution vector.
4617 
4618   Level: beginner
4619 
4620   Note:
4621   The user should initialize the vector, `x`, with the initial guess
4622   for the nonlinear solve prior to calling `SNESSolve()` or use `SNESSetInitialSolution()`.  In particular,
4623   to employ an initial guess of zero, the user should explicitly set
4624   this vector to zero by calling `VecSet()`.
4625 
4626 .seealso: [](ch_snes), `SNES`, `SNESCreate()`, `SNESDestroy()`, `SNESSetFunction()`, `SNESSetJacobian()`, `SNESSetGridSequence()`, `SNESGetSolution()`,
4627           `SNESNewtonTRSetPreCheck()`, `SNESNewtonTRGetPreCheck()`, `SNESNewtonTRSetPostCheck()`, `SNESNewtonTRGetPostCheck()`,
4628           `SNESLineSearchSetPostCheck()`, `SNESLineSearchGetPostCheck()`, `SNESLineSearchSetPreCheck()`, `SNESLineSearchGetPreCheck()`, `SNESSetInitialSolution()`
4629 @*/
4630 PetscErrorCode SNESSolve(SNES snes, Vec b, Vec x)
4631 {
4632   PetscBool flg;
4633   PetscInt  grid;
4634   Vec       xcreated = NULL;
4635   DM        dm;
4636 
4637   PetscFunctionBegin;
4638   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
4639   if (x) PetscValidHeaderSpecific(x, VEC_CLASSID, 3);
4640   if (x) PetscCheckSameComm(snes, 1, x, 3);
4641   if (b) PetscValidHeaderSpecific(b, VEC_CLASSID, 2);
4642   if (b) PetscCheckSameComm(snes, 1, b, 2);
4643 
4644   /* High level operations using the nonlinear solver */
4645   {
4646     PetscViewer       viewer;
4647     PetscViewerFormat format;
4648     PetscInt          num;
4649     PetscBool         flg;
4650     static PetscBool  incall = PETSC_FALSE;
4651 
4652     if (!incall) {
4653       /* Estimate the convergence rate of the discretization */
4654       PetscCall(PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes), ((PetscObject)snes)->options, ((PetscObject)snes)->prefix, "-snes_convergence_estimate", &viewer, &format, &flg));
4655       if (flg) {
4656         PetscConvEst conv;
4657         DM           dm;
4658         PetscReal   *alpha; /* Convergence rate of the solution error for each field in the L_2 norm */
4659         PetscInt     Nf;
4660 
4661         incall = PETSC_TRUE;
4662         PetscCall(SNESGetDM(snes, &dm));
4663         PetscCall(DMGetNumFields(dm, &Nf));
4664         PetscCall(PetscCalloc1(Nf, &alpha));
4665         PetscCall(PetscConvEstCreate(PetscObjectComm((PetscObject)snes), &conv));
4666         PetscCall(PetscConvEstSetSolver(conv, (PetscObject)snes));
4667         PetscCall(PetscConvEstSetFromOptions(conv));
4668         PetscCall(PetscConvEstSetUp(conv));
4669         PetscCall(PetscConvEstGetConvRate(conv, alpha));
4670         PetscCall(PetscViewerPushFormat(viewer, format));
4671         PetscCall(PetscConvEstRateView(conv, alpha, viewer));
4672         PetscCall(PetscViewerPopFormat(viewer));
4673         PetscCall(PetscOptionsRestoreViewer(&viewer));
4674         PetscCall(PetscConvEstDestroy(&conv));
4675         PetscCall(PetscFree(alpha));
4676         incall = PETSC_FALSE;
4677       }
4678       /* Adaptively refine the initial grid */
4679       num = 1;
4680       PetscCall(PetscOptionsGetInt(NULL, ((PetscObject)snes)->prefix, "-snes_adapt_initial", &num, &flg));
4681       if (flg) {
4682         DMAdaptor adaptor;
4683 
4684         incall = PETSC_TRUE;
4685         PetscCall(DMAdaptorCreate(PetscObjectComm((PetscObject)snes), &adaptor));
4686         PetscCall(DMAdaptorSetSolver(adaptor, snes));
4687         PetscCall(DMAdaptorSetSequenceLength(adaptor, num));
4688         PetscCall(DMAdaptorSetFromOptions(adaptor));
4689         PetscCall(DMAdaptorSetUp(adaptor));
4690         PetscCall(DMAdaptorAdapt(adaptor, x, DM_ADAPTATION_INITIAL, &dm, &x));
4691         PetscCall(DMAdaptorDestroy(&adaptor));
4692         incall = PETSC_FALSE;
4693       }
4694       /* Use grid sequencing to adapt */
4695       num = 0;
4696       PetscCall(PetscOptionsGetInt(NULL, ((PetscObject)snes)->prefix, "-snes_adapt_sequence", &num, NULL));
4697       if (num) {
4698         DMAdaptor adaptor;
4699 
4700         incall = PETSC_TRUE;
4701         PetscCall(DMAdaptorCreate(PetscObjectComm((PetscObject)snes), &adaptor));
4702         PetscCall(DMAdaptorSetSolver(adaptor, snes));
4703         PetscCall(DMAdaptorSetSequenceLength(adaptor, num));
4704         PetscCall(DMAdaptorSetFromOptions(adaptor));
4705         PetscCall(DMAdaptorSetUp(adaptor));
4706         PetscCall(DMAdaptorAdapt(adaptor, x, DM_ADAPTATION_SEQUENTIAL, &dm, &x));
4707         PetscCall(DMAdaptorDestroy(&adaptor));
4708         incall = PETSC_FALSE;
4709       }
4710     }
4711   }
4712   if (!x) x = snes->vec_sol;
4713   if (!x) {
4714     PetscCall(SNESGetDM(snes, &dm));
4715     PetscCall(DMCreateGlobalVector(dm, &xcreated));
4716     x = xcreated;
4717   }
4718   PetscCall(SNESViewFromOptions(snes, NULL, "-snes_view_pre"));
4719 
4720   for (grid = 0; grid < snes->gridsequence; grid++) PetscCall(PetscViewerASCIIPushTab(PETSC_VIEWER_STDOUT_(PetscObjectComm((PetscObject)snes))));
4721   for (grid = 0; grid < snes->gridsequence + 1; grid++) {
4722     /* set solution vector */
4723     if (!grid) PetscCall(PetscObjectReference((PetscObject)x));
4724     PetscCall(VecDestroy(&snes->vec_sol));
4725     snes->vec_sol = x;
4726     PetscCall(SNESGetDM(snes, &dm));
4727 
4728     /* set affine vector if provided */
4729     if (b) PetscCall(PetscObjectReference((PetscObject)b));
4730     PetscCall(VecDestroy(&snes->vec_rhs));
4731     snes->vec_rhs = b;
4732 
4733     if (snes->vec_rhs) PetscCheck(snes->vec_func != snes->vec_rhs, PETSC_COMM_SELF, PETSC_ERR_ARG_IDN, "Right hand side vector cannot be function vector");
4734     PetscCheck(snes->vec_func != snes->vec_sol, PETSC_COMM_SELF, PETSC_ERR_ARG_IDN, "Solution vector cannot be function vector");
4735     PetscCheck(snes->vec_rhs != snes->vec_sol, PETSC_COMM_SELF, PETSC_ERR_ARG_IDN, "Solution vector cannot be right-hand side vector");
4736     if (!snes->vec_sol_update /* && snes->vec_sol */) PetscCall(VecDuplicate(snes->vec_sol, &snes->vec_sol_update));
4737     PetscCall(DMShellSetGlobalVector(dm, snes->vec_sol));
4738     PetscCall(SNESSetUp(snes));
4739 
4740     if (!grid) {
4741       if (snes->ops->computeinitialguess) PetscCallBack("SNES callback compute initial guess", (*snes->ops->computeinitialguess)(snes, snes->vec_sol, snes->initialguessP));
4742     }
4743 
4744     if (snes->conv_hist_reset) snes->conv_hist_len = 0;
4745     if (snes->counters_reset) {
4746       snes->nfuncs      = 0;
4747       snes->linear_its  = 0;
4748       snes->numFailures = 0;
4749     }
4750 
4751     snes->reason = SNES_CONVERGED_ITERATING;
4752     PetscCall(PetscLogEventBegin(SNES_Solve, snes, 0, 0, 0));
4753     PetscUseTypeMethod(snes, solve);
4754     PetscCall(PetscLogEventEnd(SNES_Solve, snes, 0, 0, 0));
4755     PetscCheck(snes->reason, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Internal error, solver %s returned without setting converged reason", ((PetscObject)snes)->type_name);
4756     snes->domainerror = PETSC_FALSE; /* clear the flag if it has been set */
4757 
4758     if (snes->lagjac_persist) snes->jac_iter += snes->iter;
4759     if (snes->lagpre_persist) snes->pre_iter += snes->iter;
4760 
4761     PetscCall(PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes), ((PetscObject)snes)->options, ((PetscObject)snes)->prefix, "-snes_test_local_min", NULL, NULL, &flg));
4762     if (flg && !PetscPreLoadingOn) PetscCall(SNESTestLocalMin(snes));
4763     /* Call converged reason views. This may involve user-provided viewers as well */
4764     PetscCall(SNESConvergedReasonViewFromOptions(snes));
4765 
4766     if (snes->errorifnotconverged) PetscCheck(snes->reason >= 0, PetscObjectComm((PetscObject)snes), PETSC_ERR_NOT_CONVERGED, "SNESSolve has not converged");
4767     if (snes->reason < 0) break;
4768     if (grid < snes->gridsequence) {
4769       DM  fine;
4770       Vec xnew;
4771       Mat interp;
4772 
4773       PetscCall(DMRefine(snes->dm, PetscObjectComm((PetscObject)snes), &fine));
4774       PetscCheck(fine, PetscObjectComm((PetscObject)snes), PETSC_ERR_ARG_INCOMP, "DMRefine() did not perform any refinement, cannot continue grid sequencing");
4775       PetscCall(DMCreateInterpolation(snes->dm, fine, &interp, NULL));
4776       PetscCall(DMCreateGlobalVector(fine, &xnew));
4777       PetscCall(MatInterpolate(interp, x, xnew));
4778       PetscCall(DMInterpolate(snes->dm, interp, fine));
4779       PetscCall(MatDestroy(&interp));
4780       x = xnew;
4781 
4782       PetscCall(SNESReset(snes));
4783       PetscCall(SNESSetDM(snes, fine));
4784       PetscCall(SNESResetFromOptions(snes));
4785       PetscCall(DMDestroy(&fine));
4786       PetscCall(PetscViewerASCIIPopTab(PETSC_VIEWER_STDOUT_(PetscObjectComm((PetscObject)snes))));
4787     }
4788   }
4789   PetscCall(SNESViewFromOptions(snes, NULL, "-snes_view"));
4790   PetscCall(VecViewFromOptions(snes->vec_sol, (PetscObject)snes, "-snes_view_solution"));
4791   PetscCall(DMMonitor(snes->dm));
4792   PetscCall(SNESMonitorPauseFinal_Internal(snes));
4793 
4794   PetscCall(VecDestroy(&xcreated));
4795   PetscCall(PetscObjectSAWsBlock((PetscObject)snes));
4796   PetscFunctionReturn(PETSC_SUCCESS);
4797 }
4798 
4799 /* --------- Internal routines for SNES Package --------- */
4800 
4801 /*@
4802   SNESSetType - Sets the method for the nonlinear solver.
4803 
4804   Collective
4805 
4806   Input Parameters:
4807 + snes - the `SNES` context
4808 - type - a known method
4809 
4810   Options Database Key:
4811 . -snes_type <type> - Sets the method; use -help for a list
4812    of available methods (for instance, newtonls or newtontr)
4813 
4814   Level: intermediate
4815 
4816   Notes:
4817   See "petsc/include/petscsnes.h" for available methods (for instance)
4818 +    `SNESNEWTONLS` - Newton's method with line search
4819   (systems of nonlinear equations)
4820 -    `SNESNEWTONTR` - Newton's method with trust region
4821   (systems of nonlinear equations)
4822 
4823   Normally, it is best to use the `SNESSetFromOptions()` command and then
4824   set the `SNES` solver type from the options database rather than by using
4825   this routine.  Using the options database provides the user with
4826   maximum flexibility in evaluating the many nonlinear solvers.
4827   The `SNESSetType()` routine is provided for those situations where it
4828   is necessary to set the nonlinear solver independently of the command
4829   line or options database.  This might be the case, for example, when
4830   the choice of solver changes during the execution of the program,
4831   and the user's application is taking responsibility for choosing the
4832   appropriate method.
4833 
4834   Developer Note:
4835   `SNESRegister()` adds a constructor for a new `SNESType` to `SNESList`, `SNESSetType()` locates
4836   the constructor in that list and calls it to create the specific object.
4837 
4838 .seealso: [](ch_snes), `SNES`, `SNESSolve()`, `SNESType`, `SNESCreate()`, `SNESDestroy()`, `SNESGetType()`, `SNESSetFromOptions()`
4839 @*/
4840 PetscErrorCode SNESSetType(SNES snes, SNESType type)
4841 {
4842   PetscBool match;
4843   PetscErrorCode (*r)(SNES);
4844 
4845   PetscFunctionBegin;
4846   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
4847   PetscAssertPointer(type, 2);
4848 
4849   PetscCall(PetscObjectTypeCompare((PetscObject)snes, type, &match));
4850   if (match) PetscFunctionReturn(PETSC_SUCCESS);
4851 
4852   PetscCall(PetscFunctionListFind(SNESList, type, &r));
4853   PetscCheck(r, PetscObjectComm((PetscObject)snes), PETSC_ERR_ARG_UNKNOWN_TYPE, "Unable to find requested SNES type %s", type);
4854   /* Destroy the previous private SNES context */
4855   PetscTryTypeMethod(snes, destroy);
4856   /* Reinitialize function pointers in SNESOps structure */
4857   snes->ops->setup          = NULL;
4858   snes->ops->solve          = NULL;
4859   snes->ops->view           = NULL;
4860   snes->ops->setfromoptions = NULL;
4861   snes->ops->destroy        = NULL;
4862 
4863   /* It may happen the user has customized the line search before calling SNESSetType */
4864   if (((PetscObject)snes)->type_name) PetscCall(SNESLineSearchDestroy(&snes->linesearch));
4865 
4866   /* Call the SNESCreate_XXX routine for this particular Nonlinear solver */
4867   snes->setupcalled = PETSC_FALSE;
4868 
4869   PetscCall(PetscObjectChangeTypeName((PetscObject)snes, type));
4870   PetscCall((*r)(snes));
4871   PetscFunctionReturn(PETSC_SUCCESS);
4872 }
4873 
4874 /*@
4875   SNESGetType - Gets the `SNES` method type and name (as a string).
4876 
4877   Not Collective
4878 
4879   Input Parameter:
4880 . snes - nonlinear solver context
4881 
4882   Output Parameter:
4883 . type - `SNES` method (a character string)
4884 
4885   Level: intermediate
4886 
4887 .seealso: [](ch_snes), `SNESSetType()`, `SNESType`, `SNESSetFromOptions()`, `SNES`
4888 @*/
4889 PetscErrorCode SNESGetType(SNES snes, SNESType *type)
4890 {
4891   PetscFunctionBegin;
4892   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
4893   PetscAssertPointer(type, 2);
4894   *type = ((PetscObject)snes)->type_name;
4895   PetscFunctionReturn(PETSC_SUCCESS);
4896 }
4897 
4898 /*@
4899   SNESSetSolution - Sets the solution vector for use by the `SNES` routines.
4900 
4901   Logically Collective
4902 
4903   Input Parameters:
4904 + snes - the `SNES` context obtained from `SNESCreate()`
4905 - u    - the solution vector
4906 
4907   Level: beginner
4908 
4909 .seealso: [](ch_snes), `SNES`, `SNESSolve()`, `SNESGetSolution()`, `Vec`
4910 @*/
4911 PetscErrorCode SNESSetSolution(SNES snes, Vec u)
4912 {
4913   DM dm;
4914 
4915   PetscFunctionBegin;
4916   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
4917   PetscValidHeaderSpecific(u, VEC_CLASSID, 2);
4918   PetscCall(PetscObjectReference((PetscObject)u));
4919   PetscCall(VecDestroy(&snes->vec_sol));
4920 
4921   snes->vec_sol = u;
4922 
4923   PetscCall(SNESGetDM(snes, &dm));
4924   PetscCall(DMShellSetGlobalVector(dm, u));
4925   PetscFunctionReturn(PETSC_SUCCESS);
4926 }
4927 
4928 /*@
4929   SNESGetSolution - Returns the vector where the approximate solution is
4930   stored. This is the fine grid solution when using `SNESSetGridSequence()`.
4931 
4932   Not Collective, but `x` is parallel if `snes` is parallel
4933 
4934   Input Parameter:
4935 . snes - the `SNES` context
4936 
4937   Output Parameter:
4938 . x - the solution
4939 
4940   Level: intermediate
4941 
4942 .seealso: [](ch_snes), `SNESSetSolution()`, `SNESSolve()`, `SNES`, `SNESGetSolutionUpdate()`, `SNESGetFunction()`
4943 @*/
4944 PetscErrorCode SNESGetSolution(SNES snes, Vec *x)
4945 {
4946   PetscFunctionBegin;
4947   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
4948   PetscAssertPointer(x, 2);
4949   *x = snes->vec_sol;
4950   PetscFunctionReturn(PETSC_SUCCESS);
4951 }
4952 
4953 /*@
4954   SNESGetSolutionUpdate - Returns the vector where the solution update is
4955   stored.
4956 
4957   Not Collective, but `x` is parallel if `snes` is parallel
4958 
4959   Input Parameter:
4960 . snes - the `SNES` context
4961 
4962   Output Parameter:
4963 . x - the solution update
4964 
4965   Level: advanced
4966 
4967 .seealso: [](ch_snes), `SNES`, `SNESGetSolution()`, `SNESGetFunction()`
4968 @*/
4969 PetscErrorCode SNESGetSolutionUpdate(SNES snes, Vec *x)
4970 {
4971   PetscFunctionBegin;
4972   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
4973   PetscAssertPointer(x, 2);
4974   *x = snes->vec_sol_update;
4975   PetscFunctionReturn(PETSC_SUCCESS);
4976 }
4977 
4978 /*@C
4979   SNESGetFunction - Returns the function that defines the nonlinear system set with `SNESSetFunction()`
4980 
4981   Not Collective, but `r` is parallel if `snes` is parallel. Collective if `r` is requested, but has not been created yet.
4982 
4983   Input Parameter:
4984 . snes - the `SNES` context
4985 
4986   Output Parameters:
4987 + r   - the vector that is used to store residuals (or `NULL` if you don't want it)
4988 . f   - the function (or `NULL` if you don't want it);  for calling sequence see `SNESFunctionFn`
4989 - ctx - the function context (or `NULL` if you don't want it)
4990 
4991   Level: advanced
4992 
4993   Note:
4994   The vector `r` DOES NOT, in general, contain the current value of the `SNES` nonlinear function
4995 
4996 .seealso: [](ch_snes), `SNES`, `SNESSolve()`, `SNESSetFunction()`, `SNESGetSolution()`, `SNESFunctionFn`
4997 @*/
4998 PetscErrorCode SNESGetFunction(SNES snes, Vec *r, SNESFunctionFn **f, void **ctx)
4999 {
5000   DM dm;
5001 
5002   PetscFunctionBegin;
5003   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
5004   if (r) {
5005     if (!snes->vec_func) {
5006       if (snes->vec_rhs) {
5007         PetscCall(VecDuplicate(snes->vec_rhs, &snes->vec_func));
5008       } else if (snes->vec_sol) {
5009         PetscCall(VecDuplicate(snes->vec_sol, &snes->vec_func));
5010       } else if (snes->dm) {
5011         PetscCall(DMCreateGlobalVector(snes->dm, &snes->vec_func));
5012       }
5013     }
5014     *r = snes->vec_func;
5015   }
5016   PetscCall(SNESGetDM(snes, &dm));
5017   PetscCall(DMSNESGetFunction(dm, f, ctx));
5018   PetscFunctionReturn(PETSC_SUCCESS);
5019 }
5020 
5021 /*@C
5022   SNESGetNGS - Returns the function and context set with `SNESSetNGS()`
5023 
5024   Input Parameter:
5025 . snes - the `SNES` context
5026 
5027   Output Parameters:
5028 + f   - the function (or `NULL`) see `SNESNGSFn` for calling sequence
5029 - ctx - the function context (or `NULL`)
5030 
5031   Level: advanced
5032 
5033 .seealso: [](ch_snes), `SNESSetNGS()`, `SNESGetFunction()`, `SNESNGSFn`
5034 @*/
5035 PetscErrorCode SNESGetNGS(SNES snes, SNESNGSFn **f, void **ctx)
5036 {
5037   DM dm;
5038 
5039   PetscFunctionBegin;
5040   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
5041   PetscCall(SNESGetDM(snes, &dm));
5042   PetscCall(DMSNESGetNGS(dm, f, ctx));
5043   PetscFunctionReturn(PETSC_SUCCESS);
5044 }
5045 
5046 /*@
5047   SNESSetOptionsPrefix - Sets the prefix used for searching for all
5048   `SNES` options in the database.
5049 
5050   Logically Collective
5051 
5052   Input Parameters:
5053 + snes   - the `SNES` context
5054 - prefix - the prefix to prepend to all option names
5055 
5056   Level: advanced
5057 
5058   Note:
5059   A hyphen (-) must NOT be given at the beginning of the prefix name.
5060   The first character of all runtime options is AUTOMATICALLY the hyphen.
5061 
5062 .seealso: [](ch_snes), `SNES`, `SNESSetFromOptions()`, `SNESAppendOptionsPrefix()`
5063 @*/
5064 PetscErrorCode SNESSetOptionsPrefix(SNES snes, const char prefix[])
5065 {
5066   PetscFunctionBegin;
5067   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
5068   PetscCall(PetscObjectSetOptionsPrefix((PetscObject)snes, prefix));
5069   if (!snes->ksp) PetscCall(SNESGetKSP(snes, &snes->ksp));
5070   if (snes->linesearch) {
5071     PetscCall(SNESGetLineSearch(snes, &snes->linesearch));
5072     PetscCall(PetscObjectSetOptionsPrefix((PetscObject)snes->linesearch, prefix));
5073   }
5074   PetscCall(KSPSetOptionsPrefix(snes->ksp, prefix));
5075   PetscFunctionReturn(PETSC_SUCCESS);
5076 }
5077 
5078 /*@
5079   SNESAppendOptionsPrefix - Appends to the prefix used for searching for all
5080   `SNES` options in the database.
5081 
5082   Logically Collective
5083 
5084   Input Parameters:
5085 + snes   - the `SNES` context
5086 - prefix - the prefix to prepend to all option names
5087 
5088   Level: advanced
5089 
5090   Note:
5091   A hyphen (-) must NOT be given at the beginning of the prefix name.
5092   The first character of all runtime options is AUTOMATICALLY the hyphen.
5093 
5094 .seealso: [](ch_snes), `SNESGetOptionsPrefix()`, `SNESSetOptionsPrefix()`
5095 @*/
5096 PetscErrorCode SNESAppendOptionsPrefix(SNES snes, const char prefix[])
5097 {
5098   PetscFunctionBegin;
5099   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
5100   PetscCall(PetscObjectAppendOptionsPrefix((PetscObject)snes, prefix));
5101   if (!snes->ksp) PetscCall(SNESGetKSP(snes, &snes->ksp));
5102   if (snes->linesearch) {
5103     PetscCall(SNESGetLineSearch(snes, &snes->linesearch));
5104     PetscCall(PetscObjectAppendOptionsPrefix((PetscObject)snes->linesearch, prefix));
5105   }
5106   PetscCall(KSPAppendOptionsPrefix(snes->ksp, prefix));
5107   PetscFunctionReturn(PETSC_SUCCESS);
5108 }
5109 
5110 /*@
5111   SNESGetOptionsPrefix - Gets the prefix used for searching for all
5112   `SNES` options in the database.
5113 
5114   Not Collective
5115 
5116   Input Parameter:
5117 . snes - the `SNES` context
5118 
5119   Output Parameter:
5120 . prefix - pointer to the prefix string used
5121 
5122   Level: advanced
5123 
5124   Fortran Note:
5125   The user should pass in a string 'prefix' of
5126   sufficient length to hold the prefix.
5127 
5128 .seealso: [](ch_snes), `SNES`, `SNESSetOptionsPrefix()`, `SNESAppendOptionsPrefix()`
5129 @*/
5130 PetscErrorCode SNESGetOptionsPrefix(SNES snes, const char *prefix[])
5131 {
5132   PetscFunctionBegin;
5133   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
5134   PetscCall(PetscObjectGetOptionsPrefix((PetscObject)snes, prefix));
5135   PetscFunctionReturn(PETSC_SUCCESS);
5136 }
5137 
5138 /*@C
5139   SNESRegister - Adds a method to the nonlinear solver package.
5140 
5141   Not Collective
5142 
5143   Input Parameters:
5144 + sname    - name of a new user-defined solver
5145 - function - routine to create method context
5146 
5147   Level: advanced
5148 
5149   Note:
5150   `SNESRegister()` may be called multiple times to add several user-defined solvers.
5151 
5152   Example Usage:
5153 .vb
5154    SNESRegister("my_solver", MySolverCreate);
5155 .ve
5156 
5157   Then, your solver can be chosen with the procedural interface via
5158 $     SNESSetType(snes, "my_solver")
5159   or at runtime via the option
5160 $     -snes_type my_solver
5161 
5162 .seealso: [](ch_snes), `SNESRegisterAll()`, `SNESRegisterDestroy()`
5163 @*/
5164 PetscErrorCode SNESRegister(const char sname[], PetscErrorCode (*function)(SNES))
5165 {
5166   PetscFunctionBegin;
5167   PetscCall(SNESInitializePackage());
5168   PetscCall(PetscFunctionListAdd(&SNESList, sname, function));
5169   PetscFunctionReturn(PETSC_SUCCESS);
5170 }
5171 
5172 PetscErrorCode SNESTestLocalMin(SNES snes)
5173 {
5174   PetscInt    N, i, j;
5175   Vec         u, uh, fh;
5176   PetscScalar value;
5177   PetscReal   norm;
5178 
5179   PetscFunctionBegin;
5180   PetscCall(SNESGetSolution(snes, &u));
5181   PetscCall(VecDuplicate(u, &uh));
5182   PetscCall(VecDuplicate(u, &fh));
5183 
5184   /* currently only works for sequential */
5185   PetscCall(PetscPrintf(PetscObjectComm((PetscObject)snes), "Testing FormFunction() for local min\n"));
5186   PetscCall(VecGetSize(u, &N));
5187   for (i = 0; i < N; i++) {
5188     PetscCall(VecCopy(u, uh));
5189     PetscCall(PetscPrintf(PetscObjectComm((PetscObject)snes), "i = %" PetscInt_FMT "\n", i));
5190     for (j = -10; j < 11; j++) {
5191       value = PetscSign(j) * PetscExpReal(PetscAbs(j) - 10.0);
5192       PetscCall(VecSetValue(uh, i, value, ADD_VALUES));
5193       PetscCall(SNESComputeFunction(snes, uh, fh));
5194       PetscCall(VecNorm(fh, NORM_2, &norm));
5195       PetscCall(PetscPrintf(PetscObjectComm((PetscObject)snes), "       j norm %" PetscInt_FMT " %18.16e\n", j, (double)norm));
5196       value = -value;
5197       PetscCall(VecSetValue(uh, i, value, ADD_VALUES));
5198     }
5199   }
5200   PetscCall(VecDestroy(&uh));
5201   PetscCall(VecDestroy(&fh));
5202   PetscFunctionReturn(PETSC_SUCCESS);
5203 }
5204 
5205 /*@
5206   SNESKSPSetUseEW - Sets `SNES` to the use Eisenstat-Walker method for
5207   computing relative tolerance for linear solvers within an inexact
5208   Newton method.
5209 
5210   Logically Collective
5211 
5212   Input Parameters:
5213 + snes - `SNES` context
5214 - flag - `PETSC_TRUE` or `PETSC_FALSE`
5215 
5216   Options Database Keys:
5217 + -snes_ksp_ew                       - use Eisenstat-Walker method for determining linear system convergence
5218 . -snes_ksp_ew_version ver           - version of  Eisenstat-Walker method
5219 . -snes_ksp_ew_rtol0 <rtol0>         - Sets rtol0
5220 . -snes_ksp_ew_rtolmax <rtolmax>     - Sets rtolmax
5221 . -snes_ksp_ew_gamma <gamma>         - Sets gamma
5222 . -snes_ksp_ew_alpha <alpha>         - Sets alpha
5223 . -snes_ksp_ew_alpha2 <alpha2>       - Sets alpha2
5224 - -snes_ksp_ew_threshold <threshold> - Sets threshold
5225 
5226   Level: advanced
5227 
5228   Note:
5229   The default is to use a constant relative tolerance for
5230   the inner linear solvers.  Alternatively, one can use the
5231   Eisenstat-Walker method {cite}`ew96`, where the relative convergence tolerance
5232   is reset at each Newton iteration according progress of the nonlinear
5233   solver.
5234 
5235 .seealso: [](ch_snes), `KSP`, `SNES`, `SNESKSPGetUseEW()`, `SNESKSPGetParametersEW()`, `SNESKSPSetParametersEW()`
5236 @*/
5237 PetscErrorCode SNESKSPSetUseEW(SNES snes, PetscBool flag)
5238 {
5239   PetscFunctionBegin;
5240   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
5241   PetscValidLogicalCollectiveBool(snes, flag, 2);
5242   snes->ksp_ewconv = flag;
5243   PetscFunctionReturn(PETSC_SUCCESS);
5244 }
5245 
5246 /*@
5247   SNESKSPGetUseEW - Gets if `SNES` is using Eisenstat-Walker method
5248   for computing relative tolerance for linear solvers within an
5249   inexact Newton method.
5250 
5251   Not Collective
5252 
5253   Input Parameter:
5254 . snes - `SNES` context
5255 
5256   Output Parameter:
5257 . flag - `PETSC_TRUE` or `PETSC_FALSE`
5258 
5259   Level: advanced
5260 
5261 .seealso: [](ch_snes), `SNESKSPSetUseEW()`, `SNESKSPGetParametersEW()`, `SNESKSPSetParametersEW()`
5262 @*/
5263 PetscErrorCode SNESKSPGetUseEW(SNES snes, PetscBool *flag)
5264 {
5265   PetscFunctionBegin;
5266   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
5267   PetscAssertPointer(flag, 2);
5268   *flag = snes->ksp_ewconv;
5269   PetscFunctionReturn(PETSC_SUCCESS);
5270 }
5271 
5272 /*@
5273   SNESKSPSetParametersEW - Sets parameters for Eisenstat-Walker
5274   convergence criteria for the linear solvers within an inexact
5275   Newton method.
5276 
5277   Logically Collective
5278 
5279   Input Parameters:
5280 + snes      - `SNES` context
5281 . version   - version 1, 2 (default is 2), 3 or 4
5282 . rtol_0    - initial relative tolerance (0 <= rtol_0 < 1)
5283 . rtol_max  - maximum relative tolerance (0 <= rtol_max < 1)
5284 . gamma     - multiplicative factor for version 2 rtol computation
5285              (0 <= gamma2 <= 1)
5286 . alpha     - power for version 2 rtol computation (1 < alpha <= 2)
5287 . alpha2    - power for safeguard
5288 - threshold - threshold for imposing safeguard (0 < threshold < 1)
5289 
5290   Level: advanced
5291 
5292   Notes:
5293   Version 3 was contributed by Luis Chacon, June 2006.
5294 
5295   Use `PETSC_DEFAULT` to retain the default for any of the parameters.
5296 
5297 .seealso: [](ch_snes), `SNES`, `SNESKSPSetUseEW()`, `SNESKSPGetUseEW()`, `SNESKSPGetParametersEW()`
5298 @*/
5299 PetscErrorCode SNESKSPSetParametersEW(SNES snes, PetscInt version, PetscReal rtol_0, PetscReal rtol_max, PetscReal gamma, PetscReal alpha, PetscReal alpha2, PetscReal threshold)
5300 {
5301   SNESKSPEW *kctx;
5302 
5303   PetscFunctionBegin;
5304   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
5305   kctx = (SNESKSPEW *)snes->kspconvctx;
5306   PetscCheck(kctx, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "No Eisenstat-Walker context existing");
5307   PetscValidLogicalCollectiveInt(snes, version, 2);
5308   PetscValidLogicalCollectiveReal(snes, rtol_0, 3);
5309   PetscValidLogicalCollectiveReal(snes, rtol_max, 4);
5310   PetscValidLogicalCollectiveReal(snes, gamma, 5);
5311   PetscValidLogicalCollectiveReal(snes, alpha, 6);
5312   PetscValidLogicalCollectiveReal(snes, alpha2, 7);
5313   PetscValidLogicalCollectiveReal(snes, threshold, 8);
5314 
5315   if (version != PETSC_DEFAULT) kctx->version = version;
5316   if (rtol_0 != (PetscReal)PETSC_DEFAULT) kctx->rtol_0 = rtol_0;
5317   if (rtol_max != (PetscReal)PETSC_DEFAULT) kctx->rtol_max = rtol_max;
5318   if (gamma != (PetscReal)PETSC_DEFAULT) kctx->gamma = gamma;
5319   if (alpha != (PetscReal)PETSC_DEFAULT) kctx->alpha = alpha;
5320   if (alpha2 != (PetscReal)PETSC_DEFAULT) kctx->alpha2 = alpha2;
5321   if (threshold != (PetscReal)PETSC_DEFAULT) kctx->threshold = threshold;
5322 
5323   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);
5324   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);
5325   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);
5326   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);
5327   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);
5328   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);
5329   PetscFunctionReturn(PETSC_SUCCESS);
5330 }
5331 
5332 /*@
5333   SNESKSPGetParametersEW - Gets parameters for Eisenstat-Walker
5334   convergence criteria for the linear solvers within an inexact
5335   Newton method.
5336 
5337   Not Collective
5338 
5339   Input Parameter:
5340 . snes - `SNES` context
5341 
5342   Output Parameters:
5343 + version   - version 1, 2 (default is 2), 3 or 4
5344 . rtol_0    - initial relative tolerance (0 <= rtol_0 < 1)
5345 . rtol_max  - maximum relative tolerance (0 <= rtol_max < 1)
5346 . gamma     - multiplicative factor for version 2 rtol computation (0 <= gamma2 <= 1)
5347 . alpha     - power for version 2 rtol computation (1 < alpha <= 2)
5348 . alpha2    - power for safeguard
5349 - threshold - threshold for imposing safeguard (0 < threshold < 1)
5350 
5351   Level: advanced
5352 
5353 .seealso: [](ch_snes), `SNES`, `SNESKSPSetUseEW()`, `SNESKSPGetUseEW()`, `SNESKSPSetParametersEW()`
5354 @*/
5355 PetscErrorCode SNESKSPGetParametersEW(SNES snes, PetscInt *version, PetscReal *rtol_0, PetscReal *rtol_max, PetscReal *gamma, PetscReal *alpha, PetscReal *alpha2, PetscReal *threshold)
5356 {
5357   SNESKSPEW *kctx;
5358 
5359   PetscFunctionBegin;
5360   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
5361   kctx = (SNESKSPEW *)snes->kspconvctx;
5362   PetscCheck(kctx, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "No Eisenstat-Walker context existing");
5363   if (version) *version = kctx->version;
5364   if (rtol_0) *rtol_0 = kctx->rtol_0;
5365   if (rtol_max) *rtol_max = kctx->rtol_max;
5366   if (gamma) *gamma = kctx->gamma;
5367   if (alpha) *alpha = kctx->alpha;
5368   if (alpha2) *alpha2 = kctx->alpha2;
5369   if (threshold) *threshold = kctx->threshold;
5370   PetscFunctionReturn(PETSC_SUCCESS);
5371 }
5372 
5373 PetscErrorCode KSPPreSolve_SNESEW(KSP ksp, Vec b, Vec x, void *ctx)
5374 {
5375   SNES       snes = (SNES)ctx;
5376   SNESKSPEW *kctx = (SNESKSPEW *)snes->kspconvctx;
5377   PetscReal  rtol = PETSC_DEFAULT, stol;
5378 
5379   PetscFunctionBegin;
5380   if (!snes->ksp_ewconv) PetscFunctionReturn(PETSC_SUCCESS);
5381   if (!snes->iter) {
5382     rtol = kctx->rtol_0; /* first time in, so use the original user rtol */
5383     PetscCall(VecNorm(snes->vec_func, NORM_2, &kctx->norm_first));
5384   } else {
5385     PetscCheck(kctx->version >= 1 && kctx->version <= 4, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Only versions 1-4 are supported: %" PetscInt_FMT, kctx->version);
5386     if (kctx->version == 1) {
5387       rtol = PetscAbsReal(snes->norm - kctx->lresid_last) / kctx->norm_last;
5388       stol = PetscPowReal(kctx->rtol_last, kctx->alpha2);
5389       if (stol > kctx->threshold) rtol = PetscMax(rtol, stol);
5390     } else if (kctx->version == 2) {
5391       rtol = kctx->gamma * PetscPowReal(snes->norm / kctx->norm_last, kctx->alpha);
5392       stol = kctx->gamma * PetscPowReal(kctx->rtol_last, kctx->alpha);
5393       if (stol > kctx->threshold) rtol = PetscMax(rtol, stol);
5394     } else if (kctx->version == 3) { /* contributed by Luis Chacon, June 2006. */
5395       rtol = kctx->gamma * PetscPowReal(snes->norm / kctx->norm_last, kctx->alpha);
5396       /* safeguard: avoid sharp decrease of rtol */
5397       stol = kctx->gamma * PetscPowReal(kctx->rtol_last, kctx->alpha);
5398       stol = PetscMax(rtol, stol);
5399       rtol = PetscMin(kctx->rtol_0, stol);
5400       /* safeguard: avoid oversolving */
5401       stol = kctx->gamma * (kctx->norm_first * snes->rtol) / snes->norm;
5402       stol = PetscMax(rtol, stol);
5403       rtol = PetscMin(kctx->rtol_0, stol);
5404     } else /* if (kctx->version == 4) */ {
5405       /* H.-B. An et al. Journal of Computational and Applied Mathematics 200 (2007) 47-60 */
5406       PetscReal ared = PetscAbsReal(kctx->norm_last - snes->norm);
5407       PetscReal pred = PetscAbsReal(kctx->norm_last - kctx->lresid_last);
5408       PetscReal rk   = ared / pred;
5409       if (rk < kctx->v4_p1) rtol = 1. - 2. * kctx->v4_p1;
5410       else if (rk < kctx->v4_p2) rtol = kctx->rtol_last;
5411       else if (rk < kctx->v4_p3) rtol = kctx->v4_m1 * kctx->rtol_last;
5412       else rtol = kctx->v4_m2 * kctx->rtol_last;
5413 
5414       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;
5415       kctx->rtol_last_2 = kctx->rtol_last;
5416       kctx->rk_last_2   = kctx->rk_last;
5417       kctx->rk_last     = rk;
5418     }
5419   }
5420   /* safeguard: avoid rtol greater than rtol_max */
5421   rtol = PetscMin(rtol, kctx->rtol_max);
5422   PetscCall(KSPSetTolerances(ksp, rtol, PETSC_DEFAULT, PETSC_DEFAULT, PETSC_DEFAULT));
5423   PetscCall(PetscInfo(snes, "iter %" PetscInt_FMT ", Eisenstat-Walker (version %" PetscInt_FMT ") KSP rtol=%g\n", snes->iter, kctx->version, (double)rtol));
5424   PetscFunctionReturn(PETSC_SUCCESS);
5425 }
5426 
5427 PetscErrorCode KSPPostSolve_SNESEW(KSP ksp, Vec b, Vec x, void *ctx)
5428 {
5429   SNES       snes = (SNES)ctx;
5430   SNESKSPEW *kctx = (SNESKSPEW *)snes->kspconvctx;
5431   PCSide     pcside;
5432   Vec        lres;
5433 
5434   PetscFunctionBegin;
5435   if (!snes->ksp_ewconv) PetscFunctionReturn(PETSC_SUCCESS);
5436   PetscCall(KSPGetTolerances(ksp, &kctx->rtol_last, NULL, NULL, NULL));
5437   kctx->norm_last = snes->norm;
5438   if (kctx->version == 1 || kctx->version == 4) {
5439     PC        pc;
5440     PetscBool getRes;
5441 
5442     PetscCall(KSPGetPC(ksp, &pc));
5443     PetscCall(PetscObjectTypeCompare((PetscObject)pc, PCNONE, &getRes));
5444     if (!getRes) {
5445       KSPNormType normtype;
5446 
5447       PetscCall(KSPGetNormType(ksp, &normtype));
5448       getRes = (PetscBool)(normtype == KSP_NORM_UNPRECONDITIONED);
5449     }
5450     PetscCall(KSPGetPCSide(ksp, &pcside));
5451     if (pcside == PC_RIGHT || getRes) { /* KSP residual is true linear residual */
5452       PetscCall(KSPGetResidualNorm(ksp, &kctx->lresid_last));
5453     } else {
5454       /* KSP residual is preconditioned residual */
5455       /* compute true linear residual norm */
5456       Mat J;
5457       PetscCall(KSPGetOperators(ksp, &J, NULL));
5458       PetscCall(VecDuplicate(b, &lres));
5459       PetscCall(MatMult(J, x, lres));
5460       PetscCall(VecAYPX(lres, -1.0, b));
5461       PetscCall(VecNorm(lres, NORM_2, &kctx->lresid_last));
5462       PetscCall(VecDestroy(&lres));
5463     }
5464   }
5465   PetscFunctionReturn(PETSC_SUCCESS);
5466 }
5467 
5468 /*@
5469   SNESGetKSP - Returns the `KSP` context for a `SNES` solver.
5470 
5471   Not Collective, but if `snes` is parallel, then `ksp` is parallel
5472 
5473   Input Parameter:
5474 . snes - the `SNES` context
5475 
5476   Output Parameter:
5477 . ksp - the `KSP` context
5478 
5479   Level: beginner
5480 
5481   Notes:
5482   The user can then directly manipulate the `KSP` context to set various
5483   options, etc.  Likewise, the user can then extract and manipulate the
5484   `PC` contexts as well.
5485 
5486   Some `SNESType`s do not use a `KSP` but a `KSP` is still returned by this function
5487 
5488 .seealso: [](ch_snes), `SNES`, `KSP`, `PC`, `KSPGetPC()`, `SNESCreate()`, `KSPCreate()`, `SNESSetKSP()`
5489 @*/
5490 PetscErrorCode SNESGetKSP(SNES snes, KSP *ksp)
5491 {
5492   PetscFunctionBegin;
5493   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
5494   PetscAssertPointer(ksp, 2);
5495 
5496   if (!snes->ksp) {
5497     PetscCall(KSPCreate(PetscObjectComm((PetscObject)snes), &snes->ksp));
5498     PetscCall(PetscObjectIncrementTabLevel((PetscObject)snes->ksp, (PetscObject)snes, 1));
5499 
5500     PetscCall(KSPSetPreSolve(snes->ksp, KSPPreSolve_SNESEW, snes));
5501     PetscCall(KSPSetPostSolve(snes->ksp, KSPPostSolve_SNESEW, snes));
5502 
5503     PetscCall(KSPMonitorSetFromOptions(snes->ksp, "-snes_monitor_ksp", "snes_preconditioned_residual", snes));
5504     PetscCall(PetscObjectSetOptions((PetscObject)snes->ksp, ((PetscObject)snes)->options));
5505   }
5506   *ksp = snes->ksp;
5507   PetscFunctionReturn(PETSC_SUCCESS);
5508 }
5509 
5510 #include <petsc/private/dmimpl.h>
5511 /*@
5512   SNESSetDM - Sets the `DM` that may be used by some nonlinear solvers or their underlying preconditioners
5513 
5514   Logically Collective
5515 
5516   Input Parameters:
5517 + snes - the nonlinear solver context
5518 - dm   - the `DM`, cannot be `NULL`
5519 
5520   Level: intermediate
5521 
5522   Note:
5523   A `DM` can only be used for solving one problem at a time because information about the problem is stored on the `DM`,
5524   even when not using interfaces like `DMSNESSetFunction()`.  Use `DMClone()` to get a distinct `DM` when solving different
5525   problems using the same function space.
5526 
5527 .seealso: [](ch_snes), `DM`, `SNES`, `SNESGetDM()`, `KSPSetDM()`, `KSPGetDM()`
5528 @*/
5529 PetscErrorCode SNESSetDM(SNES snes, DM dm)
5530 {
5531   KSP    ksp;
5532   DMSNES sdm;
5533 
5534   PetscFunctionBegin;
5535   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
5536   PetscValidHeaderSpecific(dm, DM_CLASSID, 2);
5537   PetscCall(PetscObjectReference((PetscObject)dm));
5538   if (snes->dm) { /* Move the DMSNES context over to the new DM unless the new DM already has one */
5539     if (snes->dm->dmsnes && !dm->dmsnes) {
5540       PetscCall(DMCopyDMSNES(snes->dm, dm));
5541       PetscCall(DMGetDMSNES(snes->dm, &sdm));
5542       if (sdm->originaldm == snes->dm) sdm->originaldm = dm; /* Grant write privileges to the replacement DM */
5543     }
5544     PetscCall(DMCoarsenHookRemove(snes->dm, DMCoarsenHook_SNESVecSol, DMRestrictHook_SNESVecSol, snes));
5545     PetscCall(DMDestroy(&snes->dm));
5546   }
5547   snes->dm     = dm;
5548   snes->dmAuto = PETSC_FALSE;
5549 
5550   PetscCall(SNESGetKSP(snes, &ksp));
5551   PetscCall(KSPSetDM(ksp, dm));
5552   PetscCall(KSPSetDMActive(ksp, PETSC_FALSE));
5553   if (snes->npc) {
5554     PetscCall(SNESSetDM(snes->npc, snes->dm));
5555     PetscCall(SNESSetNPCSide(snes, snes->npcside));
5556   }
5557   PetscFunctionReturn(PETSC_SUCCESS);
5558 }
5559 
5560 /*@
5561   SNESGetDM - Gets the `DM` that may be used by some solvers/preconditioners
5562 
5563   Not Collective but dm obtained is parallel on snes
5564 
5565   Input Parameter:
5566 . snes - the `SNES` context
5567 
5568   Output Parameter:
5569 . dm - the `DM`
5570 
5571   Level: intermediate
5572 
5573 .seealso: [](ch_snes), `DM`, `SNES`, `SNESSetDM()`, `KSPSetDM()`, `KSPGetDM()`
5574 @*/
5575 PetscErrorCode SNESGetDM(SNES snes, DM *dm)
5576 {
5577   PetscFunctionBegin;
5578   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
5579   if (!snes->dm) {
5580     PetscCall(DMShellCreate(PetscObjectComm((PetscObject)snes), &snes->dm));
5581     snes->dmAuto = PETSC_TRUE;
5582   }
5583   *dm = snes->dm;
5584   PetscFunctionReturn(PETSC_SUCCESS);
5585 }
5586 
5587 /*@
5588   SNESSetNPC - Sets the nonlinear preconditioner to be used.
5589 
5590   Collective
5591 
5592   Input Parameters:
5593 + snes - iterative context obtained from `SNESCreate()`
5594 - npc  - the nonlinear preconditioner object
5595 
5596   Level: developer
5597 
5598   Notes:
5599   Use `SNESGetNPC()` to retrieve the preconditioner context (for example,
5600   to configure it using the API).
5601 
5602   Only some `SNESType` can use a nonlinear preconditioner
5603 
5604 .seealso: [](ch_snes), `SNES`, `SNESNGS`, `SNESFAS`, `SNESGetNPC()`, `SNESHasNPC()`
5605 @*/
5606 PetscErrorCode SNESSetNPC(SNES snes, SNES npc)
5607 {
5608   PetscFunctionBegin;
5609   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
5610   PetscValidHeaderSpecific(npc, SNES_CLASSID, 2);
5611   PetscCheckSameComm(snes, 1, npc, 2);
5612   PetscCall(PetscObjectReference((PetscObject)npc));
5613   PetscCall(SNESDestroy(&snes->npc));
5614   snes->npc = npc;
5615   PetscFunctionReturn(PETSC_SUCCESS);
5616 }
5617 
5618 /*@
5619   SNESGetNPC - Gets a nonlinear preconditioning solver SNES` to be used to precondition the original nonlinear solver.
5620 
5621   Not Collective; but any changes to the obtained the npc object must be applied collectively
5622 
5623   Input Parameter:
5624 . snes - iterative context obtained from `SNESCreate()`
5625 
5626   Output Parameter:
5627 . pc - preconditioner context
5628 
5629   Options Database Key:
5630 . -npc_snes_type <type> - set the type of the `SNES` to use as the nonlinear preconditioner
5631 
5632   Level: developer
5633 
5634   Notes:
5635   If a `SNES` was previously set with `SNESSetNPC()` then that value is returned, otherwise a new `SNES` object is created.
5636 
5637   The (preconditioner) `SNES` returned automatically inherits the same nonlinear function and Jacobian supplied to the original
5638   `SNES`
5639 
5640 .seealso: [](ch_snes), `SNESSetNPC()`, `SNESHasNPC()`, `SNES`, `SNESCreate()`
5641 @*/
5642 PetscErrorCode SNESGetNPC(SNES snes, SNES *pc)
5643 {
5644   const char *optionsprefix;
5645 
5646   PetscFunctionBegin;
5647   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
5648   PetscAssertPointer(pc, 2);
5649   if (!snes->npc) {
5650     void *ctx;
5651 
5652     PetscCall(SNESCreate(PetscObjectComm((PetscObject)snes), &snes->npc));
5653     PetscCall(PetscObjectIncrementTabLevel((PetscObject)snes->npc, (PetscObject)snes, 1));
5654     PetscCall(SNESGetOptionsPrefix(snes, &optionsprefix));
5655     PetscCall(SNESSetOptionsPrefix(snes->npc, optionsprefix));
5656     PetscCall(SNESAppendOptionsPrefix(snes->npc, "npc_"));
5657     if (snes->ops->usercompute) {
5658       PetscCall(SNESSetComputeApplicationContext(snes, snes->ops->usercompute, snes->ops->userdestroy));
5659     } else {
5660       PetscCall(SNESGetApplicationContext(snes, &ctx));
5661       PetscCall(SNESSetApplicationContext(snes->npc, ctx));
5662     }
5663     PetscCall(SNESSetCountersReset(snes->npc, PETSC_FALSE));
5664   }
5665   *pc = snes->npc;
5666   PetscFunctionReturn(PETSC_SUCCESS);
5667 }
5668 
5669 /*@
5670   SNESHasNPC - Returns whether a nonlinear preconditioner exists
5671 
5672   Not Collective
5673 
5674   Input Parameter:
5675 . snes - iterative context obtained from `SNESCreate()`
5676 
5677   Output Parameter:
5678 . has_npc - whether the `SNES` has a nonlinear preconditioner or not
5679 
5680   Level: developer
5681 
5682 .seealso: [](ch_snes), `SNESSetNPC()`, `SNESGetNPC()`
5683 @*/
5684 PetscErrorCode SNESHasNPC(SNES snes, PetscBool *has_npc)
5685 {
5686   PetscFunctionBegin;
5687   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
5688   *has_npc = (PetscBool)(snes->npc ? PETSC_TRUE : PETSC_FALSE);
5689   PetscFunctionReturn(PETSC_SUCCESS);
5690 }
5691 
5692 /*@
5693   SNESSetNPCSide - Sets the nonlinear preconditioning side.
5694 
5695   Logically Collective
5696 
5697   Input Parameter:
5698 . snes - iterative context obtained from `SNESCreate()`
5699 
5700   Output Parameter:
5701 . side - the preconditioning side, where side is one of
5702 .vb
5703       PC_LEFT - left preconditioning
5704       PC_RIGHT - right preconditioning (default for most nonlinear solvers)
5705 .ve
5706 
5707   Options Database Key:
5708 . -snes_npc_side <right,left> - nonlinear preconditioner side
5709 
5710   Level: intermediate
5711 
5712   Note:
5713   `SNESNRICHARDSON` and `SNESNCG` only support left preconditioning.
5714 
5715 .seealso: [](ch_snes), `SNES`, `SNESNRICHARDSON`, `SNESNCG`, `SNESType`, `SNESGetNPCSide()`, `KSPSetPCSide()`, `PC_LEFT`, `PC_RIGHT`, `PCSide`
5716 @*/
5717 PetscErrorCode SNESSetNPCSide(SNES snes, PCSide side)
5718 {
5719   PetscFunctionBegin;
5720   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
5721   PetscValidLogicalCollectiveEnum(snes, side, 2);
5722   if (side == PC_SIDE_DEFAULT) side = PC_RIGHT;
5723   PetscCheck((side == PC_LEFT) || (side == PC_RIGHT), PetscObjectComm((PetscObject)snes), PETSC_ERR_ARG_WRONG, "Only PC_LEFT and PC_RIGHT are supported");
5724   snes->npcside = side;
5725   PetscFunctionReturn(PETSC_SUCCESS);
5726 }
5727 
5728 /*@
5729   SNESGetNPCSide - Gets the preconditioning side.
5730 
5731   Not Collective
5732 
5733   Input Parameter:
5734 . snes - iterative context obtained from `SNESCreate()`
5735 
5736   Output Parameter:
5737 . side - the preconditioning side, where side is one of
5738 .vb
5739       `PC_LEFT` - left preconditioning
5740       `PC_RIGHT` - right preconditioning (default for most nonlinear solvers)
5741 .ve
5742 
5743   Level: intermediate
5744 
5745 .seealso: [](ch_snes), `SNES`, `SNESSetNPCSide()`, `KSPGetPCSide()`, `PC_LEFT`, `PC_RIGHT`, `PCSide`
5746 @*/
5747 PetscErrorCode SNESGetNPCSide(SNES snes, PCSide *side)
5748 {
5749   PetscFunctionBegin;
5750   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
5751   PetscAssertPointer(side, 2);
5752   *side = snes->npcside;
5753   PetscFunctionReturn(PETSC_SUCCESS);
5754 }
5755 
5756 /*@
5757   SNESSetLineSearch - Sets the linesearch to be used for `SNES`
5758 
5759   Collective
5760 
5761   Input Parameters:
5762 + snes       - iterative context obtained from `SNESCreate()`
5763 - linesearch - the linesearch object
5764 
5765   Level: developer
5766 
5767   Note:
5768   This is almost never used, rather one uses `SNESGetLineSearch()` to retrieve the line search and set options on it
5769   to configure it using the API).
5770 
5771 .seealso: [](ch_snes), `SNES`, `SNESLineSearch`, `SNESGetLineSearch()`
5772 @*/
5773 PetscErrorCode SNESSetLineSearch(SNES snes, SNESLineSearch linesearch)
5774 {
5775   PetscFunctionBegin;
5776   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
5777   PetscValidHeaderSpecific(linesearch, SNESLINESEARCH_CLASSID, 2);
5778   PetscCheckSameComm(snes, 1, linesearch, 2);
5779   PetscCall(PetscObjectReference((PetscObject)linesearch));
5780   PetscCall(SNESLineSearchDestroy(&snes->linesearch));
5781 
5782   snes->linesearch = linesearch;
5783   PetscFunctionReturn(PETSC_SUCCESS);
5784 }
5785 
5786 /*@
5787   SNESGetLineSearch - Returns the line search context possibly set with `SNESSetLineSearch()`
5788   or creates a default line search instance associated with the `SNES` and returns it.
5789 
5790   Not Collective
5791 
5792   Input Parameter:
5793 . snes - iterative context obtained from `SNESCreate()`
5794 
5795   Output Parameter:
5796 . linesearch - linesearch context
5797 
5798   Level: beginner
5799 
5800 .seealso: [](ch_snes), `SNESLineSearch`, `SNESSetLineSearch()`, `SNESLineSearchCreate()`
5801 @*/
5802 PetscErrorCode SNESGetLineSearch(SNES snes, SNESLineSearch *linesearch)
5803 {
5804   const char *optionsprefix;
5805 
5806   PetscFunctionBegin;
5807   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
5808   PetscAssertPointer(linesearch, 2);
5809   if (!snes->linesearch) {
5810     PetscCall(SNESGetOptionsPrefix(snes, &optionsprefix));
5811     PetscCall(SNESLineSearchCreate(PetscObjectComm((PetscObject)snes), &snes->linesearch));
5812     PetscCall(SNESLineSearchSetSNES(snes->linesearch, snes));
5813     PetscCall(SNESLineSearchAppendOptionsPrefix(snes->linesearch, optionsprefix));
5814     PetscCall(PetscObjectIncrementTabLevel((PetscObject)snes->linesearch, (PetscObject)snes, 1));
5815   }
5816   *linesearch = snes->linesearch;
5817   PetscFunctionReturn(PETSC_SUCCESS);
5818 }
5819