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