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