xref: /petsc/src/snes/interface/snes.c (revision cb3ff29fa5c880872e59c11fa7fc2fbe1f738e0e)
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   Notes:
2391   `SNESComputeFunction()` is typically used within nonlinear solvers
2392   implementations, so users would not generally call this routine themselves.
2393 
2394   When solving for $F(x) = b$, this routine computes $y = F(x) - b$.
2395 
2396 .seealso: [](ch_snes), `SNES`, `SNESSetFunction()`, `SNESGetFunction()`, `SNESComputeMFFunction()`
2397 @*/
2398 PetscErrorCode SNESComputeFunction(SNES snes, Vec x, Vec y)
2399 {
2400   DM     dm;
2401   DMSNES sdm;
2402 
2403   PetscFunctionBegin;
2404   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
2405   PetscValidHeaderSpecific(x, VEC_CLASSID, 2);
2406   PetscValidHeaderSpecific(y, VEC_CLASSID, 3);
2407   PetscCheckSameComm(snes, 1, x, 2);
2408   PetscCheckSameComm(snes, 1, y, 3);
2409   PetscCall(VecValidValues_Internal(x, 2, PETSC_TRUE));
2410 
2411   PetscCall(SNESGetDM(snes, &dm));
2412   PetscCall(DMGetDMSNES(dm, &sdm));
2413   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().");
2414   if (sdm->ops->computefunction) {
2415     if (sdm->ops->computefunction != SNESObjectiveComputeFunctionDefaultFD) PetscCall(PetscLogEventBegin(SNES_FunctionEval, snes, x, y, 0));
2416     PetscCall(VecLockReadPush(x));
2417     /* ensure domainerror is false prior to computefunction evaluation (may not have been reset) */
2418     snes->domainerror = PETSC_FALSE;
2419     {
2420       void *ctx;
2421       PetscErrorCode (*computefunction)(SNES, Vec, Vec, void *);
2422       PetscCall(DMSNESGetFunction(dm, &computefunction, &ctx));
2423       PetscCallBack("SNES callback function", (*computefunction)(snes, x, y, ctx));
2424     }
2425     PetscCall(VecLockReadPop(x));
2426     if (sdm->ops->computefunction != SNESObjectiveComputeFunctionDefaultFD) PetscCall(PetscLogEventEnd(SNES_FunctionEval, snes, x, y, 0));
2427   } else /* if (snes->vec_rhs) */ {
2428     PetscCall(MatMult(snes->jacobian, x, y));
2429   }
2430   if (snes->vec_rhs) PetscCall(VecAXPY(y, -1.0, snes->vec_rhs));
2431   snes->nfuncs++;
2432   /*
2433      domainerror might not be set on all processes; so we tag vector locally with Inf and the next inner product or norm will
2434      propagate the value to all processes
2435   */
2436   if (snes->domainerror) PetscCall(VecSetInf(y));
2437   PetscFunctionReturn(PETSC_SUCCESS);
2438 }
2439 
2440 /*@
2441   SNESComputeMFFunction - Calls the function that has been set with `SNESSetMFFunction()`.
2442 
2443   Collective
2444 
2445   Input Parameters:
2446 + snes - the `SNES` context
2447 - x    - input vector
2448 
2449   Output Parameter:
2450 . y - function vector, as set by `SNESSetMFFunction()`
2451 
2452   Level: developer
2453 
2454   Notes:
2455   `SNESComputeMFFunction()` is used within the matrix-vector products called by the matrix created with `MatCreateSNESMF()`
2456   so users would not generally call this routine themselves.
2457 
2458   Since this function is intended for use with finite differencing it does not subtract the right hand side vector provided with `SNESSolve()`
2459   while `SNESComputeFunction()` does. As such, this routine cannot be used with  `MatMFFDSetBase()` with a provided F function value even if it applies the
2460   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.
2461 
2462 .seealso: [](ch_snes), `SNES`, `SNESSetFunction()`, `SNESGetFunction()`, `SNESComputeFunction()`, `MatCreateSNESMF`
2463 @*/
2464 PetscErrorCode SNESComputeMFFunction(SNES snes, Vec x, Vec y)
2465 {
2466   DM     dm;
2467   DMSNES sdm;
2468 
2469   PetscFunctionBegin;
2470   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
2471   PetscValidHeaderSpecific(x, VEC_CLASSID, 2);
2472   PetscValidHeaderSpecific(y, VEC_CLASSID, 3);
2473   PetscCheckSameComm(snes, 1, x, 2);
2474   PetscCheckSameComm(snes, 1, y, 3);
2475   PetscCall(VecValidValues_Internal(x, 2, PETSC_TRUE));
2476 
2477   PetscCall(SNESGetDM(snes, &dm));
2478   PetscCall(DMGetDMSNES(dm, &sdm));
2479   PetscCall(PetscLogEventBegin(SNES_FunctionEval, snes, x, y, 0));
2480   PetscCall(VecLockReadPush(x));
2481   /* ensure domainerror is false prior to computefunction evaluation (may not have been reset) */
2482   snes->domainerror = PETSC_FALSE;
2483   PetscCallBack("SNES callback function", (*sdm->ops->computemffunction)(snes, x, y, sdm->mffunctionctx));
2484   PetscCall(VecLockReadPop(x));
2485   PetscCall(PetscLogEventEnd(SNES_FunctionEval, snes, x, y, 0));
2486   snes->nfuncs++;
2487   /*
2488      domainerror might not be set on all processes; so we tag vector locally with Inf and the next inner product or norm will
2489      propagate the value to all processes
2490   */
2491   if (snes->domainerror) PetscCall(VecSetInf(y));
2492   PetscFunctionReturn(PETSC_SUCCESS);
2493 }
2494 
2495 /*@
2496   SNESComputeNGS - Calls the Gauss-Seidel function that has been set with  `SNESSetNGS()`.
2497 
2498   Collective
2499 
2500   Input Parameters:
2501 + snes - the `SNES` context
2502 . x    - input vector
2503 - b    - rhs vector
2504 
2505   Output Parameter:
2506 . x - new solution vector
2507 
2508   Level: developer
2509 
2510   Note:
2511   `SNESComputeNGS()` is typically used within composed nonlinear solver
2512   implementations, so most users would not generally call this routine
2513   themselves.
2514 
2515 .seealso: [](ch_snes), `SNESNGS`, `SNESSetNGS()`, `SNESComputeFunction()`
2516 @*/
2517 PetscErrorCode SNESComputeNGS(SNES snes, Vec b, Vec x)
2518 {
2519   DM     dm;
2520   DMSNES sdm;
2521 
2522   PetscFunctionBegin;
2523   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
2524   PetscValidHeaderSpecific(x, VEC_CLASSID, 3);
2525   if (b) PetscValidHeaderSpecific(b, VEC_CLASSID, 2);
2526   PetscCheckSameComm(snes, 1, x, 3);
2527   if (b) PetscCheckSameComm(snes, 1, b, 2);
2528   if (b) PetscCall(VecValidValues_Internal(b, 2, PETSC_TRUE));
2529   PetscCall(PetscLogEventBegin(SNES_NGSEval, snes, x, b, 0));
2530   PetscCall(SNESGetDM(snes, &dm));
2531   PetscCall(DMGetDMSNES(dm, &sdm));
2532   PetscCheck(sdm->ops->computegs, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Must call SNESSetNGS() before SNESComputeNGS(), likely called from SNESSolve().");
2533   if (b) PetscCall(VecLockReadPush(b));
2534   PetscCallBack("SNES callback NGS", (*sdm->ops->computegs)(snes, x, b, sdm->gsctx));
2535   if (b) PetscCall(VecLockReadPop(b));
2536   PetscCall(PetscLogEventEnd(SNES_NGSEval, snes, x, b, 0));
2537   PetscFunctionReturn(PETSC_SUCCESS);
2538 }
2539 
2540 PetscErrorCode SNESTestJacobian(SNES snes)
2541 {
2542   Mat               A, B, C, D, jacobian;
2543   Vec               x = snes->vec_sol, f = snes->vec_func;
2544   PetscReal         nrm, gnorm;
2545   PetscReal         threshold = 1.e-5;
2546   MatType           mattype;
2547   PetscInt          m, n, M, N;
2548   void             *functx;
2549   PetscBool         complete_print = PETSC_FALSE, threshold_print = PETSC_FALSE, test = PETSC_FALSE, flg, istranspose;
2550   PetscViewer       viewer, mviewer;
2551   MPI_Comm          comm;
2552   PetscInt          tabs;
2553   static PetscBool  directionsprinted = PETSC_FALSE;
2554   PetscViewerFormat format;
2555 
2556   PetscFunctionBegin;
2557   PetscObjectOptionsBegin((PetscObject)snes);
2558   PetscCall(PetscOptionsName("-snes_test_jacobian", "Compare hand-coded and finite difference Jacobians", "None", &test));
2559   PetscCall(PetscOptionsReal("-snes_test_jacobian", "Threshold for element difference between hand-coded and finite difference being meaningful", "None", threshold, &threshold, NULL));
2560   PetscCall(PetscOptionsDeprecated("-snes_test_jacobian_display", "-snes_test_jacobian_view", "3.13", NULL));
2561   PetscCall(PetscOptionsViewer("-snes_test_jacobian_view", "View difference between hand-coded and finite difference Jacobians element entries", "None", &mviewer, &format, &complete_print));
2562   PetscCall(PetscOptionsDeprecated("-snes_test_jacobian_display_threshold", "-snes_test_jacobian", "3.13", "-snes_test_jacobian accepts an optional threshold (since v3.10)"));
2563   /* 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 */
2564   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));
2565   PetscOptionsEnd();
2566   if (!test) PetscFunctionReturn(PETSC_SUCCESS);
2567 
2568   PetscCall(PetscObjectGetComm((PetscObject)snes, &comm));
2569   PetscCall(PetscViewerASCIIGetStdout(comm, &viewer));
2570   PetscCall(PetscViewerASCIIGetTab(viewer, &tabs));
2571   PetscCall(PetscViewerASCIISetTab(viewer, ((PetscObject)snes)->tablevel));
2572   PetscCall(PetscViewerASCIIPrintf(viewer, "  ---------- Testing Jacobian -------------\n"));
2573   if (!complete_print && !directionsprinted) {
2574     PetscCall(PetscViewerASCIIPrintf(viewer, "  Run with -snes_test_jacobian_view and optionally -snes_test_jacobian <threshold> to show difference\n"));
2575     PetscCall(PetscViewerASCIIPrintf(viewer, "    of hand-coded and finite difference Jacobian entries greater than <threshold>.\n"));
2576   }
2577   if (!directionsprinted) {
2578     PetscCall(PetscViewerASCIIPrintf(viewer, "  Testing hand-coded Jacobian, if (for double precision runs) ||J - Jfd||_F/||J||_F is\n"));
2579     PetscCall(PetscViewerASCIIPrintf(viewer, "    O(1.e-8), the hand-coded Jacobian is probably correct.\n"));
2580     directionsprinted = PETSC_TRUE;
2581   }
2582   if (complete_print) PetscCall(PetscViewerPushFormat(mviewer, format));
2583 
2584   PetscCall(PetscObjectTypeCompare((PetscObject)snes->jacobian, MATMFFD, &flg));
2585   if (!flg) jacobian = snes->jacobian;
2586   else jacobian = snes->jacobian_pre;
2587 
2588   if (!x) {
2589     PetscCall(MatCreateVecs(jacobian, &x, NULL));
2590   } else {
2591     PetscCall(PetscObjectReference((PetscObject)x));
2592   }
2593   if (!f) {
2594     PetscCall(VecDuplicate(x, &f));
2595   } else {
2596     PetscCall(PetscObjectReference((PetscObject)f));
2597   }
2598   /* evaluate the function at this point because SNESComputeJacobianDefault() assumes that the function has been evaluated and put into snes->vec_func */
2599   PetscCall(SNESComputeFunction(snes, x, f));
2600   PetscCall(VecDestroy(&f));
2601   PetscCall(PetscObjectTypeCompare((PetscObject)snes, SNESKSPTRANSPOSEONLY, &istranspose));
2602   while (jacobian) {
2603     Mat JT = NULL, Jsave = NULL;
2604 
2605     if (istranspose) {
2606       PetscCall(MatCreateTranspose(jacobian, &JT));
2607       Jsave    = jacobian;
2608       jacobian = JT;
2609     }
2610     PetscCall(PetscObjectBaseTypeCompareAny((PetscObject)jacobian, &flg, MATSEQAIJ, MATMPIAIJ, MATSEQDENSE, MATMPIDENSE, MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ, ""));
2611     if (flg) {
2612       A = jacobian;
2613       PetscCall(PetscObjectReference((PetscObject)A));
2614     } else {
2615       PetscCall(MatComputeOperator(jacobian, MATAIJ, &A));
2616     }
2617 
2618     PetscCall(MatGetType(A, &mattype));
2619     PetscCall(MatGetSize(A, &M, &N));
2620     PetscCall(MatGetLocalSize(A, &m, &n));
2621     PetscCall(MatCreate(PetscObjectComm((PetscObject)A), &B));
2622     PetscCall(MatSetType(B, mattype));
2623     PetscCall(MatSetSizes(B, m, n, M, N));
2624     PetscCall(MatSetBlockSizesFromMats(B, A, A));
2625     PetscCall(MatSetUp(B));
2626     PetscCall(MatSetOption(B, MAT_NEW_NONZERO_ALLOCATION_ERR, PETSC_FALSE));
2627 
2628     PetscCall(SNESGetFunction(snes, NULL, NULL, &functx));
2629     PetscCall(SNESComputeJacobianDefault(snes, x, B, B, functx));
2630 
2631     PetscCall(MatDuplicate(B, MAT_COPY_VALUES, &D));
2632     PetscCall(MatAYPX(D, -1.0, A, DIFFERENT_NONZERO_PATTERN));
2633     PetscCall(MatNorm(D, NORM_FROBENIUS, &nrm));
2634     PetscCall(MatNorm(A, NORM_FROBENIUS, &gnorm));
2635     PetscCall(MatDestroy(&D));
2636     if (!gnorm) gnorm = 1; /* just in case */
2637     PetscCall(PetscViewerASCIIPrintf(viewer, "  ||J - Jfd||_F/||J||_F = %g, ||J - Jfd||_F = %g\n", (double)(nrm / gnorm), (double)nrm));
2638 
2639     if (complete_print) {
2640       PetscCall(PetscViewerASCIIPrintf(viewer, "  Hand-coded Jacobian ----------\n"));
2641       PetscCall(MatView(A, mviewer));
2642       PetscCall(PetscViewerASCIIPrintf(viewer, "  Finite difference Jacobian ----------\n"));
2643       PetscCall(MatView(B, mviewer));
2644     }
2645 
2646     if (threshold_print || complete_print) {
2647       PetscInt           Istart, Iend, *ccols, bncols, cncols, j, row;
2648       PetscScalar       *cvals;
2649       const PetscInt    *bcols;
2650       const PetscScalar *bvals;
2651 
2652       PetscCall(MatCreate(PetscObjectComm((PetscObject)A), &C));
2653       PetscCall(MatSetType(C, mattype));
2654       PetscCall(MatSetSizes(C, m, n, M, N));
2655       PetscCall(MatSetBlockSizesFromMats(C, A, A));
2656       PetscCall(MatSetUp(C));
2657       PetscCall(MatSetOption(C, MAT_NEW_NONZERO_ALLOCATION_ERR, PETSC_FALSE));
2658 
2659       PetscCall(MatAYPX(B, -1.0, A, DIFFERENT_NONZERO_PATTERN));
2660       PetscCall(MatGetOwnershipRange(B, &Istart, &Iend));
2661 
2662       for (row = Istart; row < Iend; row++) {
2663         PetscCall(MatGetRow(B, row, &bncols, &bcols, &bvals));
2664         PetscCall(PetscMalloc2(bncols, &ccols, bncols, &cvals));
2665         for (j = 0, cncols = 0; j < bncols; j++) {
2666           if (PetscAbsScalar(bvals[j]) > threshold) {
2667             ccols[cncols] = bcols[j];
2668             cvals[cncols] = bvals[j];
2669             cncols += 1;
2670           }
2671         }
2672         if (cncols) PetscCall(MatSetValues(C, 1, &row, cncols, ccols, cvals, INSERT_VALUES));
2673         PetscCall(MatRestoreRow(B, row, &bncols, &bcols, &bvals));
2674         PetscCall(PetscFree2(ccols, cvals));
2675       }
2676       PetscCall(MatAssemblyBegin(C, MAT_FINAL_ASSEMBLY));
2677       PetscCall(MatAssemblyEnd(C, MAT_FINAL_ASSEMBLY));
2678       PetscCall(PetscViewerASCIIPrintf(viewer, "  Hand-coded minus finite-difference Jacobian with tolerance %g ----------\n", (double)threshold));
2679       PetscCall(MatView(C, complete_print ? mviewer : viewer));
2680       PetscCall(MatDestroy(&C));
2681     }
2682     PetscCall(MatDestroy(&A));
2683     PetscCall(MatDestroy(&B));
2684     PetscCall(MatDestroy(&JT));
2685     if (Jsave) jacobian = Jsave;
2686     if (jacobian != snes->jacobian_pre) {
2687       jacobian = snes->jacobian_pre;
2688       PetscCall(PetscViewerASCIIPrintf(viewer, "  ---------- Testing Jacobian for preconditioner -------------\n"));
2689     } else jacobian = NULL;
2690   }
2691   PetscCall(VecDestroy(&x));
2692   if (complete_print) PetscCall(PetscViewerPopFormat(mviewer));
2693   if (mviewer) PetscCall(PetscViewerDestroy(&mviewer));
2694   PetscCall(PetscViewerASCIISetTab(viewer, tabs));
2695   PetscFunctionReturn(PETSC_SUCCESS);
2696 }
2697 
2698 /*@
2699   SNESComputeJacobian - Computes the Jacobian matrix that has been set with `SNESSetJacobian()`.
2700 
2701   Collective
2702 
2703   Input Parameters:
2704 + snes - the `SNES` context
2705 - X    - input vector
2706 
2707   Output Parameters:
2708 + A - Jacobian matrix
2709 - B - optional matrix for building the preconditioner, usually the same as `A`
2710 
2711   Options Database Keys:
2712 + -snes_lag_preconditioner <lag>           - how often to rebuild preconditioner
2713 . -snes_lag_jacobian <lag>                 - how often to rebuild Jacobian
2714 . -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.
2715 . -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
2716 . -snes_compare_explicit                   - Compare the computed Jacobian to the finite difference Jacobian and output the differences
2717 . -snes_compare_explicit_draw              - Compare the computed Jacobian to the finite difference Jacobian and draw the result
2718 . -snes_compare_explicit_contour           - Compare the computed Jacobian to the finite difference Jacobian and draw a contour plot with the result
2719 . -snes_compare_operator                   - Make the comparison options above use the operator instead of the preconditioning matrix
2720 . -snes_compare_coloring                   - Compute the finite difference Jacobian using coloring and display norms of difference
2721 . -snes_compare_coloring_display           - Compute the finite difference Jacobian using coloring and display verbose differences
2722 . -snes_compare_coloring_threshold         - Display only those matrix entries that differ by more than a given threshold
2723 . -snes_compare_coloring_threshold_atol    - Absolute tolerance for difference in matrix entries to be displayed by `-snes_compare_coloring_threshold`
2724 . -snes_compare_coloring_threshold_rtol    - Relative tolerance for difference in matrix entries to be displayed by `-snes_compare_coloring_threshold`
2725 . -snes_compare_coloring_draw              - Compute the finite difference Jacobian using coloring and draw differences
2726 - -snes_compare_coloring_draw_contour      - Compute the finite difference Jacobian using coloring and show contours of matrices and differences
2727 
2728   Level: developer
2729 
2730   Note:
2731   Most users should not need to explicitly call this routine, as it
2732   is used internally within the nonlinear solvers.
2733 
2734   Developer Note:
2735   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
2736   with the `SNESType` of test that has been removed.
2737 
2738 .seealso: [](ch_snes), `SNESSetJacobian()`, `KSPSetOperators()`, `MatStructure`, `SNESSetLagPreconditioner()`, `SNESSetLagJacobian()`
2739 @*/
2740 PetscErrorCode SNESComputeJacobian(SNES snes, Vec X, Mat A, Mat B)
2741 {
2742   PetscBool flag;
2743   DM        dm;
2744   DMSNES    sdm;
2745   KSP       ksp;
2746 
2747   PetscFunctionBegin;
2748   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
2749   PetscValidHeaderSpecific(X, VEC_CLASSID, 2);
2750   PetscCheckSameComm(snes, 1, X, 2);
2751   PetscCall(VecValidValues_Internal(X, 2, PETSC_TRUE));
2752   PetscCall(SNESGetDM(snes, &dm));
2753   PetscCall(DMGetDMSNES(dm, &sdm));
2754 
2755   /* make sure that MatAssemblyBegin/End() is called on A matrix if it is matrix-free */
2756   if (snes->lagjacobian == -2) {
2757     snes->lagjacobian = -1;
2758 
2759     PetscCall(PetscInfo(snes, "Recomputing Jacobian/preconditioner because lag is -2 (means compute Jacobian, but then never again) \n"));
2760   } else if (snes->lagjacobian == -1) {
2761     PetscCall(PetscInfo(snes, "Reusing Jacobian/preconditioner because lag is -1\n"));
2762     PetscCall(PetscObjectTypeCompare((PetscObject)A, MATMFFD, &flag));
2763     if (flag) {
2764       PetscCall(MatAssemblyBegin(A, MAT_FINAL_ASSEMBLY));
2765       PetscCall(MatAssemblyEnd(A, MAT_FINAL_ASSEMBLY));
2766     }
2767     PetscFunctionReturn(PETSC_SUCCESS);
2768   } else if (snes->lagjacobian > 1 && (snes->iter + snes->jac_iter) % snes->lagjacobian) {
2769     PetscCall(PetscInfo(snes, "Reusing Jacobian/preconditioner because lag is %" PetscInt_FMT " and SNES iteration is %" PetscInt_FMT "\n", snes->lagjacobian, snes->iter));
2770     PetscCall(PetscObjectTypeCompare((PetscObject)A, MATMFFD, &flag));
2771     if (flag) {
2772       PetscCall(MatAssemblyBegin(A, MAT_FINAL_ASSEMBLY));
2773       PetscCall(MatAssemblyEnd(A, MAT_FINAL_ASSEMBLY));
2774     }
2775     PetscFunctionReturn(PETSC_SUCCESS);
2776   }
2777   if (snes->npc && snes->npcside == PC_LEFT) {
2778     PetscCall(MatAssemblyBegin(A, MAT_FINAL_ASSEMBLY));
2779     PetscCall(MatAssemblyEnd(A, MAT_FINAL_ASSEMBLY));
2780     PetscFunctionReturn(PETSC_SUCCESS);
2781   }
2782 
2783   PetscCall(PetscLogEventBegin(SNES_JacobianEval, snes, X, A, B));
2784   PetscCall(VecLockReadPush(X));
2785   {
2786     void *ctx;
2787     PetscErrorCode (*J)(SNES, Vec, Mat, Mat, void *);
2788     PetscCall(DMSNESGetJacobian(dm, &J, &ctx));
2789     PetscCallBack("SNES callback Jacobian", (*J)(snes, X, A, B, ctx));
2790   }
2791   PetscCall(VecLockReadPop(X));
2792   PetscCall(PetscLogEventEnd(SNES_JacobianEval, snes, X, A, B));
2793 
2794   /* attach latest linearization point to the preconditioning matrix */
2795   PetscCall(PetscObjectCompose((PetscObject)B, "__SNES_latest_X", (PetscObject)X));
2796 
2797   /* the next line ensures that snes->ksp exists */
2798   PetscCall(SNESGetKSP(snes, &ksp));
2799   if (snes->lagpreconditioner == -2) {
2800     PetscCall(PetscInfo(snes, "Rebuilding preconditioner exactly once since lag is -2\n"));
2801     PetscCall(KSPSetReusePreconditioner(snes->ksp, PETSC_FALSE));
2802     snes->lagpreconditioner = -1;
2803   } else if (snes->lagpreconditioner == -1) {
2804     PetscCall(PetscInfo(snes, "Reusing preconditioner because lag is -1\n"));
2805     PetscCall(KSPSetReusePreconditioner(snes->ksp, PETSC_TRUE));
2806   } else if (snes->lagpreconditioner > 1 && (snes->iter + snes->pre_iter) % snes->lagpreconditioner) {
2807     PetscCall(PetscInfo(snes, "Reusing preconditioner because lag is %" PetscInt_FMT " and SNES iteration is %" PetscInt_FMT "\n", snes->lagpreconditioner, snes->iter));
2808     PetscCall(KSPSetReusePreconditioner(snes->ksp, PETSC_TRUE));
2809   } else {
2810     PetscCall(PetscInfo(snes, "Rebuilding preconditioner\n"));
2811     PetscCall(KSPSetReusePreconditioner(snes->ksp, PETSC_FALSE));
2812   }
2813 
2814   PetscCall(SNESTestJacobian(snes));
2815   /* make sure user returned a correct Jacobian and preconditioner */
2816   /* PetscValidHeaderSpecific(A,MAT_CLASSID,3);
2817     PetscValidHeaderSpecific(B,MAT_CLASSID,4);   */
2818   {
2819     PetscBool flag = PETSC_FALSE, flag_draw = PETSC_FALSE, flag_contour = PETSC_FALSE, flag_operator = PETSC_FALSE;
2820     PetscCall(PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes), ((PetscObject)snes)->options, ((PetscObject)snes)->prefix, "-snes_compare_explicit", NULL, NULL, &flag));
2821     PetscCall(PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes), ((PetscObject)snes)->options, ((PetscObject)snes)->prefix, "-snes_compare_explicit_draw", NULL, NULL, &flag_draw));
2822     PetscCall(PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes), ((PetscObject)snes)->options, ((PetscObject)snes)->prefix, "-snes_compare_explicit_draw_contour", NULL, NULL, &flag_contour));
2823     PetscCall(PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes), ((PetscObject)snes)->options, ((PetscObject)snes)->prefix, "-snes_compare_operator", NULL, NULL, &flag_operator));
2824     if (flag || flag_draw || flag_contour) {
2825       Mat         Bexp_mine = NULL, Bexp, FDexp;
2826       PetscViewer vdraw, vstdout;
2827       PetscBool   flg;
2828       if (flag_operator) {
2829         PetscCall(MatComputeOperator(A, MATAIJ, &Bexp_mine));
2830         Bexp = Bexp_mine;
2831       } else {
2832         /* See if the preconditioning matrix can be viewed and added directly */
2833         PetscCall(PetscObjectBaseTypeCompareAny((PetscObject)B, &flg, MATSEQAIJ, MATMPIAIJ, MATSEQDENSE, MATMPIDENSE, MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPIBAIJ, ""));
2834         if (flg) Bexp = B;
2835         else {
2836           /* If the "preconditioning" matrix is itself MATSHELL or some other type without direct support */
2837           PetscCall(MatComputeOperator(B, MATAIJ, &Bexp_mine));
2838           Bexp = Bexp_mine;
2839         }
2840       }
2841       PetscCall(MatConvert(Bexp, MATSAME, MAT_INITIAL_MATRIX, &FDexp));
2842       PetscCall(SNESComputeJacobianDefault(snes, X, FDexp, FDexp, NULL));
2843       PetscCall(PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)snes), &vstdout));
2844       if (flag_draw || flag_contour) {
2845         PetscCall(PetscViewerDrawOpen(PetscObjectComm((PetscObject)snes), NULL, "Explicit Jacobians", PETSC_DECIDE, PETSC_DECIDE, 300, 300, &vdraw));
2846         if (flag_contour) PetscCall(PetscViewerPushFormat(vdraw, PETSC_VIEWER_DRAW_CONTOUR));
2847       } else vdraw = NULL;
2848       PetscCall(PetscViewerASCIIPrintf(vstdout, "Explicit %s\n", flag_operator ? "Jacobian" : "preconditioning Jacobian"));
2849       if (flag) PetscCall(MatView(Bexp, vstdout));
2850       if (vdraw) PetscCall(MatView(Bexp, vdraw));
2851       PetscCall(PetscViewerASCIIPrintf(vstdout, "Finite difference Jacobian\n"));
2852       if (flag) PetscCall(MatView(FDexp, vstdout));
2853       if (vdraw) PetscCall(MatView(FDexp, vdraw));
2854       PetscCall(MatAYPX(FDexp, -1.0, Bexp, SAME_NONZERO_PATTERN));
2855       PetscCall(PetscViewerASCIIPrintf(vstdout, "User-provided matrix minus finite difference Jacobian\n"));
2856       if (flag) PetscCall(MatView(FDexp, vstdout));
2857       if (vdraw) { /* Always use contour for the difference */
2858         PetscCall(PetscViewerPushFormat(vdraw, PETSC_VIEWER_DRAW_CONTOUR));
2859         PetscCall(MatView(FDexp, vdraw));
2860         PetscCall(PetscViewerPopFormat(vdraw));
2861       }
2862       if (flag_contour) PetscCall(PetscViewerPopFormat(vdraw));
2863       PetscCall(PetscViewerDestroy(&vdraw));
2864       PetscCall(MatDestroy(&Bexp_mine));
2865       PetscCall(MatDestroy(&FDexp));
2866     }
2867   }
2868   {
2869     PetscBool flag = PETSC_FALSE, flag_display = PETSC_FALSE, flag_draw = PETSC_FALSE, flag_contour = PETSC_FALSE, flag_threshold = PETSC_FALSE;
2870     PetscReal threshold_atol = PETSC_SQRT_MACHINE_EPSILON, threshold_rtol = 10 * PETSC_SQRT_MACHINE_EPSILON;
2871     PetscCall(PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes), ((PetscObject)snes)->options, ((PetscObject)snes)->prefix, "-snes_compare_coloring", NULL, NULL, &flag));
2872     PetscCall(PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes), ((PetscObject)snes)->options, ((PetscObject)snes)->prefix, "-snes_compare_coloring_display", NULL, NULL, &flag_display));
2873     PetscCall(PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes), ((PetscObject)snes)->options, ((PetscObject)snes)->prefix, "-snes_compare_coloring_draw", NULL, NULL, &flag_draw));
2874     PetscCall(PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes), ((PetscObject)snes)->options, ((PetscObject)snes)->prefix, "-snes_compare_coloring_draw_contour", NULL, NULL, &flag_contour));
2875     PetscCall(PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes), ((PetscObject)snes)->options, ((PetscObject)snes)->prefix, "-snes_compare_coloring_threshold", NULL, NULL, &flag_threshold));
2876     if (flag_threshold) {
2877       PetscCall(PetscOptionsGetReal(((PetscObject)snes)->options, ((PetscObject)snes)->prefix, "-snes_compare_coloring_threshold_rtol", &threshold_rtol, NULL));
2878       PetscCall(PetscOptionsGetReal(((PetscObject)snes)->options, ((PetscObject)snes)->prefix, "-snes_compare_coloring_threshold_atol", &threshold_atol, NULL));
2879     }
2880     if (flag || flag_display || flag_draw || flag_contour || flag_threshold) {
2881       Mat           Bfd;
2882       PetscViewer   vdraw, vstdout;
2883       MatColoring   coloring;
2884       ISColoring    iscoloring;
2885       MatFDColoring matfdcoloring;
2886       PetscErrorCode (*func)(SNES, Vec, Vec, void *);
2887       void     *funcctx;
2888       PetscReal norm1, norm2, normmax;
2889 
2890       PetscCall(MatDuplicate(B, MAT_DO_NOT_COPY_VALUES, &Bfd));
2891       PetscCall(MatColoringCreate(Bfd, &coloring));
2892       PetscCall(MatColoringSetType(coloring, MATCOLORINGSL));
2893       PetscCall(MatColoringSetFromOptions(coloring));
2894       PetscCall(MatColoringApply(coloring, &iscoloring));
2895       PetscCall(MatColoringDestroy(&coloring));
2896       PetscCall(MatFDColoringCreate(Bfd, iscoloring, &matfdcoloring));
2897       PetscCall(MatFDColoringSetFromOptions(matfdcoloring));
2898       PetscCall(MatFDColoringSetUp(Bfd, iscoloring, matfdcoloring));
2899       PetscCall(ISColoringDestroy(&iscoloring));
2900 
2901       /* This method of getting the function is currently unreliable since it doesn't work for DM local functions. */
2902       PetscCall(SNESGetFunction(snes, NULL, &func, &funcctx));
2903       PetscCall(MatFDColoringSetFunction(matfdcoloring, (PetscErrorCode(*)(void))func, funcctx));
2904       PetscCall(PetscObjectSetOptionsPrefix((PetscObject)matfdcoloring, ((PetscObject)snes)->prefix));
2905       PetscCall(PetscObjectAppendOptionsPrefix((PetscObject)matfdcoloring, "coloring_"));
2906       PetscCall(MatFDColoringSetFromOptions(matfdcoloring));
2907       PetscCall(MatFDColoringApply(Bfd, matfdcoloring, X, snes));
2908       PetscCall(MatFDColoringDestroy(&matfdcoloring));
2909 
2910       PetscCall(PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)snes), &vstdout));
2911       if (flag_draw || flag_contour) {
2912         PetscCall(PetscViewerDrawOpen(PetscObjectComm((PetscObject)snes), NULL, "Colored Jacobians", PETSC_DECIDE, PETSC_DECIDE, 300, 300, &vdraw));
2913         if (flag_contour) PetscCall(PetscViewerPushFormat(vdraw, PETSC_VIEWER_DRAW_CONTOUR));
2914       } else vdraw = NULL;
2915       PetscCall(PetscViewerASCIIPrintf(vstdout, "Explicit preconditioning Jacobian\n"));
2916       if (flag_display) PetscCall(MatView(B, vstdout));
2917       if (vdraw) PetscCall(MatView(B, vdraw));
2918       PetscCall(PetscViewerASCIIPrintf(vstdout, "Colored Finite difference Jacobian\n"));
2919       if (flag_display) PetscCall(MatView(Bfd, vstdout));
2920       if (vdraw) PetscCall(MatView(Bfd, vdraw));
2921       PetscCall(MatAYPX(Bfd, -1.0, B, SAME_NONZERO_PATTERN));
2922       PetscCall(MatNorm(Bfd, NORM_1, &norm1));
2923       PetscCall(MatNorm(Bfd, NORM_FROBENIUS, &norm2));
2924       PetscCall(MatNorm(Bfd, NORM_MAX, &normmax));
2925       PetscCall(PetscViewerASCIIPrintf(vstdout, "User-provided matrix minus finite difference Jacobian, norm1=%g normFrob=%g normmax=%g\n", (double)norm1, (double)norm2, (double)normmax));
2926       if (flag_display) PetscCall(MatView(Bfd, vstdout));
2927       if (vdraw) { /* Always use contour for the difference */
2928         PetscCall(PetscViewerPushFormat(vdraw, PETSC_VIEWER_DRAW_CONTOUR));
2929         PetscCall(MatView(Bfd, vdraw));
2930         PetscCall(PetscViewerPopFormat(vdraw));
2931       }
2932       if (flag_contour) PetscCall(PetscViewerPopFormat(vdraw));
2933 
2934       if (flag_threshold) {
2935         PetscInt bs, rstart, rend, i;
2936         PetscCall(MatGetBlockSize(B, &bs));
2937         PetscCall(MatGetOwnershipRange(B, &rstart, &rend));
2938         for (i = rstart; i < rend; i++) {
2939           const PetscScalar *ba, *ca;
2940           const PetscInt    *bj, *cj;
2941           PetscInt           bn, cn, j, maxentrycol = -1, maxdiffcol = -1, maxrdiffcol = -1;
2942           PetscReal          maxentry = 0, maxdiff = 0, maxrdiff = 0;
2943           PetscCall(MatGetRow(B, i, &bn, &bj, &ba));
2944           PetscCall(MatGetRow(Bfd, i, &cn, &cj, &ca));
2945           PetscCheck(bn == cn, ((PetscObject)A)->comm, PETSC_ERR_PLIB, "Unexpected different nonzero pattern in -snes_compare_coloring_threshold");
2946           for (j = 0; j < bn; j++) {
2947             PetscReal rdiff = PetscAbsScalar(ca[j]) / (threshold_atol + threshold_rtol * PetscAbsScalar(ba[j]));
2948             if (PetscAbsScalar(ba[j]) > PetscAbs(maxentry)) {
2949               maxentrycol = bj[j];
2950               maxentry    = PetscRealPart(ba[j]);
2951             }
2952             if (PetscAbsScalar(ca[j]) > PetscAbs(maxdiff)) {
2953               maxdiffcol = bj[j];
2954               maxdiff    = PetscRealPart(ca[j]);
2955             }
2956             if (rdiff > maxrdiff) {
2957               maxrdiffcol = bj[j];
2958               maxrdiff    = rdiff;
2959             }
2960           }
2961           if (maxrdiff > 1) {
2962             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));
2963             for (j = 0; j < bn; j++) {
2964               PetscReal rdiff;
2965               rdiff = PetscAbsScalar(ca[j]) / (threshold_atol + threshold_rtol * PetscAbsScalar(ba[j]));
2966               if (rdiff > 1) PetscCall(PetscViewerASCIIPrintf(vstdout, " (%" PetscInt_FMT ",%g:%g)", bj[j], (double)PetscRealPart(ba[j]), (double)PetscRealPart(ca[j])));
2967             }
2968             PetscCall(PetscViewerASCIIPrintf(vstdout, "\n"));
2969           }
2970           PetscCall(MatRestoreRow(B, i, &bn, &bj, &ba));
2971           PetscCall(MatRestoreRow(Bfd, i, &cn, &cj, &ca));
2972         }
2973       }
2974       PetscCall(PetscViewerDestroy(&vdraw));
2975       PetscCall(MatDestroy(&Bfd));
2976     }
2977   }
2978   PetscFunctionReturn(PETSC_SUCCESS);
2979 }
2980 
2981 /*MC
2982     SNESJacobianFunction - Functional form used by `SNES` to compute the nonlinear Jacobian of the function to be solved by `SNES`
2983 
2984      Synopsis:
2985      #include "petscsnes.h"
2986      PetscErrorCode SNESJacobianFunction(SNES snes,Vec x,Mat Amat,Mat Pmat,void *ctx);
2987 
2988      Collective
2989 
2990     Input Parameters:
2991 +  x - input vector, the Jacobian is to be computed at this value
2992 -  ctx - [optional] user-defined Jacobian context
2993 
2994     Output Parameters:
2995 +  Amat - the matrix that defines the (approximate) Jacobian
2996 -  Pmat - the matrix to be used in constructing the preconditioner, usually the same as `Amat`.
2997 
2998    Level: intermediate
2999 
3000 .seealso: [](ch_snes), `SNES`, `SNESSetFunction()`, `SNESGetFunction()`, `SNESSetJacobian()`, `SNESGetJacobian()`
3001 M*/
3002 
3003 /*@C
3004   SNESSetJacobian - Sets the function to compute Jacobian as well as the
3005   location to store the matrix.
3006 
3007   Logically Collective
3008 
3009   Input Parameters:
3010 + snes - the `SNES` context
3011 . Amat - the matrix that defines the (approximate) Jacobian
3012 . Pmat - the matrix to be used in constructing the preconditioner, usually the same as `Amat`.
3013 . J    - Jacobian evaluation routine (if `NULL` then `SNES` retains any previously set value), see `SNESJacobianFunction` for details
3014 - ctx  - [optional] user-defined context for private data for the
3015          Jacobian evaluation routine (may be `NULL`) (if `NULL` then `SNES` retains any previously set value)
3016 
3017   Level: beginner
3018 
3019   Notes:
3020   If the `Amat` matrix and `Pmat` matrix are different you must call `MatAssemblyBegin()`/`MatAssemblyEnd()` on
3021   each matrix.
3022 
3023   If you know the operator `Amat` has a null space you can use `MatSetNullSpace()` and `MatSetTransposeNullSpace()` to supply the null
3024   space to `Amat` and the `KSP` solvers will automatically use that null space as needed during the solution process.
3025 
3026   If using `SNESComputeJacobianDefaultColor()` to assemble a Jacobian, the `ctx` argument
3027   must be a `MatFDColoring`.
3028 
3029   Other defect-correction schemes can be used by computing a different matrix in place of the Jacobian.  One common
3030   example is to use the "Picard linearization" which only differentiates through the highest order parts of each term using `SNESSetPicard()`
3031 
3032 .seealso: [](ch_snes), `SNES`, `KSPSetOperators()`, `SNESSetFunction()`, `MatMFFDComputeJacobian()`, `SNESComputeJacobianDefaultColor()`, `MatStructure`,
3033           `SNESSetPicard()`, `SNESJacobianFunction`
3034 @*/
3035 PetscErrorCode SNESSetJacobian(SNES snes, Mat Amat, Mat Pmat, PetscErrorCode (*J)(SNES, Vec, Mat, Mat, void *), void *ctx)
3036 {
3037   DM dm;
3038 
3039   PetscFunctionBegin;
3040   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
3041   if (Amat) PetscValidHeaderSpecific(Amat, MAT_CLASSID, 2);
3042   if (Pmat) PetscValidHeaderSpecific(Pmat, MAT_CLASSID, 3);
3043   if (Amat) PetscCheckSameComm(snes, 1, Amat, 2);
3044   if (Pmat) PetscCheckSameComm(snes, 1, Pmat, 3);
3045   PetscCall(SNESGetDM(snes, &dm));
3046   PetscCall(DMSNESSetJacobian(dm, J, ctx));
3047   if (Amat) {
3048     PetscCall(PetscObjectReference((PetscObject)Amat));
3049     PetscCall(MatDestroy(&snes->jacobian));
3050 
3051     snes->jacobian = Amat;
3052   }
3053   if (Pmat) {
3054     PetscCall(PetscObjectReference((PetscObject)Pmat));
3055     PetscCall(MatDestroy(&snes->jacobian_pre));
3056 
3057     snes->jacobian_pre = Pmat;
3058   }
3059   PetscFunctionReturn(PETSC_SUCCESS);
3060 }
3061 
3062 /*@C
3063   SNESGetJacobian - Returns the Jacobian matrix and optionally the user
3064   provided context for evaluating the Jacobian.
3065 
3066   Not Collective, but `Mat` object will be parallel if `SNES` is
3067 
3068   Input Parameter:
3069 . snes - the nonlinear solver context
3070 
3071   Output Parameters:
3072 + Amat - location to stash (approximate) Jacobian matrix (or `NULL`)
3073 . Pmat - location to stash matrix used to compute the preconditioner (or `NULL`)
3074 . J    - location to put Jacobian function (or `NULL`), for calling sequence see `SNESJacobianFunction`
3075 - ctx  - location to stash Jacobian ctx (or `NULL`)
3076 
3077   Level: advanced
3078 
3079 .seealso: [](ch_snes), `SNES`, `Mat`, `SNESSetJacobian()`, `SNESComputeJacobian()`, `SNESJacobianFunction`, `SNESGetFunction()`
3080 @*/
3081 PetscErrorCode SNESGetJacobian(SNES snes, Mat *Amat, Mat *Pmat, PetscErrorCode (**J)(SNES, Vec, Mat, Mat, void *), void **ctx)
3082 {
3083   DM dm;
3084 
3085   PetscFunctionBegin;
3086   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
3087   if (Amat) *Amat = snes->jacobian;
3088   if (Pmat) *Pmat = snes->jacobian_pre;
3089   PetscCall(SNESGetDM(snes, &dm));
3090   PetscCall(DMSNESGetJacobian(dm, J, ctx));
3091   PetscFunctionReturn(PETSC_SUCCESS);
3092 }
3093 
3094 static PetscErrorCode SNESSetDefaultComputeJacobian(SNES snes)
3095 {
3096   DM     dm;
3097   DMSNES sdm;
3098 
3099   PetscFunctionBegin;
3100   PetscCall(SNESGetDM(snes, &dm));
3101   PetscCall(DMGetDMSNES(dm, &sdm));
3102   if (!sdm->ops->computejacobian && snes->jacobian_pre) {
3103     DM        dm;
3104     PetscBool isdense, ismf;
3105 
3106     PetscCall(SNESGetDM(snes, &dm));
3107     PetscCall(PetscObjectTypeCompareAny((PetscObject)snes->jacobian_pre, &isdense, MATSEQDENSE, MATMPIDENSE, MATDENSE, NULL));
3108     PetscCall(PetscObjectTypeCompareAny((PetscObject)snes->jacobian_pre, &ismf, MATMFFD, MATSHELL, NULL));
3109     if (isdense) {
3110       PetscCall(DMSNESSetJacobian(dm, SNESComputeJacobianDefault, NULL));
3111     } else if (!ismf) {
3112       PetscCall(DMSNESSetJacobian(dm, SNESComputeJacobianDefaultColor, NULL));
3113     }
3114   }
3115   PetscFunctionReturn(PETSC_SUCCESS);
3116 }
3117 
3118 /*@
3119   SNESSetUp - Sets up the internal data structures for the later use
3120   of a nonlinear solver.
3121 
3122   Collective
3123 
3124   Input Parameter:
3125 . snes - the `SNES` context
3126 
3127   Level: advanced
3128 
3129   Note:
3130   For basic use of the `SNES` solvers the user need not explicitly call
3131   `SNESSetUp()`, since these actions will automatically occur during
3132   the call to `SNESSolve()`.  However, if one wishes to control this
3133   phase separately, `SNESSetUp()` should be called after `SNESCreate()`
3134   and optional routines of the form SNESSetXXX(), but before `SNESSolve()`.
3135 
3136 .seealso: [](ch_snes), `SNES`, `SNESCreate()`, `SNESSolve()`, `SNESDestroy()`
3137 @*/
3138 PetscErrorCode SNESSetUp(SNES snes)
3139 {
3140   DM             dm;
3141   DMSNES         sdm;
3142   SNESLineSearch linesearch, pclinesearch;
3143   void          *lsprectx, *lspostctx;
3144   PetscBool      mf_operator, mf;
3145   Vec            f, fpc;
3146   void          *funcctx;
3147   void          *jacctx, *appctx;
3148   Mat            j, jpre;
3149   PetscErrorCode (*precheck)(SNESLineSearch, Vec, Vec, PetscBool *, void *);
3150   PetscErrorCode (*postcheck)(SNESLineSearch, Vec, Vec, Vec, PetscBool *, PetscBool *, void *);
3151   PetscErrorCode (*func)(SNES, Vec, Vec, void *);
3152   PetscErrorCode (*jac)(SNES, Vec, Mat, Mat, void *);
3153 
3154   PetscFunctionBegin;
3155   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
3156   if (snes->setupcalled) PetscFunctionReturn(PETSC_SUCCESS);
3157   PetscCall(PetscLogEventBegin(SNES_SetUp, snes, 0, 0, 0));
3158 
3159   if (!((PetscObject)snes)->type_name) PetscCall(SNESSetType(snes, SNESNEWTONLS));
3160 
3161   PetscCall(SNESGetFunction(snes, &snes->vec_func, NULL, NULL));
3162 
3163   PetscCall(SNESGetDM(snes, &dm));
3164   PetscCall(DMGetDMSNES(dm, &sdm));
3165   PetscCall(SNESSetDefaultComputeJacobian(snes));
3166 
3167   if (!snes->vec_func) PetscCall(DMCreateGlobalVector(dm, &snes->vec_func));
3168 
3169   if (!snes->ksp) PetscCall(SNESGetKSP(snes, &snes->ksp));
3170 
3171   if (snes->linesearch) {
3172     PetscCall(SNESGetLineSearch(snes, &snes->linesearch));
3173     PetscCall(SNESLineSearchSetFunction(snes->linesearch, SNESComputeFunction));
3174   }
3175 
3176   PetscCall(SNESGetUseMatrixFree(snes, &mf_operator, &mf));
3177   if (snes->npc && snes->npcside == PC_LEFT) {
3178     snes->mf          = PETSC_TRUE;
3179     snes->mf_operator = PETSC_FALSE;
3180   }
3181 
3182   if (snes->npc) {
3183     /* copy the DM over */
3184     PetscCall(SNESGetDM(snes, &dm));
3185     PetscCall(SNESSetDM(snes->npc, dm));
3186 
3187     PetscCall(SNESGetFunction(snes, &f, &func, &funcctx));
3188     PetscCall(VecDuplicate(f, &fpc));
3189     PetscCall(SNESSetFunction(snes->npc, fpc, func, funcctx));
3190     PetscCall(SNESGetJacobian(snes, &j, &jpre, &jac, &jacctx));
3191     PetscCall(SNESSetJacobian(snes->npc, j, jpre, jac, jacctx));
3192     PetscCall(SNESGetApplicationContext(snes, &appctx));
3193     PetscCall(SNESSetApplicationContext(snes->npc, appctx));
3194     PetscCall(SNESSetUseMatrixFree(snes->npc, mf_operator, mf));
3195     PetscCall(VecDestroy(&fpc));
3196 
3197     /* copy the function pointers over */
3198     PetscCall(PetscObjectCopyFortranFunctionPointers((PetscObject)snes, (PetscObject)snes->npc));
3199 
3200     /* default to 1 iteration */
3201     PetscCall(SNESSetTolerances(snes->npc, 0.0, 0.0, 0.0, 1, snes->npc->max_funcs));
3202     if (snes->npcside == PC_RIGHT) {
3203       PetscCall(SNESSetNormSchedule(snes->npc, SNES_NORM_FINAL_ONLY));
3204     } else {
3205       PetscCall(SNESSetNormSchedule(snes->npc, SNES_NORM_NONE));
3206     }
3207     PetscCall(SNESSetFromOptions(snes->npc));
3208 
3209     /* copy the line search context over */
3210     if (snes->linesearch && snes->npc->linesearch) {
3211       PetscCall(SNESGetLineSearch(snes, &linesearch));
3212       PetscCall(SNESGetLineSearch(snes->npc, &pclinesearch));
3213       PetscCall(SNESLineSearchGetPreCheck(linesearch, &precheck, &lsprectx));
3214       PetscCall(SNESLineSearchGetPostCheck(linesearch, &postcheck, &lspostctx));
3215       PetscCall(SNESLineSearchSetPreCheck(pclinesearch, precheck, lsprectx));
3216       PetscCall(SNESLineSearchSetPostCheck(pclinesearch, postcheck, lspostctx));
3217       PetscCall(PetscObjectCopyFortranFunctionPointers((PetscObject)linesearch, (PetscObject)pclinesearch));
3218     }
3219   }
3220   if (snes->mf) PetscCall(SNESSetUpMatrixFree_Private(snes, snes->mf_operator, snes->mf_version));
3221   if (snes->ops->usercompute && !snes->user) PetscCall((*snes->ops->usercompute)(snes, (void **)&snes->user));
3222 
3223   snes->jac_iter = 0;
3224   snes->pre_iter = 0;
3225 
3226   PetscTryTypeMethod(snes, setup);
3227 
3228   PetscCall(SNESSetDefaultComputeJacobian(snes));
3229 
3230   if (snes->npc && snes->npcside == PC_LEFT) {
3231     if (snes->functype == SNES_FUNCTION_PRECONDITIONED) {
3232       if (snes->linesearch) {
3233         PetscCall(SNESGetLineSearch(snes, &linesearch));
3234         PetscCall(SNESLineSearchSetFunction(linesearch, SNESComputeFunctionDefaultNPC));
3235       }
3236     }
3237   }
3238   PetscCall(PetscLogEventEnd(SNES_SetUp, snes, 0, 0, 0));
3239   snes->setupcalled = PETSC_TRUE;
3240   PetscFunctionReturn(PETSC_SUCCESS);
3241 }
3242 
3243 /*@
3244   SNESReset - Resets a `SNES` context to the snessetupcalled = 0 state and removes any allocated `Vec`s and `Mat`s
3245 
3246   Collective
3247 
3248   Input Parameter:
3249 . snes - iterative context obtained from `SNESCreate()`
3250 
3251   Level: intermediate
3252 
3253   Notes:
3254   Call this if you wish to reuse a `SNES` but with different size vectors
3255 
3256   Also calls the application context destroy routine set with `SNESSetComputeApplicationContext()`
3257 
3258 .seealso: [](ch_snes), `SNES`, `SNESDestroy()`, `SNESCreate()`, `SNESSetUp()`, `SNESSolve()`
3259 @*/
3260 PetscErrorCode SNESReset(SNES snes)
3261 {
3262   PetscFunctionBegin;
3263   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
3264   if (snes->ops->userdestroy && snes->user) {
3265     PetscCall((*snes->ops->userdestroy)((void **)&snes->user));
3266     snes->user = NULL;
3267   }
3268   if (snes->npc) PetscCall(SNESReset(snes->npc));
3269 
3270   PetscTryTypeMethod(snes, reset);
3271   if (snes->ksp) PetscCall(KSPReset(snes->ksp));
3272 
3273   if (snes->linesearch) PetscCall(SNESLineSearchReset(snes->linesearch));
3274 
3275   PetscCall(VecDestroy(&snes->vec_rhs));
3276   PetscCall(VecDestroy(&snes->vec_sol));
3277   PetscCall(VecDestroy(&snes->vec_sol_update));
3278   PetscCall(VecDestroy(&snes->vec_func));
3279   PetscCall(MatDestroy(&snes->jacobian));
3280   PetscCall(MatDestroy(&snes->jacobian_pre));
3281   PetscCall(MatDestroy(&snes->picard));
3282   PetscCall(VecDestroyVecs(snes->nwork, &snes->work));
3283   PetscCall(VecDestroyVecs(snes->nvwork, &snes->vwork));
3284 
3285   snes->alwayscomputesfinalresidual = PETSC_FALSE;
3286 
3287   snes->nwork = snes->nvwork = 0;
3288   snes->setupcalled          = PETSC_FALSE;
3289   PetscFunctionReturn(PETSC_SUCCESS);
3290 }
3291 
3292 /*@
3293   SNESConvergedReasonViewCancel - Clears all the reason view functions for a `SNES` object provided with `SNESConvergedReasonViewSet()`
3294 
3295   Collective
3296 
3297   Input Parameter:
3298 . snes - iterative context obtained from `SNESCreate()`
3299 
3300   Level: intermediate
3301 
3302 .seealso: [](ch_snes), `SNES`, `SNESCreate()`, `SNESDestroy()`, `SNESReset()`, `SNESConvergedReasonViewSet()`
3303 @*/
3304 PetscErrorCode SNESConvergedReasonViewCancel(SNES snes)
3305 {
3306   PetscInt i;
3307 
3308   PetscFunctionBegin;
3309   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
3310   for (i = 0; i < snes->numberreasonviews; i++) {
3311     if (snes->reasonviewdestroy[i]) PetscCall((*snes->reasonviewdestroy[i])(&snes->reasonviewcontext[i]));
3312   }
3313   snes->numberreasonviews = 0;
3314   PetscFunctionReturn(PETSC_SUCCESS);
3315 }
3316 
3317 /*@C
3318   SNESDestroy - Destroys the nonlinear solver context that was created
3319   with `SNESCreate()`.
3320 
3321   Collective
3322 
3323   Input Parameter:
3324 . snes - the `SNES` context
3325 
3326   Level: beginner
3327 
3328 .seealso: [](ch_snes), `SNES`, `SNESCreate()`, `SNESSolve()`
3329 @*/
3330 PetscErrorCode SNESDestroy(SNES *snes)
3331 {
3332   PetscFunctionBegin;
3333   if (!*snes) PetscFunctionReturn(PETSC_SUCCESS);
3334   PetscValidHeaderSpecific((*snes), SNES_CLASSID, 1);
3335   if (--((PetscObject)(*snes))->refct > 0) {
3336     *snes = NULL;
3337     PetscFunctionReturn(PETSC_SUCCESS);
3338   }
3339 
3340   PetscCall(SNESReset((*snes)));
3341   PetscCall(SNESDestroy(&(*snes)->npc));
3342 
3343   /* if memory was published with SAWs then destroy it */
3344   PetscCall(PetscObjectSAWsViewOff((PetscObject)*snes));
3345   PetscTryTypeMethod((*snes), destroy);
3346 
3347   if ((*snes)->dm) PetscCall(DMCoarsenHookRemove((*snes)->dm, DMCoarsenHook_SNESVecSol, DMRestrictHook_SNESVecSol, *snes));
3348   PetscCall(DMDestroy(&(*snes)->dm));
3349   PetscCall(KSPDestroy(&(*snes)->ksp));
3350   PetscCall(SNESLineSearchDestroy(&(*snes)->linesearch));
3351 
3352   PetscCall(PetscFree((*snes)->kspconvctx));
3353   if ((*snes)->ops->convergeddestroy) PetscCall((*(*snes)->ops->convergeddestroy)((*snes)->cnvP));
3354   if ((*snes)->conv_hist_alloc) PetscCall(PetscFree2((*snes)->conv_hist, (*snes)->conv_hist_its));
3355   PetscCall(SNESMonitorCancel((*snes)));
3356   PetscCall(SNESConvergedReasonViewCancel((*snes)));
3357   PetscCall(PetscHeaderDestroy(snes));
3358   PetscFunctionReturn(PETSC_SUCCESS);
3359 }
3360 
3361 /* ----------- Routines to set solver parameters ---------- */
3362 
3363 /*@
3364   SNESSetLagPreconditioner - Determines when the preconditioner is rebuilt in the nonlinear solve.
3365 
3366   Logically Collective
3367 
3368   Input Parameters:
3369 + snes - the `SNES` context
3370 - lag  - 1 means rebuild every time the Jacobian is computed within a single nonlinear solve, 2 means every second time
3371          the Jacobian is built etc. -2 indicates rebuild preconditioner at next chance but then never rebuild after that
3372 
3373   Options Database Keys:
3374 + -snes_lag_jacobian_persists <true,false>       - sets the persistence through multiple `SNESSolve()`
3375 . -snes_lag_jacobian <-2,1,2,...>                - sets the lag
3376 . -snes_lag_preconditioner_persists <true,false> - sets the persistence through multiple `SNESSolve()`
3377 - -snes_lag_preconditioner <-2,1,2,...>          - sets the lag
3378 
3379   Level: intermediate
3380 
3381   Notes:
3382   The default is 1
3383 
3384   The preconditioner is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1 or `SNESSetLagPreconditionerPersists()` was called
3385 
3386   `SNESSetLagPreconditionerPersists()` allows using the same uniform lagging (for example every second linear solve) across multiple nonlinear solves.
3387 
3388 .seealso: [](ch_snes), `SNESSetTrustRegionTolerance()`, `SNESGetLagPreconditioner()`, `SNESSetLagJacobian()`, `SNESGetLagJacobian()`, `SNESSetLagPreconditionerPersists()`,
3389           `SNESSetLagJacobianPersists()`, `SNES`, `SNESSolve()`
3390 @*/
3391 PetscErrorCode SNESSetLagPreconditioner(SNES snes, PetscInt lag)
3392 {
3393   PetscFunctionBegin;
3394   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
3395   PetscCheck(lag >= -2, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Lag must be -2, -1, 1 or greater");
3396   PetscCheck(lag, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Lag cannot be 0");
3397   PetscValidLogicalCollectiveInt(snes, lag, 2);
3398   snes->lagpreconditioner = lag;
3399   PetscFunctionReturn(PETSC_SUCCESS);
3400 }
3401 
3402 /*@
3403   SNESSetGridSequence - sets the number of steps of grid sequencing that `SNES` will do
3404 
3405   Logically Collective
3406 
3407   Input Parameters:
3408 + snes  - the `SNES` context
3409 - steps - the number of refinements to do, defaults to 0
3410 
3411   Options Database Key:
3412 . -snes_grid_sequence <steps> - Use grid sequencing to generate initial guess
3413 
3414   Level: intermediate
3415 
3416   Note:
3417   Use `SNESGetSolution()` to extract the fine grid solution after grid sequencing.
3418 
3419 .seealso: [](ch_snes), `SNES`, `SNESSetTrustRegionTolerance()`, `SNESGetLagPreconditioner()`, `SNESSetLagJacobian()`, `SNESGetLagJacobian()`, `SNESGetGridSequence()`,
3420           `SNESetDM()`
3421 @*/
3422 PetscErrorCode SNESSetGridSequence(SNES snes, PetscInt steps)
3423 {
3424   PetscFunctionBegin;
3425   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
3426   PetscValidLogicalCollectiveInt(snes, steps, 2);
3427   snes->gridsequence = steps;
3428   PetscFunctionReturn(PETSC_SUCCESS);
3429 }
3430 
3431 /*@
3432   SNESGetGridSequence - gets the number of steps of grid sequencing that `SNES` will do
3433 
3434   Logically Collective
3435 
3436   Input Parameter:
3437 . snes - the `SNES` context
3438 
3439   Output Parameter:
3440 . steps - the number of refinements to do, defaults to 0
3441 
3442   Level: intermediate
3443 
3444 .seealso: [](ch_snes), `SNESSetTrustRegionTolerance()`, `SNESGetLagPreconditioner()`, `SNESSetLagJacobian()`, `SNESGetLagJacobian()`, `SNESSetGridSequence()`
3445 @*/
3446 PetscErrorCode SNESGetGridSequence(SNES snes, PetscInt *steps)
3447 {
3448   PetscFunctionBegin;
3449   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
3450   *steps = snes->gridsequence;
3451   PetscFunctionReturn(PETSC_SUCCESS);
3452 }
3453 
3454 /*@
3455   SNESGetLagPreconditioner - Return how often the preconditioner is rebuilt
3456 
3457   Not Collective
3458 
3459   Input Parameter:
3460 . snes - the `SNES` context
3461 
3462   Output Parameter:
3463 . lag - -1 indicates NEVER rebuild, 1 means rebuild every time the Jacobian is computed within a single nonlinear solve, 2 means every second time
3464          the Jacobian is built etc. -2 indicates rebuild preconditioner at next chance but then never rebuild after that
3465 
3466   Level: intermediate
3467 
3468   Notes:
3469   The default is 1
3470 
3471   The preconditioner is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1
3472 
3473 .seealso: [](ch_snes), `SNES`, `SNESSetTrustRegionTolerance()`, `SNESSetLagPreconditioner()`, `SNESSetLagJacobianPersists()`, `SNESSetLagPreconditionerPersists()`
3474 @*/
3475 PetscErrorCode SNESGetLagPreconditioner(SNES snes, PetscInt *lag)
3476 {
3477   PetscFunctionBegin;
3478   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
3479   *lag = snes->lagpreconditioner;
3480   PetscFunctionReturn(PETSC_SUCCESS);
3481 }
3482 
3483 /*@
3484   SNESSetLagJacobian - Set when the Jacobian is rebuilt in the nonlinear solve. See `SNESSetLagPreconditioner()` for determining how
3485   often the preconditioner is rebuilt.
3486 
3487   Logically Collective
3488 
3489   Input Parameters:
3490 + snes - the `SNES` context
3491 - lag  - -1 indicates NEVER rebuild, 1 means rebuild every time the Jacobian is computed within a single nonlinear solve, 2 means every second time
3492          the Jacobian is built etc. -2 means rebuild at next chance but then never again
3493 
3494   Options Database Keys:
3495 + -snes_lag_jacobian_persists <true,false>       - sets the persistence through multiple SNES solves
3496 . -snes_lag_jacobian <-2,1,2,...>                - sets the lag
3497 . -snes_lag_preconditioner_persists <true,false> - sets the persistence through multiple SNES solves
3498 - -snes_lag_preconditioner <-2,1,2,...>          - sets the lag.
3499 
3500   Level: intermediate
3501 
3502   Notes:
3503   The default is 1
3504 
3505   The Jacobian is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1
3506 
3507   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
3508   at the next Newton step but never again (unless it is reset to another value)
3509 
3510 .seealso: [](ch_snes), `SNES`, `SNESSetTrustRegionTolerance()`, `SNESGetLagPreconditioner()`, `SNESSetLagPreconditioner()`, `SNESGetLagJacobianPersists()`, `SNESSetLagPreconditionerPersists()`
3511 @*/
3512 PetscErrorCode SNESSetLagJacobian(SNES snes, PetscInt lag)
3513 {
3514   PetscFunctionBegin;
3515   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
3516   PetscCheck(lag >= -2, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Lag must be -2, -1, 1 or greater");
3517   PetscCheck(lag, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Lag cannot be 0");
3518   PetscValidLogicalCollectiveInt(snes, lag, 2);
3519   snes->lagjacobian = lag;
3520   PetscFunctionReturn(PETSC_SUCCESS);
3521 }
3522 
3523 /*@
3524   SNESGetLagJacobian - Get how often the Jacobian is rebuilt. See `SNESGetLagPreconditioner()` to determine when the preconditioner is rebuilt
3525 
3526   Not Collective
3527 
3528   Input Parameter:
3529 . snes - the `SNES` context
3530 
3531   Output Parameter:
3532 . lag - -1 indicates NEVER rebuild, 1 means rebuild every time the Jacobian is computed within a single nonlinear solve, 2 means every second time
3533          the Jacobian is built etc.
3534 
3535   Level: intermediate
3536 
3537   Notes:
3538   The default is 1
3539 
3540   The jacobian is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1 or `SNESSetLagJacobianPersists()` was called.
3541 
3542 .seealso: [](ch_snes), `SNES`, `SNESSetTrustRegionTolerance()`, `SNESSetLagJacobian()`, `SNESSetLagPreconditioner()`, `SNESGetLagPreconditioner()`, `SNESSetLagJacobianPersists()`, `SNESSetLagPreconditionerPersists()`
3543 
3544 @*/
3545 PetscErrorCode SNESGetLagJacobian(SNES snes, PetscInt *lag)
3546 {
3547   PetscFunctionBegin;
3548   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
3549   *lag = snes->lagjacobian;
3550   PetscFunctionReturn(PETSC_SUCCESS);
3551 }
3552 
3553 /*@
3554   SNESSetLagJacobianPersists - Set whether or not the Jacobian lagging persists through multiple nonlinear solves
3555 
3556   Logically collective
3557 
3558   Input Parameters:
3559 + snes - the `SNES` context
3560 - flg  - jacobian lagging persists if true
3561 
3562   Options Database Keys:
3563 + -snes_lag_jacobian_persists <true,false>       - sets the persistence through multiple SNES solves
3564 . -snes_lag_jacobian <-2,1,2,...>                - sets the lag
3565 . -snes_lag_preconditioner_persists <true,false> - sets the persistence through multiple SNES solves
3566 - -snes_lag_preconditioner <-2,1,2,...>          - sets the lag
3567 
3568   Level: advanced
3569 
3570   Notes:
3571   Normally when `SNESSetLagJacobian()` is used, the Jacobian is always rebuilt at the beginning of each new nonlinear solve, this removes that behavior
3572 
3573   This is useful both for nonlinear preconditioning, where it's appropriate to have the Jacobian be stale by
3574   several solves, and for implicit time-stepping, where Jacobian lagging in the inner nonlinear solve over several
3575   timesteps may present huge efficiency gains.
3576 
3577 .seealso: [](ch_snes), `SNES`, `SNESSetLagPreconditionerPersists()`, `SNESSetLagJacobian()`, `SNESGetLagJacobian()`, `SNESGetNPC()`
3578 @*/
3579 PetscErrorCode SNESSetLagJacobianPersists(SNES snes, PetscBool flg)
3580 {
3581   PetscFunctionBegin;
3582   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
3583   PetscValidLogicalCollectiveBool(snes, flg, 2);
3584   snes->lagjac_persist = flg;
3585   PetscFunctionReturn(PETSC_SUCCESS);
3586 }
3587 
3588 /*@
3589   SNESSetLagPreconditionerPersists - Set whether or not the preconditioner lagging persists through multiple nonlinear solves
3590 
3591   Logically Collective
3592 
3593   Input Parameters:
3594 + snes - the `SNES` context
3595 - flg  - preconditioner lagging persists if true
3596 
3597   Options Database Keys:
3598 + -snes_lag_jacobian_persists <true,false>       - sets the persistence through multiple SNES solves
3599 . -snes_lag_jacobian <-2,1,2,...>                - sets the lag
3600 . -snes_lag_preconditioner_persists <true,false> - sets the persistence through multiple SNES solves
3601 - -snes_lag_preconditioner <-2,1,2,...>          - sets the lag
3602 
3603   Level: developer
3604 
3605   Notes:
3606   Normally when `SNESSetLagPreconditioner()` is used, the preconditioner is always rebuilt at the beginning of each new nonlinear solve, this removes that behavior
3607 
3608   This is useful both for nonlinear preconditioning, where it's appropriate to have the preconditioner be stale
3609   by several solves, and for implicit time-stepping, where preconditioner lagging in the inner nonlinear solve over
3610   several timesteps may present huge efficiency gains.
3611 
3612 .seealso: [](ch_snes), `SNES`, `SNESSetLagJacobianPersists()`, `SNESSetLagJacobian()`, `SNESGetLagJacobian()`, `SNESGetNPC()`, `SNESSetLagPreconditioner()`
3613 @*/
3614 PetscErrorCode SNESSetLagPreconditionerPersists(SNES snes, PetscBool flg)
3615 {
3616   PetscFunctionBegin;
3617   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
3618   PetscValidLogicalCollectiveBool(snes, flg, 2);
3619   snes->lagpre_persist = flg;
3620   PetscFunctionReturn(PETSC_SUCCESS);
3621 }
3622 
3623 /*@
3624   SNESSetForceIteration - force `SNESSolve()` to take at least one iteration regardless of the initial residual norm
3625 
3626   Logically Collective
3627 
3628   Input Parameters:
3629 + snes  - the `SNES` context
3630 - force - `PETSC_TRUE` require at least one iteration
3631 
3632   Options Database Key:
3633 . -snes_force_iteration <force> - Sets forcing an iteration
3634 
3635   Level: intermediate
3636 
3637   Note:
3638   This is used sometimes with `TS` to prevent `TS` from detecting a false steady state solution
3639 
3640 .seealso: [](ch_snes), `SNES`, `TS`, `SNESSetTrustRegionTolerance()`, `SNESSetDivergenceTolerance()`
3641 @*/
3642 PetscErrorCode SNESSetForceIteration(SNES snes, PetscBool force)
3643 {
3644   PetscFunctionBegin;
3645   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
3646   snes->forceiteration = force;
3647   PetscFunctionReturn(PETSC_SUCCESS);
3648 }
3649 
3650 /*@
3651   SNESGetForceIteration - Check whether or not `SNESSolve()` take at least one iteration regardless of the initial residual norm
3652 
3653   Logically Collective
3654 
3655   Input Parameter:
3656 . snes - the `SNES` context
3657 
3658   Output Parameter:
3659 . force - `PETSC_TRUE` requires at least one iteration.
3660 
3661   Level: intermediate
3662 
3663 .seealso: [](ch_snes), `SNES`, `SNESSetForceIteration()`, `SNESSetTrustRegionTolerance()`, `SNESSetDivergenceTolerance()`
3664 @*/
3665 PetscErrorCode SNESGetForceIteration(SNES snes, PetscBool *force)
3666 {
3667   PetscFunctionBegin;
3668   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
3669   *force = snes->forceiteration;
3670   PetscFunctionReturn(PETSC_SUCCESS);
3671 }
3672 
3673 /*@
3674   SNESSetTolerances - Sets `SNES` various parameters used in convergence tests.
3675 
3676   Logically Collective
3677 
3678   Input Parameters:
3679 + snes   - the `SNES` context
3680 . abstol - absolute convergence tolerance
3681 . rtol   - relative convergence tolerance
3682 . stol   - convergence tolerance in terms of the norm of the change in the solution between steps,  || delta x || < stol*|| x ||
3683 . maxit  - maximum number of iterations, default 50.
3684 - maxf   - maximum number of function evaluations (-1 indicates no limit), default 1000
3685 
3686   Options Database Keys:
3687 + -snes_atol <abstol>    - Sets abstol
3688 . -snes_rtol <rtol>      - Sets rtol
3689 . -snes_stol <stol>      - Sets stol
3690 . -snes_max_it <maxit>   - Sets maxit
3691 - -snes_max_funcs <maxf> - Sets maxf
3692 
3693   Level: intermediate
3694 
3695 .seealso: [](ch_snes), `SNESSolve()`, `SNES`, `SNESSetTrustRegionTolerance()`, `SNESSetDivergenceTolerance()`, `SNESSetForceIteration()`
3696 @*/
3697 PetscErrorCode SNESSetTolerances(SNES snes, PetscReal abstol, PetscReal rtol, PetscReal stol, PetscInt maxit, PetscInt maxf)
3698 {
3699   PetscFunctionBegin;
3700   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
3701   PetscValidLogicalCollectiveReal(snes, abstol, 2);
3702   PetscValidLogicalCollectiveReal(snes, rtol, 3);
3703   PetscValidLogicalCollectiveReal(snes, stol, 4);
3704   PetscValidLogicalCollectiveInt(snes, maxit, 5);
3705   PetscValidLogicalCollectiveInt(snes, maxf, 6);
3706 
3707   if (abstol != (PetscReal)PETSC_DEFAULT) {
3708     PetscCheck(abstol >= 0.0, PetscObjectComm((PetscObject)snes), PETSC_ERR_ARG_OUTOFRANGE, "Absolute tolerance %g must be non-negative", (double)abstol);
3709     snes->abstol = abstol;
3710   }
3711   if (rtol != (PetscReal)PETSC_DEFAULT) {
3712     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);
3713     snes->rtol = rtol;
3714   }
3715   if (stol != (PetscReal)PETSC_DEFAULT) {
3716     PetscCheck(stol >= 0.0, PetscObjectComm((PetscObject)snes), PETSC_ERR_ARG_OUTOFRANGE, "Step tolerance %g must be non-negative", (double)stol);
3717     snes->stol = stol;
3718   }
3719   if (maxit != PETSC_DEFAULT) {
3720     PetscCheck(maxit >= 0, PetscObjectComm((PetscObject)snes), PETSC_ERR_ARG_OUTOFRANGE, "Maximum number of iterations %" PetscInt_FMT " must be non-negative", maxit);
3721     snes->max_its = maxit;
3722   }
3723   if (maxf != PETSC_DEFAULT) {
3724     PetscCheck(maxf >= -1, PetscObjectComm((PetscObject)snes), PETSC_ERR_ARG_OUTOFRANGE, "Maximum number of function evaluations %" PetscInt_FMT " must be -1 or nonnegative", maxf);
3725     snes->max_funcs = maxf;
3726   }
3727   snes->tolerancesset = PETSC_TRUE;
3728   PetscFunctionReturn(PETSC_SUCCESS);
3729 }
3730 
3731 /*@
3732   SNESSetDivergenceTolerance - Sets the divergence tolerance used for the `SNES` divergence test.
3733 
3734   Logically Collective
3735 
3736   Input Parameters:
3737 + snes   - the `SNES` context
3738 - divtol - the divergence tolerance. Use -1 to deactivate the test, default is 1e4
3739 
3740   Options Database Key:
3741 . -snes_divergence_tolerance <divtol> - Sets `divtol`
3742 
3743   Level: intermediate
3744 
3745 .seealso: [](ch_snes), `SNES`, `SNESSolve()`, `SNESSetTolerances()`, `SNESGetDivergenceTolerance`
3746 @*/
3747 PetscErrorCode SNESSetDivergenceTolerance(SNES snes, PetscReal divtol)
3748 {
3749   PetscFunctionBegin;
3750   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
3751   PetscValidLogicalCollectiveReal(snes, divtol, 2);
3752 
3753   if (divtol != (PetscReal)PETSC_DEFAULT) {
3754     snes->divtol = divtol;
3755   } else {
3756     snes->divtol = 1.0e4;
3757   }
3758   PetscFunctionReturn(PETSC_SUCCESS);
3759 }
3760 
3761 /*@
3762   SNESGetTolerances - Gets various parameters used in convergence tests.
3763 
3764   Not Collective
3765 
3766   Input Parameters:
3767 + snes  - the `SNES` context
3768 . atol  - absolute convergence tolerance
3769 . rtol  - relative convergence tolerance
3770 . stol  - convergence tolerance in terms of the norm
3771            of the change in the solution between steps
3772 . maxit - maximum number of iterations
3773 - maxf  - maximum number of function evaluations
3774 
3775   Level: intermediate
3776 
3777   Note:
3778   The user can specify `NULL` for any parameter that is not needed.
3779 
3780 .seealso: [](ch_snes), `SNES`, `SNESSetTolerances()`
3781 @*/
3782 PetscErrorCode SNESGetTolerances(SNES snes, PetscReal *atol, PetscReal *rtol, PetscReal *stol, PetscInt *maxit, PetscInt *maxf)
3783 {
3784   PetscFunctionBegin;
3785   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
3786   if (atol) *atol = snes->abstol;
3787   if (rtol) *rtol = snes->rtol;
3788   if (stol) *stol = snes->stol;
3789   if (maxit) *maxit = snes->max_its;
3790   if (maxf) *maxf = snes->max_funcs;
3791   PetscFunctionReturn(PETSC_SUCCESS);
3792 }
3793 
3794 /*@
3795   SNESGetDivergenceTolerance - Gets divergence tolerance used in divergence test.
3796 
3797   Not Collective
3798 
3799   Input Parameters:
3800 + snes   - the `SNES` context
3801 - divtol - divergence tolerance
3802 
3803   Level: intermediate
3804 
3805 .seealso: [](ch_snes), `SNES`, `SNESSetDivergenceTolerance()`
3806 @*/
3807 PetscErrorCode SNESGetDivergenceTolerance(SNES snes, PetscReal *divtol)
3808 {
3809   PetscFunctionBegin;
3810   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
3811   if (divtol) *divtol = snes->divtol;
3812   PetscFunctionReturn(PETSC_SUCCESS);
3813 }
3814 
3815 /*@
3816   SNESSetTrustRegionTolerance - Sets the trust region parameter tolerance.
3817 
3818   Logically Collective
3819 
3820   Input Parameters:
3821 + snes - the `SNES` context
3822 - tol  - tolerance
3823 
3824   Options Database Key:
3825 . -snes_tr_tol <tol> - Sets tol
3826 
3827   Level: intermediate
3828 
3829 .seealso: [](ch_snes), `SNES`, `SNESNEWTONTR`, `SNESSetTolerances()`
3830 @*/
3831 PetscErrorCode SNESSetTrustRegionTolerance(SNES snes, PetscReal tol)
3832 {
3833   PetscFunctionBegin;
3834   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
3835   PetscValidLogicalCollectiveReal(snes, tol, 2);
3836   snes->deltatol = tol;
3837   PetscFunctionReturn(PETSC_SUCCESS);
3838 }
3839 
3840 PETSC_INTERN PetscErrorCode SNESMonitorRange_Private(SNES, PetscInt, PetscReal *);
3841 
3842 PetscErrorCode SNESMonitorLGRange(SNES snes, PetscInt n, PetscReal rnorm, void *monctx)
3843 {
3844   PetscDrawLG      lg;
3845   PetscReal        x, y, per;
3846   PetscViewer      v = (PetscViewer)monctx;
3847   static PetscReal prev; /* should be in the context */
3848   PetscDraw        draw;
3849 
3850   PetscFunctionBegin;
3851   PetscValidHeaderSpecific(v, PETSC_VIEWER_CLASSID, 4);
3852   PetscCall(PetscViewerDrawGetDrawLG(v, 0, &lg));
3853   if (!n) PetscCall(PetscDrawLGReset(lg));
3854   PetscCall(PetscDrawLGGetDraw(lg, &draw));
3855   PetscCall(PetscDrawSetTitle(draw, "Residual norm"));
3856   x = (PetscReal)n;
3857   if (rnorm > 0.0) y = PetscLog10Real(rnorm);
3858   else y = -15.0;
3859   PetscCall(PetscDrawLGAddPoint(lg, &x, &y));
3860   if (n < 20 || !(n % 5) || snes->reason) {
3861     PetscCall(PetscDrawLGDraw(lg));
3862     PetscCall(PetscDrawLGSave(lg));
3863   }
3864 
3865   PetscCall(PetscViewerDrawGetDrawLG(v, 1, &lg));
3866   if (!n) PetscCall(PetscDrawLGReset(lg));
3867   PetscCall(PetscDrawLGGetDraw(lg, &draw));
3868   PetscCall(PetscDrawSetTitle(draw, "% elements > .2*max element"));
3869   PetscCall(SNESMonitorRange_Private(snes, n, &per));
3870   x = (PetscReal)n;
3871   y = 100.0 * per;
3872   PetscCall(PetscDrawLGAddPoint(lg, &x, &y));
3873   if (n < 20 || !(n % 5) || snes->reason) {
3874     PetscCall(PetscDrawLGDraw(lg));
3875     PetscCall(PetscDrawLGSave(lg));
3876   }
3877 
3878   PetscCall(PetscViewerDrawGetDrawLG(v, 2, &lg));
3879   if (!n) {
3880     prev = rnorm;
3881     PetscCall(PetscDrawLGReset(lg));
3882   }
3883   PetscCall(PetscDrawLGGetDraw(lg, &draw));
3884   PetscCall(PetscDrawSetTitle(draw, "(norm -oldnorm)/oldnorm"));
3885   x = (PetscReal)n;
3886   y = (prev - rnorm) / prev;
3887   PetscCall(PetscDrawLGAddPoint(lg, &x, &y));
3888   if (n < 20 || !(n % 5) || snes->reason) {
3889     PetscCall(PetscDrawLGDraw(lg));
3890     PetscCall(PetscDrawLGSave(lg));
3891   }
3892 
3893   PetscCall(PetscViewerDrawGetDrawLG(v, 3, &lg));
3894   if (!n) PetscCall(PetscDrawLGReset(lg));
3895   PetscCall(PetscDrawLGGetDraw(lg, &draw));
3896   PetscCall(PetscDrawSetTitle(draw, "(norm -oldnorm)/oldnorm*(% > .2 max)"));
3897   x = (PetscReal)n;
3898   y = (prev - rnorm) / (prev * per);
3899   if (n > 2) { /*skip initial crazy value */
3900     PetscCall(PetscDrawLGAddPoint(lg, &x, &y));
3901   }
3902   if (n < 20 || !(n % 5) || snes->reason) {
3903     PetscCall(PetscDrawLGDraw(lg));
3904     PetscCall(PetscDrawLGSave(lg));
3905   }
3906   prev = rnorm;
3907   PetscFunctionReturn(PETSC_SUCCESS);
3908 }
3909 
3910 /*@
3911   SNESConverged - Run the convergence test and update the `SNESConvergedReason`.
3912 
3913   Collective
3914 
3915   Input Parameters:
3916 + snes  - the `SNES` context
3917 . it    - current iteration
3918 . xnorm - 2-norm of current iterate
3919 . snorm - 2-norm of current step
3920 - fnorm - 2-norm of function
3921 
3922   Level: developer
3923 
3924   Note:
3925   This routine is called by the `SNESSolve()` implementations.
3926   It does not typically need to be called by the user.
3927 
3928 .seealso: [](ch_snes), `SNES`, `SNESSolve`, `SNESSetConvergenceTest()`, `SNESGetConvergenceTest()`
3929 @*/
3930 PetscErrorCode SNESConverged(SNES snes, PetscInt it, PetscReal xnorm, PetscReal snorm, PetscReal fnorm)
3931 {
3932   PetscFunctionBegin;
3933   if (!snes->reason) {
3934     if (snes->normschedule == SNES_NORM_ALWAYS) PetscUseTypeMethod(snes, converged, it, xnorm, snorm, fnorm, &snes->reason, snes->cnvP);
3935     if (it == snes->max_its && !snes->reason) {
3936       if (snes->normschedule == SNES_NORM_ALWAYS) {
3937         PetscCall(PetscInfo(snes, "Maximum number of iterations has been reached: %" PetscInt_FMT "\n", snes->max_its));
3938         snes->reason = SNES_DIVERGED_MAX_IT;
3939       } else snes->reason = SNES_CONVERGED_ITS;
3940     }
3941   }
3942   PetscFunctionReturn(PETSC_SUCCESS);
3943 }
3944 
3945 /*@
3946   SNESMonitor - runs the user provided monitor routines, if they exist
3947 
3948   Collective
3949 
3950   Input Parameters:
3951 + snes  - nonlinear solver context obtained from `SNESCreate()`
3952 . iter  - iteration number
3953 - rnorm - relative norm of the residual
3954 
3955   Level: developer
3956 
3957   Note:
3958   This routine is called by the `SNESSolve()` implementations.
3959   It does not typically need to be called by the user.
3960 
3961 .seealso: [](ch_snes), `SNES`, `SNESMonitorSet()`
3962 @*/
3963 PetscErrorCode SNESMonitor(SNES snes, PetscInt iter, PetscReal rnorm)
3964 {
3965   PetscInt i, n = snes->numbermonitors;
3966 
3967   PetscFunctionBegin;
3968   if (n > 0) SNESCheckFunctionNorm(snes, rnorm);
3969   PetscCall(VecLockReadPush(snes->vec_sol));
3970   for (i = 0; i < n; i++) PetscCall((*snes->monitor[i])(snes, iter, rnorm, snes->monitorcontext[i]));
3971   PetscCall(VecLockReadPop(snes->vec_sol));
3972   PetscFunctionReturn(PETSC_SUCCESS);
3973 }
3974 
3975 /* ------------ Routines to set performance monitoring options ----------- */
3976 
3977 /*MC
3978     SNESMonitorFunction - functional form passed to `SNESMonitorSet()` to monitor convergence of nonlinear solver
3979 
3980      Synopsis:
3981      #include <petscsnes.h>
3982     PetscErrorCode SNESMonitorFunction(SNES snes, PetscInt its, PetscReal norm, void *mctx)
3983 
3984      Collective
3985 
3986     Input Parameters:
3987 +    snes - the `SNES` context
3988 .    its - iteration number
3989 .    norm - 2-norm function value (may be estimated)
3990 -    mctx - [optional] monitoring context
3991 
3992    Level: advanced
3993 
3994 .seealso: [](ch_snes), `SNESMonitorSet()`, `SNESMonitorSet()`, `SNESMonitorGet()`
3995 M*/
3996 
3997 /*@C
3998   SNESMonitorSet - Sets an ADDITIONAL function that is to be used at every
3999   iteration of the nonlinear solver to display the iteration's
4000   progress.
4001 
4002   Logically Collective
4003 
4004   Input Parameters:
4005 + snes           - the `SNES` context
4006 . f              - the monitor function,  for the calling sequence see `SNESMonitorFunction`
4007 . mctx           - [optional] user-defined context for private data for the monitor routine (use `NULL` if no context is desired)
4008 - monitordestroy - [optional] routine that frees monitor context (may be `NULL`)
4009 
4010   Options Database Keys:
4011 + -snes_monitor               - sets `SNESMonitorDefault()`
4012 . -snes_monitor draw::draw_lg - sets line graph monitor,
4013 - -snes_monitor_cancel        - cancels all monitors that have been hardwired into a code by calls to `SNESMonitorSet()`, but does not cancel those set via
4014                             the options database.
4015 
4016   Level: intermediate
4017 
4018   Note:
4019   Several different monitoring routines may be set by calling
4020   `SNESMonitorSet()` multiple times; all will be called in the
4021   order in which they were set.
4022 
4023   Fortran Note:
4024   Only a single monitor function can be set for each `SNES` object
4025 
4026 .seealso: [](ch_snes), `SNES`, `SNESSolve()`, `SNESMonitorDefault()`, `SNESMonitorCancel()`, `SNESMonitorFunction`
4027 @*/
4028 PetscErrorCode SNESMonitorSet(SNES snes, PetscErrorCode (*f)(SNES, PetscInt, PetscReal, void *), void *mctx, PetscErrorCode (*monitordestroy)(void **))
4029 {
4030   PetscInt  i;
4031   PetscBool identical;
4032 
4033   PetscFunctionBegin;
4034   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
4035   for (i = 0; i < snes->numbermonitors; i++) {
4036     PetscCall(PetscMonitorCompare((PetscErrorCode(*)(void))f, mctx, monitordestroy, (PetscErrorCode(*)(void))snes->monitor[i], snes->monitorcontext[i], snes->monitordestroy[i], &identical));
4037     if (identical) PetscFunctionReturn(PETSC_SUCCESS);
4038   }
4039   PetscCheck(snes->numbermonitors < MAXSNESMONITORS, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Too many monitors set");
4040   snes->monitor[snes->numbermonitors]          = f;
4041   snes->monitordestroy[snes->numbermonitors]   = monitordestroy;
4042   snes->monitorcontext[snes->numbermonitors++] = (void *)mctx;
4043   PetscFunctionReturn(PETSC_SUCCESS);
4044 }
4045 
4046 /*@
4047   SNESMonitorCancel - Clears all the monitor functions for a `SNES` object.
4048 
4049   Logically Collective
4050 
4051   Input Parameter:
4052 . snes - the `SNES` context
4053 
4054   Options Database Key:
4055 . -snes_monitor_cancel - cancels all monitors that have been hardwired
4056     into a code by calls to `SNESMonitorSet()`, but does not cancel those
4057     set via the options database
4058 
4059   Level: intermediate
4060 
4061   Note:
4062   There is no way to clear one specific monitor from a `SNES` object.
4063 
4064 .seealso: [](ch_snes), `SNES`, `SNESMonitorGet()`, `SNESMonitorDefault()`, `SNESMonitorSet()`
4065 @*/
4066 PetscErrorCode SNESMonitorCancel(SNES snes)
4067 {
4068   PetscInt i;
4069 
4070   PetscFunctionBegin;
4071   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
4072   for (i = 0; i < snes->numbermonitors; i++) {
4073     if (snes->monitordestroy[i]) PetscCall((*snes->monitordestroy[i])(&snes->monitorcontext[i]));
4074   }
4075   snes->numbermonitors = 0;
4076   PetscFunctionReturn(PETSC_SUCCESS);
4077 }
4078 
4079 /*MC
4080     SNESConvergenceTestFunction - functional form used for testing of convergence of nonlinear solver
4081 
4082      Synopsis:
4083      #include <petscsnes.h>
4084      PetscErrorCode SNESConvergenceTest(SNES snes, PetscInt it, PetscReal xnorm, PetscReal gnorm, PetscReal f, SNESConvergedReason *reason, void *cctx)
4085 
4086      Collective
4087 
4088     Input Parameters:
4089 +    snes - the `SNES` context
4090 .    it - current iteration (0 is the first and is before any Newton step)
4091 .    xnorm - 2-norm of current iterate
4092 .    gnorm - 2-norm of current step
4093 .    f - 2-norm of function
4094 -    cctx - [optional] convergence context
4095 
4096     Output Parameter:
4097 .    reason - reason for convergence/divergence, only needs to be set when convergence or divergence is detected
4098 
4099    Level: intermediate
4100 
4101 .seealso: [](ch_snes), `SNES`, `SNESSolve`, `SNESSetConvergenceTest()`, `SNESGetConvergenceTest()`
4102 M*/
4103 
4104 /*@C
4105   SNESSetConvergenceTest - Sets the function that is to be used
4106   to test for convergence of the nonlinear iterative solution.
4107 
4108   Logically Collective
4109 
4110   Input Parameters:
4111 + snes                        - the `SNES` context
4112 . SNESConvergenceTestFunction - routine to test for convergence
4113 . cctx                        - [optional] context for private data for the convergence routine  (may be `NULL`)
4114 - destroy                     - [optional] destructor for the context (may be `NULL`; `PETSC_NULL_FUNCTION` in Fortran)
4115 
4116   Level: advanced
4117 
4118 .seealso: [](ch_snes), `SNES`, `SNESConvergedDefault()`, `SNESConvergedSkip()`, `SNESConvergenceTestFunction`
4119 @*/
4120 PetscErrorCode SNESSetConvergenceTest(SNES snes, PetscErrorCode (*SNESConvergenceTestFunction)(SNES, PetscInt, PetscReal, PetscReal, PetscReal, SNESConvergedReason *, void *), void *cctx, PetscErrorCode (*destroy)(void *))
4121 {
4122   PetscFunctionBegin;
4123   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
4124   if (!SNESConvergenceTestFunction) SNESConvergenceTestFunction = SNESConvergedSkip;
4125   if (snes->ops->convergeddestroy) PetscCall((*snes->ops->convergeddestroy)(snes->cnvP));
4126   snes->ops->converged        = SNESConvergenceTestFunction;
4127   snes->ops->convergeddestroy = destroy;
4128   snes->cnvP                  = cctx;
4129   PetscFunctionReturn(PETSC_SUCCESS);
4130 }
4131 
4132 /*@
4133   SNESGetConvergedReason - Gets the reason the `SNES` iteration was stopped.
4134 
4135   Not Collective
4136 
4137   Input Parameter:
4138 . snes - the `SNES` context
4139 
4140   Output Parameter:
4141 . reason - negative value indicates diverged, positive value converged, see `SNESConvergedReason` for the individual convergence tests for complete lists
4142 
4143   Options Database Key:
4144 . -snes_converged_reason - prints the reason to standard out
4145 
4146   Level: intermediate
4147 
4148   Note:
4149   Should only be called after the call the `SNESSolve()` is complete, if it is called earlier it returns the value `SNES__CONVERGED_ITERATING`.
4150 
4151 .seealso: [](ch_snes), `SNESSolve()`, `SNESSetConvergenceTest()`, `SNESSetConvergedReason()`, `SNESConvergedReason`, `SNESGetConvergedReasonString()`
4152 @*/
4153 PetscErrorCode SNESGetConvergedReason(SNES snes, SNESConvergedReason *reason)
4154 {
4155   PetscFunctionBegin;
4156   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
4157   PetscAssertPointer(reason, 2);
4158   *reason = snes->reason;
4159   PetscFunctionReturn(PETSC_SUCCESS);
4160 }
4161 
4162 /*@C
4163   SNESGetConvergedReasonString - Return a human readable string for `SNESConvergedReason`
4164 
4165   Not Collective
4166 
4167   Input Parameter:
4168 . snes - the `SNES` context
4169 
4170   Output Parameter:
4171 . strreason - a human readable string that describes `SNES` converged reason
4172 
4173   Level: beginner
4174 
4175 .seealso: [](ch_snes), `SNES`, `SNESGetConvergedReason()`
4176 @*/
4177 PetscErrorCode SNESGetConvergedReasonString(SNES snes, const char **strreason)
4178 {
4179   PetscFunctionBegin;
4180   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
4181   PetscAssertPointer(strreason, 2);
4182   *strreason = SNESConvergedReasons[snes->reason];
4183   PetscFunctionReturn(PETSC_SUCCESS);
4184 }
4185 
4186 /*@
4187   SNESSetConvergedReason - Sets the reason the `SNES` iteration was stopped.
4188 
4189   Not Collective
4190 
4191   Input Parameters:
4192 + snes   - the `SNES` context
4193 - reason - negative value indicates diverged, positive value converged, see `SNESConvergedReason` or the
4194             manual pages for the individual convergence tests for complete lists
4195 
4196   Level: developer
4197 
4198   Developer Note:
4199   Called inside the various `SNESSolve()` implementations
4200 
4201 .seealso: [](ch_snes), `SNESGetConvergedReason()`, `SNESSetConvergenceTest()`, `SNESConvergedReason`
4202 @*/
4203 PetscErrorCode SNESSetConvergedReason(SNES snes, SNESConvergedReason reason)
4204 {
4205   PetscFunctionBegin;
4206   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
4207   PetscCheck(!snes->errorifnotconverged || reason > 0, PetscObjectComm((PetscObject)snes), PETSC_ERR_PLIB, "SNES code should have previously errored due to negative reason");
4208   snes->reason = reason;
4209   PetscFunctionReturn(PETSC_SUCCESS);
4210 }
4211 
4212 /*@
4213   SNESSetConvergenceHistory - Sets the arrays used to hold the convergence history.
4214 
4215   Logically Collective
4216 
4217   Input Parameters:
4218 + snes  - iterative context obtained from `SNESCreate()`
4219 . a     - array to hold history, this array will contain the function norms computed at each step
4220 . its   - integer array holds the number of linear iterations for each solve.
4221 . na    - size of `a` and `its`
4222 - reset - `PETSC_TRUE` indicates each new nonlinear solve resets the history counter to zero,
4223            else it continues storing new values for new nonlinear solves after the old ones
4224 
4225   Level: intermediate
4226 
4227   Notes:
4228   If 'a' and 'its' are `NULL` then space is allocated for the history. If 'na' `PETSC_DECIDE` or `PETSC_DEFAULT` then a
4229   default array of length 10000 is allocated.
4230 
4231   This routine is useful, e.g., when running a code for purposes
4232   of accurate performance monitoring, when no I/O should be done
4233   during the section of code that is being timed.
4234 
4235   If the arrays run out of space after a number of iterations then the later values are not saved in the history
4236 
4237 .seealso: [](ch_snes), `SNES`, `SNESSolve()`, `SNESGetConvergenceHistory()`
4238 @*/
4239 PetscErrorCode SNESSetConvergenceHistory(SNES snes, PetscReal a[], PetscInt its[], PetscInt na, PetscBool reset)
4240 {
4241   PetscFunctionBegin;
4242   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
4243   if (a) PetscAssertPointer(a, 2);
4244   if (its) PetscAssertPointer(its, 3);
4245   if (!a) {
4246     if (na == PETSC_DECIDE || na == PETSC_DEFAULT) na = 1000;
4247     PetscCall(PetscCalloc2(na, &a, na, &its));
4248     snes->conv_hist_alloc = PETSC_TRUE;
4249   }
4250   snes->conv_hist       = a;
4251   snes->conv_hist_its   = its;
4252   snes->conv_hist_max   = (size_t)na;
4253   snes->conv_hist_len   = 0;
4254   snes->conv_hist_reset = reset;
4255   PetscFunctionReturn(PETSC_SUCCESS);
4256 }
4257 
4258 #if defined(PETSC_HAVE_MATLAB)
4259   #include <engine.h> /* MATLAB include file */
4260   #include <mex.h>    /* MATLAB include file */
4261 
4262 PETSC_EXTERN mxArray *SNESGetConvergenceHistoryMatlab(SNES snes)
4263 {
4264   mxArray   *mat;
4265   PetscInt   i;
4266   PetscReal *ar;
4267 
4268   mat = mxCreateDoubleMatrix(snes->conv_hist_len, 1, mxREAL);
4269   ar  = (PetscReal *)mxGetData(mat);
4270   for (i = 0; i < snes->conv_hist_len; i++) ar[i] = snes->conv_hist[i];
4271   return mat;
4272 }
4273 #endif
4274 
4275 /*@C
4276   SNESGetConvergenceHistory - Gets the arrays used to hold the convergence history.
4277 
4278   Not Collective
4279 
4280   Input Parameter:
4281 . snes - iterative context obtained from `SNESCreate()`
4282 
4283   Output Parameters:
4284 + a   - array to hold history, usually was set with `SNESSetConvergenceHistory()`
4285 . its - integer array holds the number of linear iterations (or
4286          negative if not converged) for each solve.
4287 - na  - size of `a` and `its`
4288 
4289   Level: intermediate
4290 
4291   Note:
4292   This routine is useful, e.g., when running a code for purposes
4293   of accurate performance monitoring, when no I/O should be done
4294   during the section of code that is being timed.
4295 
4296   Fortran Note:
4297   The calling sequence for this routine in Fortran is
4298 .vb
4299     call SNESGetConvergenceHistory(SNES snes, integer na, integer ierr)
4300 .ve
4301 
4302 .seealso: [](ch_snes), `SNES`, `SNESSolve()`, `SNESSetConvergenceHistory()`
4303 @*/
4304 PetscErrorCode SNESGetConvergenceHistory(SNES snes, PetscReal *a[], PetscInt *its[], PetscInt *na)
4305 {
4306   PetscFunctionBegin;
4307   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
4308   if (a) *a = snes->conv_hist;
4309   if (its) *its = snes->conv_hist_its;
4310   if (na) *na = (PetscInt)snes->conv_hist_len;
4311   PetscFunctionReturn(PETSC_SUCCESS);
4312 }
4313 
4314 /*@C
4315   SNESSetUpdate - Sets the general-purpose update function called
4316   at the beginning of every iteration of the nonlinear solve. Specifically
4317   it is called just before the Jacobian is "evaluated".
4318 
4319   Logically Collective
4320 
4321   Input Parameters:
4322 + snes - The nonlinear solver context
4323 - func - The function
4324 
4325   Calling sequence of `func`:
4326 + snes - the nonlinear solver context
4327 - step - The current step of the iteration
4328 
4329   Level: advanced
4330 
4331   Notes:
4332   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
4333   to `SNESSetFunction()`, or `SNESSetPicard()`
4334   This is not used by most users.
4335 
4336   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.
4337 
4338 .seealso: [](ch_snes), `SNES`, `SNESSolve()`, `SNESSetJacobian()`, `SNESLineSearchSetPreCheck()`, `SNESLineSearchSetPostCheck()`, `SNESNewtonTRSetPreCheck()`, `SNESNewtonTRSetPostCheck()`,
4339          `SNESMonitorSet()`, `SNESSetDivergenceTest()`
4340 @*/
4341 PetscErrorCode SNESSetUpdate(SNES snes, PetscErrorCode (*func)(SNES snes, PetscInt step))
4342 {
4343   PetscFunctionBegin;
4344   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
4345   snes->ops->update = func;
4346   PetscFunctionReturn(PETSC_SUCCESS);
4347 }
4348 
4349 /*@C
4350   SNESConvergedReasonView - Displays the reason a `SNES` solve converged or diverged to a viewer
4351 
4352   Collective
4353 
4354   Input Parameters:
4355 + snes   - iterative context obtained from `SNESCreate()`
4356 - viewer - the viewer to display the reason
4357 
4358   Options Database Keys:
4359 + -snes_converged_reason          - print reason for converged or diverged, also prints number of iterations
4360 - -snes_converged_reason ::failed - only print reason and number of iterations when diverged
4361 
4362   Level: beginner
4363 
4364   Note:
4365   To change the format of the output call `PetscViewerPushFormat`(viewer,format) before this call. Use `PETSC_VIEWER_DEFAULT` for the default,
4366   use `PETSC_VIEWER_FAILED` to only display a reason if it fails.
4367 
4368 .seealso: [](ch_snes), `SNESConvergedReason`, `PetscViewer`, `SNES`,
4369           `SNESCreate()`, `SNESSetUp()`, `SNESDestroy()`, `SNESSetTolerances()`, `SNESConvergedDefault()`, `SNESGetConvergedReason()`,
4370           `SNESConvergedReasonViewFromOptions()`,
4371           `PetscViewerPushFormat()`, `PetscViewerPopFormat()`
4372 @*/
4373 PetscErrorCode SNESConvergedReasonView(SNES snes, PetscViewer viewer)
4374 {
4375   PetscViewerFormat format;
4376   PetscBool         isAscii;
4377 
4378   PetscFunctionBegin;
4379   if (!viewer) viewer = PETSC_VIEWER_STDOUT_(PetscObjectComm((PetscObject)snes));
4380   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &isAscii));
4381   if (isAscii) {
4382     PetscCall(PetscViewerGetFormat(viewer, &format));
4383     PetscCall(PetscViewerASCIIAddTab(viewer, ((PetscObject)snes)->tablevel));
4384     if (format == PETSC_VIEWER_ASCII_INFO_DETAIL) {
4385       DM       dm;
4386       Vec      u;
4387       PetscDS  prob;
4388       PetscInt Nf, f;
4389       PetscErrorCode (**exactSol)(PetscInt, PetscReal, const PetscReal[], PetscInt, PetscScalar[], void *);
4390       void    **exactCtx;
4391       PetscReal error;
4392 
4393       PetscCall(SNESGetDM(snes, &dm));
4394       PetscCall(SNESGetSolution(snes, &u));
4395       PetscCall(DMGetDS(dm, &prob));
4396       PetscCall(PetscDSGetNumFields(prob, &Nf));
4397       PetscCall(PetscMalloc2(Nf, &exactSol, Nf, &exactCtx));
4398       for (f = 0; f < Nf; ++f) PetscCall(PetscDSGetExactSolution(prob, f, &exactSol[f], &exactCtx[f]));
4399       PetscCall(DMComputeL2Diff(dm, 0.0, exactSol, exactCtx, u, &error));
4400       PetscCall(PetscFree2(exactSol, exactCtx));
4401       if (error < 1.0e-11) PetscCall(PetscViewerASCIIPrintf(viewer, "L_2 Error: < 1.0e-11\n"));
4402       else PetscCall(PetscViewerASCIIPrintf(viewer, "L_2 Error: %g\n", (double)error));
4403     }
4404     if (snes->reason > 0 && format != PETSC_VIEWER_FAILED) {
4405       if (((PetscObject)snes)->prefix) {
4406         PetscCall(PetscViewerASCIIPrintf(viewer, "Nonlinear %s solve converged due to %s iterations %" PetscInt_FMT "\n", ((PetscObject)snes)->prefix, SNESConvergedReasons[snes->reason], snes->iter));
4407       } else {
4408         PetscCall(PetscViewerASCIIPrintf(viewer, "Nonlinear solve converged due to %s iterations %" PetscInt_FMT "\n", SNESConvergedReasons[snes->reason], snes->iter));
4409       }
4410     } else if (snes->reason <= 0) {
4411       if (((PetscObject)snes)->prefix) {
4412         PetscCall(PetscViewerASCIIPrintf(viewer, "Nonlinear %s solve did not converge due to %s iterations %" PetscInt_FMT "\n", ((PetscObject)snes)->prefix, SNESConvergedReasons[snes->reason], snes->iter));
4413       } else {
4414         PetscCall(PetscViewerASCIIPrintf(viewer, "Nonlinear solve did not converge due to %s iterations %" PetscInt_FMT "\n", SNESConvergedReasons[snes->reason], snes->iter));
4415       }
4416     }
4417     PetscCall(PetscViewerASCIISubtractTab(viewer, ((PetscObject)snes)->tablevel));
4418   }
4419   PetscFunctionReturn(PETSC_SUCCESS);
4420 }
4421 
4422 /*@C
4423   SNESConvergedReasonViewSet - Sets an ADDITIONAL function that is to be used at the
4424   end of the nonlinear solver to display the convergence reason of the nonlinear solver.
4425 
4426   Logically Collective
4427 
4428   Input Parameters:
4429 + snes              - the `SNES` context
4430 . f                 - the `SNESConvergedReason` view function
4431 . vctx              - [optional] user-defined context for private data for the `SNESConvergedReason` view function (use `NULL` if no context is desired)
4432 - reasonviewdestroy - [optional] routine that frees the context (may be `NULL`)
4433 
4434   Calling sequence of `f`:
4435 + snes - the `SNES` context
4436 - vctx - [optional] user-defined context for private data for the function
4437 
4438   Calling sequence of `reasonviewerdestroy`:
4439 . vctx - [optional] user-defined context for private data for the function
4440 
4441   Options Database Keys:
4442 + -snes_converged_reason             - sets a default `SNESConvergedReasonView()`
4443 - -snes_converged_reason_view_cancel - cancels all converged reason viewers that have been hardwired into a code by
4444                             calls to `SNESConvergedReasonViewSet()`, but does not cancel those set via the options database.
4445 
4446   Level: intermediate
4447 
4448   Note:
4449   Several different converged reason view routines may be set by calling
4450   `SNESConvergedReasonViewSet()` multiple times; all will be called in the
4451   order in which they were set.
4452 
4453 .seealso: [](ch_snes), `SNES`, `SNESSolve()`, `SNESConvergedReason`, `SNESGetConvergedReason()`, `SNESConvergedReasonView()`, `SNESConvergedReasonViewCancel()`
4454 @*/
4455 PetscErrorCode SNESConvergedReasonViewSet(SNES snes, PetscErrorCode (*f)(SNES snes, void *vctx), void *vctx, PetscErrorCode (*reasonviewdestroy)(void **vctx))
4456 {
4457   PetscInt  i;
4458   PetscBool identical;
4459 
4460   PetscFunctionBegin;
4461   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
4462   for (i = 0; i < snes->numberreasonviews; i++) {
4463     PetscCall(PetscMonitorCompare((PetscErrorCode(*)(void))f, vctx, reasonviewdestroy, (PetscErrorCode(*)(void))snes->reasonview[i], snes->reasonviewcontext[i], snes->reasonviewdestroy[i], &identical));
4464     if (identical) PetscFunctionReturn(PETSC_SUCCESS);
4465   }
4466   PetscCheck(snes->numberreasonviews < MAXSNESREASONVIEWS, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Too many SNES reasonview set");
4467   snes->reasonview[snes->numberreasonviews]          = f;
4468   snes->reasonviewdestroy[snes->numberreasonviews]   = reasonviewdestroy;
4469   snes->reasonviewcontext[snes->numberreasonviews++] = (void *)vctx;
4470   PetscFunctionReturn(PETSC_SUCCESS);
4471 }
4472 
4473 /*@
4474   SNESConvergedReasonViewFromOptions - Processes command line options to determine if/how a `SNESConvergedReason` is to be viewed at the end of `SNESSolve()`
4475   All the user-provided convergedReasonView routines will be involved as well, if they exist.
4476 
4477   Collective
4478 
4479   Input Parameter:
4480 . snes - the `SNES` object
4481 
4482   Level: advanced
4483 
4484 .seealso: [](ch_snes), `SNES`, `SNESConvergedReason`, `SNESConvergedReasonViewSet()`, `SNESCreate()`, `SNESSetUp()`, `SNESDestroy()`,
4485           `SNESSetTolerances()`, `SNESConvergedDefault()`, `SNESGetConvergedReason()`, `SNESConvergedReasonView()`
4486 @*/
4487 PetscErrorCode SNESConvergedReasonViewFromOptions(SNES snes)
4488 {
4489   PetscViewer       viewer;
4490   PetscBool         flg;
4491   static PetscBool  incall = PETSC_FALSE;
4492   PetscViewerFormat format;
4493   PetscInt          i;
4494 
4495   PetscFunctionBegin;
4496   if (incall) PetscFunctionReturn(PETSC_SUCCESS);
4497   incall = PETSC_TRUE;
4498 
4499   /* All user-provided viewers are called first, if they exist. */
4500   for (i = 0; i < snes->numberreasonviews; i++) PetscCall((*snes->reasonview[i])(snes, snes->reasonviewcontext[i]));
4501 
4502   /* Call PETSc default routine if users ask for it */
4503   PetscCall(PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes), ((PetscObject)snes)->options, ((PetscObject)snes)->prefix, "-snes_converged_reason", &viewer, &format, &flg));
4504   if (flg) {
4505     PetscCall(PetscViewerPushFormat(viewer, format));
4506     PetscCall(SNESConvergedReasonView(snes, viewer));
4507     PetscCall(PetscViewerPopFormat(viewer));
4508     PetscCall(PetscViewerDestroy(&viewer));
4509   }
4510   incall = PETSC_FALSE;
4511   PetscFunctionReturn(PETSC_SUCCESS);
4512 }
4513 
4514 /*@
4515   SNESSolve - Solves a nonlinear system F(x) = b.
4516 
4517   Collective
4518 
4519   Input Parameters:
4520 + snes - the `SNES` context
4521 . b    - the constant part of the equation F(x) = b, or `NULL` to use zero.
4522 - x    - the solution vector.
4523 
4524   Level: beginner
4525 
4526   Note:
4527   The user should initialize the vector, `x`, with the initial guess
4528   for the nonlinear solve prior to calling `SNESSolve()` or use `SNESSetInitialSolution()`.  In particular,
4529   to employ an initial guess of zero, the user should explicitly set
4530   this vector to zero by calling `VecSet()`.
4531 
4532 .seealso: [](ch_snes), `SNES`, `SNESCreate()`, `SNESDestroy()`, `SNESSetFunction()`, `SNESSetJacobian()`, `SNESSetGridSequence()`, `SNESGetSolution()`,
4533           `SNESNewtonTRSetPreCheck()`, `SNESNewtonTRGetPreCheck()`, `SNESNewtonTRSetPostCheck()`, `SNESNewtonTRGetPostCheck()`,
4534           `SNESLineSearchSetPostCheck()`, `SNESLineSearchGetPostCheck()`, `SNESLineSearchSetPreCheck()`, `SNESLineSearchGetPreCheck()`, `SNESSetInitialSolution()`
4535 @*/
4536 PetscErrorCode SNESSolve(SNES snes, Vec b, Vec x)
4537 {
4538   PetscBool flg;
4539   PetscInt  grid;
4540   Vec       xcreated = NULL;
4541   DM        dm;
4542 
4543   PetscFunctionBegin;
4544   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
4545   if (x) PetscValidHeaderSpecific(x, VEC_CLASSID, 3);
4546   if (x) PetscCheckSameComm(snes, 1, x, 3);
4547   if (b) PetscValidHeaderSpecific(b, VEC_CLASSID, 2);
4548   if (b) PetscCheckSameComm(snes, 1, b, 2);
4549 
4550   /* High level operations using the nonlinear solver */
4551   {
4552     PetscViewer       viewer;
4553     PetscViewerFormat format;
4554     PetscInt          num;
4555     PetscBool         flg;
4556     static PetscBool  incall = PETSC_FALSE;
4557 
4558     if (!incall) {
4559       /* Estimate the convergence rate of the discretization */
4560       PetscCall(PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes), ((PetscObject)snes)->options, ((PetscObject)snes)->prefix, "-snes_convergence_estimate", &viewer, &format, &flg));
4561       if (flg) {
4562         PetscConvEst conv;
4563         DM           dm;
4564         PetscReal   *alpha; /* Convergence rate of the solution error for each field in the L_2 norm */
4565         PetscInt     Nf;
4566 
4567         incall = PETSC_TRUE;
4568         PetscCall(SNESGetDM(snes, &dm));
4569         PetscCall(DMGetNumFields(dm, &Nf));
4570         PetscCall(PetscCalloc1(Nf, &alpha));
4571         PetscCall(PetscConvEstCreate(PetscObjectComm((PetscObject)snes), &conv));
4572         PetscCall(PetscConvEstSetSolver(conv, (PetscObject)snes));
4573         PetscCall(PetscConvEstSetFromOptions(conv));
4574         PetscCall(PetscConvEstSetUp(conv));
4575         PetscCall(PetscConvEstGetConvRate(conv, alpha));
4576         PetscCall(PetscViewerPushFormat(viewer, format));
4577         PetscCall(PetscConvEstRateView(conv, alpha, viewer));
4578         PetscCall(PetscViewerPopFormat(viewer));
4579         PetscCall(PetscViewerDestroy(&viewer));
4580         PetscCall(PetscConvEstDestroy(&conv));
4581         PetscCall(PetscFree(alpha));
4582         incall = PETSC_FALSE;
4583       }
4584       /* Adaptively refine the initial grid */
4585       num = 1;
4586       PetscCall(PetscOptionsGetInt(NULL, ((PetscObject)snes)->prefix, "-snes_adapt_initial", &num, &flg));
4587       if (flg) {
4588         DMAdaptor adaptor;
4589 
4590         incall = PETSC_TRUE;
4591         PetscCall(DMAdaptorCreate(PetscObjectComm((PetscObject)snes), &adaptor));
4592         PetscCall(DMAdaptorSetSolver(adaptor, snes));
4593         PetscCall(DMAdaptorSetSequenceLength(adaptor, num));
4594         PetscCall(DMAdaptorSetFromOptions(adaptor));
4595         PetscCall(DMAdaptorSetUp(adaptor));
4596         PetscCall(DMAdaptorAdapt(adaptor, x, DM_ADAPTATION_INITIAL, &dm, &x));
4597         PetscCall(DMAdaptorDestroy(&adaptor));
4598         incall = PETSC_FALSE;
4599       }
4600       /* Use grid sequencing to adapt */
4601       num = 0;
4602       PetscCall(PetscOptionsGetInt(NULL, ((PetscObject)snes)->prefix, "-snes_adapt_sequence", &num, NULL));
4603       if (num) {
4604         DMAdaptor adaptor;
4605 
4606         incall = PETSC_TRUE;
4607         PetscCall(DMAdaptorCreate(PetscObjectComm((PetscObject)snes), &adaptor));
4608         PetscCall(DMAdaptorSetSolver(adaptor, snes));
4609         PetscCall(DMAdaptorSetSequenceLength(adaptor, num));
4610         PetscCall(DMAdaptorSetFromOptions(adaptor));
4611         PetscCall(DMAdaptorSetUp(adaptor));
4612         PetscCall(DMAdaptorAdapt(adaptor, x, DM_ADAPTATION_SEQUENTIAL, &dm, &x));
4613         PetscCall(DMAdaptorDestroy(&adaptor));
4614         incall = PETSC_FALSE;
4615       }
4616     }
4617   }
4618   if (!x) x = snes->vec_sol;
4619   if (!x) {
4620     PetscCall(SNESGetDM(snes, &dm));
4621     PetscCall(DMCreateGlobalVector(dm, &xcreated));
4622     x = xcreated;
4623   }
4624   PetscCall(SNESViewFromOptions(snes, NULL, "-snes_view_pre"));
4625 
4626   for (grid = 0; grid < snes->gridsequence; grid++) PetscCall(PetscViewerASCIIPushTab(PETSC_VIEWER_STDOUT_(PetscObjectComm((PetscObject)snes))));
4627   for (grid = 0; grid < snes->gridsequence + 1; grid++) {
4628     /* set solution vector */
4629     if (!grid) PetscCall(PetscObjectReference((PetscObject)x));
4630     PetscCall(VecDestroy(&snes->vec_sol));
4631     snes->vec_sol = x;
4632     PetscCall(SNESGetDM(snes, &dm));
4633 
4634     /* set affine vector if provided */
4635     if (b) PetscCall(PetscObjectReference((PetscObject)b));
4636     PetscCall(VecDestroy(&snes->vec_rhs));
4637     snes->vec_rhs = b;
4638 
4639     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");
4640     PetscCheck(snes->vec_func != snes->vec_sol, PETSC_COMM_SELF, PETSC_ERR_ARG_IDN, "Solution vector cannot be function vector");
4641     PetscCheck(snes->vec_rhs != snes->vec_sol, PETSC_COMM_SELF, PETSC_ERR_ARG_IDN, "Solution vector cannot be right hand side vector");
4642     if (!snes->vec_sol_update /* && snes->vec_sol */) PetscCall(VecDuplicate(snes->vec_sol, &snes->vec_sol_update));
4643     PetscCall(DMShellSetGlobalVector(dm, snes->vec_sol));
4644     PetscCall(SNESSetUp(snes));
4645 
4646     if (!grid) {
4647       if (snes->ops->computeinitialguess) PetscCallBack("SNES callback initial guess", (*snes->ops->computeinitialguess)(snes, snes->vec_sol, snes->initialguessP));
4648     }
4649 
4650     if (snes->conv_hist_reset) snes->conv_hist_len = 0;
4651     if (snes->counters_reset) {
4652       snes->nfuncs      = 0;
4653       snes->linear_its  = 0;
4654       snes->numFailures = 0;
4655     }
4656 
4657     snes->reason = SNES_CONVERGED_ITERATING;
4658     PetscCall(PetscLogEventBegin(SNES_Solve, snes, 0, 0, 0));
4659     PetscUseTypeMethod(snes, solve);
4660     PetscCall(PetscLogEventEnd(SNES_Solve, snes, 0, 0, 0));
4661     PetscCheck(snes->reason, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Internal error, solver %s returned without setting converged reason", ((PetscObject)snes)->type_name);
4662     snes->domainerror = PETSC_FALSE; /* clear the flag if it has been set */
4663 
4664     if (snes->lagjac_persist) snes->jac_iter += snes->iter;
4665     if (snes->lagpre_persist) snes->pre_iter += snes->iter;
4666 
4667     PetscCall(PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes), ((PetscObject)snes)->options, ((PetscObject)snes)->prefix, "-snes_test_local_min", NULL, NULL, &flg));
4668     if (flg && !PetscPreLoadingOn) PetscCall(SNESTestLocalMin(snes));
4669     /* Call converged reason views. This may involve user-provided viewers as well */
4670     PetscCall(SNESConvergedReasonViewFromOptions(snes));
4671 
4672     if (snes->errorifnotconverged) PetscCheck(snes->reason >= 0, PetscObjectComm((PetscObject)snes), PETSC_ERR_NOT_CONVERGED, "SNESSolve has not converged");
4673     if (snes->reason < 0) break;
4674     if (grid < snes->gridsequence) {
4675       DM  fine;
4676       Vec xnew;
4677       Mat interp;
4678 
4679       PetscCall(DMRefine(snes->dm, PetscObjectComm((PetscObject)snes), &fine));
4680       PetscCheck(fine, PetscObjectComm((PetscObject)snes), PETSC_ERR_ARG_INCOMP, "DMRefine() did not perform any refinement, cannot continue grid sequencing");
4681       PetscCall(DMCreateInterpolation(snes->dm, fine, &interp, NULL));
4682       PetscCall(DMCreateGlobalVector(fine, &xnew));
4683       PetscCall(MatInterpolate(interp, x, xnew));
4684       PetscCall(DMInterpolate(snes->dm, interp, fine));
4685       PetscCall(MatDestroy(&interp));
4686       x = xnew;
4687 
4688       PetscCall(SNESReset(snes));
4689       PetscCall(SNESSetDM(snes, fine));
4690       PetscCall(SNESResetFromOptions(snes));
4691       PetscCall(DMDestroy(&fine));
4692       PetscCall(PetscViewerASCIIPopTab(PETSC_VIEWER_STDOUT_(PetscObjectComm((PetscObject)snes))));
4693     }
4694   }
4695   PetscCall(SNESViewFromOptions(snes, NULL, "-snes_view"));
4696   PetscCall(VecViewFromOptions(snes->vec_sol, (PetscObject)snes, "-snes_view_solution"));
4697   PetscCall(DMMonitor(snes->dm));
4698   PetscCall(SNESMonitorPauseFinal_Internal(snes));
4699 
4700   PetscCall(VecDestroy(&xcreated));
4701   PetscCall(PetscObjectSAWsBlock((PetscObject)snes));
4702   PetscFunctionReturn(PETSC_SUCCESS);
4703 }
4704 
4705 /* --------- Internal routines for SNES Package --------- */
4706 
4707 /*@C
4708   SNESSetType - Sets the method for the nonlinear solver.
4709 
4710   Collective
4711 
4712   Input Parameters:
4713 + snes - the `SNES` context
4714 - type - a known method
4715 
4716   Options Database Key:
4717 . -snes_type <type> - Sets the method; use -help for a list
4718    of available methods (for instance, newtonls or newtontr)
4719 
4720   Level: intermediate
4721 
4722   Notes:
4723   See "petsc/include/petscsnes.h" for available methods (for instance)
4724 +    `SNESNEWTONLS` - Newton's method with line search
4725   (systems of nonlinear equations)
4726 -    `SNESNEWTONTR` - Newton's method with trust region
4727   (systems of nonlinear equations)
4728 
4729   Normally, it is best to use the `SNESSetFromOptions()` command and then
4730   set the `SNES` solver type from the options database rather than by using
4731   this routine.  Using the options database provides the user with
4732   maximum flexibility in evaluating the many nonlinear solvers.
4733   The `SNESSetType()` routine is provided for those situations where it
4734   is necessary to set the nonlinear solver independently of the command
4735   line or options database.  This might be the case, for example, when
4736   the choice of solver changes during the execution of the program,
4737   and the user's application is taking responsibility for choosing the
4738   appropriate method.
4739 
4740   Developer Note:
4741   `SNESRegister()` adds a constructor for a new `SNESType` to `SNESList`, `SNESSetType()` locates
4742   the constructor in that list and calls it to create the specific object.
4743 
4744 .seealso: [](ch_snes), `SNES`, `SNESSolve()`, `SNESType`, `SNESCreate()`, `SNESDestroy()`, `SNESGetType()`, `SNESSetFromOptions()`
4745 @*/
4746 PetscErrorCode SNESSetType(SNES snes, SNESType type)
4747 {
4748   PetscBool match;
4749   PetscErrorCode (*r)(SNES);
4750 
4751   PetscFunctionBegin;
4752   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
4753   PetscAssertPointer(type, 2);
4754 
4755   PetscCall(PetscObjectTypeCompare((PetscObject)snes, type, &match));
4756   if (match) PetscFunctionReturn(PETSC_SUCCESS);
4757 
4758   PetscCall(PetscFunctionListFind(SNESList, type, &r));
4759   PetscCheck(r, PetscObjectComm((PetscObject)snes), PETSC_ERR_ARG_UNKNOWN_TYPE, "Unable to find requested SNES type %s", type);
4760   /* Destroy the previous private SNES context */
4761   PetscTryTypeMethod(snes, destroy);
4762   /* Reinitialize function pointers in SNESOps structure */
4763   snes->ops->setup          = NULL;
4764   snes->ops->solve          = NULL;
4765   snes->ops->view           = NULL;
4766   snes->ops->setfromoptions = NULL;
4767   snes->ops->destroy        = NULL;
4768 
4769   /* It may happen the user has customized the line search before calling SNESSetType */
4770   if (((PetscObject)snes)->type_name) PetscCall(SNESLineSearchDestroy(&snes->linesearch));
4771 
4772   /* Call the SNESCreate_XXX routine for this particular Nonlinear solver */
4773   snes->setupcalled = PETSC_FALSE;
4774 
4775   PetscCall(PetscObjectChangeTypeName((PetscObject)snes, type));
4776   PetscCall((*r)(snes));
4777   PetscFunctionReturn(PETSC_SUCCESS);
4778 }
4779 
4780 /*@C
4781   SNESGetType - Gets the `SNES` method type and name (as a string).
4782 
4783   Not Collective
4784 
4785   Input Parameter:
4786 . snes - nonlinear solver context
4787 
4788   Output Parameter:
4789 . type - `SNES` method (a character string)
4790 
4791   Level: intermediate
4792 
4793 .seealso: [](ch_snes), `SNESSetType()`, `SNESType`, `SNESSetFromOptions()`, `SNES`
4794 @*/
4795 PetscErrorCode SNESGetType(SNES snes, SNESType *type)
4796 {
4797   PetscFunctionBegin;
4798   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
4799   PetscAssertPointer(type, 2);
4800   *type = ((PetscObject)snes)->type_name;
4801   PetscFunctionReturn(PETSC_SUCCESS);
4802 }
4803 
4804 /*@
4805   SNESSetSolution - Sets the solution vector for use by the `SNES` routines.
4806 
4807   Logically Collective
4808 
4809   Input Parameters:
4810 + snes - the `SNES` context obtained from `SNESCreate()`
4811 - u    - the solution vector
4812 
4813   Level: beginner
4814 
4815 .seealso: [](ch_snes), `SNES`, `SNESSolve()`, `SNESGetSolution()`, `Vec`
4816 @*/
4817 PetscErrorCode SNESSetSolution(SNES snes, Vec u)
4818 {
4819   DM dm;
4820 
4821   PetscFunctionBegin;
4822   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
4823   PetscValidHeaderSpecific(u, VEC_CLASSID, 2);
4824   PetscCall(PetscObjectReference((PetscObject)u));
4825   PetscCall(VecDestroy(&snes->vec_sol));
4826 
4827   snes->vec_sol = u;
4828 
4829   PetscCall(SNESGetDM(snes, &dm));
4830   PetscCall(DMShellSetGlobalVector(dm, u));
4831   PetscFunctionReturn(PETSC_SUCCESS);
4832 }
4833 
4834 /*@
4835   SNESGetSolution - Returns the vector where the approximate solution is
4836   stored. This is the fine grid solution when using `SNESSetGridSequence()`.
4837 
4838   Not Collective, but `x` is parallel if `snes` is parallel
4839 
4840   Input Parameter:
4841 . snes - the `SNES` context
4842 
4843   Output Parameter:
4844 . x - the solution
4845 
4846   Level: intermediate
4847 
4848 .seealso: [](ch_snes), `SNESSetSolution()`, `SNESSolve()`, `SNES`, `SNESGetSolutionUpdate()`, `SNESGetFunction()`
4849 @*/
4850 PetscErrorCode SNESGetSolution(SNES snes, Vec *x)
4851 {
4852   PetscFunctionBegin;
4853   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
4854   PetscAssertPointer(x, 2);
4855   *x = snes->vec_sol;
4856   PetscFunctionReturn(PETSC_SUCCESS);
4857 }
4858 
4859 /*@
4860   SNESGetSolutionUpdate - Returns the vector where the solution update is
4861   stored.
4862 
4863   Not Collective, but `x` is parallel if `snes` is parallel
4864 
4865   Input Parameter:
4866 . snes - the `SNES` context
4867 
4868   Output Parameter:
4869 . x - the solution update
4870 
4871   Level: advanced
4872 
4873 .seealso: [](ch_snes), `SNES`, `SNESGetSolution()`, `SNESGetFunction()`
4874 @*/
4875 PetscErrorCode SNESGetSolutionUpdate(SNES snes, Vec *x)
4876 {
4877   PetscFunctionBegin;
4878   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
4879   PetscAssertPointer(x, 2);
4880   *x = snes->vec_sol_update;
4881   PetscFunctionReturn(PETSC_SUCCESS);
4882 }
4883 
4884 /*@C
4885   SNESGetFunction - Returns the function that defines the nonlinear system set with `SNESSetFunction()`
4886 
4887   Not Collective, but `r` is parallel if `snes` is parallel. Collective if `r` is requested, but has not been created yet.
4888 
4889   Input Parameter:
4890 . snes - the `SNES` context
4891 
4892   Output Parameters:
4893 + r   - the vector that is used to store residuals (or `NULL` if you don't want it)
4894 . f   - the function (or `NULL` if you don't want it);  for calling sequence see `SNESFunction`
4895 - ctx - the function context (or `NULL` if you don't want it)
4896 
4897   Level: advanced
4898 
4899   Note:
4900   The vector `r` DOES NOT, in general, contain the current value of the `SNES` nonlinear function
4901 
4902 .seealso: [](ch_snes), `SNES`, `SNESSolve()`, `SNESSetFunction()`, `SNESGetSolution()`, `SNESFunction`
4903 @*/
4904 PetscErrorCode SNESGetFunction(SNES snes, Vec *r, PetscErrorCode (**f)(SNES, Vec, Vec, void *), void **ctx)
4905 {
4906   DM dm;
4907 
4908   PetscFunctionBegin;
4909   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
4910   if (r) {
4911     if (!snes->vec_func) {
4912       if (snes->vec_rhs) {
4913         PetscCall(VecDuplicate(snes->vec_rhs, &snes->vec_func));
4914       } else if (snes->vec_sol) {
4915         PetscCall(VecDuplicate(snes->vec_sol, &snes->vec_func));
4916       } else if (snes->dm) {
4917         PetscCall(DMCreateGlobalVector(snes->dm, &snes->vec_func));
4918       }
4919     }
4920     *r = snes->vec_func;
4921   }
4922   PetscCall(SNESGetDM(snes, &dm));
4923   PetscCall(DMSNESGetFunction(dm, f, ctx));
4924   PetscFunctionReturn(PETSC_SUCCESS);
4925 }
4926 
4927 /*@C
4928   SNESGetNGS - Returns the function and context set with `SNESSetNGS()`
4929 
4930   Input Parameter:
4931 . snes - the `SNES` context
4932 
4933   Output Parameters:
4934 + f   - the function (or `NULL`) see `SNESSetNGS()` for details
4935 - ctx - the function context (or `NULL`)
4936 
4937   Level: advanced
4938 
4939 .seealso: [](ch_snes), `SNESSetNGS()`, `SNESGetFunction()`
4940 @*/
4941 PetscErrorCode SNESGetNGS(SNES snes, PetscErrorCode (**f)(SNES, Vec, Vec, void *), void **ctx)
4942 {
4943   DM dm;
4944 
4945   PetscFunctionBegin;
4946   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
4947   PetscCall(SNESGetDM(snes, &dm));
4948   PetscCall(DMSNESGetNGS(dm, f, ctx));
4949   PetscFunctionReturn(PETSC_SUCCESS);
4950 }
4951 
4952 /*@C
4953   SNESSetOptionsPrefix - Sets the prefix used for searching for all
4954   `SNES` options in the database.
4955 
4956   Logically Collective
4957 
4958   Input Parameters:
4959 + snes   - the `SNES` context
4960 - prefix - the prefix to prepend to all option names
4961 
4962   Level: advanced
4963 
4964   Note:
4965   A hyphen (-) must NOT be given at the beginning of the prefix name.
4966   The first character of all runtime options is AUTOMATICALLY the hyphen.
4967 
4968 .seealso: [](ch_snes), `SNES`, `SNESSetFromOptions()`, `SNESAppendOptionsPrefix()`
4969 @*/
4970 PetscErrorCode SNESSetOptionsPrefix(SNES snes, const char prefix[])
4971 {
4972   PetscFunctionBegin;
4973   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
4974   PetscCall(PetscObjectSetOptionsPrefix((PetscObject)snes, prefix));
4975   if (!snes->ksp) PetscCall(SNESGetKSP(snes, &snes->ksp));
4976   if (snes->linesearch) {
4977     PetscCall(SNESGetLineSearch(snes, &snes->linesearch));
4978     PetscCall(PetscObjectSetOptionsPrefix((PetscObject)snes->linesearch, prefix));
4979   }
4980   PetscCall(KSPSetOptionsPrefix(snes->ksp, prefix));
4981   PetscFunctionReturn(PETSC_SUCCESS);
4982 }
4983 
4984 /*@C
4985   SNESAppendOptionsPrefix - Appends to the prefix used for searching for all
4986   `SNES` options in the database.
4987 
4988   Logically Collective
4989 
4990   Input Parameters:
4991 + snes   - the `SNES` context
4992 - prefix - the prefix to prepend to all option names
4993 
4994   Level: advanced
4995 
4996   Note:
4997   A hyphen (-) must NOT be given at the beginning of the prefix name.
4998   The first character of all runtime options is AUTOMATICALLY the hyphen.
4999 
5000 .seealso: [](ch_snes), `SNESGetOptionsPrefix()`, `SNESSetOptionsPrefix()`
5001 @*/
5002 PetscErrorCode SNESAppendOptionsPrefix(SNES snes, const char prefix[])
5003 {
5004   PetscFunctionBegin;
5005   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
5006   PetscCall(PetscObjectAppendOptionsPrefix((PetscObject)snes, prefix));
5007   if (!snes->ksp) PetscCall(SNESGetKSP(snes, &snes->ksp));
5008   if (snes->linesearch) {
5009     PetscCall(SNESGetLineSearch(snes, &snes->linesearch));
5010     PetscCall(PetscObjectAppendOptionsPrefix((PetscObject)snes->linesearch, prefix));
5011   }
5012   PetscCall(KSPAppendOptionsPrefix(snes->ksp, prefix));
5013   PetscFunctionReturn(PETSC_SUCCESS);
5014 }
5015 
5016 /*@C
5017   SNESGetOptionsPrefix - Gets the prefix used for searching for all
5018   `SNES` options in the database.
5019 
5020   Not Collective
5021 
5022   Input Parameter:
5023 . snes - the `SNES` context
5024 
5025   Output Parameter:
5026 . prefix - pointer to the prefix string used
5027 
5028   Level: advanced
5029 
5030   Fortran Note:
5031   The user should pass in a string 'prefix' of
5032   sufficient length to hold the prefix.
5033 
5034 .seealso: [](ch_snes), `SNES`, `SNESSetOptionsPrefix()`, `SNESAppendOptionsPrefix()`
5035 @*/
5036 PetscErrorCode SNESGetOptionsPrefix(SNES snes, const char *prefix[])
5037 {
5038   PetscFunctionBegin;
5039   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
5040   PetscCall(PetscObjectGetOptionsPrefix((PetscObject)snes, prefix));
5041   PetscFunctionReturn(PETSC_SUCCESS);
5042 }
5043 
5044 /*@C
5045   SNESRegister - Adds a method to the nonlinear solver package.
5046 
5047   Not Collective
5048 
5049   Input Parameters:
5050 + sname    - name of a new user-defined solver
5051 - function - routine to create method context
5052 
5053   Level: advanced
5054 
5055   Note:
5056   `SNESRegister()` may be called multiple times to add several user-defined solvers.
5057 
5058   Example Usage:
5059 .vb
5060    SNESRegister("my_solver", MySolverCreate);
5061 .ve
5062 
5063   Then, your solver can be chosen with the procedural interface via
5064 $     SNESSetType(snes, "my_solver")
5065   or at runtime via the option
5066 $     -snes_type my_solver
5067 
5068 .seealso: [](ch_snes), `SNESRegisterAll()`, `SNESRegisterDestroy()`
5069 @*/
5070 PetscErrorCode SNESRegister(const char sname[], PetscErrorCode (*function)(SNES))
5071 {
5072   PetscFunctionBegin;
5073   PetscCall(SNESInitializePackage());
5074   PetscCall(PetscFunctionListAdd(&SNESList, sname, function));
5075   PetscFunctionReturn(PETSC_SUCCESS);
5076 }
5077 
5078 PetscErrorCode SNESTestLocalMin(SNES snes)
5079 {
5080   PetscInt    N, i, j;
5081   Vec         u, uh, fh;
5082   PetscScalar value;
5083   PetscReal   norm;
5084 
5085   PetscFunctionBegin;
5086   PetscCall(SNESGetSolution(snes, &u));
5087   PetscCall(VecDuplicate(u, &uh));
5088   PetscCall(VecDuplicate(u, &fh));
5089 
5090   /* currently only works for sequential */
5091   PetscCall(PetscPrintf(PetscObjectComm((PetscObject)snes), "Testing FormFunction() for local min\n"));
5092   PetscCall(VecGetSize(u, &N));
5093   for (i = 0; i < N; i++) {
5094     PetscCall(VecCopy(u, uh));
5095     PetscCall(PetscPrintf(PetscObjectComm((PetscObject)snes), "i = %" PetscInt_FMT "\n", i));
5096     for (j = -10; j < 11; j++) {
5097       value = PetscSign(j) * PetscExpReal(PetscAbs(j) - 10.0);
5098       PetscCall(VecSetValue(uh, i, value, ADD_VALUES));
5099       PetscCall(SNESComputeFunction(snes, uh, fh));
5100       PetscCall(VecNorm(fh, NORM_2, &norm));
5101       PetscCall(PetscPrintf(PetscObjectComm((PetscObject)snes), "       j norm %" PetscInt_FMT " %18.16e\n", j, (double)norm));
5102       value = -value;
5103       PetscCall(VecSetValue(uh, i, value, ADD_VALUES));
5104     }
5105   }
5106   PetscCall(VecDestroy(&uh));
5107   PetscCall(VecDestroy(&fh));
5108   PetscFunctionReturn(PETSC_SUCCESS);
5109 }
5110 
5111 /*@
5112   SNESKSPSetUseEW - Sets `SNES` to the use Eisenstat-Walker method for
5113   computing relative tolerance for linear solvers within an inexact
5114   Newton method.
5115 
5116   Logically Collective
5117 
5118   Input Parameters:
5119 + snes - `SNES` context
5120 - flag - `PETSC_TRUE` or `PETSC_FALSE`
5121 
5122   Options Database Keys:
5123 + -snes_ksp_ew                       - use Eisenstat-Walker method for determining linear system convergence
5124 . -snes_ksp_ew_version ver           - version of  Eisenstat-Walker method
5125 . -snes_ksp_ew_rtol0 <rtol0>         - Sets rtol0
5126 . -snes_ksp_ew_rtolmax <rtolmax>     - Sets rtolmax
5127 . -snes_ksp_ew_gamma <gamma>         - Sets gamma
5128 . -snes_ksp_ew_alpha <alpha>         - Sets alpha
5129 . -snes_ksp_ew_alpha2 <alpha2>       - Sets alpha2
5130 - -snes_ksp_ew_threshold <threshold> - Sets threshold
5131 
5132   Level: advanced
5133 
5134   Note:
5135   The default is to use a constant relative tolerance for
5136   the inner linear solvers.  Alternatively, one can use the
5137   Eisenstat-Walker method {cite}`ew96`, where the relative convergence tolerance
5138   is reset at each Newton iteration according progress of the nonlinear
5139   solver.
5140 
5141 .seealso: [](ch_snes), `KSP`, `SNES`, `SNESKSPGetUseEW()`, `SNESKSPGetParametersEW()`, `SNESKSPSetParametersEW()`
5142 @*/
5143 PetscErrorCode SNESKSPSetUseEW(SNES snes, PetscBool flag)
5144 {
5145   PetscFunctionBegin;
5146   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
5147   PetscValidLogicalCollectiveBool(snes, flag, 2);
5148   snes->ksp_ewconv = flag;
5149   PetscFunctionReturn(PETSC_SUCCESS);
5150 }
5151 
5152 /*@
5153   SNESKSPGetUseEW - Gets if `SNES` is using Eisenstat-Walker method
5154   for computing relative tolerance for linear solvers within an
5155   inexact Newton method.
5156 
5157   Not Collective
5158 
5159   Input Parameter:
5160 . snes - `SNES` context
5161 
5162   Output Parameter:
5163 . flag - `PETSC_TRUE` or `PETSC_FALSE`
5164 
5165   Level: advanced
5166 
5167 .seealso: [](ch_snes), `SNESKSPSetUseEW()`, `SNESKSPGetParametersEW()`, `SNESKSPSetParametersEW()`
5168 @*/
5169 PetscErrorCode SNESKSPGetUseEW(SNES snes, PetscBool *flag)
5170 {
5171   PetscFunctionBegin;
5172   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
5173   PetscAssertPointer(flag, 2);
5174   *flag = snes->ksp_ewconv;
5175   PetscFunctionReturn(PETSC_SUCCESS);
5176 }
5177 
5178 /*@
5179   SNESKSPSetParametersEW - Sets parameters for Eisenstat-Walker
5180   convergence criteria for the linear solvers within an inexact
5181   Newton method.
5182 
5183   Logically Collective
5184 
5185   Input Parameters:
5186 + snes      - `SNES` context
5187 . version   - version 1, 2 (default is 2), 3 or 4
5188 . rtol_0    - initial relative tolerance (0 <= rtol_0 < 1)
5189 . rtol_max  - maximum relative tolerance (0 <= rtol_max < 1)
5190 . gamma     - multiplicative factor for version 2 rtol computation
5191              (0 <= gamma2 <= 1)
5192 . alpha     - power for version 2 rtol computation (1 < alpha <= 2)
5193 . alpha2    - power for safeguard
5194 - threshold - threshold for imposing safeguard (0 < threshold < 1)
5195 
5196   Level: advanced
5197 
5198   Notes:
5199   Version 3 was contributed by Luis Chacon, June 2006.
5200 
5201   Use `PETSC_DEFAULT` to retain the default for any of the parameters.
5202 
5203 .seealso: [](ch_snes), `SNES`, `SNESKSPSetUseEW()`, `SNESKSPGetUseEW()`, `SNESKSPGetParametersEW()`
5204 @*/
5205 PetscErrorCode SNESKSPSetParametersEW(SNES snes, PetscInt version, PetscReal rtol_0, PetscReal rtol_max, PetscReal gamma, PetscReal alpha, PetscReal alpha2, PetscReal threshold)
5206 {
5207   SNESKSPEW *kctx;
5208 
5209   PetscFunctionBegin;
5210   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
5211   kctx = (SNESKSPEW *)snes->kspconvctx;
5212   PetscCheck(kctx, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "No Eisenstat-Walker context existing");
5213   PetscValidLogicalCollectiveInt(snes, version, 2);
5214   PetscValidLogicalCollectiveReal(snes, rtol_0, 3);
5215   PetscValidLogicalCollectiveReal(snes, rtol_max, 4);
5216   PetscValidLogicalCollectiveReal(snes, gamma, 5);
5217   PetscValidLogicalCollectiveReal(snes, alpha, 6);
5218   PetscValidLogicalCollectiveReal(snes, alpha2, 7);
5219   PetscValidLogicalCollectiveReal(snes, threshold, 8);
5220 
5221   if (version != PETSC_DEFAULT) kctx->version = version;
5222   if (rtol_0 != (PetscReal)PETSC_DEFAULT) kctx->rtol_0 = rtol_0;
5223   if (rtol_max != (PetscReal)PETSC_DEFAULT) kctx->rtol_max = rtol_max;
5224   if (gamma != (PetscReal)PETSC_DEFAULT) kctx->gamma = gamma;
5225   if (alpha != (PetscReal)PETSC_DEFAULT) kctx->alpha = alpha;
5226   if (alpha2 != (PetscReal)PETSC_DEFAULT) kctx->alpha2 = alpha2;
5227   if (threshold != (PetscReal)PETSC_DEFAULT) kctx->threshold = threshold;
5228 
5229   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);
5230   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);
5231   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);
5232   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);
5233   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);
5234   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);
5235   PetscFunctionReturn(PETSC_SUCCESS);
5236 }
5237 
5238 /*@
5239   SNESKSPGetParametersEW - Gets parameters for Eisenstat-Walker
5240   convergence criteria for the linear solvers within an inexact
5241   Newton method.
5242 
5243   Not Collective
5244 
5245   Input Parameter:
5246 . snes - `SNES` context
5247 
5248   Output Parameters:
5249 + version   - version 1, 2 (default is 2), 3 or 4
5250 . rtol_0    - initial relative tolerance (0 <= rtol_0 < 1)
5251 . rtol_max  - maximum relative tolerance (0 <= rtol_max < 1)
5252 . gamma     - multiplicative factor for version 2 rtol computation (0 <= gamma2 <= 1)
5253 . alpha     - power for version 2 rtol computation (1 < alpha <= 2)
5254 . alpha2    - power for safeguard
5255 - threshold - threshold for imposing safeguard (0 < threshold < 1)
5256 
5257   Level: advanced
5258 
5259 .seealso: [](ch_snes), `SNES`, `SNESKSPSetUseEW()`, `SNESKSPGetUseEW()`, `SNESKSPSetParametersEW()`
5260 @*/
5261 PetscErrorCode SNESKSPGetParametersEW(SNES snes, PetscInt *version, PetscReal *rtol_0, PetscReal *rtol_max, PetscReal *gamma, PetscReal *alpha, PetscReal *alpha2, PetscReal *threshold)
5262 {
5263   SNESKSPEW *kctx;
5264 
5265   PetscFunctionBegin;
5266   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
5267   kctx = (SNESKSPEW *)snes->kspconvctx;
5268   PetscCheck(kctx, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "No Eisenstat-Walker context existing");
5269   if (version) *version = kctx->version;
5270   if (rtol_0) *rtol_0 = kctx->rtol_0;
5271   if (rtol_max) *rtol_max = kctx->rtol_max;
5272   if (gamma) *gamma = kctx->gamma;
5273   if (alpha) *alpha = kctx->alpha;
5274   if (alpha2) *alpha2 = kctx->alpha2;
5275   if (threshold) *threshold = kctx->threshold;
5276   PetscFunctionReturn(PETSC_SUCCESS);
5277 }
5278 
5279 PetscErrorCode KSPPreSolve_SNESEW(KSP ksp, Vec b, Vec x, void *ctx)
5280 {
5281   SNES       snes = (SNES)ctx;
5282   SNESKSPEW *kctx = (SNESKSPEW *)snes->kspconvctx;
5283   PetscReal  rtol = PETSC_DEFAULT, stol;
5284 
5285   PetscFunctionBegin;
5286   if (!snes->ksp_ewconv) PetscFunctionReturn(PETSC_SUCCESS);
5287   if (!snes->iter) {
5288     rtol = kctx->rtol_0; /* first time in, so use the original user rtol */
5289     PetscCall(VecNorm(snes->vec_func, NORM_2, &kctx->norm_first));
5290   } else {
5291     PetscCheck(kctx->version >= 1 && kctx->version <= 4, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Only versions 1-4 are supported: %" PetscInt_FMT, kctx->version);
5292     if (kctx->version == 1) {
5293       rtol = PetscAbsReal(snes->norm - kctx->lresid_last) / kctx->norm_last;
5294       stol = PetscPowReal(kctx->rtol_last, kctx->alpha2);
5295       if (stol > kctx->threshold) rtol = PetscMax(rtol, stol);
5296     } else if (kctx->version == 2) {
5297       rtol = kctx->gamma * PetscPowReal(snes->norm / kctx->norm_last, kctx->alpha);
5298       stol = kctx->gamma * PetscPowReal(kctx->rtol_last, kctx->alpha);
5299       if (stol > kctx->threshold) rtol = PetscMax(rtol, stol);
5300     } else if (kctx->version == 3) { /* contributed by Luis Chacon, June 2006. */
5301       rtol = kctx->gamma * PetscPowReal(snes->norm / kctx->norm_last, kctx->alpha);
5302       /* safeguard: avoid sharp decrease of rtol */
5303       stol = kctx->gamma * PetscPowReal(kctx->rtol_last, kctx->alpha);
5304       stol = PetscMax(rtol, stol);
5305       rtol = PetscMin(kctx->rtol_0, stol);
5306       /* safeguard: avoid oversolving */
5307       stol = kctx->gamma * (kctx->norm_first * snes->rtol) / snes->norm;
5308       stol = PetscMax(rtol, stol);
5309       rtol = PetscMin(kctx->rtol_0, stol);
5310     } else /* if (kctx->version == 4) */ {
5311       /* H.-B. An et al. Journal of Computational and Applied Mathematics 200 (2007) 47-60 */
5312       PetscReal ared = PetscAbsReal(kctx->norm_last - snes->norm);
5313       PetscReal pred = PetscAbsReal(kctx->norm_last - kctx->lresid_last);
5314       PetscReal rk   = ared / pred;
5315       if (rk < kctx->v4_p1) rtol = 1. - 2. * kctx->v4_p1;
5316       else if (rk < kctx->v4_p2) rtol = kctx->rtol_last;
5317       else if (rk < kctx->v4_p3) rtol = kctx->v4_m1 * kctx->rtol_last;
5318       else rtol = kctx->v4_m2 * kctx->rtol_last;
5319 
5320       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;
5321       kctx->rtol_last_2 = kctx->rtol_last;
5322       kctx->rk_last_2   = kctx->rk_last;
5323       kctx->rk_last     = rk;
5324     }
5325   }
5326   /* safeguard: avoid rtol greater than rtol_max */
5327   rtol = PetscMin(rtol, kctx->rtol_max);
5328   PetscCall(KSPSetTolerances(ksp, rtol, PETSC_DEFAULT, PETSC_DEFAULT, PETSC_DEFAULT));
5329   PetscCall(PetscInfo(snes, "iter %" PetscInt_FMT ", Eisenstat-Walker (version %" PetscInt_FMT ") KSP rtol=%g\n", snes->iter, kctx->version, (double)rtol));
5330   PetscFunctionReturn(PETSC_SUCCESS);
5331 }
5332 
5333 PetscErrorCode KSPPostSolve_SNESEW(KSP ksp, Vec b, Vec x, void *ctx)
5334 {
5335   SNES       snes = (SNES)ctx;
5336   SNESKSPEW *kctx = (SNESKSPEW *)snes->kspconvctx;
5337   PCSide     pcside;
5338   Vec        lres;
5339 
5340   PetscFunctionBegin;
5341   if (!snes->ksp_ewconv) PetscFunctionReturn(PETSC_SUCCESS);
5342   PetscCall(KSPGetTolerances(ksp, &kctx->rtol_last, NULL, NULL, NULL));
5343   kctx->norm_last = snes->norm;
5344   if (kctx->version == 1 || kctx->version == 4) {
5345     PC        pc;
5346     PetscBool getRes;
5347 
5348     PetscCall(KSPGetPC(ksp, &pc));
5349     PetscCall(PetscObjectTypeCompare((PetscObject)pc, PCNONE, &getRes));
5350     if (!getRes) {
5351       KSPNormType normtype;
5352 
5353       PetscCall(KSPGetNormType(ksp, &normtype));
5354       getRes = (PetscBool)(normtype == KSP_NORM_UNPRECONDITIONED);
5355     }
5356     PetscCall(KSPGetPCSide(ksp, &pcside));
5357     if (pcside == PC_RIGHT || getRes) { /* KSP residual is true linear residual */
5358       PetscCall(KSPGetResidualNorm(ksp, &kctx->lresid_last));
5359     } else {
5360       /* KSP residual is preconditioned residual */
5361       /* compute true linear residual norm */
5362       Mat J;
5363       PetscCall(KSPGetOperators(ksp, &J, NULL));
5364       PetscCall(VecDuplicate(b, &lres));
5365       PetscCall(MatMult(J, x, lres));
5366       PetscCall(VecAYPX(lres, -1.0, b));
5367       PetscCall(VecNorm(lres, NORM_2, &kctx->lresid_last));
5368       PetscCall(VecDestroy(&lres));
5369     }
5370   }
5371   PetscFunctionReturn(PETSC_SUCCESS);
5372 }
5373 
5374 /*@
5375   SNESGetKSP - Returns the `KSP` context for a `SNES` solver.
5376 
5377   Not Collective, but if `snes` is parallel, then `ksp` is parallel
5378 
5379   Input Parameter:
5380 . snes - the `SNES` context
5381 
5382   Output Parameter:
5383 . ksp - the `KSP` context
5384 
5385   Level: beginner
5386 
5387   Notes:
5388   The user can then directly manipulate the `KSP` context to set various
5389   options, etc.  Likewise, the user can then extract and manipulate the
5390   `PC` contexts as well.
5391 
5392   Some `SNESType`s do not use a `KSP` but a `KSP` is still returned by this function
5393 
5394 .seealso: [](ch_snes), `SNES`, `KSP`, `PC`, `KSPGetPC()`, `SNESCreate()`, `KSPCreate()`, `SNESSetKSP()`
5395 @*/
5396 PetscErrorCode SNESGetKSP(SNES snes, KSP *ksp)
5397 {
5398   PetscFunctionBegin;
5399   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
5400   PetscAssertPointer(ksp, 2);
5401 
5402   if (!snes->ksp) {
5403     PetscCall(KSPCreate(PetscObjectComm((PetscObject)snes), &snes->ksp));
5404     PetscCall(PetscObjectIncrementTabLevel((PetscObject)snes->ksp, (PetscObject)snes, 1));
5405 
5406     PetscCall(KSPSetPreSolve(snes->ksp, KSPPreSolve_SNESEW, snes));
5407     PetscCall(KSPSetPostSolve(snes->ksp, KSPPostSolve_SNESEW, snes));
5408 
5409     PetscCall(KSPMonitorSetFromOptions(snes->ksp, "-snes_monitor_ksp", "snes_preconditioned_residual", snes));
5410     PetscCall(PetscObjectSetOptions((PetscObject)snes->ksp, ((PetscObject)snes)->options));
5411   }
5412   *ksp = snes->ksp;
5413   PetscFunctionReturn(PETSC_SUCCESS);
5414 }
5415 
5416 #include <petsc/private/dmimpl.h>
5417 /*@
5418   SNESSetDM - Sets the `DM` that may be used by some nonlinear solvers or their underlying preconditioners
5419 
5420   Logically Collective
5421 
5422   Input Parameters:
5423 + snes - the nonlinear solver context
5424 - dm   - the `DM`, cannot be `NULL`
5425 
5426   Level: intermediate
5427 
5428   Note:
5429   A `DM` can only be used for solving one problem at a time because information about the problem is stored on the `DM`,
5430   even when not using interfaces like `DMSNESSetFunction()`.  Use `DMClone()` to get a distinct `DM` when solving different
5431   problems using the same function space.
5432 
5433 .seealso: [](ch_snes), `DM`, `SNES`, `SNESGetDM()`, `KSPSetDM()`, `KSPGetDM()`
5434 @*/
5435 PetscErrorCode SNESSetDM(SNES snes, DM dm)
5436 {
5437   KSP    ksp;
5438   DMSNES sdm;
5439 
5440   PetscFunctionBegin;
5441   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
5442   PetscValidHeaderSpecific(dm, DM_CLASSID, 2);
5443   PetscCall(PetscObjectReference((PetscObject)dm));
5444   if (snes->dm) { /* Move the DMSNES context over to the new DM unless the new DM already has one */
5445     if (snes->dm->dmsnes && !dm->dmsnes) {
5446       PetscCall(DMCopyDMSNES(snes->dm, dm));
5447       PetscCall(DMGetDMSNES(snes->dm, &sdm));
5448       if (sdm->originaldm == snes->dm) sdm->originaldm = dm; /* Grant write privileges to the replacement DM */
5449     }
5450     PetscCall(DMCoarsenHookRemove(snes->dm, DMCoarsenHook_SNESVecSol, DMRestrictHook_SNESVecSol, snes));
5451     PetscCall(DMDestroy(&snes->dm));
5452   }
5453   snes->dm     = dm;
5454   snes->dmAuto = PETSC_FALSE;
5455 
5456   PetscCall(SNESGetKSP(snes, &ksp));
5457   PetscCall(KSPSetDM(ksp, dm));
5458   PetscCall(KSPSetDMActive(ksp, PETSC_FALSE));
5459   if (snes->npc) {
5460     PetscCall(SNESSetDM(snes->npc, snes->dm));
5461     PetscCall(SNESSetNPCSide(snes, snes->npcside));
5462   }
5463   PetscFunctionReturn(PETSC_SUCCESS);
5464 }
5465 
5466 /*@
5467   SNESGetDM - Gets the `DM` that may be used by some solvers/preconditioners
5468 
5469   Not Collective but dm obtained is parallel on snes
5470 
5471   Input Parameter:
5472 . snes - the `SNES` context
5473 
5474   Output Parameter:
5475 . dm - the `DM`
5476 
5477   Level: intermediate
5478 
5479 .seealso: [](ch_snes), `DM`, `SNES`, `SNESSetDM()`, `KSPSetDM()`, `KSPGetDM()`
5480 @*/
5481 PetscErrorCode SNESGetDM(SNES snes, DM *dm)
5482 {
5483   PetscFunctionBegin;
5484   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
5485   if (!snes->dm) {
5486     PetscCall(DMShellCreate(PetscObjectComm((PetscObject)snes), &snes->dm));
5487     snes->dmAuto = PETSC_TRUE;
5488   }
5489   *dm = snes->dm;
5490   PetscFunctionReturn(PETSC_SUCCESS);
5491 }
5492 
5493 /*@
5494   SNESSetNPC - Sets the nonlinear preconditioner to be used.
5495 
5496   Collective
5497 
5498   Input Parameters:
5499 + snes - iterative context obtained from `SNESCreate()`
5500 - npc  - the nonlinear preconditioner object
5501 
5502   Level: developer
5503 
5504   Notes:
5505   Use `SNESGetNPC()` to retrieve the preconditioner context (for example,
5506   to configure it using the API).
5507 
5508   Only some `SNESType` can use a nonlinear preconditioner
5509 
5510 .seealso: [](ch_snes), `SNES`, `SNESNGS`, `SNESFAS`, `SNESGetNPC()`, `SNESHasNPC()`
5511 @*/
5512 PetscErrorCode SNESSetNPC(SNES snes, SNES npc)
5513 {
5514   PetscFunctionBegin;
5515   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
5516   PetscValidHeaderSpecific(npc, SNES_CLASSID, 2);
5517   PetscCheckSameComm(snes, 1, npc, 2);
5518   PetscCall(PetscObjectReference((PetscObject)npc));
5519   PetscCall(SNESDestroy(&snes->npc));
5520   snes->npc = npc;
5521   PetscFunctionReturn(PETSC_SUCCESS);
5522 }
5523 
5524 /*@
5525   SNESGetNPC - Gets a nonlinear preconditioning solver SNES` to be used to precondition the original nonlinear solver.
5526 
5527   Not Collective; but any changes to the obtained the npc object must be applied collectively
5528 
5529   Input Parameter:
5530 . snes - iterative context obtained from `SNESCreate()`
5531 
5532   Output Parameter:
5533 . pc - preconditioner context
5534 
5535   Options Database Key:
5536 . -npc_snes_type <type> - set the type of the `SNES` to use as the nonlinear preconditioner
5537 
5538   Level: developer
5539 
5540   Notes:
5541   If a `SNES` was previously set with `SNESSetNPC()` then that value is returned, otherwise a new `SNES` object is created.
5542 
5543   The (preconditioner) `SNES` returned automatically inherits the same nonlinear function and Jacobian supplied to the original
5544   `SNES`
5545 
5546 .seealso: [](ch_snes), `SNESSetNPC()`, `SNESHasNPC()`, `SNES`, `SNESCreate()`
5547 @*/
5548 PetscErrorCode SNESGetNPC(SNES snes, SNES *pc)
5549 {
5550   const char *optionsprefix;
5551 
5552   PetscFunctionBegin;
5553   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
5554   PetscAssertPointer(pc, 2);
5555   if (!snes->npc) {
5556     void *ctx;
5557 
5558     PetscCall(SNESCreate(PetscObjectComm((PetscObject)snes), &snes->npc));
5559     PetscCall(PetscObjectIncrementTabLevel((PetscObject)snes->npc, (PetscObject)snes, 1));
5560     PetscCall(SNESGetOptionsPrefix(snes, &optionsprefix));
5561     PetscCall(SNESSetOptionsPrefix(snes->npc, optionsprefix));
5562     PetscCall(SNESAppendOptionsPrefix(snes->npc, "npc_"));
5563     PetscCall(SNESGetApplicationContext(snes, &ctx));
5564     PetscCall(SNESSetApplicationContext(snes->npc, ctx));
5565     PetscCall(SNESSetCountersReset(snes->npc, PETSC_FALSE));
5566   }
5567   *pc = snes->npc;
5568   PetscFunctionReturn(PETSC_SUCCESS);
5569 }
5570 
5571 /*@
5572   SNESHasNPC - Returns whether a nonlinear preconditioner exists
5573 
5574   Not Collective
5575 
5576   Input Parameter:
5577 . snes - iterative context obtained from `SNESCreate()`
5578 
5579   Output Parameter:
5580 . has_npc - whether the `SNES` has a nonlinear preconditioner or not
5581 
5582   Level: developer
5583 
5584 .seealso: [](ch_snes), `SNESSetNPC()`, `SNESGetNPC()`
5585 @*/
5586 PetscErrorCode SNESHasNPC(SNES snes, PetscBool *has_npc)
5587 {
5588   PetscFunctionBegin;
5589   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
5590   *has_npc = (PetscBool)(snes->npc ? PETSC_TRUE : PETSC_FALSE);
5591   PetscFunctionReturn(PETSC_SUCCESS);
5592 }
5593 
5594 /*@
5595   SNESSetNPCSide - Sets the nonlinear preconditioning side.
5596 
5597   Logically Collective
5598 
5599   Input Parameter:
5600 . snes - iterative context obtained from `SNESCreate()`
5601 
5602   Output Parameter:
5603 . side - the preconditioning side, where side is one of
5604 .vb
5605       PC_LEFT - left preconditioning
5606       PC_RIGHT - right preconditioning (default for most nonlinear solvers)
5607 .ve
5608 
5609   Options Database Key:
5610 . -snes_npc_side <right,left> - nonlinear preconditioner side
5611 
5612   Level: intermediate
5613 
5614   Note:
5615   `SNESNRICHARDSON` and `SNESNCG` only support left preconditioning.
5616 
5617 .seealso: [](ch_snes), `SNES`, `SNESNRICHARDSON`, `SNESNCG`, `SNESType`, `SNESGetNPCSide()`, `KSPSetPCSide()`, `PC_LEFT`, `PC_RIGHT`, `PCSide`
5618 @*/
5619 PetscErrorCode SNESSetNPCSide(SNES snes, PCSide side)
5620 {
5621   PetscFunctionBegin;
5622   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
5623   PetscValidLogicalCollectiveEnum(snes, side, 2);
5624   if (side == PC_SIDE_DEFAULT) side = PC_RIGHT;
5625   PetscCheck((side == PC_LEFT) || (side == PC_RIGHT), PetscObjectComm((PetscObject)snes), PETSC_ERR_ARG_WRONG, "Only PC_LEFT and PC_RIGHT are supported");
5626   snes->npcside = side;
5627   PetscFunctionReturn(PETSC_SUCCESS);
5628 }
5629 
5630 /*@
5631   SNESGetNPCSide - Gets the preconditioning side.
5632 
5633   Not Collective
5634 
5635   Input Parameter:
5636 . snes - iterative context obtained from `SNESCreate()`
5637 
5638   Output Parameter:
5639 . side - the preconditioning side, where side is one of
5640 .vb
5641       `PC_LEFT` - left preconditioning
5642       `PC_RIGHT` - right preconditioning (default for most nonlinear solvers)
5643 .ve
5644 
5645   Level: intermediate
5646 
5647 .seealso: [](ch_snes), `SNES`, `SNESSetNPCSide()`, `KSPGetPCSide()`, `PC_LEFT`, `PC_RIGHT`, `PCSide`
5648 @*/
5649 PetscErrorCode SNESGetNPCSide(SNES snes, PCSide *side)
5650 {
5651   PetscFunctionBegin;
5652   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
5653   PetscAssertPointer(side, 2);
5654   *side = snes->npcside;
5655   PetscFunctionReturn(PETSC_SUCCESS);
5656 }
5657 
5658 /*@
5659   SNESSetLineSearch - Sets the linesearch to be used for `SNES`
5660 
5661   Collective
5662 
5663   Input Parameters:
5664 + snes       - iterative context obtained from `SNESCreate()`
5665 - linesearch - the linesearch object
5666 
5667   Level: developer
5668 
5669   Note:
5670   This is almost never used, rather one uses `SNESGetLineSearch()` to retrieve the line search and set options on it
5671   to configure it using the API).
5672 
5673 .seealso: [](ch_snes), `SNES`, `SNESLineSearch`, `SNESGetLineSearch()`
5674 @*/
5675 PetscErrorCode SNESSetLineSearch(SNES snes, SNESLineSearch linesearch)
5676 {
5677   PetscFunctionBegin;
5678   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
5679   PetscValidHeaderSpecific(linesearch, SNESLINESEARCH_CLASSID, 2);
5680   PetscCheckSameComm(snes, 1, linesearch, 2);
5681   PetscCall(PetscObjectReference((PetscObject)linesearch));
5682   PetscCall(SNESLineSearchDestroy(&snes->linesearch));
5683 
5684   snes->linesearch = linesearch;
5685 
5686   PetscFunctionReturn(PETSC_SUCCESS);
5687 }
5688 
5689 /*@
5690   SNESGetLineSearch - Returns the line search context possibly set with `SNESSetLineSearch()`
5691   or creates a default line search instance associated with the `SNES` and returns it.
5692 
5693   Not Collective
5694 
5695   Input Parameter:
5696 . snes - iterative context obtained from `SNESCreate()`
5697 
5698   Output Parameter:
5699 . linesearch - linesearch context
5700 
5701   Level: beginner
5702 
5703 .seealso: [](ch_snes), `SNESLineSearch`, `SNESSetLineSearch()`, `SNESLineSearchCreate()`
5704 @*/
5705 PetscErrorCode SNESGetLineSearch(SNES snes, SNESLineSearch *linesearch)
5706 {
5707   const char *optionsprefix;
5708 
5709   PetscFunctionBegin;
5710   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
5711   PetscAssertPointer(linesearch, 2);
5712   if (!snes->linesearch) {
5713     PetscCall(SNESGetOptionsPrefix(snes, &optionsprefix));
5714     PetscCall(SNESLineSearchCreate(PetscObjectComm((PetscObject)snes), &snes->linesearch));
5715     PetscCall(SNESLineSearchSetSNES(snes->linesearch, snes));
5716     PetscCall(SNESLineSearchAppendOptionsPrefix(snes->linesearch, optionsprefix));
5717     PetscCall(PetscObjectIncrementTabLevel((PetscObject)snes->linesearch, (PetscObject)snes, 1));
5718   }
5719   *linesearch = snes->linesearch;
5720   PetscFunctionReturn(PETSC_SUCCESS);
5721 }
5722