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