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