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