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