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