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