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