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