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