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