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