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