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