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