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