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