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