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