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