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