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