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