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