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