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