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