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