xref: /petsc/src/snes/interface/snes.c (revision 3201ab8d70a3eea669f338f8bd746342de1cf5db)
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_MAX_INT;
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_MAX_INT;
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   SNESSetKSP - Sets a `KSP` context for the `SNES` object to use
1723 
1724   Not Collective, but the `SNES` and `KSP` objects must live on the same `MPI_Comm`
1725 
1726   Input Parameters:
1727 + snes - the `SNES` context
1728 - ksp  - the `KSP` context
1729 
1730   Level: developer
1731 
1732   Notes:
1733   The `SNES` object already has its `KSP` object, you can obtain with `SNESGetKSP()`
1734   so this routine is rarely needed.
1735 
1736   The `KSP` object that is already in the `SNES` object has its reference count
1737   decreased by one when this is called.
1738 
1739 .seealso: [](ch_snes), `SNES`, `KSP`, `KSPGetPC()`, `SNESCreate()`, `KSPCreate()`
1740 @*/
1741 PetscErrorCode SNESSetKSP(SNES snes, KSP ksp)
1742 {
1743   PetscFunctionBegin;
1744   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
1745   PetscValidHeaderSpecific(ksp, KSP_CLASSID, 2);
1746   PetscCheckSameComm(snes, 1, ksp, 2);
1747   PetscCall(PetscObjectReference((PetscObject)ksp));
1748   if (snes->ksp) PetscCall(PetscObjectDereference((PetscObject)snes->ksp));
1749   snes->ksp = ksp;
1750   PetscFunctionReturn(PETSC_SUCCESS);
1751 }
1752 
1753 /*@
1754   SNESParametersInitialize - Sets all the parameters in `snes` to their default value (when `SNESCreate()` was called) if they
1755   currently contain default values
1756 
1757   Collective
1758 
1759   Input Parameter:
1760 . snes - the `SNES` object
1761 
1762   Level: developer
1763 
1764   Developer Note:
1765   This is called by all the `SNESCreate_XXX()` routines.
1766 
1767 .seealso: [](ch_snes), `SNES`, `SNESSolve()`, `SNESDestroy()`, `SNESSetLagPreconditioner()`, `SNESSetLagJacobian()`,
1768           `PetscObjectParameterSetDefault()`
1769 @*/
1770 PetscErrorCode SNESParametersInitialize(SNES snes)
1771 {
1772   PetscObjectParameterSetDefault(snes, max_its, 50);
1773   PetscObjectParameterSetDefault(snes, max_funcs, 10000);
1774   PetscObjectParameterSetDefault(snes, rtol, PetscDefined(USE_REAL_SINGLE) ? 1.e-5 : 1.e-8);
1775   PetscObjectParameterSetDefault(snes, abstol, PetscDefined(USE_REAL_SINGLE) ? 1.e-25 : 1.e-50);
1776   PetscObjectParameterSetDefault(snes, stol, PetscDefined(USE_REAL_SINGLE) ? 1.e-5 : 1.e-8);
1777   PetscObjectParameterSetDefault(snes, divtol, 1.e4);
1778   return PETSC_SUCCESS;
1779 }
1780 
1781 /*@
1782   SNESCreate - Creates a nonlinear solver context used to manage a set of nonlinear solves
1783 
1784   Collective
1785 
1786   Input Parameter:
1787 . comm - MPI communicator
1788 
1789   Output Parameter:
1790 . outsnes - the new `SNES` context
1791 
1792   Options Database Keys:
1793 + -snes_mf          - Activates default matrix-free Jacobian-vector products, and no preconditioning matrix
1794 . -snes_mf_operator - Activates default matrix-free Jacobian-vector products, and a user-provided preconditioning matrix
1795                       as set by `SNESSetJacobian()`
1796 . -snes_fd_coloring - uses a relative fast computation of the Jacobian using finite differences and a graph coloring
1797 - -snes_fd          - Uses (slow!) finite differences to compute Jacobian
1798 
1799   Level: beginner
1800 
1801   Developer Notes:
1802   `SNES` always creates a `KSP` object even though many `SNES` methods do not use it. This is
1803   unfortunate and should be fixed at some point. The flag snes->usesksp indicates if the
1804   particular method does use `KSP` and regulates if the information about the `KSP` is printed
1805   in `SNESView()`.
1806 
1807   `TSSetFromOptions()` does call `SNESSetFromOptions()` which can lead to users being confused
1808   by help messages about meaningless `SNES` options.
1809 
1810   `SNES` always creates the snes->kspconvctx even though it is used by only one type. This should be fixed.
1811 
1812 .seealso: [](ch_snes), `SNES`, `SNESSolve()`, `SNESDestroy()`, `SNESSetLagPreconditioner()`, `SNESSetLagJacobian()`
1813 @*/
1814 PetscErrorCode SNESCreate(MPI_Comm comm, SNES *outsnes)
1815 {
1816   SNES       snes;
1817   SNESKSPEW *kctx;
1818 
1819   PetscFunctionBegin;
1820   PetscAssertPointer(outsnes, 2);
1821   PetscCall(SNESInitializePackage());
1822 
1823   PetscCall(PetscHeaderCreate(snes, SNES_CLASSID, "SNES", "Nonlinear solver", "SNES", comm, SNESDestroy, SNESView));
1824   snes->ops->converged = SNESConvergedDefault;
1825   snes->usesksp        = PETSC_TRUE;
1826   snes->norm           = 0.0;
1827   snes->xnorm          = 0.0;
1828   snes->ynorm          = 0.0;
1829   snes->normschedule   = SNES_NORM_ALWAYS;
1830   snes->functype       = SNES_FUNCTION_DEFAULT;
1831   snes->ttol           = 0.0;
1832 
1833   snes->rnorm0               = 0;
1834   snes->nfuncs               = 0;
1835   snes->numFailures          = 0;
1836   snes->maxFailures          = 1;
1837   snes->linear_its           = 0;
1838   snes->lagjacobian          = 1;
1839   snes->jac_iter             = 0;
1840   snes->lagjac_persist       = PETSC_FALSE;
1841   snes->lagpreconditioner    = 1;
1842   snes->pre_iter             = 0;
1843   snes->lagpre_persist       = PETSC_FALSE;
1844   snes->numbermonitors       = 0;
1845   snes->numberreasonviews    = 0;
1846   snes->data                 = NULL;
1847   snes->setupcalled          = PETSC_FALSE;
1848   snes->ksp_ewconv           = PETSC_FALSE;
1849   snes->nwork                = 0;
1850   snes->work                 = NULL;
1851   snes->nvwork               = 0;
1852   snes->vwork                = NULL;
1853   snes->conv_hist_len        = 0;
1854   snes->conv_hist_max        = 0;
1855   snes->conv_hist            = NULL;
1856   snes->conv_hist_its        = NULL;
1857   snes->conv_hist_reset      = PETSC_TRUE;
1858   snes->counters_reset       = PETSC_TRUE;
1859   snes->vec_func_init_set    = PETSC_FALSE;
1860   snes->reason               = SNES_CONVERGED_ITERATING;
1861   snes->npcside              = PC_RIGHT;
1862   snes->setfromoptionscalled = 0;
1863 
1864   snes->mf          = PETSC_FALSE;
1865   snes->mf_operator = PETSC_FALSE;
1866   snes->mf_version  = 1;
1867 
1868   snes->numLinearSolveFailures = 0;
1869   snes->maxLinearSolveFailures = 1;
1870 
1871   snes->vizerotolerance     = 1.e-8;
1872   snes->checkjacdomainerror = PetscDefined(USE_DEBUG) ? PETSC_TRUE : PETSC_FALSE;
1873 
1874   /* Set this to true if the implementation of SNESSolve_XXX does compute the residual at the final solution. */
1875   snes->alwayscomputesfinalresidual = PETSC_FALSE;
1876 
1877   /* Create context to compute Eisenstat-Walker relative tolerance for KSP */
1878   PetscCall(PetscNew(&kctx));
1879 
1880   snes->kspconvctx  = (void *)kctx;
1881   kctx->version     = 2;
1882   kctx->rtol_0      = 0.3; /* Eisenstat and Walker suggest rtol_0=.5, but
1883                              this was too large for some test cases */
1884   kctx->rtol_last   = 0.0;
1885   kctx->rtol_max    = 0.9;
1886   kctx->gamma       = 1.0;
1887   kctx->alpha       = 0.5 * (1.0 + PetscSqrtReal(5.0));
1888   kctx->alpha2      = kctx->alpha;
1889   kctx->threshold   = 0.1;
1890   kctx->lresid_last = 0.0;
1891   kctx->norm_last   = 0.0;
1892 
1893   kctx->rk_last     = 0.0;
1894   kctx->rk_last_2   = 0.0;
1895   kctx->rtol_last_2 = 0.0;
1896   kctx->v4_p1       = 0.1;
1897   kctx->v4_p2       = 0.4;
1898   kctx->v4_p3       = 0.7;
1899   kctx->v4_m1       = 0.8;
1900   kctx->v4_m2       = 0.5;
1901   kctx->v4_m3       = 0.1;
1902   kctx->v4_m4       = 0.5;
1903 
1904   *outsnes = snes;
1905   PetscFunctionReturn(PETSC_SUCCESS);
1906 }
1907 
1908 /*@C
1909   SNESSetFunction - Sets the function evaluation routine and function
1910   vector for use by the `SNES` routines in solving systems of nonlinear
1911   equations.
1912 
1913   Logically Collective
1914 
1915   Input Parameters:
1916 + snes - the `SNES` context
1917 . r    - vector to store function values, may be `NULL`
1918 . f    - function evaluation routine;  for calling sequence see `SNESFunctionFn`
1919 - ctx  - [optional] user-defined context for private data for the
1920          function evaluation routine (may be `NULL`)
1921 
1922   Level: beginner
1923 
1924 .seealso: [](ch_snes), `SNES`, `SNESGetFunction()`, `SNESComputeFunction()`, `SNESSetJacobian()`, `SNESSetPicard()`, `SNESFunctionFn`
1925 @*/
1926 PetscErrorCode SNESSetFunction(SNES snes, Vec r, SNESFunctionFn *f, void *ctx)
1927 {
1928   DM dm;
1929 
1930   PetscFunctionBegin;
1931   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
1932   if (r) {
1933     PetscValidHeaderSpecific(r, VEC_CLASSID, 2);
1934     PetscCheckSameComm(snes, 1, r, 2);
1935     PetscCall(PetscObjectReference((PetscObject)r));
1936     PetscCall(VecDestroy(&snes->vec_func));
1937     snes->vec_func = r;
1938   }
1939   PetscCall(SNESGetDM(snes, &dm));
1940   PetscCall(DMSNESSetFunction(dm, f, ctx));
1941   if (f == SNESPicardComputeFunction) PetscCall(DMSNESSetMFFunction(dm, SNESPicardComputeMFFunction, ctx));
1942   PetscFunctionReturn(PETSC_SUCCESS);
1943 }
1944 
1945 /*@C
1946   SNESSetInitialFunction - Set an already computed function evaluation at the initial guess to be reused by `SNESSolve()`.
1947 
1948   Logically Collective
1949 
1950   Input Parameters:
1951 + snes - the `SNES` context
1952 - f    - vector to store function value
1953 
1954   Level: developer
1955 
1956   Notes:
1957   This should not be modified during the solution procedure.
1958 
1959   This is used extensively in the `SNESFAS` hierarchy and in nonlinear preconditioning.
1960 
1961 .seealso: [](ch_snes), `SNES`, `SNESFAS`, `SNESSetFunction()`, `SNESComputeFunction()`, `SNESSetInitialFunctionNorm()`
1962 @*/
1963 PetscErrorCode SNESSetInitialFunction(SNES snes, Vec f)
1964 {
1965   Vec vec_func;
1966 
1967   PetscFunctionBegin;
1968   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
1969   PetscValidHeaderSpecific(f, VEC_CLASSID, 2);
1970   PetscCheckSameComm(snes, 1, f, 2);
1971   if (snes->npcside == PC_LEFT && snes->functype == SNES_FUNCTION_PRECONDITIONED) {
1972     snes->vec_func_init_set = PETSC_FALSE;
1973     PetscFunctionReturn(PETSC_SUCCESS);
1974   }
1975   PetscCall(SNESGetFunction(snes, &vec_func, NULL, NULL));
1976   PetscCall(VecCopy(f, vec_func));
1977 
1978   snes->vec_func_init_set = PETSC_TRUE;
1979   PetscFunctionReturn(PETSC_SUCCESS);
1980 }
1981 
1982 /*@
1983   SNESSetNormSchedule - Sets the `SNESNormSchedule` used in convergence and monitoring
1984   of the `SNES` method, when norms are computed in the solving process
1985 
1986   Logically Collective
1987 
1988   Input Parameters:
1989 + snes         - the `SNES` context
1990 - normschedule - the frequency of norm computation
1991 
1992   Options Database Key:
1993 . -snes_norm_schedule <none, always, initialonly, finalonly, initialfinalonly> - set the schedule
1994 
1995   Level: advanced
1996 
1997   Notes:
1998   Only certain `SNES` methods support certain `SNESNormSchedules`.  Most require evaluation
1999   of the nonlinear function and the taking of its norm at every iteration to
2000   even ensure convergence at all.  However, methods such as custom Gauss-Seidel methods
2001   `SNESNGS` and the like do not require the norm of the function to be computed, and therefore
2002   may either be monitored for convergence or not.  As these are often used as nonlinear
2003   preconditioners, monitoring the norm of their error is not a useful enterprise within
2004   their solution.
2005 
2006 .seealso: [](ch_snes), `SNESNormSchedule`, `SNESGetNormSchedule()`, `SNESComputeFunction()`, `VecNorm()`, `SNESSetFunction()`, `SNESSetInitialFunction()`
2007 @*/
2008 PetscErrorCode SNESSetNormSchedule(SNES snes, SNESNormSchedule normschedule)
2009 {
2010   PetscFunctionBegin;
2011   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
2012   snes->normschedule = normschedule;
2013   PetscFunctionReturn(PETSC_SUCCESS);
2014 }
2015 
2016 /*@
2017   SNESGetNormSchedule - Gets the `SNESNormSchedule` used in convergence and monitoring
2018   of the `SNES` method.
2019 
2020   Logically Collective
2021 
2022   Input Parameters:
2023 + snes         - the `SNES` context
2024 - normschedule - the type of the norm used
2025 
2026   Level: advanced
2027 
2028 .seealso: [](ch_snes), `SNES`, `SNESSetNormSchedule()`, `SNESComputeFunction()`, `VecNorm()`, `SNESSetFunction()`, `SNESSetInitialFunction()`, `SNESNormSchedule`
2029 @*/
2030 PetscErrorCode SNESGetNormSchedule(SNES snes, SNESNormSchedule *normschedule)
2031 {
2032   PetscFunctionBegin;
2033   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
2034   *normschedule = snes->normschedule;
2035   PetscFunctionReturn(PETSC_SUCCESS);
2036 }
2037 
2038 /*@
2039   SNESSetFunctionNorm - Sets the last computed residual norm.
2040 
2041   Logically Collective
2042 
2043   Input Parameters:
2044 + snes - the `SNES` context
2045 - norm - the value of the norm
2046 
2047   Level: developer
2048 
2049 .seealso: [](ch_snes), `SNES`, `SNESGetNormSchedule()`, `SNESComputeFunction()`, `VecNorm()`, `SNESSetFunction()`, `SNESSetInitialFunction()`, `SNESNormSchedule`
2050 @*/
2051 PetscErrorCode SNESSetFunctionNorm(SNES snes, PetscReal norm)
2052 {
2053   PetscFunctionBegin;
2054   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
2055   snes->norm = norm;
2056   PetscFunctionReturn(PETSC_SUCCESS);
2057 }
2058 
2059 /*@
2060   SNESGetFunctionNorm - Gets the last computed norm of the residual
2061 
2062   Not Collective
2063 
2064   Input Parameter:
2065 . snes - the `SNES` context
2066 
2067   Output Parameter:
2068 . norm - the last computed residual norm
2069 
2070   Level: developer
2071 
2072 .seealso: [](ch_snes), `SNES`, `SNESSetNormSchedule()`, `SNESComputeFunction()`, `VecNorm()`, `SNESSetFunction()`, `SNESSetInitialFunction()`, `SNESNormSchedule`
2073 @*/
2074 PetscErrorCode SNESGetFunctionNorm(SNES snes, PetscReal *norm)
2075 {
2076   PetscFunctionBegin;
2077   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
2078   PetscAssertPointer(norm, 2);
2079   *norm = snes->norm;
2080   PetscFunctionReturn(PETSC_SUCCESS);
2081 }
2082 
2083 /*@
2084   SNESGetUpdateNorm - Gets the last computed norm of the solution update
2085 
2086   Not Collective
2087 
2088   Input Parameter:
2089 . snes - the `SNES` context
2090 
2091   Output Parameter:
2092 . ynorm - the last computed update norm
2093 
2094   Level: developer
2095 
2096   Note:
2097   The new solution is the current solution plus the update, so this norm is an indication of the size of the update
2098 
2099 .seealso: [](ch_snes), `SNES`, `SNESSetNormSchedule()`, `SNESComputeFunction()`, `SNESGetFunctionNorm()`
2100 @*/
2101 PetscErrorCode SNESGetUpdateNorm(SNES snes, PetscReal *ynorm)
2102 {
2103   PetscFunctionBegin;
2104   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
2105   PetscAssertPointer(ynorm, 2);
2106   *ynorm = snes->ynorm;
2107   PetscFunctionReturn(PETSC_SUCCESS);
2108 }
2109 
2110 /*@
2111   SNESGetSolutionNorm - Gets the last computed norm of the solution
2112 
2113   Not Collective
2114 
2115   Input Parameter:
2116 . snes - the `SNES` context
2117 
2118   Output Parameter:
2119 . xnorm - the last computed solution norm
2120 
2121   Level: developer
2122 
2123 .seealso: [](ch_snes), `SNES`, `SNESSetNormSchedule()`, `SNESComputeFunction()`, `SNESGetFunctionNorm()`, `SNESGetUpdateNorm()`
2124 @*/
2125 PetscErrorCode SNESGetSolutionNorm(SNES snes, PetscReal *xnorm)
2126 {
2127   PetscFunctionBegin;
2128   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
2129   PetscAssertPointer(xnorm, 2);
2130   *xnorm = snes->xnorm;
2131   PetscFunctionReturn(PETSC_SUCCESS);
2132 }
2133 
2134 /*@
2135   SNESSetFunctionType - Sets the `SNESFunctionType`
2136   of the `SNES` method.
2137 
2138   Logically Collective
2139 
2140   Input Parameters:
2141 + snes - the `SNES` context
2142 - type - the function type
2143 
2144   Level: developer
2145 
2146   Values of the function type\:
2147 +  `SNES_FUNCTION_DEFAULT`          - the default for the given `SNESType`
2148 .  `SNES_FUNCTION_UNPRECONDITIONED` - an unpreconditioned function evaluation (this is the function provided with `SNESSetFunction()`
2149 -  `SNES_FUNCTION_PRECONDITIONED`   - a transformation of the function provided with `SNESSetFunction()`
2150 
2151   Note:
2152   Different `SNESType`s use this value in different ways
2153 
2154 .seealso: [](ch_snes), `SNES`, `SNESFunctionType`, `SNESGetNormSchedule()`, `SNESComputeFunction()`, `VecNorm()`, `SNESSetFunction()`, `SNESSetInitialFunction()`, `SNESNormSchedule`
2155 @*/
2156 PetscErrorCode SNESSetFunctionType(SNES snes, SNESFunctionType type)
2157 {
2158   PetscFunctionBegin;
2159   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
2160   snes->functype = type;
2161   PetscFunctionReturn(PETSC_SUCCESS);
2162 }
2163 
2164 /*@
2165   SNESGetFunctionType - Gets the `SNESFunctionType` used in convergence and monitoring set with `SNESSetFunctionType()`
2166   of the SNES method.
2167 
2168   Logically Collective
2169 
2170   Input Parameters:
2171 + snes - the `SNES` context
2172 - type - the type of the function evaluation, see `SNESSetFunctionType()`
2173 
2174   Level: advanced
2175 
2176 .seealso: [](ch_snes), `SNESSetFunctionType()`, `SNESFunctionType`, `SNESSetNormSchedule()`, `SNESComputeFunction()`, `VecNorm()`, `SNESSetFunction()`, `SNESSetInitialFunction()`, `SNESNormSchedule`
2177 @*/
2178 PetscErrorCode SNESGetFunctionType(SNES snes, SNESFunctionType *type)
2179 {
2180   PetscFunctionBegin;
2181   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
2182   *type = snes->functype;
2183   PetscFunctionReturn(PETSC_SUCCESS);
2184 }
2185 
2186 /*@C
2187   SNESSetNGS - Sets the user nonlinear Gauss-Seidel routine for
2188   use with composed nonlinear solvers.
2189 
2190   Input Parameters:
2191 + snes - the `SNES` context, usually of the `SNESType` `SNESNGS`
2192 . f    - function evaluation routine to apply Gauss-Seidel, see `SNESNGSFn` for calling sequence
2193 - ctx  - [optional] user-defined context for private data for the smoother evaluation routine (may be `NULL`)
2194 
2195   Level: intermediate
2196 
2197   Note:
2198   The `SNESNGS` routines are used by the composed nonlinear solver to generate
2199   a problem appropriate update to the solution, particularly `SNESFAS`.
2200 
2201 .seealso: [](ch_snes), `SNESNGS`, `SNESGetNGS()`, `SNESNCG`, `SNESGetFunction()`, `SNESComputeNGS()`, `SNESNGSFn`
2202 @*/
2203 PetscErrorCode SNESSetNGS(SNES snes, SNESNGSFn *f, void *ctx)
2204 {
2205   DM dm;
2206 
2207   PetscFunctionBegin;
2208   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
2209   PetscCall(SNESGetDM(snes, &dm));
2210   PetscCall(DMSNESSetNGS(dm, f, ctx));
2211   PetscFunctionReturn(PETSC_SUCCESS);
2212 }
2213 
2214 /*
2215      This is used for -snes_mf_operator; it uses a duplicate of snes->jacobian_pre because snes->jacobian_pre cannot be
2216    changed during the KSPSolve()
2217 */
2218 PetscErrorCode SNESPicardComputeMFFunction(SNES snes, Vec x, Vec f, void *ctx)
2219 {
2220   DM     dm;
2221   DMSNES sdm;
2222 
2223   PetscFunctionBegin;
2224   PetscCall(SNESGetDM(snes, &dm));
2225   PetscCall(DMGetDMSNES(dm, &sdm));
2226   /*  A(x)*x - b(x) */
2227   if (sdm->ops->computepfunction) {
2228     PetscCallBack("SNES Picard callback function", (*sdm->ops->computepfunction)(snes, x, f, sdm->pctx));
2229     PetscCall(VecScale(f, -1.0));
2230     /* Cannot share nonzero pattern because of the possible use of SNESComputeJacobianDefault() */
2231     if (!snes->picard) PetscCall(MatDuplicate(snes->jacobian_pre, MAT_DO_NOT_COPY_VALUES, &snes->picard));
2232     PetscCallBack("SNES Picard callback Jacobian", (*sdm->ops->computepjacobian)(snes, x, snes->picard, snes->picard, sdm->pctx));
2233     PetscCall(MatMultAdd(snes->picard, x, f, f));
2234   } else {
2235     PetscCallBack("SNES Picard callback Jacobian", (*sdm->ops->computepjacobian)(snes, x, snes->picard, snes->picard, sdm->pctx));
2236     PetscCall(MatMult(snes->picard, x, f));
2237   }
2238   PetscFunctionReturn(PETSC_SUCCESS);
2239 }
2240 
2241 PetscErrorCode SNESPicardComputeFunction(SNES snes, Vec x, Vec f, void *ctx)
2242 {
2243   DM     dm;
2244   DMSNES sdm;
2245 
2246   PetscFunctionBegin;
2247   PetscCall(SNESGetDM(snes, &dm));
2248   PetscCall(DMGetDMSNES(dm, &sdm));
2249   /*  A(x)*x - b(x) */
2250   if (sdm->ops->computepfunction) {
2251     PetscCallBack("SNES Picard callback function", (*sdm->ops->computepfunction)(snes, x, f, sdm->pctx));
2252     PetscCall(VecScale(f, -1.0));
2253     PetscCallBack("SNES Picard callback Jacobian", (*sdm->ops->computepjacobian)(snes, x, snes->jacobian, snes->jacobian_pre, sdm->pctx));
2254     PetscCall(MatMultAdd(snes->jacobian_pre, x, f, f));
2255   } else {
2256     PetscCallBack("SNES Picard callback Jacobian", (*sdm->ops->computepjacobian)(snes, x, snes->jacobian, snes->jacobian_pre, sdm->pctx));
2257     PetscCall(MatMult(snes->jacobian_pre, x, f));
2258   }
2259   PetscFunctionReturn(PETSC_SUCCESS);
2260 }
2261 
2262 PetscErrorCode SNESPicardComputeJacobian(SNES snes, Vec x1, Mat J, Mat B, void *ctx)
2263 {
2264   PetscFunctionBegin;
2265   /* the jacobian matrix should be pre-filled in SNESPicardComputeFunction */
2266   /* must assembly if matrix-free to get the last SNES solution */
2267   PetscCall(MatAssemblyBegin(J, MAT_FINAL_ASSEMBLY));
2268   PetscCall(MatAssemblyEnd(J, MAT_FINAL_ASSEMBLY));
2269   PetscFunctionReturn(PETSC_SUCCESS);
2270 }
2271 
2272 /*@C
2273   SNESSetPicard - Use `SNES` to solve the system $A(x) x = bp(x) + b $ via a Picard type iteration (Picard linearization)
2274 
2275   Logically Collective
2276 
2277   Input Parameters:
2278 + snes - the `SNES` context
2279 . r    - vector to store function values, may be `NULL`
2280 . bp   - function evaluation routine, may be `NULL`, for the calling sequence see `SNESFunctionFn`
2281 . Amat - matrix with which A(x) x - bp(x) - b is to be computed
2282 . Pmat - matrix from which preconditioner is computed (usually the same as `Amat`)
2283 . J    - function to compute matrix values, for the calling sequence see `SNESJacobianFn`
2284 - ctx  - [optional] user-defined context for private data for the function evaluation routine (may be `NULL`)
2285 
2286   Level: intermediate
2287 
2288   Notes:
2289   It is often better to provide the nonlinear function F() and some approximation to its Jacobian directly and use
2290   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.
2291 
2292   One can call `SNESSetPicard()` or `SNESSetFunction()` (and possibly `SNESSetJacobian()`) but cannot call both
2293 
2294   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}$.
2295   When an exact solver is used this corresponds to the "classic" Picard $A(x^{n}) x^{n+1} = bp(x^{n}) + b$ iteration.
2296 
2297   Run with `-snes_mf_operator` to solve the system with Newton's method using A(x^{n}) to construct the preconditioner.
2298 
2299   We implement the defect correction form of the Picard iteration because it converges much more generally when inexact linear solvers are used then
2300   the direct Picard iteration $A(x^n) x^{n+1} = bp(x^n) + b$
2301 
2302   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
2303   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
2304   different please contact us at petsc-dev@mcs.anl.gov and we'll have an entirely new argument \:-).
2305 
2306   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
2307   A(x^{n}) is used to build the preconditioner
2308 
2309   When used with `-snes_fd` this will compute the true Jacobian (very slowly one column at a time) and thus represent Newton's method.
2310 
2311   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
2312   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
2313   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`.
2314   See the comment in src/snes/tutorials/ex15.c.
2315 
2316 .seealso: [](ch_snes), `SNES`, `SNESGetFunction()`, `SNESSetFunction()`, `SNESComputeFunction()`, `SNESSetJacobian()`, `SNESGetPicard()`, `SNESLineSearchPreCheckPicard()`,
2317           `SNESFunctionFn`, `SNESJacobianFn`
2318 @*/
2319 PetscErrorCode SNESSetPicard(SNES snes, Vec r, SNESFunctionFn *bp, Mat Amat, Mat Pmat, SNESJacobianFn *J, void *ctx)
2320 {
2321   DM dm;
2322 
2323   PetscFunctionBegin;
2324   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
2325   PetscCall(SNESGetDM(snes, &dm));
2326   PetscCall(DMSNESSetPicard(dm, bp, J, ctx));
2327   PetscCall(DMSNESSetMFFunction(dm, SNESPicardComputeMFFunction, ctx));
2328   PetscCall(SNESSetFunction(snes, r, SNESPicardComputeFunction, ctx));
2329   PetscCall(SNESSetJacobian(snes, Amat, Pmat, SNESPicardComputeJacobian, ctx));
2330   PetscFunctionReturn(PETSC_SUCCESS);
2331 }
2332 
2333 /*@C
2334   SNESGetPicard - Returns the context for the Picard iteration
2335 
2336   Not Collective, but `Vec` is parallel if `SNES` is parallel. Collective if `Vec` is requested, but has not been created yet.
2337 
2338   Input Parameter:
2339 . snes - the `SNES` context
2340 
2341   Output Parameters:
2342 + r    - the function (or `NULL`)
2343 . f    - the function (or `NULL`);  for calling sequence see `SNESFunctionFn`
2344 . Amat - the matrix used to defined the operation A(x) x - b(x) (or `NULL`)
2345 . Pmat - the matrix from which the preconditioner will be constructed (or `NULL`)
2346 . J    - the function for matrix evaluation (or `NULL`);  for calling sequence see `SNESJacobianFn`
2347 - ctx  - the function context (or `NULL`)
2348 
2349   Level: advanced
2350 
2351 .seealso: [](ch_snes), `SNESSetFunction()`, `SNESSetPicard()`, `SNESGetFunction()`, `SNESGetJacobian()`, `SNESGetDM()`, `SNESFunctionFn`, `SNESJacobianFn`
2352 @*/
2353 PetscErrorCode SNESGetPicard(SNES snes, Vec *r, SNESFunctionFn **f, Mat *Amat, Mat *Pmat, SNESJacobianFn **J, void **ctx)
2354 {
2355   DM dm;
2356 
2357   PetscFunctionBegin;
2358   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
2359   PetscCall(SNESGetFunction(snes, r, NULL, NULL));
2360   PetscCall(SNESGetJacobian(snes, Amat, Pmat, NULL, NULL));
2361   PetscCall(SNESGetDM(snes, &dm));
2362   PetscCall(DMSNESGetPicard(dm, f, J, ctx));
2363   PetscFunctionReturn(PETSC_SUCCESS);
2364 }
2365 
2366 /*@C
2367   SNESSetComputeInitialGuess - Sets a routine used to compute an initial guess for the nonlinear problem
2368 
2369   Logically Collective
2370 
2371   Input Parameters:
2372 + snes - the `SNES` context
2373 . func - function evaluation routine, see `SNESInitialGuessFn` for the calling sequence
2374 - ctx  - [optional] user-defined context for private data for the
2375          function evaluation routine (may be `NULL`)
2376 
2377   Level: intermediate
2378 
2379 .seealso: [](ch_snes), `SNES`, `SNESSolve()`, `SNESSetFunction()`, `SNESGetFunction()`, `SNESComputeFunction()`, `SNESSetJacobian()`, `SNESInitialGuessFn`
2380 @*/
2381 PetscErrorCode SNESSetComputeInitialGuess(SNES snes, SNESInitialGuessFn *func, void *ctx)
2382 {
2383   PetscFunctionBegin;
2384   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
2385   if (func) snes->ops->computeinitialguess = func;
2386   if (ctx) snes->initialguessP = ctx;
2387   PetscFunctionReturn(PETSC_SUCCESS);
2388 }
2389 
2390 /*@C
2391   SNESGetRhs - Gets the vector for solving F(x) = `rhs`. If `rhs` is not set
2392   it assumes a zero right-hand side.
2393 
2394   Logically Collective
2395 
2396   Input Parameter:
2397 . snes - the `SNES` context
2398 
2399   Output Parameter:
2400 . rhs - the right-hand side vector or `NULL` if there is no right-hand side vector
2401 
2402   Level: intermediate
2403 
2404 .seealso: [](ch_snes), `SNES`, `SNESGetSolution()`, `SNESGetFunction()`, `SNESComputeFunction()`, `SNESSetJacobian()`, `SNESSetFunction()`
2405 @*/
2406 PetscErrorCode SNESGetRhs(SNES snes, Vec *rhs)
2407 {
2408   PetscFunctionBegin;
2409   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
2410   PetscAssertPointer(rhs, 2);
2411   *rhs = snes->vec_rhs;
2412   PetscFunctionReturn(PETSC_SUCCESS);
2413 }
2414 
2415 /*@
2416   SNESComputeFunction - Calls the function that has been set with `SNESSetFunction()`.
2417 
2418   Collective
2419 
2420   Input Parameters:
2421 + snes - the `SNES` context
2422 - x    - input vector
2423 
2424   Output Parameter:
2425 . y - function vector, as set by `SNESSetFunction()`
2426 
2427   Level: developer
2428 
2429   Notes:
2430   `SNESComputeFunction()` is typically used within nonlinear solvers
2431   implementations, so users would not generally call this routine themselves.
2432 
2433   When solving for $F(x) = b$, this routine computes $y = F(x) - b$.
2434 
2435 .seealso: [](ch_snes), `SNES`, `SNESSetFunction()`, `SNESGetFunction()`, `SNESComputeMFFunction()`
2436 @*/
2437 PetscErrorCode SNESComputeFunction(SNES snes, Vec x, Vec y)
2438 {
2439   DM     dm;
2440   DMSNES sdm;
2441 
2442   PetscFunctionBegin;
2443   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
2444   PetscValidHeaderSpecific(x, VEC_CLASSID, 2);
2445   PetscValidHeaderSpecific(y, VEC_CLASSID, 3);
2446   PetscCheckSameComm(snes, 1, x, 2);
2447   PetscCheckSameComm(snes, 1, y, 3);
2448   PetscCall(VecValidValues_Internal(x, 2, PETSC_TRUE));
2449 
2450   PetscCall(SNESGetDM(snes, &dm));
2451   PetscCall(DMGetDMSNES(dm, &sdm));
2452   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().");
2453   if (sdm->ops->computefunction) {
2454     if (sdm->ops->computefunction != SNESObjectiveComputeFunctionDefaultFD) PetscCall(PetscLogEventBegin(SNES_FunctionEval, snes, x, y, 0));
2455     PetscCall(VecLockReadPush(x));
2456     /* ensure domainerror is false prior to computefunction evaluation (may not have been reset) */
2457     snes->domainerror = PETSC_FALSE;
2458     {
2459       void           *ctx;
2460       SNESFunctionFn *computefunction;
2461       PetscCall(DMSNESGetFunction(dm, &computefunction, &ctx));
2462       PetscCallBack("SNES callback function", (*computefunction)(snes, x, y, ctx));
2463     }
2464     PetscCall(VecLockReadPop(x));
2465     if (sdm->ops->computefunction != SNESObjectiveComputeFunctionDefaultFD) PetscCall(PetscLogEventEnd(SNES_FunctionEval, snes, x, y, 0));
2466   } else /* if (snes->vec_rhs) */ {
2467     PetscCall(MatMult(snes->jacobian, x, y));
2468   }
2469   if (snes->vec_rhs) PetscCall(VecAXPY(y, -1.0, snes->vec_rhs));
2470   snes->nfuncs++;
2471   /*
2472      domainerror might not be set on all processes; so we tag vector locally with Inf and the next inner product or norm will
2473      propagate the value to all processes
2474   */
2475   PetscCall(VecFlag(y, snes->domainerror));
2476   PetscFunctionReturn(PETSC_SUCCESS);
2477 }
2478 
2479 /*@
2480   SNESComputeMFFunction - Calls the function that has been set with `SNESSetMFFunction()`.
2481 
2482   Collective
2483 
2484   Input Parameters:
2485 + snes - the `SNES` context
2486 - x    - input vector
2487 
2488   Output Parameter:
2489 . y - function vector, as set by `SNESSetMFFunction()`
2490 
2491   Level: developer
2492 
2493   Notes:
2494   `SNESComputeMFFunction()` is used within the matrix-vector products called by the matrix created with `MatCreateSNESMF()`
2495   so users would not generally call this routine themselves.
2496 
2497   Since this function is intended for use with finite differencing it does not subtract the right-hand side vector provided with `SNESSolve()`
2498   while `SNESComputeFunction()` does. As such, this routine cannot be used with  `MatMFFDSetBase()` with a provided F function value even if it applies the
2499   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.
2500 
2501 .seealso: [](ch_snes), `SNES`, `SNESSetFunction()`, `SNESGetFunction()`, `SNESComputeFunction()`, `MatCreateSNESMF`
2502 @*/
2503 PetscErrorCode SNESComputeMFFunction(SNES snes, Vec x, Vec y)
2504 {
2505   DM     dm;
2506   DMSNES sdm;
2507 
2508   PetscFunctionBegin;
2509   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
2510   PetscValidHeaderSpecific(x, VEC_CLASSID, 2);
2511   PetscValidHeaderSpecific(y, VEC_CLASSID, 3);
2512   PetscCheckSameComm(snes, 1, x, 2);
2513   PetscCheckSameComm(snes, 1, y, 3);
2514   PetscCall(VecValidValues_Internal(x, 2, PETSC_TRUE));
2515 
2516   PetscCall(SNESGetDM(snes, &dm));
2517   PetscCall(DMGetDMSNES(dm, &sdm));
2518   PetscCall(PetscLogEventBegin(SNES_FunctionEval, snes, x, y, 0));
2519   PetscCall(VecLockReadPush(x));
2520   /* ensure domainerror is false prior to computefunction evaluation (may not have been reset) */
2521   snes->domainerror = PETSC_FALSE;
2522   PetscCallBack("SNES callback function", (*sdm->ops->computemffunction)(snes, x, y, sdm->mffunctionctx));
2523   PetscCall(VecLockReadPop(x));
2524   PetscCall(PetscLogEventEnd(SNES_FunctionEval, snes, x, y, 0));
2525   snes->nfuncs++;
2526   /*
2527      domainerror might not be set on all processes; so we tag vector locally with Inf and the next inner product or norm will
2528      propagate the value to all processes
2529   */
2530   PetscCall(VecFlag(y, snes->domainerror));
2531   PetscFunctionReturn(PETSC_SUCCESS);
2532 }
2533 
2534 /*@
2535   SNESComputeNGS - Calls the Gauss-Seidel function that has been set with `SNESSetNGS()`.
2536 
2537   Collective
2538 
2539   Input Parameters:
2540 + snes - the `SNES` context
2541 . x    - input vector
2542 - b    - rhs vector
2543 
2544   Output Parameter:
2545 . x - new solution vector
2546 
2547   Level: developer
2548 
2549   Note:
2550   `SNESComputeNGS()` is typically used within composed nonlinear solver
2551   implementations, so most users would not generally call this routine
2552   themselves.
2553 
2554 .seealso: [](ch_snes), `SNESNGSFn`, `SNESSetNGS()`, `SNESComputeFunction()`, `SNESNGS`
2555 @*/
2556 PetscErrorCode SNESComputeNGS(SNES snes, Vec b, Vec x)
2557 {
2558   DM     dm;
2559   DMSNES sdm;
2560 
2561   PetscFunctionBegin;
2562   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
2563   PetscValidHeaderSpecific(x, VEC_CLASSID, 3);
2564   if (b) PetscValidHeaderSpecific(b, VEC_CLASSID, 2);
2565   PetscCheckSameComm(snes, 1, x, 3);
2566   if (b) PetscCheckSameComm(snes, 1, b, 2);
2567   if (b) PetscCall(VecValidValues_Internal(b, 2, PETSC_TRUE));
2568   PetscCall(PetscLogEventBegin(SNES_NGSEval, snes, x, b, 0));
2569   PetscCall(SNESGetDM(snes, &dm));
2570   PetscCall(DMGetDMSNES(dm, &sdm));
2571   PetscCheck(sdm->ops->computegs, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Must call SNESSetNGS() before SNESComputeNGS(), likely called from SNESSolve().");
2572   if (b) PetscCall(VecLockReadPush(b));
2573   PetscCallBack("SNES callback NGS", (*sdm->ops->computegs)(snes, x, b, sdm->gsctx));
2574   if (b) PetscCall(VecLockReadPop(b));
2575   PetscCall(PetscLogEventEnd(SNES_NGSEval, snes, x, b, 0));
2576   PetscFunctionReturn(PETSC_SUCCESS);
2577 }
2578 
2579 static PetscErrorCode SNESComputeFunction_FD(SNES snes, Vec Xin, Vec G)
2580 {
2581   Vec          X;
2582   PetscScalar *g;
2583   PetscReal    f, f2;
2584   PetscInt     low, high, N, i;
2585   PetscBool    flg;
2586   PetscReal    h = .5 * PETSC_SQRT_MACHINE_EPSILON;
2587 
2588   PetscFunctionBegin;
2589   PetscCall(PetscOptionsGetReal(((PetscObject)snes)->options, ((PetscObject)snes)->prefix, "-snes_fd_delta", &h, &flg));
2590   PetscCall(VecDuplicate(Xin, &X));
2591   PetscCall(VecCopy(Xin, X));
2592   PetscCall(VecGetSize(X, &N));
2593   PetscCall(VecGetOwnershipRange(X, &low, &high));
2594   PetscCall(VecSetOption(X, VEC_IGNORE_OFF_PROC_ENTRIES, PETSC_TRUE));
2595   PetscCall(VecGetArray(G, &g));
2596   for (i = 0; i < N; i++) {
2597     PetscCall(VecSetValue(X, i, -h, ADD_VALUES));
2598     PetscCall(VecAssemblyBegin(X));
2599     PetscCall(VecAssemblyEnd(X));
2600     PetscCall(SNESComputeObjective(snes, X, &f));
2601     PetscCall(VecSetValue(X, i, 2.0 * h, ADD_VALUES));
2602     PetscCall(VecAssemblyBegin(X));
2603     PetscCall(VecAssemblyEnd(X));
2604     PetscCall(SNESComputeObjective(snes, X, &f2));
2605     PetscCall(VecSetValue(X, i, -h, ADD_VALUES));
2606     PetscCall(VecAssemblyBegin(X));
2607     PetscCall(VecAssemblyEnd(X));
2608     if (i >= low && i < high) g[i - low] = (f2 - f) / (2.0 * h);
2609   }
2610   PetscCall(VecRestoreArray(G, &g));
2611   PetscCall(VecDestroy(&X));
2612   PetscFunctionReturn(PETSC_SUCCESS);
2613 }
2614 
2615 PetscErrorCode SNESTestFunction(SNES snes)
2616 {
2617   Vec               x, g1, g2, g3;
2618   PetscBool         complete_print = PETSC_FALSE, test = PETSC_FALSE;
2619   PetscReal         hcnorm, fdnorm, hcmax, fdmax, diffmax, diffnorm;
2620   PetscScalar       dot;
2621   MPI_Comm          comm;
2622   PetscViewer       viewer, mviewer;
2623   PetscViewerFormat format;
2624   PetscInt          tabs;
2625   static PetscBool  directionsprinted = PETSC_FALSE;
2626   SNESObjectiveFn  *objective;
2627 
2628   PetscFunctionBegin;
2629   PetscCall(SNESGetObjective(snes, &objective, NULL));
2630   if (!objective) PetscFunctionReturn(PETSC_SUCCESS);
2631 
2632   PetscObjectOptionsBegin((PetscObject)snes);
2633   PetscCall(PetscOptionsName("-snes_test_function", "Compare hand-coded and finite difference function", "None", &test));
2634   PetscCall(PetscOptionsViewer("-snes_test_function_view", "View difference between hand-coded and finite difference function element entries", "None", &mviewer, &format, &complete_print));
2635   PetscOptionsEnd();
2636   if (!test) {
2637     if (complete_print) PetscCall(PetscViewerDestroy(&mviewer));
2638     PetscFunctionReturn(PETSC_SUCCESS);
2639   }
2640 
2641   PetscCall(PetscObjectGetComm((PetscObject)snes, &comm));
2642   PetscCall(PetscViewerASCIIGetStdout(comm, &viewer));
2643   PetscCall(PetscViewerASCIIGetTab(viewer, &tabs));
2644   PetscCall(PetscViewerASCIISetTab(viewer, ((PetscObject)snes)->tablevel));
2645   PetscCall(PetscViewerASCIIPrintf(viewer, "  ---------- Testing Function -------------\n"));
2646   if (!complete_print && !directionsprinted) {
2647     PetscCall(PetscViewerASCIIPrintf(viewer, "  Run with -snes_test_function_view and optionally -snes_test_function <threshold> to show difference\n"));
2648     PetscCall(PetscViewerASCIIPrintf(viewer, "    of hand-coded and finite difference function entries greater than <threshold>.\n"));
2649   }
2650   if (!directionsprinted) {
2651     PetscCall(PetscViewerASCIIPrintf(viewer, "  Testing hand-coded Function, if (for double precision runs) ||F - Ffd||/||F|| is\n"));
2652     PetscCall(PetscViewerASCIIPrintf(viewer, "    O(1.e-8), the hand-coded Function is probably correct.\n"));
2653     directionsprinted = PETSC_TRUE;
2654   }
2655   if (complete_print) PetscCall(PetscViewerPushFormat(mviewer, format));
2656 
2657   PetscCall(SNESGetSolution(snes, &x));
2658   PetscCall(VecDuplicate(x, &g1));
2659   PetscCall(VecDuplicate(x, &g2));
2660   PetscCall(VecDuplicate(x, &g3));
2661   PetscCall(SNESComputeFunction(snes, x, g1));
2662   PetscCall(SNESComputeFunction_FD(snes, x, g2));
2663 
2664   PetscCall(VecNorm(g2, NORM_2, &fdnorm));
2665   PetscCall(VecNorm(g1, NORM_2, &hcnorm));
2666   PetscCall(VecNorm(g2, NORM_INFINITY, &fdmax));
2667   PetscCall(VecNorm(g1, NORM_INFINITY, &hcmax));
2668   PetscCall(VecDot(g1, g2, &dot));
2669   PetscCall(VecCopy(g1, g3));
2670   PetscCall(VecAXPY(g3, -1.0, g2));
2671   PetscCall(VecNorm(g3, NORM_2, &diffnorm));
2672   PetscCall(VecNorm(g3, NORM_INFINITY, &diffmax));
2673   PetscCall(PetscViewerASCIIPrintf(viewer, "  ||Ffd|| %g, ||F|| = %g, angle cosine = (Ffd'F)/||Ffd||||F|| = %g\n", (double)fdnorm, (double)hcnorm, (double)(PetscRealPart(dot) / (fdnorm * hcnorm))));
2674   PetscCall(PetscViewerASCIIPrintf(viewer, "  2-norm ||F - Ffd||/||F|| = %g, ||F - Ffd|| = %g\n", (double)(diffnorm / PetscMax(hcnorm, fdnorm)), (double)diffnorm));
2675   PetscCall(PetscViewerASCIIPrintf(viewer, "  max-norm ||F - Ffd||/||F|| = %g, ||F - Ffd|| = %g\n", (double)(diffmax / PetscMax(hcmax, fdmax)), (double)diffmax));
2676 
2677   if (complete_print) {
2678     PetscCall(PetscViewerASCIIPrintf(viewer, "  Hand-coded function ----------\n"));
2679     PetscCall(VecView(g1, mviewer));
2680     PetscCall(PetscViewerASCIIPrintf(viewer, "  Finite difference function ----------\n"));
2681     PetscCall(VecView(g2, mviewer));
2682     PetscCall(PetscViewerASCIIPrintf(viewer, "  Hand-coded minus finite-difference function ----------\n"));
2683     PetscCall(VecView(g3, mviewer));
2684   }
2685   PetscCall(VecDestroy(&g1));
2686   PetscCall(VecDestroy(&g2));
2687   PetscCall(VecDestroy(&g3));
2688 
2689   if (complete_print) {
2690     PetscCall(PetscViewerPopFormat(mviewer));
2691     PetscCall(PetscViewerDestroy(&mviewer));
2692   }
2693   PetscCall(PetscViewerASCIISetTab(viewer, tabs));
2694   PetscFunctionReturn(PETSC_SUCCESS);
2695 }
2696 
2697 PetscErrorCode SNESTestJacobian(SNES snes)
2698 {
2699   Mat               A, B, C, D, jacobian;
2700   Vec               x = snes->vec_sol, f;
2701   PetscReal         nrm, gnorm;
2702   PetscReal         threshold = 1.e-5;
2703   MatType           mattype;
2704   PetscInt          m, n, M, N;
2705   void             *functx;
2706   PetscBool         complete_print = PETSC_FALSE, threshold_print = PETSC_FALSE, test = PETSC_FALSE, flg, istranspose;
2707   PetscViewer       viewer, mviewer;
2708   MPI_Comm          comm;
2709   PetscInt          tabs;
2710   static PetscBool  directionsprinted = PETSC_FALSE;
2711   PetscViewerFormat format;
2712 
2713   PetscFunctionBegin;
2714   PetscObjectOptionsBegin((PetscObject)snes);
2715   PetscCall(PetscOptionsName("-snes_test_jacobian", "Compare hand-coded and finite difference Jacobians", "None", &test));
2716   PetscCall(PetscOptionsReal("-snes_test_jacobian", "Threshold for element difference between hand-coded and finite difference being meaningful", "None", threshold, &threshold, NULL));
2717   PetscCall(PetscOptionsDeprecated("-snes_test_jacobian_display", "-snes_test_jacobian_view", "3.13", NULL));
2718   PetscCall(PetscOptionsViewer("-snes_test_jacobian_view", "View difference between hand-coded and finite difference Jacobians element entries", "None", &mviewer, &format, &complete_print));
2719   PetscCall(PetscOptionsDeprecated("-snes_test_jacobian_display_threshold", "-snes_test_jacobian", "3.13", "-snes_test_jacobian accepts an optional threshold (since v3.10)"));
2720   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));
2721   PetscOptionsEnd();
2722   if (!test) PetscFunctionReturn(PETSC_SUCCESS);
2723 
2724   PetscCall(PetscObjectGetComm((PetscObject)snes, &comm));
2725   PetscCall(PetscViewerASCIIGetStdout(comm, &viewer));
2726   PetscCall(PetscViewerASCIIGetTab(viewer, &tabs));
2727   PetscCall(PetscViewerASCIISetTab(viewer, ((PetscObject)snes)->tablevel));
2728   PetscCall(PetscViewerASCIIPrintf(viewer, "  ---------- Testing Jacobian -------------\n"));
2729   if (!complete_print && !directionsprinted) {
2730     PetscCall(PetscViewerASCIIPrintf(viewer, "  Run with -snes_test_jacobian_view and optionally -snes_test_jacobian <threshold> to show difference\n"));
2731     PetscCall(PetscViewerASCIIPrintf(viewer, "    of hand-coded and finite difference Jacobian entries greater than <threshold>.\n"));
2732   }
2733   if (!directionsprinted) {
2734     PetscCall(PetscViewerASCIIPrintf(viewer, "  Testing hand-coded Jacobian, if (for double precision runs) ||J - Jfd||_F/||J||_F is\n"));
2735     PetscCall(PetscViewerASCIIPrintf(viewer, "    O(1.e-8), the hand-coded Jacobian is probably correct.\n"));
2736     directionsprinted = PETSC_TRUE;
2737   }
2738   if (complete_print) PetscCall(PetscViewerPushFormat(mviewer, format));
2739 
2740   PetscCall(PetscObjectTypeCompare((PetscObject)snes->jacobian, MATMFFD, &flg));
2741   if (!flg) jacobian = snes->jacobian;
2742   else jacobian = snes->jacobian_pre;
2743 
2744   if (!x) PetscCall(MatCreateVecs(jacobian, &x, NULL));
2745   else PetscCall(PetscObjectReference((PetscObject)x));
2746   PetscCall(VecDuplicate(x, &f));
2747 
2748   /* evaluate the function at this point because SNESComputeJacobianDefault() assumes that the function has been evaluated and put into snes->vec_func */
2749   PetscCall(SNESComputeFunction(snes, x, f));
2750   PetscCall(VecDestroy(&f));
2751   PetscCall(PetscObjectTypeCompare((PetscObject)snes, SNESKSPTRANSPOSEONLY, &istranspose));
2752   while (jacobian) {
2753     Mat JT = NULL, Jsave = NULL;
2754 
2755     if (istranspose) {
2756       PetscCall(MatCreateTranspose(jacobian, &JT));
2757       Jsave    = jacobian;
2758       jacobian = JT;
2759     }
2760     PetscCall(PetscObjectBaseTypeCompareAny((PetscObject)jacobian, &flg, MATSEQAIJ, MATMPIAIJ, MATSEQDENSE, MATMPIDENSE, MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ, ""));
2761     if (flg) {
2762       A = jacobian;
2763       PetscCall(PetscObjectReference((PetscObject)A));
2764     } else {
2765       PetscCall(MatComputeOperator(jacobian, MATAIJ, &A));
2766     }
2767 
2768     PetscCall(MatGetType(A, &mattype));
2769     PetscCall(MatGetSize(A, &M, &N));
2770     PetscCall(MatGetLocalSize(A, &m, &n));
2771     PetscCall(MatCreate(PetscObjectComm((PetscObject)A), &B));
2772     PetscCall(MatSetType(B, mattype));
2773     PetscCall(MatSetSizes(B, m, n, M, N));
2774     PetscCall(MatSetBlockSizesFromMats(B, A, A));
2775     PetscCall(MatSetUp(B));
2776     PetscCall(MatSetOption(B, MAT_NEW_NONZERO_ALLOCATION_ERR, PETSC_FALSE));
2777 
2778     PetscCall(SNESGetFunction(snes, NULL, NULL, &functx));
2779     PetscCall(SNESComputeJacobianDefault(snes, x, B, B, functx));
2780 
2781     PetscCall(MatDuplicate(B, MAT_COPY_VALUES, &D));
2782     PetscCall(MatAYPX(D, -1.0, A, DIFFERENT_NONZERO_PATTERN));
2783     PetscCall(MatNorm(D, NORM_FROBENIUS, &nrm));
2784     PetscCall(MatNorm(A, NORM_FROBENIUS, &gnorm));
2785     PetscCall(MatDestroy(&D));
2786     if (!gnorm) gnorm = 1; /* just in case */
2787     PetscCall(PetscViewerASCIIPrintf(viewer, "  ||J - Jfd||_F/||J||_F = %g, ||J - Jfd||_F = %g\n", (double)(nrm / gnorm), (double)nrm));
2788 
2789     if (complete_print) {
2790       PetscCall(PetscViewerASCIIPrintf(viewer, "  Hand-coded Jacobian ----------\n"));
2791       PetscCall(MatView(A, mviewer));
2792       PetscCall(PetscViewerASCIIPrintf(viewer, "  Finite difference Jacobian ----------\n"));
2793       PetscCall(MatView(B, mviewer));
2794     }
2795 
2796     if (threshold_print || complete_print) {
2797       PetscInt           Istart, Iend, *ccols, bncols, cncols, j, row;
2798       PetscScalar       *cvals;
2799       const PetscInt    *bcols;
2800       const PetscScalar *bvals;
2801 
2802       PetscCall(MatCreate(PetscObjectComm((PetscObject)A), &C));
2803       PetscCall(MatSetType(C, mattype));
2804       PetscCall(MatSetSizes(C, m, n, M, N));
2805       PetscCall(MatSetBlockSizesFromMats(C, A, A));
2806       PetscCall(MatSetUp(C));
2807       PetscCall(MatSetOption(C, MAT_NEW_NONZERO_ALLOCATION_ERR, PETSC_FALSE));
2808 
2809       PetscCall(MatAYPX(B, -1.0, A, DIFFERENT_NONZERO_PATTERN));
2810       PetscCall(MatGetOwnershipRange(B, &Istart, &Iend));
2811 
2812       for (row = Istart; row < Iend; row++) {
2813         PetscCall(MatGetRow(B, row, &bncols, &bcols, &bvals));
2814         PetscCall(PetscMalloc2(bncols, &ccols, bncols, &cvals));
2815         for (j = 0, cncols = 0; j < bncols; j++) {
2816           if (PetscAbsScalar(bvals[j]) > threshold) {
2817             ccols[cncols] = bcols[j];
2818             cvals[cncols] = bvals[j];
2819             cncols += 1;
2820           }
2821         }
2822         if (cncols) PetscCall(MatSetValues(C, 1, &row, cncols, ccols, cvals, INSERT_VALUES));
2823         PetscCall(MatRestoreRow(B, row, &bncols, &bcols, &bvals));
2824         PetscCall(PetscFree2(ccols, cvals));
2825       }
2826       PetscCall(MatAssemblyBegin(C, MAT_FINAL_ASSEMBLY));
2827       PetscCall(MatAssemblyEnd(C, MAT_FINAL_ASSEMBLY));
2828       PetscCall(PetscViewerASCIIPrintf(viewer, "  Hand-coded minus finite-difference Jacobian with tolerance %g ----------\n", (double)threshold));
2829       PetscCall(MatView(C, complete_print ? mviewer : viewer));
2830       PetscCall(MatDestroy(&C));
2831     }
2832     PetscCall(MatDestroy(&A));
2833     PetscCall(MatDestroy(&B));
2834     PetscCall(MatDestroy(&JT));
2835     if (Jsave) jacobian = Jsave;
2836     if (jacobian != snes->jacobian_pre) {
2837       jacobian = snes->jacobian_pre;
2838       PetscCall(PetscViewerASCIIPrintf(viewer, "  ---------- Testing Jacobian for preconditioner -------------\n"));
2839     } else jacobian = NULL;
2840   }
2841   PetscCall(VecDestroy(&x));
2842   if (complete_print) PetscCall(PetscViewerPopFormat(mviewer));
2843   if (mviewer) PetscCall(PetscViewerDestroy(&mviewer));
2844   PetscCall(PetscViewerASCIISetTab(viewer, tabs));
2845   PetscFunctionReturn(PETSC_SUCCESS);
2846 }
2847 
2848 /*@
2849   SNESComputeJacobian - Computes the Jacobian matrix that has been set with `SNESSetJacobian()`.
2850 
2851   Collective
2852 
2853   Input Parameters:
2854 + snes - the `SNES` context
2855 - X    - input vector
2856 
2857   Output Parameters:
2858 + A - Jacobian matrix
2859 - B - optional matrix for building the preconditioner, usually the same as `A`
2860 
2861   Options Database Keys:
2862 + -snes_lag_preconditioner <lag>           - how often to rebuild preconditioner
2863 . -snes_lag_jacobian <lag>                 - how often to rebuild Jacobian
2864 . -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.
2865 . -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
2866 . -snes_compare_explicit                   - Compare the computed Jacobian to the finite difference Jacobian and output the differences
2867 . -snes_compare_explicit_draw              - Compare the computed Jacobian to the finite difference Jacobian and draw the result
2868 . -snes_compare_explicit_contour           - Compare the computed Jacobian to the finite difference Jacobian and draw a contour plot with the result
2869 . -snes_compare_operator                   - Make the comparison options above use the operator instead of the preconditioning matrix
2870 . -snes_compare_coloring                   - Compute the finite difference Jacobian using coloring and display norms of difference
2871 . -snes_compare_coloring_display           - Compute the finite difference Jacobian using coloring and display verbose differences
2872 . -snes_compare_coloring_threshold         - Display only those matrix entries that differ by more than a given threshold
2873 . -snes_compare_coloring_threshold_atol    - Absolute tolerance for difference in matrix entries to be displayed by `-snes_compare_coloring_threshold`
2874 . -snes_compare_coloring_threshold_rtol    - Relative tolerance for difference in matrix entries to be displayed by `-snes_compare_coloring_threshold`
2875 . -snes_compare_coloring_draw              - Compute the finite difference Jacobian using coloring and draw differences
2876 - -snes_compare_coloring_draw_contour      - Compute the finite difference Jacobian using coloring and show contours of matrices and differences
2877 
2878   Level: developer
2879 
2880   Note:
2881   Most users should not need to explicitly call this routine, as it
2882   is used internally within the nonlinear solvers.
2883 
2884   Developer Note:
2885   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
2886   with the `SNESType` of test that has been removed.
2887 
2888 .seealso: [](ch_snes), `SNESSetJacobian()`, `KSPSetOperators()`, `MatStructure`, `SNESSetLagPreconditioner()`, `SNESSetLagJacobian()`
2889 @*/
2890 PetscErrorCode SNESComputeJacobian(SNES snes, Vec X, Mat A, Mat B)
2891 {
2892   PetscBool flag;
2893   DM        dm;
2894   DMSNES    sdm;
2895   KSP       ksp;
2896 
2897   PetscFunctionBegin;
2898   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
2899   PetscValidHeaderSpecific(X, VEC_CLASSID, 2);
2900   PetscCheckSameComm(snes, 1, X, 2);
2901   PetscCall(VecValidValues_Internal(X, 2, PETSC_TRUE));
2902   PetscCall(SNESGetDM(snes, &dm));
2903   PetscCall(DMGetDMSNES(dm, &sdm));
2904 
2905   /* make sure that MatAssemblyBegin/End() is called on A matrix if it is matrix-free */
2906   if (snes->lagjacobian == -2) {
2907     snes->lagjacobian = -1;
2908 
2909     PetscCall(PetscInfo(snes, "Recomputing Jacobian/preconditioner because lag is -2 (means compute Jacobian, but then never again) \n"));
2910   } else if (snes->lagjacobian == -1) {
2911     PetscCall(PetscInfo(snes, "Reusing Jacobian/preconditioner because lag is -1\n"));
2912     PetscCall(PetscObjectTypeCompare((PetscObject)A, MATMFFD, &flag));
2913     if (flag) {
2914       PetscCall(MatAssemblyBegin(A, MAT_FINAL_ASSEMBLY));
2915       PetscCall(MatAssemblyEnd(A, MAT_FINAL_ASSEMBLY));
2916     }
2917     PetscFunctionReturn(PETSC_SUCCESS);
2918   } else if (snes->lagjacobian > 1 && (snes->iter + snes->jac_iter) % snes->lagjacobian) {
2919     PetscCall(PetscInfo(snes, "Reusing Jacobian/preconditioner because lag is %" PetscInt_FMT " and SNES iteration is %" PetscInt_FMT "\n", snes->lagjacobian, snes->iter));
2920     PetscCall(PetscObjectTypeCompare((PetscObject)A, MATMFFD, &flag));
2921     if (flag) {
2922       PetscCall(MatAssemblyBegin(A, MAT_FINAL_ASSEMBLY));
2923       PetscCall(MatAssemblyEnd(A, MAT_FINAL_ASSEMBLY));
2924     }
2925     PetscFunctionReturn(PETSC_SUCCESS);
2926   }
2927   if (snes->npc && snes->npcside == PC_LEFT) {
2928     PetscCall(MatAssemblyBegin(A, MAT_FINAL_ASSEMBLY));
2929     PetscCall(MatAssemblyEnd(A, MAT_FINAL_ASSEMBLY));
2930     PetscFunctionReturn(PETSC_SUCCESS);
2931   }
2932 
2933   PetscCall(PetscLogEventBegin(SNES_JacobianEval, snes, X, A, B));
2934   PetscCall(VecLockReadPush(X));
2935   {
2936     void           *ctx;
2937     SNESJacobianFn *J;
2938     PetscCall(DMSNESGetJacobian(dm, &J, &ctx));
2939     PetscCallBack("SNES callback Jacobian", (*J)(snes, X, A, B, ctx));
2940   }
2941   PetscCall(VecLockReadPop(X));
2942   PetscCall(PetscLogEventEnd(SNES_JacobianEval, snes, X, A, B));
2943 
2944   /* attach latest linearization point to the preconditioning matrix */
2945   PetscCall(PetscObjectCompose((PetscObject)B, "__SNES_latest_X", (PetscObject)X));
2946 
2947   /* the next line ensures that snes->ksp exists */
2948   PetscCall(SNESGetKSP(snes, &ksp));
2949   if (snes->lagpreconditioner == -2) {
2950     PetscCall(PetscInfo(snes, "Rebuilding preconditioner exactly once since lag is -2\n"));
2951     PetscCall(KSPSetReusePreconditioner(snes->ksp, PETSC_FALSE));
2952     snes->lagpreconditioner = -1;
2953   } else if (snes->lagpreconditioner == -1) {
2954     PetscCall(PetscInfo(snes, "Reusing preconditioner because lag is -1\n"));
2955     PetscCall(KSPSetReusePreconditioner(snes->ksp, PETSC_TRUE));
2956   } else if (snes->lagpreconditioner > 1 && (snes->iter + snes->pre_iter) % snes->lagpreconditioner) {
2957     PetscCall(PetscInfo(snes, "Reusing preconditioner because lag is %" PetscInt_FMT " and SNES iteration is %" PetscInt_FMT "\n", snes->lagpreconditioner, snes->iter));
2958     PetscCall(KSPSetReusePreconditioner(snes->ksp, PETSC_TRUE));
2959   } else {
2960     PetscCall(PetscInfo(snes, "Rebuilding preconditioner\n"));
2961     PetscCall(KSPSetReusePreconditioner(snes->ksp, PETSC_FALSE));
2962   }
2963 
2964   /* monkey business to allow testing Jacobians in multilevel solvers.
2965      This is needed because the SNESTestXXX interface does not accept vectors and matrices */
2966   {
2967     Vec xsave            = snes->vec_sol;
2968     Mat jacobiansave     = snes->jacobian;
2969     Mat jacobian_presave = snes->jacobian_pre;
2970 
2971     snes->vec_sol      = X;
2972     snes->jacobian     = A;
2973     snes->jacobian_pre = B;
2974     PetscCall(SNESTestFunction(snes));
2975     PetscCall(SNESTestJacobian(snes));
2976 
2977     snes->vec_sol      = xsave;
2978     snes->jacobian     = jacobiansave;
2979     snes->jacobian_pre = jacobian_presave;
2980   }
2981 
2982   {
2983     PetscBool flag = PETSC_FALSE, flag_draw = PETSC_FALSE, flag_contour = PETSC_FALSE, flag_operator = PETSC_FALSE;
2984     PetscCall(PetscOptionsCreateViewer(PetscObjectComm((PetscObject)snes), ((PetscObject)snes)->options, ((PetscObject)snes)->prefix, "-snes_compare_explicit", NULL, NULL, &flag));
2985     PetscCall(PetscOptionsCreateViewer(PetscObjectComm((PetscObject)snes), ((PetscObject)snes)->options, ((PetscObject)snes)->prefix, "-snes_compare_explicit_draw", NULL, NULL, &flag_draw));
2986     PetscCall(PetscOptionsCreateViewer(PetscObjectComm((PetscObject)snes), ((PetscObject)snes)->options, ((PetscObject)snes)->prefix, "-snes_compare_explicit_draw_contour", NULL, NULL, &flag_contour));
2987     PetscCall(PetscOptionsCreateViewer(PetscObjectComm((PetscObject)snes), ((PetscObject)snes)->options, ((PetscObject)snes)->prefix, "-snes_compare_operator", NULL, NULL, &flag_operator));
2988     if (flag || flag_draw || flag_contour) {
2989       Mat         Bexp_mine = NULL, Bexp, FDexp;
2990       PetscViewer vdraw, vstdout;
2991       PetscBool   flg;
2992       if (flag_operator) {
2993         PetscCall(MatComputeOperator(A, MATAIJ, &Bexp_mine));
2994         Bexp = Bexp_mine;
2995       } else {
2996         /* See if the preconditioning matrix can be viewed and added directly */
2997         PetscCall(PetscObjectBaseTypeCompareAny((PetscObject)B, &flg, MATSEQAIJ, MATMPIAIJ, MATSEQDENSE, MATMPIDENSE, MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPIBAIJ, ""));
2998         if (flg) Bexp = B;
2999         else {
3000           /* If the "preconditioning" matrix is itself MATSHELL or some other type without direct support */
3001           PetscCall(MatComputeOperator(B, MATAIJ, &Bexp_mine));
3002           Bexp = Bexp_mine;
3003         }
3004       }
3005       PetscCall(MatConvert(Bexp, MATSAME, MAT_INITIAL_MATRIX, &FDexp));
3006       PetscCall(SNESComputeJacobianDefault(snes, X, FDexp, FDexp, NULL));
3007       PetscCall(PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)snes), &vstdout));
3008       if (flag_draw || flag_contour) {
3009         PetscCall(PetscViewerDrawOpen(PetscObjectComm((PetscObject)snes), NULL, "Explicit Jacobians", PETSC_DECIDE, PETSC_DECIDE, 300, 300, &vdraw));
3010         if (flag_contour) PetscCall(PetscViewerPushFormat(vdraw, PETSC_VIEWER_DRAW_CONTOUR));
3011       } else vdraw = NULL;
3012       PetscCall(PetscViewerASCIIPrintf(vstdout, "Explicit %s\n", flag_operator ? "Jacobian" : "preconditioning Jacobian"));
3013       if (flag) PetscCall(MatView(Bexp, vstdout));
3014       if (vdraw) PetscCall(MatView(Bexp, vdraw));
3015       PetscCall(PetscViewerASCIIPrintf(vstdout, "Finite difference Jacobian\n"));
3016       if (flag) PetscCall(MatView(FDexp, vstdout));
3017       if (vdraw) PetscCall(MatView(FDexp, vdraw));
3018       PetscCall(MatAYPX(FDexp, -1.0, Bexp, SAME_NONZERO_PATTERN));
3019       PetscCall(PetscViewerASCIIPrintf(vstdout, "User-provided matrix minus finite difference Jacobian\n"));
3020       if (flag) PetscCall(MatView(FDexp, vstdout));
3021       if (vdraw) { /* Always use contour for the difference */
3022         PetscCall(PetscViewerPushFormat(vdraw, PETSC_VIEWER_DRAW_CONTOUR));
3023         PetscCall(MatView(FDexp, vdraw));
3024         PetscCall(PetscViewerPopFormat(vdraw));
3025       }
3026       if (flag_contour) PetscCall(PetscViewerPopFormat(vdraw));
3027       PetscCall(PetscViewerDestroy(&vdraw));
3028       PetscCall(MatDestroy(&Bexp_mine));
3029       PetscCall(MatDestroy(&FDexp));
3030     }
3031   }
3032   {
3033     PetscBool flag = PETSC_FALSE, flag_display = PETSC_FALSE, flag_draw = PETSC_FALSE, flag_contour = PETSC_FALSE, flag_threshold = PETSC_FALSE;
3034     PetscReal threshold_atol = PETSC_SQRT_MACHINE_EPSILON, threshold_rtol = 10 * PETSC_SQRT_MACHINE_EPSILON;
3035     PetscCall(PetscOptionsCreateViewer(PetscObjectComm((PetscObject)snes), ((PetscObject)snes)->options, ((PetscObject)snes)->prefix, "-snes_compare_coloring", NULL, NULL, &flag));
3036     PetscCall(PetscOptionsCreateViewer(PetscObjectComm((PetscObject)snes), ((PetscObject)snes)->options, ((PetscObject)snes)->prefix, "-snes_compare_coloring_display", NULL, NULL, &flag_display));
3037     PetscCall(PetscOptionsCreateViewer(PetscObjectComm((PetscObject)snes), ((PetscObject)snes)->options, ((PetscObject)snes)->prefix, "-snes_compare_coloring_draw", NULL, NULL, &flag_draw));
3038     PetscCall(PetscOptionsCreateViewer(PetscObjectComm((PetscObject)snes), ((PetscObject)snes)->options, ((PetscObject)snes)->prefix, "-snes_compare_coloring_draw_contour", NULL, NULL, &flag_contour));
3039     PetscCall(PetscOptionsCreateViewer(PetscObjectComm((PetscObject)snes), ((PetscObject)snes)->options, ((PetscObject)snes)->prefix, "-snes_compare_coloring_threshold", NULL, NULL, &flag_threshold));
3040     if (flag_threshold) {
3041       PetscCall(PetscOptionsGetReal(((PetscObject)snes)->options, ((PetscObject)snes)->prefix, "-snes_compare_coloring_threshold_rtol", &threshold_rtol, NULL));
3042       PetscCall(PetscOptionsGetReal(((PetscObject)snes)->options, ((PetscObject)snes)->prefix, "-snes_compare_coloring_threshold_atol", &threshold_atol, NULL));
3043     }
3044     if (flag || flag_display || flag_draw || flag_contour || flag_threshold) {
3045       Mat             Bfd;
3046       PetscViewer     vdraw, vstdout;
3047       MatColoring     coloring;
3048       ISColoring      iscoloring;
3049       MatFDColoring   matfdcoloring;
3050       SNESFunctionFn *func;
3051       void           *funcctx;
3052       PetscReal       norm1, norm2, normmax;
3053 
3054       PetscCall(MatDuplicate(B, MAT_DO_NOT_COPY_VALUES, &Bfd));
3055       PetscCall(MatColoringCreate(Bfd, &coloring));
3056       PetscCall(MatColoringSetType(coloring, MATCOLORINGSL));
3057       PetscCall(MatColoringSetFromOptions(coloring));
3058       PetscCall(MatColoringApply(coloring, &iscoloring));
3059       PetscCall(MatColoringDestroy(&coloring));
3060       PetscCall(MatFDColoringCreate(Bfd, iscoloring, &matfdcoloring));
3061       PetscCall(MatFDColoringSetFromOptions(matfdcoloring));
3062       PetscCall(MatFDColoringSetUp(Bfd, iscoloring, matfdcoloring));
3063       PetscCall(ISColoringDestroy(&iscoloring));
3064 
3065       /* This method of getting the function is currently unreliable since it doesn't work for DM local functions. */
3066       PetscCall(SNESGetFunction(snes, NULL, &func, &funcctx));
3067       PetscCall(MatFDColoringSetFunction(matfdcoloring, (PetscErrorCode(*)(void))func, funcctx));
3068       PetscCall(PetscObjectSetOptionsPrefix((PetscObject)matfdcoloring, ((PetscObject)snes)->prefix));
3069       PetscCall(PetscObjectAppendOptionsPrefix((PetscObject)matfdcoloring, "coloring_"));
3070       PetscCall(MatFDColoringSetFromOptions(matfdcoloring));
3071       PetscCall(MatFDColoringApply(Bfd, matfdcoloring, X, snes));
3072       PetscCall(MatFDColoringDestroy(&matfdcoloring));
3073 
3074       PetscCall(PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)snes), &vstdout));
3075       if (flag_draw || flag_contour) {
3076         PetscCall(PetscViewerDrawOpen(PetscObjectComm((PetscObject)snes), NULL, "Colored Jacobians", PETSC_DECIDE, PETSC_DECIDE, 300, 300, &vdraw));
3077         if (flag_contour) PetscCall(PetscViewerPushFormat(vdraw, PETSC_VIEWER_DRAW_CONTOUR));
3078       } else vdraw = NULL;
3079       PetscCall(PetscViewerASCIIPrintf(vstdout, "Explicit preconditioning Jacobian\n"));
3080       if (flag_display) PetscCall(MatView(B, vstdout));
3081       if (vdraw) PetscCall(MatView(B, vdraw));
3082       PetscCall(PetscViewerASCIIPrintf(vstdout, "Colored Finite difference Jacobian\n"));
3083       if (flag_display) PetscCall(MatView(Bfd, vstdout));
3084       if (vdraw) PetscCall(MatView(Bfd, vdraw));
3085       PetscCall(MatAYPX(Bfd, -1.0, B, SAME_NONZERO_PATTERN));
3086       PetscCall(MatNorm(Bfd, NORM_1, &norm1));
3087       PetscCall(MatNorm(Bfd, NORM_FROBENIUS, &norm2));
3088       PetscCall(MatNorm(Bfd, NORM_MAX, &normmax));
3089       PetscCall(PetscViewerASCIIPrintf(vstdout, "User-provided matrix minus finite difference Jacobian, norm1=%g normFrob=%g normmax=%g\n", (double)norm1, (double)norm2, (double)normmax));
3090       if (flag_display) PetscCall(MatView(Bfd, vstdout));
3091       if (vdraw) { /* Always use contour for the difference */
3092         PetscCall(PetscViewerPushFormat(vdraw, PETSC_VIEWER_DRAW_CONTOUR));
3093         PetscCall(MatView(Bfd, vdraw));
3094         PetscCall(PetscViewerPopFormat(vdraw));
3095       }
3096       if (flag_contour) PetscCall(PetscViewerPopFormat(vdraw));
3097 
3098       if (flag_threshold) {
3099         PetscInt bs, rstart, rend, i;
3100         PetscCall(MatGetBlockSize(B, &bs));
3101         PetscCall(MatGetOwnershipRange(B, &rstart, &rend));
3102         for (i = rstart; i < rend; i++) {
3103           const PetscScalar *ba, *ca;
3104           const PetscInt    *bj, *cj;
3105           PetscInt           bn, cn, j, maxentrycol = -1, maxdiffcol = -1, maxrdiffcol = -1;
3106           PetscReal          maxentry = 0, maxdiff = 0, maxrdiff = 0;
3107           PetscCall(MatGetRow(B, i, &bn, &bj, &ba));
3108           PetscCall(MatGetRow(Bfd, i, &cn, &cj, &ca));
3109           PetscCheck(bn == cn, ((PetscObject)A)->comm, PETSC_ERR_PLIB, "Unexpected different nonzero pattern in -snes_compare_coloring_threshold");
3110           for (j = 0; j < bn; j++) {
3111             PetscReal rdiff = PetscAbsScalar(ca[j]) / (threshold_atol + threshold_rtol * PetscAbsScalar(ba[j]));
3112             if (PetscAbsScalar(ba[j]) > PetscAbs(maxentry)) {
3113               maxentrycol = bj[j];
3114               maxentry    = PetscRealPart(ba[j]);
3115             }
3116             if (PetscAbsScalar(ca[j]) > PetscAbs(maxdiff)) {
3117               maxdiffcol = bj[j];
3118               maxdiff    = PetscRealPart(ca[j]);
3119             }
3120             if (rdiff > maxrdiff) {
3121               maxrdiffcol = bj[j];
3122               maxrdiff    = rdiff;
3123             }
3124           }
3125           if (maxrdiff > 1) {
3126             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));
3127             for (j = 0; j < bn; j++) {
3128               PetscReal rdiff;
3129               rdiff = PetscAbsScalar(ca[j]) / (threshold_atol + threshold_rtol * PetscAbsScalar(ba[j]));
3130               if (rdiff > 1) PetscCall(PetscViewerASCIIPrintf(vstdout, " (%" PetscInt_FMT ",%g:%g)", bj[j], (double)PetscRealPart(ba[j]), (double)PetscRealPart(ca[j])));
3131             }
3132             PetscCall(PetscViewerASCIIPrintf(vstdout, "\n"));
3133           }
3134           PetscCall(MatRestoreRow(B, i, &bn, &bj, &ba));
3135           PetscCall(MatRestoreRow(Bfd, i, &cn, &cj, &ca));
3136         }
3137       }
3138       PetscCall(PetscViewerDestroy(&vdraw));
3139       PetscCall(MatDestroy(&Bfd));
3140     }
3141   }
3142   PetscFunctionReturn(PETSC_SUCCESS);
3143 }
3144 
3145 /*@C
3146   SNESSetJacobian - Sets the function to compute Jacobian as well as the
3147   location to store the matrix.
3148 
3149   Logically Collective
3150 
3151   Input Parameters:
3152 + snes - the `SNES` context
3153 . Amat - the matrix that defines the (approximate) Jacobian
3154 . Pmat - the matrix to be used in constructing the preconditioner, usually the same as `Amat`.
3155 . J    - Jacobian evaluation routine (if `NULL` then `SNES` retains any previously set value), see `SNESJacobianFn` for details
3156 - ctx  - [optional] user-defined context for private data for the
3157          Jacobian evaluation routine (may be `NULL`) (if `NULL` then `SNES` retains any previously set value)
3158 
3159   Level: beginner
3160 
3161   Notes:
3162   If the `Amat` matrix and `Pmat` matrix are different you must call `MatAssemblyBegin()`/`MatAssemblyEnd()` on
3163   each matrix.
3164 
3165   If you know the operator `Amat` has a null space you can use `MatSetNullSpace()` and `MatSetTransposeNullSpace()` to supply the null
3166   space to `Amat` and the `KSP` solvers will automatically use that null space as needed during the solution process.
3167 
3168   If using `SNESComputeJacobianDefaultColor()` to assemble a Jacobian, the `ctx` argument
3169   must be a `MatFDColoring`.
3170 
3171   Other defect-correction schemes can be used by computing a different matrix in place of the Jacobian.  One common
3172   example is to use the "Picard linearization" which only differentiates through the highest order parts of each term using `SNESSetPicard()`
3173 
3174 .seealso: [](ch_snes), `SNES`, `KSPSetOperators()`, `SNESSetFunction()`, `MatMFFDComputeJacobian()`, `SNESComputeJacobianDefaultColor()`, `MatStructure`,
3175           `SNESSetPicard()`, `SNESJacobianFn`, `SNESFunctionFn`
3176 @*/
3177 PetscErrorCode SNESSetJacobian(SNES snes, Mat Amat, Mat Pmat, SNESJacobianFn *J, void *ctx)
3178 {
3179   DM dm;
3180 
3181   PetscFunctionBegin;
3182   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
3183   if (Amat) PetscValidHeaderSpecific(Amat, MAT_CLASSID, 2);
3184   if (Pmat) PetscValidHeaderSpecific(Pmat, MAT_CLASSID, 3);
3185   if (Amat) PetscCheckSameComm(snes, 1, Amat, 2);
3186   if (Pmat) PetscCheckSameComm(snes, 1, Pmat, 3);
3187   PetscCall(SNESGetDM(snes, &dm));
3188   PetscCall(DMSNESSetJacobian(dm, J, ctx));
3189   if (Amat) {
3190     PetscCall(PetscObjectReference((PetscObject)Amat));
3191     PetscCall(MatDestroy(&snes->jacobian));
3192 
3193     snes->jacobian = Amat;
3194   }
3195   if (Pmat) {
3196     PetscCall(PetscObjectReference((PetscObject)Pmat));
3197     PetscCall(MatDestroy(&snes->jacobian_pre));
3198 
3199     snes->jacobian_pre = Pmat;
3200   }
3201   PetscFunctionReturn(PETSC_SUCCESS);
3202 }
3203 
3204 /*@C
3205   SNESGetJacobian - Returns the Jacobian matrix and optionally the user
3206   provided context for evaluating the Jacobian.
3207 
3208   Not Collective, but `Mat` object will be parallel if `SNES` is
3209 
3210   Input Parameter:
3211 . snes - the nonlinear solver context
3212 
3213   Output Parameters:
3214 + Amat - location to stash (approximate) Jacobian matrix (or `NULL`)
3215 . Pmat - location to stash matrix used to compute the preconditioner (or `NULL`)
3216 . J    - location to put Jacobian function (or `NULL`), for calling sequence see `SNESJacobianFn`
3217 - ctx  - location to stash Jacobian ctx (or `NULL`)
3218 
3219   Level: advanced
3220 
3221 .seealso: [](ch_snes), `SNES`, `Mat`, `SNESSetJacobian()`, `SNESComputeJacobian()`, `SNESJacobianFn`, `SNESGetFunction()`
3222 @*/
3223 PetscErrorCode SNESGetJacobian(SNES snes, Mat *Amat, Mat *Pmat, SNESJacobianFn **J, void **ctx)
3224 {
3225   DM dm;
3226 
3227   PetscFunctionBegin;
3228   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
3229   if (Amat) *Amat = snes->jacobian;
3230   if (Pmat) *Pmat = snes->jacobian_pre;
3231   PetscCall(SNESGetDM(snes, &dm));
3232   PetscCall(DMSNESGetJacobian(dm, J, ctx));
3233   PetscFunctionReturn(PETSC_SUCCESS);
3234 }
3235 
3236 static PetscErrorCode SNESSetDefaultComputeJacobian(SNES snes)
3237 {
3238   DM     dm;
3239   DMSNES sdm;
3240 
3241   PetscFunctionBegin;
3242   PetscCall(SNESGetDM(snes, &dm));
3243   PetscCall(DMGetDMSNES(dm, &sdm));
3244   if (!sdm->ops->computejacobian && snes->jacobian_pre) {
3245     DM        dm;
3246     PetscBool isdense, ismf;
3247 
3248     PetscCall(SNESGetDM(snes, &dm));
3249     PetscCall(PetscObjectTypeCompareAny((PetscObject)snes->jacobian_pre, &isdense, MATSEQDENSE, MATMPIDENSE, MATDENSE, NULL));
3250     PetscCall(PetscObjectTypeCompareAny((PetscObject)snes->jacobian_pre, &ismf, MATMFFD, MATSHELL, NULL));
3251     if (isdense) {
3252       PetscCall(DMSNESSetJacobian(dm, SNESComputeJacobianDefault, NULL));
3253     } else if (!ismf) {
3254       PetscCall(DMSNESSetJacobian(dm, SNESComputeJacobianDefaultColor, NULL));
3255     }
3256   }
3257   PetscFunctionReturn(PETSC_SUCCESS);
3258 }
3259 
3260 /*@
3261   SNESSetUp - Sets up the internal data structures for the later use
3262   of a nonlinear solver.
3263 
3264   Collective
3265 
3266   Input Parameter:
3267 . snes - the `SNES` context
3268 
3269   Level: advanced
3270 
3271   Note:
3272   For basic use of the `SNES` solvers the user need not explicitly call
3273   `SNESSetUp()`, since these actions will automatically occur during
3274   the call to `SNESSolve()`.  However, if one wishes to control this
3275   phase separately, `SNESSetUp()` should be called after `SNESCreate()`
3276   and optional routines of the form SNESSetXXX(), but before `SNESSolve()`.
3277 
3278 .seealso: [](ch_snes), `SNES`, `SNESCreate()`, `SNESSolve()`, `SNESDestroy()`
3279 @*/
3280 PetscErrorCode SNESSetUp(SNES snes)
3281 {
3282   DM             dm;
3283   DMSNES         sdm;
3284   SNESLineSearch linesearch, pclinesearch;
3285   void          *lsprectx, *lspostctx;
3286   PetscBool      mf_operator, mf;
3287   Vec            f, fpc;
3288   void          *funcctx;
3289   void          *jacctx, *appctx;
3290   Mat            j, jpre;
3291   PetscErrorCode (*precheck)(SNESLineSearch, Vec, Vec, PetscBool *, void *);
3292   PetscErrorCode (*postcheck)(SNESLineSearch, Vec, Vec, Vec, PetscBool *, PetscBool *, void *);
3293   SNESFunctionFn *func;
3294   SNESJacobianFn *jac;
3295 
3296   PetscFunctionBegin;
3297   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
3298   if (snes->setupcalled) PetscFunctionReturn(PETSC_SUCCESS);
3299   PetscCall(PetscLogEventBegin(SNES_SetUp, snes, 0, 0, 0));
3300 
3301   if (!((PetscObject)snes)->type_name) PetscCall(SNESSetType(snes, SNESNEWTONLS));
3302 
3303   PetscCall(SNESGetFunction(snes, &snes->vec_func, NULL, NULL));
3304 
3305   PetscCall(SNESGetDM(snes, &dm));
3306   PetscCall(DMGetDMSNES(dm, &sdm));
3307   PetscCall(SNESSetDefaultComputeJacobian(snes));
3308 
3309   if (!snes->vec_func) PetscCall(DMCreateGlobalVector(dm, &snes->vec_func));
3310 
3311   if (!snes->ksp) PetscCall(SNESGetKSP(snes, &snes->ksp));
3312 
3313   if (snes->linesearch) {
3314     PetscCall(SNESGetLineSearch(snes, &snes->linesearch));
3315     PetscCall(SNESLineSearchSetFunction(snes->linesearch, SNESComputeFunction));
3316   }
3317 
3318   PetscCall(SNESGetUseMatrixFree(snes, &mf_operator, &mf));
3319   if (snes->npc && snes->npcside == PC_LEFT) {
3320     snes->mf          = PETSC_TRUE;
3321     snes->mf_operator = PETSC_FALSE;
3322   }
3323 
3324   if (snes->npc) {
3325     /* copy the DM over */
3326     PetscCall(SNESGetDM(snes, &dm));
3327     PetscCall(SNESSetDM(snes->npc, dm));
3328 
3329     PetscCall(SNESGetFunction(snes, &f, &func, &funcctx));
3330     PetscCall(VecDuplicate(f, &fpc));
3331     PetscCall(SNESSetFunction(snes->npc, fpc, func, funcctx));
3332     PetscCall(SNESGetJacobian(snes, &j, &jpre, &jac, &jacctx));
3333     PetscCall(SNESSetJacobian(snes->npc, j, jpre, jac, jacctx));
3334     PetscCall(SNESGetApplicationContext(snes, &appctx));
3335     PetscCall(SNESSetApplicationContext(snes->npc, appctx));
3336     PetscCall(SNESSetUseMatrixFree(snes->npc, mf_operator, mf));
3337     PetscCall(VecDestroy(&fpc));
3338 
3339     /* copy the function pointers over */
3340     PetscCall(PetscObjectCopyFortranFunctionPointers((PetscObject)snes, (PetscObject)snes->npc));
3341 
3342     /* default to 1 iteration */
3343     PetscCall(SNESSetTolerances(snes->npc, 0.0, 0.0, 0.0, 1, snes->npc->max_funcs));
3344     if (snes->npcside == PC_RIGHT) {
3345       PetscCall(SNESSetNormSchedule(snes->npc, SNES_NORM_FINAL_ONLY));
3346     } else {
3347       PetscCall(SNESSetNormSchedule(snes->npc, SNES_NORM_NONE));
3348     }
3349     PetscCall(SNESSetFromOptions(snes->npc));
3350 
3351     /* copy the line search context over */
3352     if (snes->linesearch && snes->npc->linesearch) {
3353       PetscCall(SNESGetLineSearch(snes, &linesearch));
3354       PetscCall(SNESGetLineSearch(snes->npc, &pclinesearch));
3355       PetscCall(SNESLineSearchGetPreCheck(linesearch, &precheck, &lsprectx));
3356       PetscCall(SNESLineSearchGetPostCheck(linesearch, &postcheck, &lspostctx));
3357       PetscCall(SNESLineSearchSetPreCheck(pclinesearch, precheck, lsprectx));
3358       PetscCall(SNESLineSearchSetPostCheck(pclinesearch, postcheck, lspostctx));
3359       PetscCall(PetscObjectCopyFortranFunctionPointers((PetscObject)linesearch, (PetscObject)pclinesearch));
3360     }
3361   }
3362   if (snes->mf) PetscCall(SNESSetUpMatrixFree_Private(snes, snes->mf_operator, snes->mf_version));
3363   if (snes->ops->usercompute && !snes->user) PetscCallBack("SNES callback compute application context", (*snes->ops->usercompute)(snes, (void **)&snes->user));
3364 
3365   snes->jac_iter = 0;
3366   snes->pre_iter = 0;
3367 
3368   PetscTryTypeMethod(snes, setup);
3369 
3370   PetscCall(SNESSetDefaultComputeJacobian(snes));
3371 
3372   if (snes->npc && snes->npcside == PC_LEFT) {
3373     if (snes->functype == SNES_FUNCTION_PRECONDITIONED) {
3374       if (snes->linesearch) {
3375         PetscCall(SNESGetLineSearch(snes, &linesearch));
3376         PetscCall(SNESLineSearchSetFunction(linesearch, SNESComputeFunctionDefaultNPC));
3377       }
3378     }
3379   }
3380   PetscCall(PetscLogEventEnd(SNES_SetUp, snes, 0, 0, 0));
3381   snes->setupcalled = PETSC_TRUE;
3382   PetscFunctionReturn(PETSC_SUCCESS);
3383 }
3384 
3385 /*@
3386   SNESReset - Resets a `SNES` context to the snessetupcalled = 0 state and removes any allocated `Vec`s and `Mat`s
3387 
3388   Collective
3389 
3390   Input Parameter:
3391 . snes - iterative context obtained from `SNESCreate()`
3392 
3393   Level: intermediate
3394 
3395   Notes:
3396   Call this if you wish to reuse a `SNES` but with different size vectors
3397 
3398   Also calls the application context destroy routine set with `SNESSetComputeApplicationContext()`
3399 
3400 .seealso: [](ch_snes), `SNES`, `SNESDestroy()`, `SNESCreate()`, `SNESSetUp()`, `SNESSolve()`
3401 @*/
3402 PetscErrorCode SNESReset(SNES snes)
3403 {
3404   PetscFunctionBegin;
3405   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
3406   if (snes->ops->userdestroy && snes->user) {
3407     PetscCallBack("SNES callback destroy application context", (*snes->ops->userdestroy)((void **)&snes->user));
3408     snes->user = NULL;
3409   }
3410   if (snes->npc) PetscCall(SNESReset(snes->npc));
3411 
3412   PetscTryTypeMethod(snes, reset);
3413   if (snes->ksp) PetscCall(KSPReset(snes->ksp));
3414 
3415   if (snes->linesearch) PetscCall(SNESLineSearchReset(snes->linesearch));
3416 
3417   PetscCall(VecDestroy(&snes->vec_rhs));
3418   PetscCall(VecDestroy(&snes->vec_sol));
3419   PetscCall(VecDestroy(&snes->vec_sol_update));
3420   PetscCall(VecDestroy(&snes->vec_func));
3421   PetscCall(MatDestroy(&snes->jacobian));
3422   PetscCall(MatDestroy(&snes->jacobian_pre));
3423   PetscCall(MatDestroy(&snes->picard));
3424   PetscCall(VecDestroyVecs(snes->nwork, &snes->work));
3425   PetscCall(VecDestroyVecs(snes->nvwork, &snes->vwork));
3426 
3427   snes->alwayscomputesfinalresidual = PETSC_FALSE;
3428 
3429   snes->nwork = snes->nvwork = 0;
3430   snes->setupcalled          = PETSC_FALSE;
3431   PetscFunctionReturn(PETSC_SUCCESS);
3432 }
3433 
3434 /*@
3435   SNESConvergedReasonViewCancel - Clears all the reason view functions for a `SNES` object provided with `SNESConvergedReasonViewSet()` also
3436   removes the default viewer.
3437 
3438   Collective
3439 
3440   Input Parameter:
3441 . snes - iterative context obtained from `SNESCreate()`
3442 
3443   Level: intermediate
3444 
3445 .seealso: [](ch_snes), `SNES`, `SNESCreate()`, `SNESDestroy()`, `SNESReset()`, `SNESConvergedReasonViewSet()`
3446 @*/
3447 PetscErrorCode SNESConvergedReasonViewCancel(SNES snes)
3448 {
3449   PetscInt i;
3450 
3451   PetscFunctionBegin;
3452   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
3453   for (i = 0; i < snes->numberreasonviews; i++) {
3454     if (snes->reasonviewdestroy[i]) PetscCall((*snes->reasonviewdestroy[i])(&snes->reasonviewcontext[i]));
3455   }
3456   snes->numberreasonviews = 0;
3457   PetscCall(PetscViewerDestroy(&snes->convergedreasonviewer));
3458   PetscFunctionReturn(PETSC_SUCCESS);
3459 }
3460 
3461 /*@
3462   SNESDestroy - Destroys the nonlinear solver context that was created
3463   with `SNESCreate()`.
3464 
3465   Collective
3466 
3467   Input Parameter:
3468 . snes - the `SNES` context
3469 
3470   Level: beginner
3471 
3472 .seealso: [](ch_snes), `SNES`, `SNESCreate()`, `SNESSolve()`
3473 @*/
3474 PetscErrorCode SNESDestroy(SNES *snes)
3475 {
3476   PetscFunctionBegin;
3477   if (!*snes) PetscFunctionReturn(PETSC_SUCCESS);
3478   PetscValidHeaderSpecific(*snes, SNES_CLASSID, 1);
3479   if (--((PetscObject)*snes)->refct > 0) {
3480     *snes = NULL;
3481     PetscFunctionReturn(PETSC_SUCCESS);
3482   }
3483 
3484   PetscCall(SNESReset(*snes));
3485   PetscCall(SNESDestroy(&(*snes)->npc));
3486 
3487   /* if memory was published with SAWs then destroy it */
3488   PetscCall(PetscObjectSAWsViewOff((PetscObject)*snes));
3489   PetscTryTypeMethod(*snes, destroy);
3490 
3491   if ((*snes)->dm) PetscCall(DMCoarsenHookRemove((*snes)->dm, DMCoarsenHook_SNESVecSol, DMRestrictHook_SNESVecSol, *snes));
3492   PetscCall(DMDestroy(&(*snes)->dm));
3493   PetscCall(KSPDestroy(&(*snes)->ksp));
3494   PetscCall(SNESLineSearchDestroy(&(*snes)->linesearch));
3495 
3496   PetscCall(PetscFree((*snes)->kspconvctx));
3497   if ((*snes)->ops->convergeddestroy) PetscCall((*(*snes)->ops->convergeddestroy)((*snes)->cnvP));
3498   if ((*snes)->conv_hist_alloc) PetscCall(PetscFree2((*snes)->conv_hist, (*snes)->conv_hist_its));
3499   PetscCall(SNESMonitorCancel(*snes));
3500   PetscCall(SNESConvergedReasonViewCancel(*snes));
3501   PetscCall(PetscHeaderDestroy(snes));
3502   PetscFunctionReturn(PETSC_SUCCESS);
3503 }
3504 
3505 /* ----------- Routines to set solver parameters ---------- */
3506 
3507 /*@
3508   SNESSetLagPreconditioner - Determines when the preconditioner is rebuilt in the nonlinear solve.
3509 
3510   Logically Collective
3511 
3512   Input Parameters:
3513 + snes - the `SNES` context
3514 - lag  - 1 means rebuild every time the Jacobian is computed within a single nonlinear solve, 2 means every second time
3515          the Jacobian is built etc. -2 indicates rebuild preconditioner at next chance but then never rebuild after that
3516 
3517   Options Database Keys:
3518 + -snes_lag_jacobian_persists <true,false>       - sets the persistence through multiple `SNESSolve()`
3519 . -snes_lag_jacobian <-2,1,2,...>                - sets the lag
3520 . -snes_lag_preconditioner_persists <true,false> - sets the persistence through multiple `SNESSolve()`
3521 - -snes_lag_preconditioner <-2,1,2,...>          - sets the lag
3522 
3523   Level: intermediate
3524 
3525   Notes:
3526   The default is 1
3527 
3528   The preconditioner is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1 or `SNESSetLagPreconditionerPersists()` was called
3529 
3530   `SNESSetLagPreconditionerPersists()` allows using the same uniform lagging (for example every second linear solve) across multiple nonlinear solves.
3531 
3532 .seealso: [](ch_snes), `SNESGetLagPreconditioner()`, `SNESSetLagJacobian()`, `SNESGetLagJacobian()`, `SNESSetLagPreconditionerPersists()`,
3533           `SNESSetLagJacobianPersists()`, `SNES`, `SNESSolve()`
3534 @*/
3535 PetscErrorCode SNESSetLagPreconditioner(SNES snes, PetscInt lag)
3536 {
3537   PetscFunctionBegin;
3538   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
3539   PetscCheck(lag >= -2, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Lag must be -2, -1, 1 or greater");
3540   PetscCheck(lag, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Lag cannot be 0");
3541   PetscValidLogicalCollectiveInt(snes, lag, 2);
3542   snes->lagpreconditioner = lag;
3543   PetscFunctionReturn(PETSC_SUCCESS);
3544 }
3545 
3546 /*@
3547   SNESSetGridSequence - sets the number of steps of grid sequencing that `SNES` will do
3548 
3549   Logically Collective
3550 
3551   Input Parameters:
3552 + snes  - the `SNES` context
3553 - steps - the number of refinements to do, defaults to 0
3554 
3555   Options Database Key:
3556 . -snes_grid_sequence <steps> - Use grid sequencing to generate initial guess
3557 
3558   Level: intermediate
3559 
3560   Note:
3561   Use `SNESGetSolution()` to extract the fine grid solution after grid sequencing.
3562 
3563 .seealso: [](ch_snes), `SNES`, `SNESGetLagPreconditioner()`, `SNESSetLagJacobian()`, `SNESGetLagJacobian()`, `SNESGetGridSequence()`,
3564           `SNESetDM()`
3565 @*/
3566 PetscErrorCode SNESSetGridSequence(SNES snes, PetscInt steps)
3567 {
3568   PetscFunctionBegin;
3569   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
3570   PetscValidLogicalCollectiveInt(snes, steps, 2);
3571   snes->gridsequence = steps;
3572   PetscFunctionReturn(PETSC_SUCCESS);
3573 }
3574 
3575 /*@
3576   SNESGetGridSequence - gets the number of steps of grid sequencing that `SNES` will do
3577 
3578   Logically Collective
3579 
3580   Input Parameter:
3581 . snes - the `SNES` context
3582 
3583   Output Parameter:
3584 . steps - the number of refinements to do, defaults to 0
3585 
3586   Level: intermediate
3587 
3588 .seealso: [](ch_snes), `SNESGetLagPreconditioner()`, `SNESSetLagJacobian()`, `SNESGetLagJacobian()`, `SNESSetGridSequence()`
3589 @*/
3590 PetscErrorCode SNESGetGridSequence(SNES snes, PetscInt *steps)
3591 {
3592   PetscFunctionBegin;
3593   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
3594   *steps = snes->gridsequence;
3595   PetscFunctionReturn(PETSC_SUCCESS);
3596 }
3597 
3598 /*@
3599   SNESGetLagPreconditioner - Return how often the preconditioner is rebuilt
3600 
3601   Not Collective
3602 
3603   Input Parameter:
3604 . snes - the `SNES` context
3605 
3606   Output Parameter:
3607 . lag - -1 indicates NEVER rebuild, 1 means rebuild every time the Jacobian is computed within a single nonlinear solve, 2 means every second time
3608          the Jacobian is built etc. -2 indicates rebuild preconditioner at next chance but then never rebuild after that
3609 
3610   Level: intermediate
3611 
3612   Notes:
3613   The default is 1
3614 
3615   The preconditioner is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1
3616 
3617 .seealso: [](ch_snes), `SNES`, `SNESSetLagPreconditioner()`, `SNESSetLagJacobianPersists()`, `SNESSetLagPreconditionerPersists()`
3618 @*/
3619 PetscErrorCode SNESGetLagPreconditioner(SNES snes, PetscInt *lag)
3620 {
3621   PetscFunctionBegin;
3622   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
3623   *lag = snes->lagpreconditioner;
3624   PetscFunctionReturn(PETSC_SUCCESS);
3625 }
3626 
3627 /*@
3628   SNESSetLagJacobian - Set when the Jacobian is rebuilt in the nonlinear solve. See `SNESSetLagPreconditioner()` for determining how
3629   often the preconditioner is rebuilt.
3630 
3631   Logically Collective
3632 
3633   Input Parameters:
3634 + snes - the `SNES` context
3635 - lag  - -1 indicates NEVER rebuild, 1 means rebuild every time the Jacobian is computed within a single nonlinear solve, 2 means every second time
3636          the Jacobian is built etc. -2 means rebuild at next chance but then never again
3637 
3638   Options Database Keys:
3639 + -snes_lag_jacobian_persists <true,false>       - sets the persistence through multiple SNES solves
3640 . -snes_lag_jacobian <-2,1,2,...>                - sets the lag
3641 . -snes_lag_preconditioner_persists <true,false> - sets the persistence through multiple SNES solves
3642 - -snes_lag_preconditioner <-2,1,2,...>          - sets the lag.
3643 
3644   Level: intermediate
3645 
3646   Notes:
3647   The default is 1
3648 
3649   The Jacobian is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1
3650 
3651   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
3652   at the next Newton step but never again (unless it is reset to another value)
3653 
3654 .seealso: [](ch_snes), `SNES`, `SNESGetLagPreconditioner()`, `SNESSetLagPreconditioner()`, `SNESGetLagJacobianPersists()`, `SNESSetLagPreconditionerPersists()`
3655 @*/
3656 PetscErrorCode SNESSetLagJacobian(SNES snes, PetscInt lag)
3657 {
3658   PetscFunctionBegin;
3659   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
3660   PetscCheck(lag >= -2, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Lag must be -2, -1, 1 or greater");
3661   PetscCheck(lag, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Lag cannot be 0");
3662   PetscValidLogicalCollectiveInt(snes, lag, 2);
3663   snes->lagjacobian = lag;
3664   PetscFunctionReturn(PETSC_SUCCESS);
3665 }
3666 
3667 /*@
3668   SNESGetLagJacobian - Get how often the Jacobian is rebuilt. See `SNESGetLagPreconditioner()` to determine when the preconditioner is rebuilt
3669 
3670   Not Collective
3671 
3672   Input Parameter:
3673 . snes - the `SNES` context
3674 
3675   Output Parameter:
3676 . lag - -1 indicates NEVER rebuild, 1 means rebuild every time the Jacobian is computed within a single nonlinear solve, 2 means every second time
3677          the Jacobian is built etc.
3678 
3679   Level: intermediate
3680 
3681   Notes:
3682   The default is 1
3683 
3684   The jacobian is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1 or `SNESSetLagJacobianPersists()` was called.
3685 
3686 .seealso: [](ch_snes), `SNES`, `SNESSetLagJacobian()`, `SNESSetLagPreconditioner()`, `SNESGetLagPreconditioner()`, `SNESSetLagJacobianPersists()`, `SNESSetLagPreconditionerPersists()`
3687 
3688 @*/
3689 PetscErrorCode SNESGetLagJacobian(SNES snes, PetscInt *lag)
3690 {
3691   PetscFunctionBegin;
3692   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
3693   *lag = snes->lagjacobian;
3694   PetscFunctionReturn(PETSC_SUCCESS);
3695 }
3696 
3697 /*@
3698   SNESSetLagJacobianPersists - Set whether or not the Jacobian lagging persists through multiple nonlinear solves
3699 
3700   Logically collective
3701 
3702   Input Parameters:
3703 + snes - the `SNES` context
3704 - flg  - jacobian lagging persists if true
3705 
3706   Options Database Keys:
3707 + -snes_lag_jacobian_persists <true,false>       - sets the persistence through multiple SNES solves
3708 . -snes_lag_jacobian <-2,1,2,...>                - sets the lag
3709 . -snes_lag_preconditioner_persists <true,false> - sets the persistence through multiple SNES solves
3710 - -snes_lag_preconditioner <-2,1,2,...>          - sets the lag
3711 
3712   Level: advanced
3713 
3714   Notes:
3715   Normally when `SNESSetLagJacobian()` is used, the Jacobian is always rebuilt at the beginning of each new nonlinear solve, this removes that behavior
3716 
3717   This is useful both for nonlinear preconditioning, where it's appropriate to have the Jacobian be stale by
3718   several solves, and for implicit time-stepping, where Jacobian lagging in the inner nonlinear solve over several
3719   timesteps may present huge efficiency gains.
3720 
3721 .seealso: [](ch_snes), `SNES`, `SNESSetLagPreconditionerPersists()`, `SNESSetLagJacobian()`, `SNESGetLagJacobian()`, `SNESGetNPC()`
3722 @*/
3723 PetscErrorCode SNESSetLagJacobianPersists(SNES snes, PetscBool flg)
3724 {
3725   PetscFunctionBegin;
3726   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
3727   PetscValidLogicalCollectiveBool(snes, flg, 2);
3728   snes->lagjac_persist = flg;
3729   PetscFunctionReturn(PETSC_SUCCESS);
3730 }
3731 
3732 /*@
3733   SNESSetLagPreconditionerPersists - Set whether or not the preconditioner lagging persists through multiple nonlinear solves
3734 
3735   Logically Collective
3736 
3737   Input Parameters:
3738 + snes - the `SNES` context
3739 - flg  - preconditioner lagging persists if true
3740 
3741   Options Database Keys:
3742 + -snes_lag_jacobian_persists <true,false>       - sets the persistence through multiple SNES solves
3743 . -snes_lag_jacobian <-2,1,2,...>                - sets the lag
3744 . -snes_lag_preconditioner_persists <true,false> - sets the persistence through multiple SNES solves
3745 - -snes_lag_preconditioner <-2,1,2,...>          - sets the lag
3746 
3747   Level: developer
3748 
3749   Notes:
3750   Normally when `SNESSetLagPreconditioner()` is used, the preconditioner is always rebuilt at the beginning of each new nonlinear solve, this removes that behavior
3751 
3752   This is useful both for nonlinear preconditioning, where it's appropriate to have the preconditioner be stale
3753   by several solves, and for implicit time-stepping, where preconditioner lagging in the inner nonlinear solve over
3754   several timesteps may present huge efficiency gains.
3755 
3756 .seealso: [](ch_snes), `SNES`, `SNESSetLagJacobianPersists()`, `SNESSetLagJacobian()`, `SNESGetLagJacobian()`, `SNESGetNPC()`, `SNESSetLagPreconditioner()`
3757 @*/
3758 PetscErrorCode SNESSetLagPreconditionerPersists(SNES snes, PetscBool flg)
3759 {
3760   PetscFunctionBegin;
3761   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
3762   PetscValidLogicalCollectiveBool(snes, flg, 2);
3763   snes->lagpre_persist = flg;
3764   PetscFunctionReturn(PETSC_SUCCESS);
3765 }
3766 
3767 /*@
3768   SNESSetForceIteration - force `SNESSolve()` to take at least one iteration regardless of the initial residual norm
3769 
3770   Logically Collective
3771 
3772   Input Parameters:
3773 + snes  - the `SNES` context
3774 - force - `PETSC_TRUE` require at least one iteration
3775 
3776   Options Database Key:
3777 . -snes_force_iteration <force> - Sets forcing an iteration
3778 
3779   Level: intermediate
3780 
3781   Note:
3782   This is used sometimes with `TS` to prevent `TS` from detecting a false steady state solution
3783 
3784 .seealso: [](ch_snes), `SNES`, `TS`, `SNESSetDivergenceTolerance()`
3785 @*/
3786 PetscErrorCode SNESSetForceIteration(SNES snes, PetscBool force)
3787 {
3788   PetscFunctionBegin;
3789   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
3790   snes->forceiteration = force;
3791   PetscFunctionReturn(PETSC_SUCCESS);
3792 }
3793 
3794 /*@
3795   SNESGetForceIteration - Check whether or not `SNESSolve()` take at least one iteration regardless of the initial residual norm
3796 
3797   Logically Collective
3798 
3799   Input Parameter:
3800 . snes - the `SNES` context
3801 
3802   Output Parameter:
3803 . force - `PETSC_TRUE` requires at least one iteration.
3804 
3805   Level: intermediate
3806 
3807 .seealso: [](ch_snes), `SNES`, `SNESSetForceIteration()`, `SNESSetDivergenceTolerance()`
3808 @*/
3809 PetscErrorCode SNESGetForceIteration(SNES snes, PetscBool *force)
3810 {
3811   PetscFunctionBegin;
3812   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
3813   *force = snes->forceiteration;
3814   PetscFunctionReturn(PETSC_SUCCESS);
3815 }
3816 
3817 /*@
3818   SNESSetTolerances - Sets `SNES` various parameters used in convergence tests.
3819 
3820   Logically Collective
3821 
3822   Input Parameters:
3823 + snes   - the `SNES` context
3824 . abstol - absolute convergence tolerance
3825 . rtol   - relative convergence tolerance
3826 . stol   - convergence tolerance in terms of the norm of the change in the solution between steps,  || delta x || < stol*|| x ||
3827 . maxit  - maximum number of iterations, default 50.
3828 - maxf   - maximum number of function evaluations (use `PETSC_UNLIMITED` indicates no limit), default 10,000
3829 
3830   Options Database Keys:
3831 + -snes_atol <abstol>    - Sets `abstol`
3832 . -snes_rtol <rtol>      - Sets `rtol`
3833 . -snes_stol <stol>      - Sets `stol`
3834 . -snes_max_it <maxit>   - Sets `maxit`
3835 - -snes_max_funcs <maxf> - Sets `maxf` (use `unlimited` to have no maximum)
3836 
3837   Level: intermediate
3838 
3839   Note:
3840   All parameters must be non-negative
3841 
3842   Use `PETSC_CURRENT` to retain the current value of any parameter and `PETSC_DETERMINE` to use the default value for the given `SNES`.
3843   The default value is the value in the object when its type is set.
3844 
3845   Use `PETSC_UNLIMITED` on `maxit` or `maxf` to indicate there is no bound on the number of iterations or number of function evaluations.
3846 
3847   Fortran Note:
3848   Use `PETSC_CURRENT_INTEGER`, `PETSC_CURRENT_REAL`, `PETSC_UNLIMITED_INTEGER`, `PETSC_DETERMINE_INTEGER`, or `PETSC_DETERMINE_REAL`
3849 
3850 .seealso: [](ch_snes), `SNESSolve()`, `SNES`, `SNESSetDivergenceTolerance()`, `SNESSetForceIteration()`
3851 @*/
3852 PetscErrorCode SNESSetTolerances(SNES snes, PetscReal abstol, PetscReal rtol, PetscReal stol, PetscInt maxit, PetscInt maxf)
3853 {
3854   PetscFunctionBegin;
3855   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
3856   PetscValidLogicalCollectiveReal(snes, abstol, 2);
3857   PetscValidLogicalCollectiveReal(snes, rtol, 3);
3858   PetscValidLogicalCollectiveReal(snes, stol, 4);
3859   PetscValidLogicalCollectiveInt(snes, maxit, 5);
3860   PetscValidLogicalCollectiveInt(snes, maxf, 6);
3861 
3862   if (abstol == (PetscReal)PETSC_DETERMINE) {
3863     snes->abstol = snes->default_abstol;
3864   } else if (abstol != (PetscReal)PETSC_CURRENT) {
3865     PetscCheck(abstol >= 0.0, PetscObjectComm((PetscObject)snes), PETSC_ERR_ARG_OUTOFRANGE, "Absolute tolerance %g must be non-negative", (double)abstol);
3866     snes->abstol = abstol;
3867   }
3868 
3869   if (rtol == (PetscReal)PETSC_DETERMINE) {
3870     snes->rtol = snes->default_rtol;
3871   } else if (rtol != (PetscReal)PETSC_CURRENT) {
3872     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);
3873     snes->rtol = rtol;
3874   }
3875 
3876   if (stol == (PetscReal)PETSC_DETERMINE) {
3877     snes->stol = snes->default_stol;
3878   } else if (stol != (PetscReal)PETSC_CURRENT) {
3879     PetscCheck(stol >= 0.0, PetscObjectComm((PetscObject)snes), PETSC_ERR_ARG_OUTOFRANGE, "Step tolerance %g must be non-negative", (double)stol);
3880     snes->stol = stol;
3881   }
3882 
3883   if (maxit == (PetscInt)PETSC_DETERMINE) {
3884     snes->max_its = snes->default_max_its;
3885   } else if (maxit == (PetscInt)PETSC_UNLIMITED) {
3886     snes->max_its = PETSC_INT_MAX;
3887   } else if (maxit != PETSC_CURRENT) {
3888     PetscCheck(maxit >= 0, PetscObjectComm((PetscObject)snes), PETSC_ERR_ARG_OUTOFRANGE, "Maximum number of iterations %" PetscInt_FMT " must be non-negative", maxit);
3889     snes->max_its = maxit;
3890   }
3891 
3892   if (maxf == (PetscInt)PETSC_DETERMINE) {
3893     snes->max_funcs = snes->default_max_funcs;
3894   } else if (maxf == (PetscInt)PETSC_UNLIMITED || maxf == -1) {
3895     snes->max_funcs = PETSC_UNLIMITED;
3896   } else if (maxf != PETSC_CURRENT) {
3897     PetscCheck(maxf >= 0, PetscObjectComm((PetscObject)snes), PETSC_ERR_ARG_OUTOFRANGE, "Maximum number of function evaluations %" PetscInt_FMT " must be nonnegative", maxf);
3898     snes->max_funcs = maxf;
3899   }
3900   PetscFunctionReturn(PETSC_SUCCESS);
3901 }
3902 
3903 /*@
3904   SNESSetDivergenceTolerance - Sets the divergence tolerance used for the `SNES` divergence test.
3905 
3906   Logically Collective
3907 
3908   Input Parameters:
3909 + snes   - the `SNES` context
3910 - divtol - the divergence tolerance. Use `PETSC_UNLIMITED` to deactivate the test.
3911 
3912   Options Database Key:
3913 . -snes_divergence_tolerance <divtol> - Sets `divtol`
3914 
3915   Level: intermediate
3916 
3917   Notes:
3918   Use `PETSC_DETERMINE` to use the default value from when the object's type was set.
3919 
3920   Fortran Note:
3921   Use ``PETSC_DETERMINE_REAL` or `PETSC_UNLIMITED_REAL`
3922 
3923   Developer Note:
3924   Also supports the deprecated -1 to indicate no bound on the growth of the residual
3925 
3926 .seealso: [](ch_snes), `SNES`, `SNESSolve()`, `SNESSetTolerances()`, `SNESGetDivergenceTolerance()`
3927 @*/
3928 PetscErrorCode SNESSetDivergenceTolerance(SNES snes, PetscReal divtol)
3929 {
3930   PetscFunctionBegin;
3931   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
3932   PetscValidLogicalCollectiveReal(snes, divtol, 2);
3933 
3934   if (divtol == (PetscReal)PETSC_DETERMINE) {
3935     snes->divtol = snes->default_divtol;
3936   } else if (divtol == (PetscReal)PETSC_UNLIMITED || divtol == -1) {
3937     snes->divtol = PETSC_UNLIMITED;
3938   } else if (divtol != (PetscReal)PETSC_CURRENT) {
3939     PetscCheck(divtol >= 1.0, PetscObjectComm((PetscObject)snes), PETSC_ERR_ARG_OUTOFRANGE, "Divergence tolerance %g must be greater than 1.0", (double)divtol);
3940     snes->divtol = divtol;
3941   }
3942   PetscFunctionReturn(PETSC_SUCCESS);
3943 }
3944 
3945 /*@
3946   SNESGetTolerances - Gets various parameters used in convergence tests.
3947 
3948   Not Collective
3949 
3950   Input Parameter:
3951 . snes - the `SNES` context
3952 
3953   Output Parameters:
3954 + atol  - absolute convergence tolerance
3955 . rtol  - relative convergence tolerance
3956 . stol  - convergence tolerance in terms of the norm of the change in the solution between steps
3957 . maxit - maximum number of iterations
3958 - maxf  - maximum number of function evaluations, `PETSC_UNLIMITED` indicates no bound
3959 
3960   Level: intermediate
3961 
3962   Note:
3963   The user can specify `NULL` for any parameter that is not needed.
3964 
3965 .seealso: [](ch_snes), `SNES`, `SNESSetTolerances()`
3966 @*/
3967 PetscErrorCode SNESGetTolerances(SNES snes, PetscReal *atol, PetscReal *rtol, PetscReal *stol, PetscInt *maxit, PetscInt *maxf)
3968 {
3969   PetscFunctionBegin;
3970   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
3971   if (atol) *atol = snes->abstol;
3972   if (rtol) *rtol = snes->rtol;
3973   if (stol) *stol = snes->stol;
3974   if (maxit) *maxit = snes->max_its;
3975   if (maxf) *maxf = snes->max_funcs;
3976   PetscFunctionReturn(PETSC_SUCCESS);
3977 }
3978 
3979 /*@
3980   SNESGetDivergenceTolerance - Gets divergence tolerance used in divergence test.
3981 
3982   Not Collective
3983 
3984   Input Parameters:
3985 + snes   - the `SNES` context
3986 - divtol - divergence tolerance
3987 
3988   Level: intermediate
3989 
3990 .seealso: [](ch_snes), `SNES`, `SNESSetDivergenceTolerance()`
3991 @*/
3992 PetscErrorCode SNESGetDivergenceTolerance(SNES snes, PetscReal *divtol)
3993 {
3994   PetscFunctionBegin;
3995   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
3996   if (divtol) *divtol = snes->divtol;
3997   PetscFunctionReturn(PETSC_SUCCESS);
3998 }
3999 
4000 PETSC_INTERN PetscErrorCode SNESMonitorRange_Private(SNES, PetscInt, PetscReal *);
4001 
4002 PetscErrorCode SNESMonitorLGRange(SNES snes, PetscInt n, PetscReal rnorm, void *monctx)
4003 {
4004   PetscDrawLG      lg;
4005   PetscReal        x, y, per;
4006   PetscViewer      v = (PetscViewer)monctx;
4007   static PetscReal prev; /* should be in the context */
4008   PetscDraw        draw;
4009 
4010   PetscFunctionBegin;
4011   PetscValidHeaderSpecific(v, PETSC_VIEWER_CLASSID, 4);
4012   PetscCall(PetscViewerDrawGetDrawLG(v, 0, &lg));
4013   if (!n) PetscCall(PetscDrawLGReset(lg));
4014   PetscCall(PetscDrawLGGetDraw(lg, &draw));
4015   PetscCall(PetscDrawSetTitle(draw, "Residual norm"));
4016   x = (PetscReal)n;
4017   if (rnorm > 0.0) y = PetscLog10Real(rnorm);
4018   else y = -15.0;
4019   PetscCall(PetscDrawLGAddPoint(lg, &x, &y));
4020   if (n < 20 || !(n % 5) || snes->reason) {
4021     PetscCall(PetscDrawLGDraw(lg));
4022     PetscCall(PetscDrawLGSave(lg));
4023   }
4024 
4025   PetscCall(PetscViewerDrawGetDrawLG(v, 1, &lg));
4026   if (!n) PetscCall(PetscDrawLGReset(lg));
4027   PetscCall(PetscDrawLGGetDraw(lg, &draw));
4028   PetscCall(PetscDrawSetTitle(draw, "% elements > .2*max element"));
4029   PetscCall(SNESMonitorRange_Private(snes, n, &per));
4030   x = (PetscReal)n;
4031   y = 100.0 * per;
4032   PetscCall(PetscDrawLGAddPoint(lg, &x, &y));
4033   if (n < 20 || !(n % 5) || snes->reason) {
4034     PetscCall(PetscDrawLGDraw(lg));
4035     PetscCall(PetscDrawLGSave(lg));
4036   }
4037 
4038   PetscCall(PetscViewerDrawGetDrawLG(v, 2, &lg));
4039   if (!n) {
4040     prev = rnorm;
4041     PetscCall(PetscDrawLGReset(lg));
4042   }
4043   PetscCall(PetscDrawLGGetDraw(lg, &draw));
4044   PetscCall(PetscDrawSetTitle(draw, "(norm -oldnorm)/oldnorm"));
4045   x = (PetscReal)n;
4046   y = (prev - rnorm) / prev;
4047   PetscCall(PetscDrawLGAddPoint(lg, &x, &y));
4048   if (n < 20 || !(n % 5) || snes->reason) {
4049     PetscCall(PetscDrawLGDraw(lg));
4050     PetscCall(PetscDrawLGSave(lg));
4051   }
4052 
4053   PetscCall(PetscViewerDrawGetDrawLG(v, 3, &lg));
4054   if (!n) PetscCall(PetscDrawLGReset(lg));
4055   PetscCall(PetscDrawLGGetDraw(lg, &draw));
4056   PetscCall(PetscDrawSetTitle(draw, "(norm -oldnorm)/oldnorm*(% > .2 max)"));
4057   x = (PetscReal)n;
4058   y = (prev - rnorm) / (prev * per);
4059   if (n > 2) { /*skip initial crazy value */
4060     PetscCall(PetscDrawLGAddPoint(lg, &x, &y));
4061   }
4062   if (n < 20 || !(n % 5) || snes->reason) {
4063     PetscCall(PetscDrawLGDraw(lg));
4064     PetscCall(PetscDrawLGSave(lg));
4065   }
4066   prev = rnorm;
4067   PetscFunctionReturn(PETSC_SUCCESS);
4068 }
4069 
4070 /*@
4071   SNESConverged - Run the convergence test and update the `SNESConvergedReason`.
4072 
4073   Collective
4074 
4075   Input Parameters:
4076 + snes  - the `SNES` context
4077 . it    - current iteration
4078 . xnorm - 2-norm of current iterate
4079 . snorm - 2-norm of current step
4080 - fnorm - 2-norm of function
4081 
4082   Level: developer
4083 
4084   Note:
4085   This routine is called by the `SNESSolve()` implementations.
4086   It does not typically need to be called by the user.
4087 
4088 .seealso: [](ch_snes), `SNES`, `SNESSolve`, `SNESSetConvergenceTest()`, `SNESGetConvergenceTest()`
4089 @*/
4090 PetscErrorCode SNESConverged(SNES snes, PetscInt it, PetscReal xnorm, PetscReal snorm, PetscReal fnorm)
4091 {
4092   PetscFunctionBegin;
4093   if (!snes->reason) {
4094     if (snes->normschedule == SNES_NORM_ALWAYS) PetscUseTypeMethod(snes, converged, it, xnorm, snorm, fnorm, &snes->reason, snes->cnvP);
4095     if (it == snes->max_its && !snes->reason) {
4096       if (snes->normschedule == SNES_NORM_ALWAYS) {
4097         PetscCall(PetscInfo(snes, "Maximum number of iterations has been reached: %" PetscInt_FMT "\n", snes->max_its));
4098         snes->reason = SNES_DIVERGED_MAX_IT;
4099       } else snes->reason = SNES_CONVERGED_ITS;
4100     }
4101   }
4102   PetscFunctionReturn(PETSC_SUCCESS);
4103 }
4104 
4105 /*@
4106   SNESMonitor - runs the user provided monitor routines, if they exist
4107 
4108   Collective
4109 
4110   Input Parameters:
4111 + snes  - nonlinear solver context obtained from `SNESCreate()`
4112 . iter  - iteration number
4113 - rnorm - relative norm of the residual
4114 
4115   Level: developer
4116 
4117   Note:
4118   This routine is called by the `SNESSolve()` implementations.
4119   It does not typically need to be called by the user.
4120 
4121 .seealso: [](ch_snes), `SNES`, `SNESMonitorSet()`
4122 @*/
4123 PetscErrorCode SNESMonitor(SNES snes, PetscInt iter, PetscReal rnorm)
4124 {
4125   PetscInt i, n = snes->numbermonitors;
4126 
4127   PetscFunctionBegin;
4128   if (n > 0) SNESCheckFunctionNorm(snes, rnorm);
4129   PetscCall(VecLockReadPush(snes->vec_sol));
4130   for (i = 0; i < n; i++) PetscCall((*snes->monitor[i])(snes, iter, rnorm, snes->monitorcontext[i]));
4131   PetscCall(VecLockReadPop(snes->vec_sol));
4132   PetscFunctionReturn(PETSC_SUCCESS);
4133 }
4134 
4135 /* ------------ Routines to set performance monitoring options ----------- */
4136 
4137 /*MC
4138     SNESMonitorFunction - functional form passed to `SNESMonitorSet()` to monitor convergence of nonlinear solver
4139 
4140      Synopsis:
4141      #include <petscsnes.h>
4142     PetscErrorCode SNESMonitorFunction(SNES snes, PetscInt its, PetscReal norm, void *mctx)
4143 
4144      Collective
4145 
4146     Input Parameters:
4147 +    snes - the `SNES` context
4148 .    its - iteration number
4149 .    norm - 2-norm function value (may be estimated)
4150 -    mctx - [optional] monitoring context
4151 
4152    Level: advanced
4153 
4154 .seealso: [](ch_snes), `SNESMonitorSet()`, `SNESMonitorSet()`, `SNESMonitorGet()`
4155 M*/
4156 
4157 /*@C
4158   SNESMonitorSet - Sets an ADDITIONAL function that is to be used at every
4159   iteration of the nonlinear solver to display the iteration's
4160   progress.
4161 
4162   Logically Collective
4163 
4164   Input Parameters:
4165 + snes           - the `SNES` context
4166 . f              - the monitor function,  for the calling sequence see `SNESMonitorFunction`
4167 . mctx           - [optional] user-defined context for private data for the monitor routine (use `NULL` if no context is desired)
4168 - monitordestroy - [optional] routine that frees monitor context (may be `NULL`)
4169 
4170   Options Database Keys:
4171 + -snes_monitor               - sets `SNESMonitorDefault()`
4172 . -snes_monitor draw::draw_lg - sets line graph monitor,
4173 - -snes_monitor_cancel        - cancels all monitors that have been hardwired into a code by calls to `SNESMonitorSet()`, but does not cancel those set via
4174                                 the options database.
4175 
4176   Level: intermediate
4177 
4178   Note:
4179   Several different monitoring routines may be set by calling
4180   `SNESMonitorSet()` multiple times; all will be called in the
4181   order in which they were set.
4182 
4183   Fortran Note:
4184   Only a single monitor function can be set for each `SNES` object
4185 
4186 .seealso: [](ch_snes), `SNES`, `SNESSolve()`, `SNESMonitorDefault()`, `SNESMonitorCancel()`, `SNESMonitorFunction`
4187 @*/
4188 PetscErrorCode SNESMonitorSet(SNES snes, PetscErrorCode (*f)(SNES, PetscInt, PetscReal, void *), void *mctx, PetscErrorCode (*monitordestroy)(void **))
4189 {
4190   PetscInt  i;
4191   PetscBool identical;
4192 
4193   PetscFunctionBegin;
4194   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
4195   for (i = 0; i < snes->numbermonitors; i++) {
4196     PetscCall(PetscMonitorCompare((PetscErrorCode(*)(void))f, mctx, monitordestroy, (PetscErrorCode(*)(void))snes->monitor[i], snes->monitorcontext[i], snes->monitordestroy[i], &identical));
4197     if (identical) PetscFunctionReturn(PETSC_SUCCESS);
4198   }
4199   PetscCheck(snes->numbermonitors < MAXSNESMONITORS, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Too many monitors set");
4200   snes->monitor[snes->numbermonitors]          = f;
4201   snes->monitordestroy[snes->numbermonitors]   = monitordestroy;
4202   snes->monitorcontext[snes->numbermonitors++] = (void *)mctx;
4203   PetscFunctionReturn(PETSC_SUCCESS);
4204 }
4205 
4206 /*@
4207   SNESMonitorCancel - Clears all the monitor functions for a `SNES` object.
4208 
4209   Logically Collective
4210 
4211   Input Parameter:
4212 . snes - the `SNES` context
4213 
4214   Options Database Key:
4215 . -snes_monitor_cancel - cancels all monitors that have been hardwired
4216     into a code by calls to `SNESMonitorSet()`, but does not cancel those
4217     set via the options database
4218 
4219   Level: intermediate
4220 
4221   Note:
4222   There is no way to clear one specific monitor from a `SNES` object.
4223 
4224 .seealso: [](ch_snes), `SNES`, `SNESMonitorGet()`, `SNESMonitorDefault()`, `SNESMonitorSet()`
4225 @*/
4226 PetscErrorCode SNESMonitorCancel(SNES snes)
4227 {
4228   PetscInt i;
4229 
4230   PetscFunctionBegin;
4231   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
4232   for (i = 0; i < snes->numbermonitors; i++) {
4233     if (snes->monitordestroy[i]) PetscCall((*snes->monitordestroy[i])(&snes->monitorcontext[i]));
4234   }
4235   snes->numbermonitors = 0;
4236   PetscFunctionReturn(PETSC_SUCCESS);
4237 }
4238 
4239 /*MC
4240     SNESConvergenceTestFunction - functional form used for testing of convergence of nonlinear solver
4241 
4242      Synopsis:
4243      #include <petscsnes.h>
4244      PetscErrorCode SNESConvergenceTest(SNES snes, PetscInt it, PetscReal xnorm, PetscReal gnorm, PetscReal f, SNESConvergedReason *reason, void *cctx)
4245 
4246      Collective
4247 
4248     Input Parameters:
4249 +    snes - the `SNES` context
4250 .    it - current iteration (0 is the first and is before any Newton step)
4251 .    xnorm - 2-norm of current iterate
4252 .    gnorm - 2-norm of current step
4253 .    f - 2-norm of function
4254 -    cctx - [optional] convergence context
4255 
4256     Output Parameter:
4257 .    reason - reason for convergence/divergence, only needs to be set when convergence or divergence is detected
4258 
4259    Level: intermediate
4260 
4261 .seealso: [](ch_snes), `SNES`, `SNESSolve`, `SNESSetConvergenceTest()`, `SNESGetConvergenceTest()`
4262 M*/
4263 
4264 /*@C
4265   SNESSetConvergenceTest - Sets the function that is to be used
4266   to test for convergence of the nonlinear iterative solution.
4267 
4268   Logically Collective
4269 
4270   Input Parameters:
4271 + snes                        - the `SNES` context
4272 . SNESConvergenceTestFunction - routine to test for convergence
4273 . cctx                        - [optional] context for private data for the convergence routine  (may be `NULL`)
4274 - destroy                     - [optional] destructor for the context (may be `NULL`; `PETSC_NULL_FUNCTION` in Fortran)
4275 
4276   Level: advanced
4277 
4278 .seealso: [](ch_snes), `SNES`, `SNESConvergedDefault()`, `SNESConvergedSkip()`, `SNESConvergenceTestFunction`
4279 @*/
4280 PetscErrorCode SNESSetConvergenceTest(SNES snes, PetscErrorCode (*SNESConvergenceTestFunction)(SNES, PetscInt, PetscReal, PetscReal, PetscReal, SNESConvergedReason *, void *), void *cctx, PetscErrorCode (*destroy)(void *))
4281 {
4282   PetscFunctionBegin;
4283   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
4284   if (!SNESConvergenceTestFunction) SNESConvergenceTestFunction = SNESConvergedSkip;
4285   if (snes->ops->convergeddestroy) PetscCall((*snes->ops->convergeddestroy)(snes->cnvP));
4286   snes->ops->converged        = SNESConvergenceTestFunction;
4287   snes->ops->convergeddestroy = destroy;
4288   snes->cnvP                  = cctx;
4289   PetscFunctionReturn(PETSC_SUCCESS);
4290 }
4291 
4292 /*@
4293   SNESGetConvergedReason - Gets the reason the `SNES` iteration was stopped.
4294 
4295   Not Collective
4296 
4297   Input Parameter:
4298 . snes - the `SNES` context
4299 
4300   Output Parameter:
4301 . reason - negative value indicates diverged, positive value converged, see `SNESConvergedReason` for the individual convergence tests for complete lists
4302 
4303   Options Database Key:
4304 . -snes_converged_reason - prints the reason to standard out
4305 
4306   Level: intermediate
4307 
4308   Note:
4309   Should only be called after the call the `SNESSolve()` is complete, if it is called earlier it returns the value `SNES__CONVERGED_ITERATING`.
4310 
4311 .seealso: [](ch_snes), `SNESSolve()`, `SNESSetConvergenceTest()`, `SNESSetConvergedReason()`, `SNESConvergedReason`, `SNESGetConvergedReasonString()`
4312 @*/
4313 PetscErrorCode SNESGetConvergedReason(SNES snes, SNESConvergedReason *reason)
4314 {
4315   PetscFunctionBegin;
4316   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
4317   PetscAssertPointer(reason, 2);
4318   *reason = snes->reason;
4319   PetscFunctionReturn(PETSC_SUCCESS);
4320 }
4321 
4322 /*@C
4323   SNESGetConvergedReasonString - Return a human readable string for `SNESConvergedReason`
4324 
4325   Not Collective
4326 
4327   Input Parameter:
4328 . snes - the `SNES` context
4329 
4330   Output Parameter:
4331 . strreason - a human readable string that describes `SNES` converged reason
4332 
4333   Level: beginner
4334 
4335 .seealso: [](ch_snes), `SNES`, `SNESGetConvergedReason()`
4336 @*/
4337 PetscErrorCode SNESGetConvergedReasonString(SNES snes, const char **strreason)
4338 {
4339   PetscFunctionBegin;
4340   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
4341   PetscAssertPointer(strreason, 2);
4342   *strreason = SNESConvergedReasons[snes->reason];
4343   PetscFunctionReturn(PETSC_SUCCESS);
4344 }
4345 
4346 /*@
4347   SNESSetConvergedReason - Sets the reason the `SNES` iteration was stopped.
4348 
4349   Not Collective
4350 
4351   Input Parameters:
4352 + snes   - the `SNES` context
4353 - reason - negative value indicates diverged, positive value converged, see `SNESConvergedReason` or the
4354             manual pages for the individual convergence tests for complete lists
4355 
4356   Level: developer
4357 
4358   Developer Note:
4359   Called inside the various `SNESSolve()` implementations
4360 
4361 .seealso: [](ch_snes), `SNESGetConvergedReason()`, `SNESSetConvergenceTest()`, `SNESConvergedReason`
4362 @*/
4363 PetscErrorCode SNESSetConvergedReason(SNES snes, SNESConvergedReason reason)
4364 {
4365   PetscFunctionBegin;
4366   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
4367   PetscCheck(!snes->errorifnotconverged || reason > 0, PetscObjectComm((PetscObject)snes), PETSC_ERR_PLIB, "SNES code should have previously errored due to negative reason");
4368   snes->reason = reason;
4369   PetscFunctionReturn(PETSC_SUCCESS);
4370 }
4371 
4372 /*@
4373   SNESSetConvergenceHistory - Sets the arrays used to hold the convergence history.
4374 
4375   Logically Collective
4376 
4377   Input Parameters:
4378 + snes  - iterative context obtained from `SNESCreate()`
4379 . a     - array to hold history, this array will contain the function norms computed at each step
4380 . its   - integer array holds the number of linear iterations for each solve.
4381 . na    - size of `a` and `its`
4382 - reset - `PETSC_TRUE` indicates each new nonlinear solve resets the history counter to zero,
4383           else it continues storing new values for new nonlinear solves after the old ones
4384 
4385   Level: intermediate
4386 
4387   Notes:
4388   If 'a' and 'its' are `NULL` then space is allocated for the history. If 'na' is `PETSC_DECIDE` then a
4389   default array of length 1,000 is allocated.
4390 
4391   This routine is useful, e.g., when running a code for purposes
4392   of accurate performance monitoring, when no I/O should be done
4393   during the section of code that is being timed.
4394 
4395   If the arrays run out of space after a number of iterations then the later values are not saved in the history
4396 
4397 .seealso: [](ch_snes), `SNES`, `SNESSolve()`, `SNESGetConvergenceHistory()`
4398 @*/
4399 PetscErrorCode SNESSetConvergenceHistory(SNES snes, PetscReal a[], PetscInt its[], PetscInt na, PetscBool reset)
4400 {
4401   PetscFunctionBegin;
4402   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
4403   if (a) PetscAssertPointer(a, 2);
4404   if (its) PetscAssertPointer(its, 3);
4405   if (!a) {
4406     if (na == PETSC_DECIDE) na = 1000;
4407     PetscCall(PetscCalloc2(na, &a, na, &its));
4408     snes->conv_hist_alloc = PETSC_TRUE;
4409   }
4410   snes->conv_hist       = a;
4411   snes->conv_hist_its   = its;
4412   snes->conv_hist_max   = (size_t)na;
4413   snes->conv_hist_len   = 0;
4414   snes->conv_hist_reset = reset;
4415   PetscFunctionReturn(PETSC_SUCCESS);
4416 }
4417 
4418 #if defined(PETSC_HAVE_MATLAB)
4419   #include <engine.h> /* MATLAB include file */
4420   #include <mex.h>    /* MATLAB include file */
4421 
4422 PETSC_EXTERN mxArray *SNESGetConvergenceHistoryMatlab(SNES snes)
4423 {
4424   mxArray   *mat;
4425   PetscInt   i;
4426   PetscReal *ar;
4427 
4428   mat = mxCreateDoubleMatrix(snes->conv_hist_len, 1, mxREAL);
4429   ar  = (PetscReal *)mxGetData(mat);
4430   for (i = 0; i < snes->conv_hist_len; i++) ar[i] = snes->conv_hist[i];
4431   return mat;
4432 }
4433 #endif
4434 
4435 /*@C
4436   SNESGetConvergenceHistory - Gets the arrays used to hold the convergence history.
4437 
4438   Not Collective
4439 
4440   Input Parameter:
4441 . snes - iterative context obtained from `SNESCreate()`
4442 
4443   Output Parameters:
4444 + a   - array to hold history, usually was set with `SNESSetConvergenceHistory()`
4445 . its - integer array holds the number of linear iterations (or
4446          negative if not converged) for each solve.
4447 - na  - size of `a` and `its`
4448 
4449   Level: intermediate
4450 
4451   Note:
4452   This routine is useful, e.g., when running a code for purposes
4453   of accurate performance monitoring, when no I/O should be done
4454   during the section of code that is being timed.
4455 
4456   Fortran Note:
4457   The calling sequence for this routine in Fortran is
4458 .vb
4459     call SNESGetConvergenceHistory(SNES snes, integer na, integer ierr)
4460 .ve
4461 
4462 .seealso: [](ch_snes), `SNES`, `SNESSolve()`, `SNESSetConvergenceHistory()`
4463 @*/
4464 PetscErrorCode SNESGetConvergenceHistory(SNES snes, PetscReal *a[], PetscInt *its[], PetscInt *na)
4465 {
4466   PetscFunctionBegin;
4467   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
4468   if (a) *a = snes->conv_hist;
4469   if (its) *its = snes->conv_hist_its;
4470   if (na) *na = (PetscInt)snes->conv_hist_len;
4471   PetscFunctionReturn(PETSC_SUCCESS);
4472 }
4473 
4474 /*@C
4475   SNESSetUpdate - Sets the general-purpose update function called
4476   at the beginning of every iteration of the nonlinear solve. Specifically
4477   it is called just before the Jacobian is "evaluated" and after the function
4478   evaluation.
4479 
4480   Logically Collective
4481 
4482   Input Parameters:
4483 + snes - The nonlinear solver context
4484 - func - The update function; for calling sequence see `SNESUpdateFn`
4485 
4486   Level: advanced
4487 
4488   Notes:
4489   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
4490   to `SNESSetFunction()`, or `SNESSetPicard()`
4491   This is not used by most users, and it is intended to provide a general hook that is run
4492   right before the direction step is computed.
4493   Users are free to modify the current residual vector,
4494   the current linearization point, or any other vector associated to the specific solver used.
4495   If such modifications take place, it is the user responsibility to update all the relevant
4496   vectors.
4497 
4498   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.
4499 
4500 .seealso: [](ch_snes), `SNES`, `SNESSolve()`, `SNESSetJacobian()`, `SNESLineSearchSetPreCheck()`, `SNESLineSearchSetPostCheck()`, `SNESNewtonTRSetPreCheck()`, `SNESNewtonTRSetPostCheck()`,
4501          `SNESMonitorSet()`
4502 @*/
4503 PetscErrorCode SNESSetUpdate(SNES snes, SNESUpdateFn *func)
4504 {
4505   PetscFunctionBegin;
4506   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
4507   snes->ops->update = func;
4508   PetscFunctionReturn(PETSC_SUCCESS);
4509 }
4510 
4511 /*@
4512   SNESConvergedReasonView - Displays the reason a `SNES` solve converged or diverged to a viewer
4513 
4514   Collective
4515 
4516   Input Parameters:
4517 + snes   - iterative context obtained from `SNESCreate()`
4518 - viewer - the viewer to display the reason
4519 
4520   Options Database Keys:
4521 + -snes_converged_reason          - print reason for converged or diverged, also prints number of iterations
4522 - -snes_converged_reason ::failed - only print reason and number of iterations when diverged
4523 
4524   Level: beginner
4525 
4526   Note:
4527   To change the format of the output call `PetscViewerPushFormat`(viewer,format) before this call. Use `PETSC_VIEWER_DEFAULT` for the default,
4528   use `PETSC_VIEWER_FAILED` to only display a reason if it fails.
4529 
4530 .seealso: [](ch_snes), `SNESConvergedReason`, `PetscViewer`, `SNES`,
4531           `SNESCreate()`, `SNESSetUp()`, `SNESDestroy()`, `SNESSetTolerances()`, `SNESConvergedDefault()`, `SNESGetConvergedReason()`,
4532           `SNESConvergedReasonViewFromOptions()`,
4533           `PetscViewerPushFormat()`, `PetscViewerPopFormat()`
4534 @*/
4535 PetscErrorCode SNESConvergedReasonView(SNES snes, PetscViewer viewer)
4536 {
4537   PetscViewerFormat format;
4538   PetscBool         isAscii;
4539 
4540   PetscFunctionBegin;
4541   if (!viewer) viewer = PETSC_VIEWER_STDOUT_(PetscObjectComm((PetscObject)snes));
4542   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &isAscii));
4543   if (isAscii) {
4544     PetscCall(PetscViewerGetFormat(viewer, &format));
4545     PetscCall(PetscViewerASCIIAddTab(viewer, ((PetscObject)snes)->tablevel + 1));
4546     if (format == PETSC_VIEWER_ASCII_INFO_DETAIL) {
4547       DM       dm;
4548       Vec      u;
4549       PetscDS  prob;
4550       PetscInt Nf, f;
4551       PetscErrorCode (**exactSol)(PetscInt, PetscReal, const PetscReal[], PetscInt, PetscScalar[], void *);
4552       void    **exactCtx;
4553       PetscReal error;
4554 
4555       PetscCall(SNESGetDM(snes, &dm));
4556       PetscCall(SNESGetSolution(snes, &u));
4557       PetscCall(DMGetDS(dm, &prob));
4558       PetscCall(PetscDSGetNumFields(prob, &Nf));
4559       PetscCall(PetscMalloc2(Nf, &exactSol, Nf, &exactCtx));
4560       for (f = 0; f < Nf; ++f) PetscCall(PetscDSGetExactSolution(prob, f, &exactSol[f], &exactCtx[f]));
4561       PetscCall(DMComputeL2Diff(dm, 0.0, exactSol, exactCtx, u, &error));
4562       PetscCall(PetscFree2(exactSol, exactCtx));
4563       if (error < 1.0e-11) PetscCall(PetscViewerASCIIPrintf(viewer, "L_2 Error: < 1.0e-11\n"));
4564       else PetscCall(PetscViewerASCIIPrintf(viewer, "L_2 Error: %g\n", (double)error));
4565     }
4566     if (snes->reason > 0 && format != PETSC_VIEWER_FAILED) {
4567       if (((PetscObject)snes)->prefix) {
4568         PetscCall(PetscViewerASCIIPrintf(viewer, "Nonlinear %s solve converged due to %s iterations %" PetscInt_FMT "\n", ((PetscObject)snes)->prefix, SNESConvergedReasons[snes->reason], snes->iter));
4569       } else {
4570         PetscCall(PetscViewerASCIIPrintf(viewer, "Nonlinear solve converged due to %s iterations %" PetscInt_FMT "\n", SNESConvergedReasons[snes->reason], snes->iter));
4571       }
4572     } else if (snes->reason <= 0) {
4573       if (((PetscObject)snes)->prefix) {
4574         PetscCall(PetscViewerASCIIPrintf(viewer, "Nonlinear %s solve did not converge due to %s iterations %" PetscInt_FMT "\n", ((PetscObject)snes)->prefix, SNESConvergedReasons[snes->reason], snes->iter));
4575       } else {
4576         PetscCall(PetscViewerASCIIPrintf(viewer, "Nonlinear solve did not converge due to %s iterations %" PetscInt_FMT "\n", SNESConvergedReasons[snes->reason], snes->iter));
4577       }
4578     }
4579     PetscCall(PetscViewerASCIISubtractTab(viewer, ((PetscObject)snes)->tablevel + 1));
4580   }
4581   PetscFunctionReturn(PETSC_SUCCESS);
4582 }
4583 
4584 /*@C
4585   SNESConvergedReasonViewSet - Sets an ADDITIONAL function that is to be used at the
4586   end of the nonlinear solver to display the convergence reason of the nonlinear solver.
4587 
4588   Logically Collective
4589 
4590   Input Parameters:
4591 + snes              - the `SNES` context
4592 . f                 - the `SNESConvergedReason` view function
4593 . vctx              - [optional] user-defined context for private data for the `SNESConvergedReason` view function (use `NULL` if no context is desired)
4594 - reasonviewdestroy - [optional] routine that frees the context (may be `NULL`)
4595 
4596   Calling sequence of `f`:
4597 + snes - the `SNES` context
4598 - vctx - [optional] user-defined context for private data for the function
4599 
4600   Calling sequence of `reasonviewerdestroy`:
4601 . vctx - [optional] user-defined context for private data for the function
4602 
4603   Options Database Keys:
4604 + -snes_converged_reason             - sets a default `SNESConvergedReasonView()`
4605 - -snes_converged_reason_view_cancel - cancels all converged reason viewers that have been hardwired into a code by
4606                                        calls to `SNESConvergedReasonViewSet()`, but does not cancel those set via the options database.
4607 
4608   Level: intermediate
4609 
4610   Note:
4611   Several different converged reason view routines may be set by calling
4612   `SNESConvergedReasonViewSet()` multiple times; all will be called in the
4613   order in which they were set.
4614 
4615 .seealso: [](ch_snes), `SNES`, `SNESSolve()`, `SNESConvergedReason`, `SNESGetConvergedReason()`, `SNESConvergedReasonView()`, `SNESConvergedReasonViewCancel()`
4616 @*/
4617 PetscErrorCode SNESConvergedReasonViewSet(SNES snes, PetscErrorCode (*f)(SNES snes, void *vctx), void *vctx, PetscErrorCode (*reasonviewdestroy)(void **vctx))
4618 {
4619   PetscInt  i;
4620   PetscBool identical;
4621 
4622   PetscFunctionBegin;
4623   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
4624   for (i = 0; i < snes->numberreasonviews; i++) {
4625     PetscCall(PetscMonitorCompare((PetscErrorCode(*)(void))f, vctx, reasonviewdestroy, (PetscErrorCode(*)(void))snes->reasonview[i], snes->reasonviewcontext[i], snes->reasonviewdestroy[i], &identical));
4626     if (identical) PetscFunctionReturn(PETSC_SUCCESS);
4627   }
4628   PetscCheck(snes->numberreasonviews < MAXSNESREASONVIEWS, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Too many SNES reasonview set");
4629   snes->reasonview[snes->numberreasonviews]          = f;
4630   snes->reasonviewdestroy[snes->numberreasonviews]   = reasonviewdestroy;
4631   snes->reasonviewcontext[snes->numberreasonviews++] = (void *)vctx;
4632   PetscFunctionReturn(PETSC_SUCCESS);
4633 }
4634 
4635 /*@
4636   SNESConvergedReasonViewFromOptions - Processes command line options to determine if/how a `SNESConvergedReason` is to be viewed at the end of `SNESSolve()`
4637   All the user-provided convergedReasonView routines will be involved as well, if they exist.
4638 
4639   Collective
4640 
4641   Input Parameter:
4642 . snes - the `SNES` object
4643 
4644   Level: advanced
4645 
4646 .seealso: [](ch_snes), `SNES`, `SNESConvergedReason`, `SNESConvergedReasonViewSet()`, `SNESCreate()`, `SNESSetUp()`, `SNESDestroy()`,
4647           `SNESSetTolerances()`, `SNESConvergedDefault()`, `SNESGetConvergedReason()`, `SNESConvergedReasonView()`
4648 @*/
4649 PetscErrorCode SNESConvergedReasonViewFromOptions(SNES snes)
4650 {
4651   static PetscBool incall = PETSC_FALSE;
4652 
4653   PetscFunctionBegin;
4654   if (incall) PetscFunctionReturn(PETSC_SUCCESS);
4655   incall = PETSC_TRUE;
4656 
4657   /* All user-provided viewers are called first, if they exist. */
4658   for (PetscInt i = 0; i < snes->numberreasonviews; i++) PetscCall((*snes->reasonview[i])(snes, snes->reasonviewcontext[i]));
4659 
4660   /* Call PETSc default routine if users ask for it */
4661   if (snes->convergedreasonviewer) {
4662     PetscCall(PetscViewerPushFormat(snes->convergedreasonviewer, snes->convergedreasonformat));
4663     PetscCall(SNESConvergedReasonView(snes, snes->convergedreasonviewer));
4664     PetscCall(PetscViewerPopFormat(snes->convergedreasonviewer));
4665   }
4666   incall = PETSC_FALSE;
4667   PetscFunctionReturn(PETSC_SUCCESS);
4668 }
4669 
4670 /*@
4671   SNESSolve - Solves a nonlinear system F(x) = b.
4672 
4673   Collective
4674 
4675   Input Parameters:
4676 + snes - the `SNES` context
4677 . b    - the constant part of the equation F(x) = b, or `NULL` to use zero.
4678 - x    - the solution vector.
4679 
4680   Level: beginner
4681 
4682   Note:
4683   The user should initialize the vector, `x`, with the initial guess
4684   for the nonlinear solve prior to calling `SNESSolve()` or use `SNESSetInitialSolution()`.  In particular,
4685   to employ an initial guess of zero, the user should explicitly set
4686   this vector to zero by calling `VecSet()`.
4687 
4688 .seealso: [](ch_snes), `SNES`, `SNESCreate()`, `SNESDestroy()`, `SNESSetFunction()`, `SNESSetJacobian()`, `SNESSetGridSequence()`, `SNESGetSolution()`,
4689           `SNESNewtonTRSetPreCheck()`, `SNESNewtonTRGetPreCheck()`, `SNESNewtonTRSetPostCheck()`, `SNESNewtonTRGetPostCheck()`,
4690           `SNESLineSearchSetPostCheck()`, `SNESLineSearchGetPostCheck()`, `SNESLineSearchSetPreCheck()`, `SNESLineSearchGetPreCheck()`, `SNESSetInitialSolution()`
4691 @*/
4692 PetscErrorCode SNESSolve(SNES snes, Vec b, Vec x)
4693 {
4694   PetscBool flg;
4695   PetscInt  grid;
4696   Vec       xcreated = NULL;
4697   DM        dm;
4698 
4699   PetscFunctionBegin;
4700   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
4701   if (x) PetscValidHeaderSpecific(x, VEC_CLASSID, 3);
4702   if (x) PetscCheckSameComm(snes, 1, x, 3);
4703   if (b) PetscValidHeaderSpecific(b, VEC_CLASSID, 2);
4704   if (b) PetscCheckSameComm(snes, 1, b, 2);
4705 
4706   /* High level operations using the nonlinear solver */
4707   {
4708     PetscViewer       viewer;
4709     PetscViewerFormat format;
4710     PetscInt          num;
4711     PetscBool         flg;
4712     static PetscBool  incall = PETSC_FALSE;
4713 
4714     if (!incall) {
4715       /* Estimate the convergence rate of the discretization */
4716       PetscCall(PetscOptionsCreateViewer(PetscObjectComm((PetscObject)snes), ((PetscObject)snes)->options, ((PetscObject)snes)->prefix, "-snes_convergence_estimate", &viewer, &format, &flg));
4717       if (flg) {
4718         PetscConvEst conv;
4719         DM           dm;
4720         PetscReal   *alpha; /* Convergence rate of the solution error for each field in the L_2 norm */
4721         PetscInt     Nf;
4722 
4723         incall = PETSC_TRUE;
4724         PetscCall(SNESGetDM(snes, &dm));
4725         PetscCall(DMGetNumFields(dm, &Nf));
4726         PetscCall(PetscCalloc1(Nf, &alpha));
4727         PetscCall(PetscConvEstCreate(PetscObjectComm((PetscObject)snes), &conv));
4728         PetscCall(PetscConvEstSetSolver(conv, (PetscObject)snes));
4729         PetscCall(PetscConvEstSetFromOptions(conv));
4730         PetscCall(PetscConvEstSetUp(conv));
4731         PetscCall(PetscConvEstGetConvRate(conv, alpha));
4732         PetscCall(PetscViewerPushFormat(viewer, format));
4733         PetscCall(PetscConvEstRateView(conv, alpha, viewer));
4734         PetscCall(PetscViewerPopFormat(viewer));
4735         PetscCall(PetscViewerDestroy(&viewer));
4736         PetscCall(PetscConvEstDestroy(&conv));
4737         PetscCall(PetscFree(alpha));
4738         incall = PETSC_FALSE;
4739       }
4740       /* Adaptively refine the initial grid */
4741       num = 1;
4742       PetscCall(PetscOptionsGetInt(NULL, ((PetscObject)snes)->prefix, "-snes_adapt_initial", &num, &flg));
4743       if (flg) {
4744         DMAdaptor adaptor;
4745 
4746         incall = PETSC_TRUE;
4747         PetscCall(DMAdaptorCreate(PetscObjectComm((PetscObject)snes), &adaptor));
4748         PetscCall(DMAdaptorSetSolver(adaptor, snes));
4749         PetscCall(DMAdaptorSetSequenceLength(adaptor, num));
4750         PetscCall(DMAdaptorSetFromOptions(adaptor));
4751         PetscCall(DMAdaptorSetUp(adaptor));
4752         PetscCall(DMAdaptorAdapt(adaptor, x, DM_ADAPTATION_INITIAL, &dm, &x));
4753         PetscCall(DMAdaptorDestroy(&adaptor));
4754         incall = PETSC_FALSE;
4755       }
4756       /* Use grid sequencing to adapt */
4757       num = 0;
4758       PetscCall(PetscOptionsGetInt(NULL, ((PetscObject)snes)->prefix, "-snes_adapt_sequence", &num, NULL));
4759       if (num) {
4760         DMAdaptor   adaptor;
4761         const char *prefix;
4762 
4763         incall = PETSC_TRUE;
4764         PetscCall(DMAdaptorCreate(PetscObjectComm((PetscObject)snes), &adaptor));
4765         PetscCall(SNESGetOptionsPrefix(snes, &prefix));
4766         PetscCall(DMAdaptorSetOptionsPrefix(adaptor, prefix));
4767         PetscCall(DMAdaptorSetSolver(adaptor, snes));
4768         PetscCall(DMAdaptorSetSequenceLength(adaptor, num));
4769         PetscCall(DMAdaptorSetFromOptions(adaptor));
4770         PetscCall(DMAdaptorSetUp(adaptor));
4771         PetscCall(PetscObjectViewFromOptions((PetscObject)adaptor, NULL, "-snes_adapt_view"));
4772         PetscCall(DMAdaptorAdapt(adaptor, x, DM_ADAPTATION_SEQUENTIAL, &dm, &x));
4773         PetscCall(DMAdaptorDestroy(&adaptor));
4774         incall = PETSC_FALSE;
4775       }
4776     }
4777   }
4778   if (!x) x = snes->vec_sol;
4779   if (!x) {
4780     PetscCall(SNESGetDM(snes, &dm));
4781     PetscCall(DMCreateGlobalVector(dm, &xcreated));
4782     x = xcreated;
4783   }
4784   PetscCall(SNESViewFromOptions(snes, NULL, "-snes_view_pre"));
4785 
4786   for (grid = 0; grid < snes->gridsequence; grid++) PetscCall(PetscViewerASCIIPushTab(PETSC_VIEWER_STDOUT_(PetscObjectComm((PetscObject)snes))));
4787   for (grid = 0; grid < snes->gridsequence + 1; grid++) {
4788     /* set solution vector */
4789     if (!grid) PetscCall(PetscObjectReference((PetscObject)x));
4790     PetscCall(VecDestroy(&snes->vec_sol));
4791     snes->vec_sol = x;
4792     PetscCall(SNESGetDM(snes, &dm));
4793 
4794     /* set affine vector if provided */
4795     if (b) PetscCall(PetscObjectReference((PetscObject)b));
4796     PetscCall(VecDestroy(&snes->vec_rhs));
4797     snes->vec_rhs = b;
4798 
4799     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");
4800     PetscCheck(snes->vec_func != snes->vec_sol, PETSC_COMM_SELF, PETSC_ERR_ARG_IDN, "Solution vector cannot be function vector");
4801     PetscCheck(snes->vec_rhs != snes->vec_sol, PETSC_COMM_SELF, PETSC_ERR_ARG_IDN, "Solution vector cannot be right-hand side vector");
4802     if (!snes->vec_sol_update /* && snes->vec_sol */) PetscCall(VecDuplicate(snes->vec_sol, &snes->vec_sol_update));
4803     PetscCall(DMShellSetGlobalVector(dm, snes->vec_sol));
4804     PetscCall(SNESSetUp(snes));
4805 
4806     if (!grid) {
4807       if (snes->ops->computeinitialguess) PetscCallBack("SNES callback compute initial guess", (*snes->ops->computeinitialguess)(snes, snes->vec_sol, snes->initialguessP));
4808     }
4809 
4810     if (snes->conv_hist_reset) snes->conv_hist_len = 0;
4811     if (snes->counters_reset) {
4812       snes->nfuncs      = 0;
4813       snes->linear_its  = 0;
4814       snes->numFailures = 0;
4815     }
4816 
4817     snes->reason = SNES_CONVERGED_ITERATING;
4818     PetscCall(PetscLogEventBegin(SNES_Solve, snes, 0, 0, 0));
4819     PetscUseTypeMethod(snes, solve);
4820     PetscCall(PetscLogEventEnd(SNES_Solve, snes, 0, 0, 0));
4821     PetscCheck(snes->reason, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Internal error, solver %s returned without setting converged reason", ((PetscObject)snes)->type_name);
4822     snes->domainerror = PETSC_FALSE; /* clear the flag if it has been set */
4823 
4824     if (snes->lagjac_persist) snes->jac_iter += snes->iter;
4825     if (snes->lagpre_persist) snes->pre_iter += snes->iter;
4826 
4827     PetscCall(PetscOptionsCreateViewer(PetscObjectComm((PetscObject)snes), ((PetscObject)snes)->options, ((PetscObject)snes)->prefix, "-snes_test_local_min", NULL, NULL, &flg));
4828     if (flg && !PetscPreLoadingOn) PetscCall(SNESTestLocalMin(snes));
4829     /* Call converged reason views. This may involve user-provided viewers as well */
4830     PetscCall(SNESConvergedReasonViewFromOptions(snes));
4831 
4832     if (snes->errorifnotconverged) PetscCheck(snes->reason >= 0, PetscObjectComm((PetscObject)snes), PETSC_ERR_NOT_CONVERGED, "SNESSolve has not converged");
4833     if (snes->reason < 0) break;
4834     if (grid < snes->gridsequence) {
4835       DM  fine;
4836       Vec xnew;
4837       Mat interp;
4838 
4839       PetscCall(DMRefine(snes->dm, PetscObjectComm((PetscObject)snes), &fine));
4840       PetscCheck(fine, PetscObjectComm((PetscObject)snes), PETSC_ERR_ARG_INCOMP, "DMRefine() did not perform any refinement, cannot continue grid sequencing");
4841       PetscCall(DMCreateInterpolation(snes->dm, fine, &interp, NULL));
4842       PetscCall(DMCreateGlobalVector(fine, &xnew));
4843       PetscCall(MatInterpolate(interp, x, xnew));
4844       PetscCall(DMInterpolate(snes->dm, interp, fine));
4845       PetscCall(MatDestroy(&interp));
4846       x = xnew;
4847 
4848       PetscCall(SNESReset(snes));
4849       PetscCall(SNESSetDM(snes, fine));
4850       PetscCall(SNESResetFromOptions(snes));
4851       PetscCall(DMDestroy(&fine));
4852       PetscCall(PetscViewerASCIIPopTab(PETSC_VIEWER_STDOUT_(PetscObjectComm((PetscObject)snes))));
4853     }
4854   }
4855   PetscCall(SNESViewFromOptions(snes, NULL, "-snes_view"));
4856   PetscCall(VecViewFromOptions(snes->vec_sol, (PetscObject)snes, "-snes_view_solution"));
4857   PetscCall(DMMonitor(snes->dm));
4858   PetscCall(SNESMonitorPauseFinal_Internal(snes));
4859 
4860   PetscCall(VecDestroy(&xcreated));
4861   PetscCall(PetscObjectSAWsBlock((PetscObject)snes));
4862   PetscFunctionReturn(PETSC_SUCCESS);
4863 }
4864 
4865 /* --------- Internal routines for SNES Package --------- */
4866 
4867 /*@
4868   SNESSetType - Sets the method for the nonlinear solver.
4869 
4870   Collective
4871 
4872   Input Parameters:
4873 + snes - the `SNES` context
4874 - type - a known method
4875 
4876   Options Database Key:
4877 . -snes_type <type> - Sets the method; use -help for a list
4878    of available methods (for instance, newtonls or newtontr)
4879 
4880   Level: intermediate
4881 
4882   Notes:
4883   See "petsc/include/petscsnes.h" for available methods (for instance)
4884 +    `SNESNEWTONLS` - Newton's method with line search
4885   (systems of nonlinear equations)
4886 -    `SNESNEWTONTR` - Newton's method with trust region
4887   (systems of nonlinear equations)
4888 
4889   Normally, it is best to use the `SNESSetFromOptions()` command and then
4890   set the `SNES` solver type from the options database rather than by using
4891   this routine.  Using the options database provides the user with
4892   maximum flexibility in evaluating the many nonlinear solvers.
4893   The `SNESSetType()` routine is provided for those situations where it
4894   is necessary to set the nonlinear solver independently of the command
4895   line or options database.  This might be the case, for example, when
4896   the choice of solver changes during the execution of the program,
4897   and the user's application is taking responsibility for choosing the
4898   appropriate method.
4899 
4900   Developer Note:
4901   `SNESRegister()` adds a constructor for a new `SNESType` to `SNESList`, `SNESSetType()` locates
4902   the constructor in that list and calls it to create the specific object.
4903 
4904 .seealso: [](ch_snes), `SNES`, `SNESSolve()`, `SNESType`, `SNESCreate()`, `SNESDestroy()`, `SNESGetType()`, `SNESSetFromOptions()`
4905 @*/
4906 PetscErrorCode SNESSetType(SNES snes, SNESType type)
4907 {
4908   PetscBool match;
4909   PetscErrorCode (*r)(SNES);
4910 
4911   PetscFunctionBegin;
4912   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
4913   PetscAssertPointer(type, 2);
4914 
4915   PetscCall(PetscObjectTypeCompare((PetscObject)snes, type, &match));
4916   if (match) PetscFunctionReturn(PETSC_SUCCESS);
4917 
4918   PetscCall(PetscFunctionListFind(SNESList, type, &r));
4919   PetscCheck(r, PetscObjectComm((PetscObject)snes), PETSC_ERR_ARG_UNKNOWN_TYPE, "Unable to find requested SNES type %s", type);
4920   /* Destroy the previous private SNES context */
4921   PetscTryTypeMethod(snes, destroy);
4922   /* Reinitialize function pointers in SNESOps structure */
4923   snes->ops->setup          = NULL;
4924   snes->ops->solve          = NULL;
4925   snes->ops->view           = NULL;
4926   snes->ops->setfromoptions = NULL;
4927   snes->ops->destroy        = NULL;
4928 
4929   /* It may happen the user has customized the line search before calling SNESSetType */
4930   if (((PetscObject)snes)->type_name) PetscCall(SNESLineSearchDestroy(&snes->linesearch));
4931 
4932   /* Call the SNESCreate_XXX routine for this particular Nonlinear solver */
4933   snes->setupcalled = PETSC_FALSE;
4934 
4935   PetscCall(PetscObjectChangeTypeName((PetscObject)snes, type));
4936   PetscCall((*r)(snes));
4937   PetscFunctionReturn(PETSC_SUCCESS);
4938 }
4939 
4940 /*@
4941   SNESGetType - Gets the `SNES` method type and name (as a string).
4942 
4943   Not Collective
4944 
4945   Input Parameter:
4946 . snes - nonlinear solver context
4947 
4948   Output Parameter:
4949 . type - `SNES` method (a character string)
4950 
4951   Level: intermediate
4952 
4953 .seealso: [](ch_snes), `SNESSetType()`, `SNESType`, `SNESSetFromOptions()`, `SNES`
4954 @*/
4955 PetscErrorCode SNESGetType(SNES snes, SNESType *type)
4956 {
4957   PetscFunctionBegin;
4958   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
4959   PetscAssertPointer(type, 2);
4960   *type = ((PetscObject)snes)->type_name;
4961   PetscFunctionReturn(PETSC_SUCCESS);
4962 }
4963 
4964 /*@
4965   SNESSetSolution - Sets the solution vector for use by the `SNES` routines.
4966 
4967   Logically Collective
4968 
4969   Input Parameters:
4970 + snes - the `SNES` context obtained from `SNESCreate()`
4971 - u    - the solution vector
4972 
4973   Level: beginner
4974 
4975 .seealso: [](ch_snes), `SNES`, `SNESSolve()`, `SNESGetSolution()`, `Vec`
4976 @*/
4977 PetscErrorCode SNESSetSolution(SNES snes, Vec u)
4978 {
4979   DM dm;
4980 
4981   PetscFunctionBegin;
4982   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
4983   PetscValidHeaderSpecific(u, VEC_CLASSID, 2);
4984   PetscCall(PetscObjectReference((PetscObject)u));
4985   PetscCall(VecDestroy(&snes->vec_sol));
4986 
4987   snes->vec_sol = u;
4988 
4989   PetscCall(SNESGetDM(snes, &dm));
4990   PetscCall(DMShellSetGlobalVector(dm, u));
4991   PetscFunctionReturn(PETSC_SUCCESS);
4992 }
4993 
4994 /*@
4995   SNESGetSolution - Returns the vector where the approximate solution is
4996   stored. This is the fine grid solution when using `SNESSetGridSequence()`.
4997 
4998   Not Collective, but `x` is parallel if `snes` is parallel
4999 
5000   Input Parameter:
5001 . snes - the `SNES` context
5002 
5003   Output Parameter:
5004 . x - the solution
5005 
5006   Level: intermediate
5007 
5008 .seealso: [](ch_snes), `SNESSetSolution()`, `SNESSolve()`, `SNES`, `SNESGetSolutionUpdate()`, `SNESGetFunction()`
5009 @*/
5010 PetscErrorCode SNESGetSolution(SNES snes, Vec *x)
5011 {
5012   PetscFunctionBegin;
5013   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
5014   PetscAssertPointer(x, 2);
5015   *x = snes->vec_sol;
5016   PetscFunctionReturn(PETSC_SUCCESS);
5017 }
5018 
5019 /*@
5020   SNESGetSolutionUpdate - Returns the vector where the solution update is
5021   stored.
5022 
5023   Not Collective, but `x` is parallel if `snes` is parallel
5024 
5025   Input Parameter:
5026 . snes - the `SNES` context
5027 
5028   Output Parameter:
5029 . x - the solution update
5030 
5031   Level: advanced
5032 
5033 .seealso: [](ch_snes), `SNES`, `SNESGetSolution()`, `SNESGetFunction()`
5034 @*/
5035 PetscErrorCode SNESGetSolutionUpdate(SNES snes, Vec *x)
5036 {
5037   PetscFunctionBegin;
5038   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
5039   PetscAssertPointer(x, 2);
5040   *x = snes->vec_sol_update;
5041   PetscFunctionReturn(PETSC_SUCCESS);
5042 }
5043 
5044 /*@C
5045   SNESGetFunction - Returns the function that defines the nonlinear system set with `SNESSetFunction()`
5046 
5047   Not Collective, but `r` is parallel if `snes` is parallel. Collective if `r` is requested, but has not been created yet.
5048 
5049   Input Parameter:
5050 . snes - the `SNES` context
5051 
5052   Output Parameters:
5053 + r   - the vector that is used to store residuals (or `NULL` if you don't want it)
5054 . f   - the function (or `NULL` if you don't want it);  for calling sequence see `SNESFunctionFn`
5055 - ctx - the function context (or `NULL` if you don't want it)
5056 
5057   Level: advanced
5058 
5059   Note:
5060   The vector `r` DOES NOT, in general, contain the current value of the `SNES` nonlinear function
5061 
5062 .seealso: [](ch_snes), `SNES`, `SNESSolve()`, `SNESSetFunction()`, `SNESGetSolution()`, `SNESFunctionFn`
5063 @*/
5064 PetscErrorCode SNESGetFunction(SNES snes, Vec *r, SNESFunctionFn **f, void **ctx)
5065 {
5066   DM dm;
5067 
5068   PetscFunctionBegin;
5069   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
5070   if (r) {
5071     if (!snes->vec_func) {
5072       if (snes->vec_rhs) {
5073         PetscCall(VecDuplicate(snes->vec_rhs, &snes->vec_func));
5074       } else if (snes->vec_sol) {
5075         PetscCall(VecDuplicate(snes->vec_sol, &snes->vec_func));
5076       } else if (snes->dm) {
5077         PetscCall(DMCreateGlobalVector(snes->dm, &snes->vec_func));
5078       }
5079     }
5080     *r = snes->vec_func;
5081   }
5082   PetscCall(SNESGetDM(snes, &dm));
5083   PetscCall(DMSNESGetFunction(dm, f, ctx));
5084   PetscFunctionReturn(PETSC_SUCCESS);
5085 }
5086 
5087 /*@C
5088   SNESGetNGS - Returns the function and context set with `SNESSetNGS()`
5089 
5090   Input Parameter:
5091 . snes - the `SNES` context
5092 
5093   Output Parameters:
5094 + f   - the function (or `NULL`) see `SNESNGSFn` for calling sequence
5095 - ctx - the function context (or `NULL`)
5096 
5097   Level: advanced
5098 
5099 .seealso: [](ch_snes), `SNESSetNGS()`, `SNESGetFunction()`, `SNESNGSFn`
5100 @*/
5101 PetscErrorCode SNESGetNGS(SNES snes, SNESNGSFn **f, void **ctx)
5102 {
5103   DM dm;
5104 
5105   PetscFunctionBegin;
5106   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
5107   PetscCall(SNESGetDM(snes, &dm));
5108   PetscCall(DMSNESGetNGS(dm, f, ctx));
5109   PetscFunctionReturn(PETSC_SUCCESS);
5110 }
5111 
5112 /*@
5113   SNESSetOptionsPrefix - Sets the prefix used for searching for all
5114   `SNES` options in the database.
5115 
5116   Logically Collective
5117 
5118   Input Parameters:
5119 + snes   - the `SNES` context
5120 - prefix - the prefix to prepend to all option names
5121 
5122   Level: advanced
5123 
5124   Note:
5125   A hyphen (-) must NOT be given at the beginning of the prefix name.
5126   The first character of all runtime options is AUTOMATICALLY the hyphen.
5127 
5128 .seealso: [](ch_snes), `SNES`, `SNESSetFromOptions()`, `SNESAppendOptionsPrefix()`
5129 @*/
5130 PetscErrorCode SNESSetOptionsPrefix(SNES snes, const char prefix[])
5131 {
5132   PetscFunctionBegin;
5133   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
5134   PetscCall(PetscObjectSetOptionsPrefix((PetscObject)snes, prefix));
5135   if (!snes->ksp) PetscCall(SNESGetKSP(snes, &snes->ksp));
5136   if (snes->linesearch) {
5137     PetscCall(SNESGetLineSearch(snes, &snes->linesearch));
5138     PetscCall(PetscObjectSetOptionsPrefix((PetscObject)snes->linesearch, prefix));
5139   }
5140   PetscCall(KSPSetOptionsPrefix(snes->ksp, prefix));
5141   PetscFunctionReturn(PETSC_SUCCESS);
5142 }
5143 
5144 /*@
5145   SNESAppendOptionsPrefix - Appends to the prefix used for searching for all
5146   `SNES` options in the database.
5147 
5148   Logically Collective
5149 
5150   Input Parameters:
5151 + snes   - the `SNES` context
5152 - prefix - the prefix to prepend to all option names
5153 
5154   Level: advanced
5155 
5156   Note:
5157   A hyphen (-) must NOT be given at the beginning of the prefix name.
5158   The first character of all runtime options is AUTOMATICALLY the hyphen.
5159 
5160 .seealso: [](ch_snes), `SNESGetOptionsPrefix()`, `SNESSetOptionsPrefix()`
5161 @*/
5162 PetscErrorCode SNESAppendOptionsPrefix(SNES snes, const char prefix[])
5163 {
5164   PetscFunctionBegin;
5165   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
5166   PetscCall(PetscObjectAppendOptionsPrefix((PetscObject)snes, prefix));
5167   if (!snes->ksp) PetscCall(SNESGetKSP(snes, &snes->ksp));
5168   if (snes->linesearch) {
5169     PetscCall(SNESGetLineSearch(snes, &snes->linesearch));
5170     PetscCall(PetscObjectAppendOptionsPrefix((PetscObject)snes->linesearch, prefix));
5171   }
5172   PetscCall(KSPAppendOptionsPrefix(snes->ksp, prefix));
5173   PetscFunctionReturn(PETSC_SUCCESS);
5174 }
5175 
5176 /*@
5177   SNESGetOptionsPrefix - Gets the prefix used for searching for all
5178   `SNES` options in the database.
5179 
5180   Not Collective
5181 
5182   Input Parameter:
5183 . snes - the `SNES` context
5184 
5185   Output Parameter:
5186 . prefix - pointer to the prefix string used
5187 
5188   Level: advanced
5189 
5190   Fortran Note:
5191   The user should pass in a string 'prefix' of
5192   sufficient length to hold the prefix.
5193 
5194 .seealso: [](ch_snes), `SNES`, `SNESSetOptionsPrefix()`, `SNESAppendOptionsPrefix()`
5195 @*/
5196 PetscErrorCode SNESGetOptionsPrefix(SNES snes, const char *prefix[])
5197 {
5198   PetscFunctionBegin;
5199   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
5200   PetscCall(PetscObjectGetOptionsPrefix((PetscObject)snes, prefix));
5201   PetscFunctionReturn(PETSC_SUCCESS);
5202 }
5203 
5204 /*@C
5205   SNESRegister - Adds a method to the nonlinear solver package.
5206 
5207   Not Collective
5208 
5209   Input Parameters:
5210 + sname    - name of a new user-defined solver
5211 - function - routine to create method context
5212 
5213   Level: advanced
5214 
5215   Note:
5216   `SNESRegister()` may be called multiple times to add several user-defined solvers.
5217 
5218   Example Usage:
5219 .vb
5220    SNESRegister("my_solver", MySolverCreate);
5221 .ve
5222 
5223   Then, your solver can be chosen with the procedural interface via
5224 $     SNESSetType(snes, "my_solver")
5225   or at runtime via the option
5226 $     -snes_type my_solver
5227 
5228 .seealso: [](ch_snes), `SNESRegisterAll()`, `SNESRegisterDestroy()`
5229 @*/
5230 PetscErrorCode SNESRegister(const char sname[], PetscErrorCode (*function)(SNES))
5231 {
5232   PetscFunctionBegin;
5233   PetscCall(SNESInitializePackage());
5234   PetscCall(PetscFunctionListAdd(&SNESList, sname, function));
5235   PetscFunctionReturn(PETSC_SUCCESS);
5236 }
5237 
5238 PetscErrorCode SNESTestLocalMin(SNES snes)
5239 {
5240   PetscInt    N, i, j;
5241   Vec         u, uh, fh;
5242   PetscScalar value;
5243   PetscReal   norm;
5244 
5245   PetscFunctionBegin;
5246   PetscCall(SNESGetSolution(snes, &u));
5247   PetscCall(VecDuplicate(u, &uh));
5248   PetscCall(VecDuplicate(u, &fh));
5249 
5250   /* currently only works for sequential */
5251   PetscCall(PetscPrintf(PetscObjectComm((PetscObject)snes), "Testing FormFunction() for local min\n"));
5252   PetscCall(VecGetSize(u, &N));
5253   for (i = 0; i < N; i++) {
5254     PetscCall(VecCopy(u, uh));
5255     PetscCall(PetscPrintf(PetscObjectComm((PetscObject)snes), "i = %" PetscInt_FMT "\n", i));
5256     for (j = -10; j < 11; j++) {
5257       value = PetscSign(j) * PetscExpReal(PetscAbs(j) - 10.0);
5258       PetscCall(VecSetValue(uh, i, value, ADD_VALUES));
5259       PetscCall(SNESComputeFunction(snes, uh, fh));
5260       PetscCall(VecNorm(fh, NORM_2, &norm));
5261       PetscCall(PetscPrintf(PetscObjectComm((PetscObject)snes), "       j norm %" PetscInt_FMT " %18.16e\n", j, (double)norm));
5262       value = -value;
5263       PetscCall(VecSetValue(uh, i, value, ADD_VALUES));
5264     }
5265   }
5266   PetscCall(VecDestroy(&uh));
5267   PetscCall(VecDestroy(&fh));
5268   PetscFunctionReturn(PETSC_SUCCESS);
5269 }
5270 
5271 /*@
5272   SNESKSPSetUseEW - Sets `SNES` to the use Eisenstat-Walker method for
5273   computing relative tolerance for linear solvers within an inexact
5274   Newton method.
5275 
5276   Logically Collective
5277 
5278   Input Parameters:
5279 + snes - `SNES` context
5280 - flag - `PETSC_TRUE` or `PETSC_FALSE`
5281 
5282   Options Database Keys:
5283 + -snes_ksp_ew                       - use Eisenstat-Walker method for determining linear system convergence
5284 . -snes_ksp_ew_version ver           - version of  Eisenstat-Walker method
5285 . -snes_ksp_ew_rtol0 <rtol0>         - Sets rtol0
5286 . -snes_ksp_ew_rtolmax <rtolmax>     - Sets rtolmax
5287 . -snes_ksp_ew_gamma <gamma>         - Sets gamma
5288 . -snes_ksp_ew_alpha <alpha>         - Sets alpha
5289 . -snes_ksp_ew_alpha2 <alpha2>       - Sets alpha2
5290 - -snes_ksp_ew_threshold <threshold> - Sets threshold
5291 
5292   Level: advanced
5293 
5294   Note:
5295   The default is to use a constant relative tolerance for
5296   the inner linear solvers.  Alternatively, one can use the
5297   Eisenstat-Walker method {cite}`ew96`, where the relative convergence tolerance
5298   is reset at each Newton iteration according progress of the nonlinear
5299   solver.
5300 
5301 .seealso: [](ch_snes), `KSP`, `SNES`, `SNESKSPGetUseEW()`, `SNESKSPGetParametersEW()`, `SNESKSPSetParametersEW()`
5302 @*/
5303 PetscErrorCode SNESKSPSetUseEW(SNES snes, PetscBool flag)
5304 {
5305   PetscFunctionBegin;
5306   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
5307   PetscValidLogicalCollectiveBool(snes, flag, 2);
5308   snes->ksp_ewconv = flag;
5309   PetscFunctionReturn(PETSC_SUCCESS);
5310 }
5311 
5312 /*@
5313   SNESKSPGetUseEW - Gets if `SNES` is using Eisenstat-Walker method
5314   for computing relative tolerance for linear solvers within an
5315   inexact Newton method.
5316 
5317   Not Collective
5318 
5319   Input Parameter:
5320 . snes - `SNES` context
5321 
5322   Output Parameter:
5323 . flag - `PETSC_TRUE` or `PETSC_FALSE`
5324 
5325   Level: advanced
5326 
5327 .seealso: [](ch_snes), `SNESKSPSetUseEW()`, `SNESKSPGetParametersEW()`, `SNESKSPSetParametersEW()`
5328 @*/
5329 PetscErrorCode SNESKSPGetUseEW(SNES snes, PetscBool *flag)
5330 {
5331   PetscFunctionBegin;
5332   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
5333   PetscAssertPointer(flag, 2);
5334   *flag = snes->ksp_ewconv;
5335   PetscFunctionReturn(PETSC_SUCCESS);
5336 }
5337 
5338 /*@
5339   SNESKSPSetParametersEW - Sets parameters for Eisenstat-Walker
5340   convergence criteria for the linear solvers within an inexact
5341   Newton method.
5342 
5343   Logically Collective
5344 
5345   Input Parameters:
5346 + snes      - `SNES` context
5347 . version   - version 1, 2 (default is 2), 3 or 4
5348 . rtol_0    - initial relative tolerance (0 <= rtol_0 < 1)
5349 . rtol_max  - maximum relative tolerance (0 <= rtol_max < 1)
5350 . gamma     - multiplicative factor for version 2 rtol computation
5351              (0 <= gamma2 <= 1)
5352 . alpha     - power for version 2 rtol computation (1 < alpha <= 2)
5353 . alpha2    - power for safeguard
5354 - threshold - threshold for imposing safeguard (0 < threshold < 1)
5355 
5356   Level: advanced
5357 
5358   Notes:
5359   Version 3 was contributed by Luis Chacon, June 2006.
5360 
5361   Use `PETSC_CURRENT` to retain the default for any of the parameters.
5362 
5363 .seealso: [](ch_snes), `SNES`, `SNESKSPSetUseEW()`, `SNESKSPGetUseEW()`, `SNESKSPGetParametersEW()`
5364 @*/
5365 PetscErrorCode SNESKSPSetParametersEW(SNES snes, PetscInt version, PetscReal rtol_0, PetscReal rtol_max, PetscReal gamma, PetscReal alpha, PetscReal alpha2, PetscReal threshold)
5366 {
5367   SNESKSPEW *kctx;
5368 
5369   PetscFunctionBegin;
5370   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
5371   kctx = (SNESKSPEW *)snes->kspconvctx;
5372   PetscCheck(kctx, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "No Eisenstat-Walker context existing");
5373   PetscValidLogicalCollectiveInt(snes, version, 2);
5374   PetscValidLogicalCollectiveReal(snes, rtol_0, 3);
5375   PetscValidLogicalCollectiveReal(snes, rtol_max, 4);
5376   PetscValidLogicalCollectiveReal(snes, gamma, 5);
5377   PetscValidLogicalCollectiveReal(snes, alpha, 6);
5378   PetscValidLogicalCollectiveReal(snes, alpha2, 7);
5379   PetscValidLogicalCollectiveReal(snes, threshold, 8);
5380 
5381   if (version != PETSC_CURRENT) kctx->version = version;
5382   if (rtol_0 != (PetscReal)PETSC_CURRENT) kctx->rtol_0 = rtol_0;
5383   if (rtol_max != (PetscReal)PETSC_CURRENT) kctx->rtol_max = rtol_max;
5384   if (gamma != (PetscReal)PETSC_CURRENT) kctx->gamma = gamma;
5385   if (alpha != (PetscReal)PETSC_CURRENT) kctx->alpha = alpha;
5386   if (alpha2 != (PetscReal)PETSC_CURRENT) kctx->alpha2 = alpha2;
5387   if (threshold != (PetscReal)PETSC_CURRENT) kctx->threshold = threshold;
5388 
5389   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);
5390   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);
5391   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);
5392   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);
5393   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);
5394   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);
5395   PetscFunctionReturn(PETSC_SUCCESS);
5396 }
5397 
5398 /*@
5399   SNESKSPGetParametersEW - Gets parameters for Eisenstat-Walker
5400   convergence criteria for the linear solvers within an inexact
5401   Newton method.
5402 
5403   Not Collective
5404 
5405   Input Parameter:
5406 . snes - `SNES` context
5407 
5408   Output Parameters:
5409 + version   - version 1, 2 (default is 2), 3 or 4
5410 . rtol_0    - initial relative tolerance (0 <= rtol_0 < 1)
5411 . rtol_max  - maximum relative tolerance (0 <= rtol_max < 1)
5412 . gamma     - multiplicative factor for version 2 rtol computation (0 <= gamma2 <= 1)
5413 . alpha     - power for version 2 rtol computation (1 < alpha <= 2)
5414 . alpha2    - power for safeguard
5415 - threshold - threshold for imposing safeguard (0 < threshold < 1)
5416 
5417   Level: advanced
5418 
5419 .seealso: [](ch_snes), `SNES`, `SNESKSPSetUseEW()`, `SNESKSPGetUseEW()`, `SNESKSPSetParametersEW()`
5420 @*/
5421 PetscErrorCode SNESKSPGetParametersEW(SNES snes, PetscInt *version, PetscReal *rtol_0, PetscReal *rtol_max, PetscReal *gamma, PetscReal *alpha, PetscReal *alpha2, PetscReal *threshold)
5422 {
5423   SNESKSPEW *kctx;
5424 
5425   PetscFunctionBegin;
5426   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
5427   kctx = (SNESKSPEW *)snes->kspconvctx;
5428   PetscCheck(kctx, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "No Eisenstat-Walker context existing");
5429   if (version) *version = kctx->version;
5430   if (rtol_0) *rtol_0 = kctx->rtol_0;
5431   if (rtol_max) *rtol_max = kctx->rtol_max;
5432   if (gamma) *gamma = kctx->gamma;
5433   if (alpha) *alpha = kctx->alpha;
5434   if (alpha2) *alpha2 = kctx->alpha2;
5435   if (threshold) *threshold = kctx->threshold;
5436   PetscFunctionReturn(PETSC_SUCCESS);
5437 }
5438 
5439 PetscErrorCode KSPPreSolve_SNESEW(KSP ksp, Vec b, Vec x, void *ctx)
5440 {
5441   SNES       snes = (SNES)ctx;
5442   SNESKSPEW *kctx = (SNESKSPEW *)snes->kspconvctx;
5443   PetscReal  rtol = PETSC_CURRENT, stol;
5444 
5445   PetscFunctionBegin;
5446   if (!snes->ksp_ewconv) PetscFunctionReturn(PETSC_SUCCESS);
5447   if (!snes->iter) {
5448     rtol = kctx->rtol_0; /* first time in, so use the original user rtol */
5449     PetscCall(VecNorm(snes->vec_func, NORM_2, &kctx->norm_first));
5450   } else {
5451     PetscCheck(kctx->version >= 1 && kctx->version <= 4, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Only versions 1-4 are supported: %" PetscInt_FMT, kctx->version);
5452     if (kctx->version == 1) {
5453       rtol = PetscAbsReal(snes->norm - kctx->lresid_last) / kctx->norm_last;
5454       stol = PetscPowReal(kctx->rtol_last, kctx->alpha2);
5455       if (stol > kctx->threshold) rtol = PetscMax(rtol, stol);
5456     } else if (kctx->version == 2) {
5457       rtol = kctx->gamma * PetscPowReal(snes->norm / kctx->norm_last, kctx->alpha);
5458       stol = kctx->gamma * PetscPowReal(kctx->rtol_last, kctx->alpha);
5459       if (stol > kctx->threshold) rtol = PetscMax(rtol, stol);
5460     } else if (kctx->version == 3) { /* contributed by Luis Chacon, June 2006. */
5461       rtol = kctx->gamma * PetscPowReal(snes->norm / kctx->norm_last, kctx->alpha);
5462       /* safeguard: avoid sharp decrease of rtol */
5463       stol = kctx->gamma * PetscPowReal(kctx->rtol_last, kctx->alpha);
5464       stol = PetscMax(rtol, stol);
5465       rtol = PetscMin(kctx->rtol_0, stol);
5466       /* safeguard: avoid oversolving */
5467       stol = kctx->gamma * (kctx->norm_first * snes->rtol) / snes->norm;
5468       stol = PetscMax(rtol, stol);
5469       rtol = PetscMin(kctx->rtol_0, stol);
5470     } else /* if (kctx->version == 4) */ {
5471       /* H.-B. An et al. Journal of Computational and Applied Mathematics 200 (2007) 47-60 */
5472       PetscReal ared = PetscAbsReal(kctx->norm_last - snes->norm);
5473       PetscReal pred = PetscAbsReal(kctx->norm_last - kctx->lresid_last);
5474       PetscReal rk   = ared / pred;
5475       if (rk < kctx->v4_p1) rtol = 1. - 2. * kctx->v4_p1;
5476       else if (rk < kctx->v4_p2) rtol = kctx->rtol_last;
5477       else if (rk < kctx->v4_p3) rtol = kctx->v4_m1 * kctx->rtol_last;
5478       else rtol = kctx->v4_m2 * kctx->rtol_last;
5479 
5480       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;
5481       kctx->rtol_last_2 = kctx->rtol_last;
5482       kctx->rk_last_2   = kctx->rk_last;
5483       kctx->rk_last     = rk;
5484     }
5485   }
5486   /* safeguard: avoid rtol greater than rtol_max */
5487   rtol = PetscMin(rtol, kctx->rtol_max);
5488   PetscCall(KSPSetTolerances(ksp, rtol, PETSC_CURRENT, PETSC_CURRENT, PETSC_CURRENT));
5489   PetscCall(PetscInfo(snes, "iter %" PetscInt_FMT ", Eisenstat-Walker (version %" PetscInt_FMT ") KSP rtol=%g\n", snes->iter, kctx->version, (double)rtol));
5490   PetscFunctionReturn(PETSC_SUCCESS);
5491 }
5492 
5493 PetscErrorCode KSPPostSolve_SNESEW(KSP ksp, Vec b, Vec x, void *ctx)
5494 {
5495   SNES       snes = (SNES)ctx;
5496   SNESKSPEW *kctx = (SNESKSPEW *)snes->kspconvctx;
5497   PCSide     pcside;
5498   Vec        lres;
5499 
5500   PetscFunctionBegin;
5501   if (!snes->ksp_ewconv) PetscFunctionReturn(PETSC_SUCCESS);
5502   PetscCall(KSPGetTolerances(ksp, &kctx->rtol_last, NULL, NULL, NULL));
5503   kctx->norm_last = snes->norm;
5504   if (kctx->version == 1 || kctx->version == 4) {
5505     PC        pc;
5506     PetscBool getRes;
5507 
5508     PetscCall(KSPGetPC(ksp, &pc));
5509     PetscCall(PetscObjectTypeCompare((PetscObject)pc, PCNONE, &getRes));
5510     if (!getRes) {
5511       KSPNormType normtype;
5512 
5513       PetscCall(KSPGetNormType(ksp, &normtype));
5514       getRes = (PetscBool)(normtype == KSP_NORM_UNPRECONDITIONED);
5515     }
5516     PetscCall(KSPGetPCSide(ksp, &pcside));
5517     if (pcside == PC_RIGHT || getRes) { /* KSP residual is true linear residual */
5518       PetscCall(KSPGetResidualNorm(ksp, &kctx->lresid_last));
5519     } else {
5520       /* KSP residual is preconditioned residual */
5521       /* compute true linear residual norm */
5522       Mat J;
5523       PetscCall(KSPGetOperators(ksp, &J, NULL));
5524       PetscCall(VecDuplicate(b, &lres));
5525       PetscCall(MatMult(J, x, lres));
5526       PetscCall(VecAYPX(lres, -1.0, b));
5527       PetscCall(VecNorm(lres, NORM_2, &kctx->lresid_last));
5528       PetscCall(VecDestroy(&lres));
5529     }
5530   }
5531   PetscFunctionReturn(PETSC_SUCCESS);
5532 }
5533 
5534 /*@
5535   SNESGetKSP - Returns the `KSP` context for a `SNES` solver.
5536 
5537   Not Collective, but if `snes` is parallel, then `ksp` is parallel
5538 
5539   Input Parameter:
5540 . snes - the `SNES` context
5541 
5542   Output Parameter:
5543 . ksp - the `KSP` context
5544 
5545   Level: beginner
5546 
5547   Notes:
5548   The user can then directly manipulate the `KSP` context to set various
5549   options, etc.  Likewise, the user can then extract and manipulate the
5550   `PC` contexts as well.
5551 
5552   Some `SNESType`s do not use a `KSP` but a `KSP` is still returned by this function
5553 
5554 .seealso: [](ch_snes), `SNES`, `KSP`, `PC`, `KSPGetPC()`, `SNESCreate()`, `KSPCreate()`, `SNESSetKSP()`
5555 @*/
5556 PetscErrorCode SNESGetKSP(SNES snes, KSP *ksp)
5557 {
5558   PetscFunctionBegin;
5559   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
5560   PetscAssertPointer(ksp, 2);
5561 
5562   if (!snes->ksp) {
5563     PetscCall(KSPCreate(PetscObjectComm((PetscObject)snes), &snes->ksp));
5564     PetscCall(PetscObjectIncrementTabLevel((PetscObject)snes->ksp, (PetscObject)snes, 1));
5565 
5566     PetscCall(KSPSetPreSolve(snes->ksp, KSPPreSolve_SNESEW, snes));
5567     PetscCall(KSPSetPostSolve(snes->ksp, KSPPostSolve_SNESEW, snes));
5568 
5569     PetscCall(KSPMonitorSetFromOptions(snes->ksp, "-snes_monitor_ksp", "snes_preconditioned_residual", snes));
5570     PetscCall(PetscObjectSetOptions((PetscObject)snes->ksp, ((PetscObject)snes)->options));
5571   }
5572   *ksp = snes->ksp;
5573   PetscFunctionReturn(PETSC_SUCCESS);
5574 }
5575 
5576 #include <petsc/private/dmimpl.h>
5577 /*@
5578   SNESSetDM - Sets the `DM` that may be used by some nonlinear solvers or their underlying preconditioners
5579 
5580   Logically Collective
5581 
5582   Input Parameters:
5583 + snes - the nonlinear solver context
5584 - dm   - the `DM`, cannot be `NULL`
5585 
5586   Level: intermediate
5587 
5588   Note:
5589   A `DM` can only be used for solving one problem at a time because information about the problem is stored on the `DM`,
5590   even when not using interfaces like `DMSNESSetFunction()`.  Use `DMClone()` to get a distinct `DM` when solving different
5591   problems using the same function space.
5592 
5593 .seealso: [](ch_snes), `DM`, `SNES`, `SNESGetDM()`, `KSPSetDM()`, `KSPGetDM()`
5594 @*/
5595 PetscErrorCode SNESSetDM(SNES snes, DM dm)
5596 {
5597   KSP    ksp;
5598   DMSNES sdm;
5599 
5600   PetscFunctionBegin;
5601   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
5602   PetscValidHeaderSpecific(dm, DM_CLASSID, 2);
5603   PetscCall(PetscObjectReference((PetscObject)dm));
5604   if (snes->dm) { /* Move the DMSNES context over to the new DM unless the new DM already has one */
5605     if (snes->dm->dmsnes && !dm->dmsnes) {
5606       PetscCall(DMCopyDMSNES(snes->dm, dm));
5607       PetscCall(DMGetDMSNES(snes->dm, &sdm));
5608       if (sdm->originaldm == snes->dm) sdm->originaldm = dm; /* Grant write privileges to the replacement DM */
5609     }
5610     PetscCall(DMCoarsenHookRemove(snes->dm, DMCoarsenHook_SNESVecSol, DMRestrictHook_SNESVecSol, snes));
5611     PetscCall(DMDestroy(&snes->dm));
5612   }
5613   snes->dm     = dm;
5614   snes->dmAuto = PETSC_FALSE;
5615 
5616   PetscCall(SNESGetKSP(snes, &ksp));
5617   PetscCall(KSPSetDM(ksp, dm));
5618   PetscCall(KSPSetDMActive(ksp, PETSC_FALSE));
5619   if (snes->npc) {
5620     PetscCall(SNESSetDM(snes->npc, snes->dm));
5621     PetscCall(SNESSetNPCSide(snes, snes->npcside));
5622   }
5623   PetscFunctionReturn(PETSC_SUCCESS);
5624 }
5625 
5626 /*@
5627   SNESGetDM - Gets the `DM` that may be used by some solvers/preconditioners
5628 
5629   Not Collective but dm obtained is parallel on snes
5630 
5631   Input Parameter:
5632 . snes - the `SNES` context
5633 
5634   Output Parameter:
5635 . dm - the `DM`
5636 
5637   Level: intermediate
5638 
5639 .seealso: [](ch_snes), `DM`, `SNES`, `SNESSetDM()`, `KSPSetDM()`, `KSPGetDM()`
5640 @*/
5641 PetscErrorCode SNESGetDM(SNES snes, DM *dm)
5642 {
5643   PetscFunctionBegin;
5644   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
5645   if (!snes->dm) {
5646     PetscCall(DMShellCreate(PetscObjectComm((PetscObject)snes), &snes->dm));
5647     snes->dmAuto = PETSC_TRUE;
5648   }
5649   *dm = snes->dm;
5650   PetscFunctionReturn(PETSC_SUCCESS);
5651 }
5652 
5653 /*@
5654   SNESSetNPC - Sets the nonlinear preconditioner to be used.
5655 
5656   Collective
5657 
5658   Input Parameters:
5659 + snes - iterative context obtained from `SNESCreate()`
5660 - npc  - the nonlinear preconditioner object
5661 
5662   Level: developer
5663 
5664   Notes:
5665   Use `SNESGetNPC()` to retrieve the preconditioner context (for example,
5666   to configure it using the API).
5667 
5668   Only some `SNESType` can use a nonlinear preconditioner
5669 
5670 .seealso: [](ch_snes), `SNES`, `SNESNGS`, `SNESFAS`, `SNESGetNPC()`, `SNESHasNPC()`
5671 @*/
5672 PetscErrorCode SNESSetNPC(SNES snes, SNES npc)
5673 {
5674   PetscFunctionBegin;
5675   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
5676   PetscValidHeaderSpecific(npc, SNES_CLASSID, 2);
5677   PetscCheckSameComm(snes, 1, npc, 2);
5678   PetscCall(PetscObjectReference((PetscObject)npc));
5679   PetscCall(SNESDestroy(&snes->npc));
5680   snes->npc = npc;
5681   PetscFunctionReturn(PETSC_SUCCESS);
5682 }
5683 
5684 /*@
5685   SNESGetNPC - Gets a nonlinear preconditioning solver SNES` to be used to precondition the original nonlinear solver.
5686 
5687   Not Collective; but any changes to the obtained the npc object must be applied collectively
5688 
5689   Input Parameter:
5690 . snes - iterative context obtained from `SNESCreate()`
5691 
5692   Output Parameter:
5693 . pc - preconditioner context
5694 
5695   Options Database Key:
5696 . -npc_snes_type <type> - set the type of the `SNES` to use as the nonlinear preconditioner
5697 
5698   Level: developer
5699 
5700   Notes:
5701   If a `SNES` was previously set with `SNESSetNPC()` then that value is returned, otherwise a new `SNES` object is created.
5702 
5703   The (preconditioner) `SNES` returned automatically inherits the same nonlinear function and Jacobian supplied to the original
5704   `SNES`
5705 
5706 .seealso: [](ch_snes), `SNESSetNPC()`, `SNESHasNPC()`, `SNES`, `SNESCreate()`
5707 @*/
5708 PetscErrorCode SNESGetNPC(SNES snes, SNES *pc)
5709 {
5710   const char *optionsprefix;
5711 
5712   PetscFunctionBegin;
5713   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
5714   PetscAssertPointer(pc, 2);
5715   if (!snes->npc) {
5716     void *ctx;
5717 
5718     PetscCall(SNESCreate(PetscObjectComm((PetscObject)snes), &snes->npc));
5719     PetscCall(PetscObjectIncrementTabLevel((PetscObject)snes->npc, (PetscObject)snes, 1));
5720     PetscCall(SNESGetOptionsPrefix(snes, &optionsprefix));
5721     PetscCall(SNESSetOptionsPrefix(snes->npc, optionsprefix));
5722     PetscCall(SNESAppendOptionsPrefix(snes->npc, "npc_"));
5723     if (snes->ops->usercompute) {
5724       PetscCall(SNESSetComputeApplicationContext(snes, snes->ops->usercompute, snes->ops->userdestroy));
5725     } else {
5726       PetscCall(SNESGetApplicationContext(snes, &ctx));
5727       PetscCall(SNESSetApplicationContext(snes->npc, ctx));
5728     }
5729     PetscCall(SNESSetCountersReset(snes->npc, PETSC_FALSE));
5730   }
5731   *pc = snes->npc;
5732   PetscFunctionReturn(PETSC_SUCCESS);
5733 }
5734 
5735 /*@
5736   SNESHasNPC - Returns whether a nonlinear preconditioner exists
5737 
5738   Not Collective
5739 
5740   Input Parameter:
5741 . snes - iterative context obtained from `SNESCreate()`
5742 
5743   Output Parameter:
5744 . has_npc - whether the `SNES` has a nonlinear preconditioner or not
5745 
5746   Level: developer
5747 
5748 .seealso: [](ch_snes), `SNESSetNPC()`, `SNESGetNPC()`
5749 @*/
5750 PetscErrorCode SNESHasNPC(SNES snes, PetscBool *has_npc)
5751 {
5752   PetscFunctionBegin;
5753   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
5754   *has_npc = (PetscBool)(snes->npc ? PETSC_TRUE : PETSC_FALSE);
5755   PetscFunctionReturn(PETSC_SUCCESS);
5756 }
5757 
5758 /*@
5759   SNESSetNPCSide - Sets the nonlinear preconditioning side.
5760 
5761   Logically Collective
5762 
5763   Input Parameter:
5764 . snes - iterative context obtained from `SNESCreate()`
5765 
5766   Output Parameter:
5767 . side - the preconditioning side, where side is one of
5768 .vb
5769       PC_LEFT - left preconditioning
5770       PC_RIGHT - right preconditioning (default for most nonlinear solvers)
5771 .ve
5772 
5773   Options Database Key:
5774 . -snes_npc_side <right,left> - nonlinear preconditioner side
5775 
5776   Level: intermediate
5777 
5778   Note:
5779   `SNESNRICHARDSON` and `SNESNCG` only support left preconditioning.
5780 
5781 .seealso: [](ch_snes), `SNES`, `SNESNRICHARDSON`, `SNESNCG`, `SNESType`, `SNESGetNPCSide()`, `KSPSetPCSide()`, `PC_LEFT`, `PC_RIGHT`, `PCSide`
5782 @*/
5783 PetscErrorCode SNESSetNPCSide(SNES snes, PCSide side)
5784 {
5785   PetscFunctionBegin;
5786   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
5787   PetscValidLogicalCollectiveEnum(snes, side, 2);
5788   if (side == PC_SIDE_DEFAULT) side = PC_RIGHT;
5789   PetscCheck((side == PC_LEFT) || (side == PC_RIGHT), PetscObjectComm((PetscObject)snes), PETSC_ERR_ARG_WRONG, "Only PC_LEFT and PC_RIGHT are supported");
5790   snes->npcside = side;
5791   PetscFunctionReturn(PETSC_SUCCESS);
5792 }
5793 
5794 /*@
5795   SNESGetNPCSide - Gets the preconditioning side.
5796 
5797   Not Collective
5798 
5799   Input Parameter:
5800 . snes - iterative context obtained from `SNESCreate()`
5801 
5802   Output Parameter:
5803 . side - the preconditioning side, where side is one of
5804 .vb
5805       `PC_LEFT` - left preconditioning
5806       `PC_RIGHT` - right preconditioning (default for most nonlinear solvers)
5807 .ve
5808 
5809   Level: intermediate
5810 
5811 .seealso: [](ch_snes), `SNES`, `SNESSetNPCSide()`, `KSPGetPCSide()`, `PC_LEFT`, `PC_RIGHT`, `PCSide`
5812 @*/
5813 PetscErrorCode SNESGetNPCSide(SNES snes, PCSide *side)
5814 {
5815   PetscFunctionBegin;
5816   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
5817   PetscAssertPointer(side, 2);
5818   *side = snes->npcside;
5819   PetscFunctionReturn(PETSC_SUCCESS);
5820 }
5821 
5822 /*@
5823   SNESSetLineSearch - Sets the linesearch to be used for `SNES`
5824 
5825   Collective
5826 
5827   Input Parameters:
5828 + snes       - iterative context obtained from `SNESCreate()`
5829 - linesearch - the linesearch object
5830 
5831   Level: developer
5832 
5833   Note:
5834   This is almost never used, rather one uses `SNESGetLineSearch()` to retrieve the line search and set options on it
5835   to configure it using the API).
5836 
5837 .seealso: [](ch_snes), `SNES`, `SNESLineSearch`, `SNESGetLineSearch()`
5838 @*/
5839 PetscErrorCode SNESSetLineSearch(SNES snes, SNESLineSearch linesearch)
5840 {
5841   PetscFunctionBegin;
5842   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
5843   PetscValidHeaderSpecific(linesearch, SNESLINESEARCH_CLASSID, 2);
5844   PetscCheckSameComm(snes, 1, linesearch, 2);
5845   PetscCall(PetscObjectReference((PetscObject)linesearch));
5846   PetscCall(SNESLineSearchDestroy(&snes->linesearch));
5847 
5848   snes->linesearch = linesearch;
5849   PetscFunctionReturn(PETSC_SUCCESS);
5850 }
5851 
5852 /*@
5853   SNESGetLineSearch - Returns the line search context possibly set with `SNESSetLineSearch()`
5854   or creates a default line search instance associated with the `SNES` and returns it.
5855 
5856   Not Collective
5857 
5858   Input Parameter:
5859 . snes - iterative context obtained from `SNESCreate()`
5860 
5861   Output Parameter:
5862 . linesearch - linesearch context
5863 
5864   Level: beginner
5865 
5866 .seealso: [](ch_snes), `SNESLineSearch`, `SNESSetLineSearch()`, `SNESLineSearchCreate()`
5867 @*/
5868 PetscErrorCode SNESGetLineSearch(SNES snes, SNESLineSearch *linesearch)
5869 {
5870   const char *optionsprefix;
5871 
5872   PetscFunctionBegin;
5873   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
5874   PetscAssertPointer(linesearch, 2);
5875   if (!snes->linesearch) {
5876     PetscCall(SNESGetOptionsPrefix(snes, &optionsprefix));
5877     PetscCall(SNESLineSearchCreate(PetscObjectComm((PetscObject)snes), &snes->linesearch));
5878     PetscCall(SNESLineSearchSetSNES(snes->linesearch, snes));
5879     PetscCall(SNESLineSearchAppendOptionsPrefix(snes->linesearch, optionsprefix));
5880     PetscCall(PetscObjectIncrementTabLevel((PetscObject)snes->linesearch, (PetscObject)snes, 1));
5881   }
5882   *linesearch = snes->linesearch;
5883   PetscFunctionReturn(PETSC_SUCCESS);
5884 }
5885