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