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