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