xref: /petsc/src/snes/interface/snes.c (revision 6b3eee04a67a44bd9a4e65b41b1dd96ffcd06ca3)
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->divtol            = 1.e4;
1556   snes->rnorm0            = 0;
1557   snes->nfuncs            = 0;
1558   snes->numFailures       = 0;
1559   snes->maxFailures       = 1;
1560   snes->linear_its        = 0;
1561   snes->lagjacobian       = 1;
1562   snes->jac_iter          = 0;
1563   snes->lagjac_persist    = PETSC_FALSE;
1564   snes->lagpreconditioner = 1;
1565   snes->pre_iter          = 0;
1566   snes->lagpre_persist    = PETSC_FALSE;
1567   snes->numbermonitors    = 0;
1568   snes->data              = 0;
1569   snes->setupcalled       = PETSC_FALSE;
1570   snes->ksp_ewconv        = PETSC_FALSE;
1571   snes->nwork             = 0;
1572   snes->work              = 0;
1573   snes->nvwork            = 0;
1574   snes->vwork             = 0;
1575   snes->conv_hist_len     = 0;
1576   snes->conv_hist_max     = 0;
1577   snes->conv_hist         = NULL;
1578   snes->conv_hist_its     = NULL;
1579   snes->conv_hist_reset   = PETSC_TRUE;
1580   snes->counters_reset    = PETSC_TRUE;
1581   snes->vec_func_init_set = PETSC_FALSE;
1582   snes->reason            = SNES_CONVERGED_ITERATING;
1583   snes->pcside            = PC_RIGHT;
1584 
1585   snes->mf          = PETSC_FALSE;
1586   snes->mf_operator = PETSC_FALSE;
1587   snes->mf_version  = 1;
1588 
1589   snes->numLinearSolveFailures = 0;
1590   snes->maxLinearSolveFailures = 1;
1591 
1592   snes->vizerotolerance = 1.e-8;
1593 
1594   /* Set this to true if the implementation of SNESSolve_XXX does compute the residual at the final solution. */
1595   snes->alwayscomputesfinalresidual = PETSC_FALSE;
1596 
1597   /* Create context to compute Eisenstat-Walker relative tolerance for KSP */
1598   ierr = PetscNewLog(snes,&kctx);CHKERRQ(ierr);
1599 
1600   snes->kspconvctx  = (void*)kctx;
1601   kctx->version     = 2;
1602   kctx->rtol_0      = .3; /* Eisenstat and Walker suggest rtol_0=.5, but
1603                              this was too large for some test cases */
1604   kctx->rtol_last   = 0.0;
1605   kctx->rtol_max    = .9;
1606   kctx->gamma       = 1.0;
1607   kctx->alpha       = .5*(1.0 + PetscSqrtReal(5.0));
1608   kctx->alpha2      = kctx->alpha;
1609   kctx->threshold   = .1;
1610   kctx->lresid_last = 0.0;
1611   kctx->norm_last   = 0.0;
1612 
1613   *outsnes = snes;
1614   PetscFunctionReturn(0);
1615 }
1616 
1617 /*MC
1618     SNESFunction - Functional form used to convey the nonlinear function to be solved by SNES
1619 
1620      Synopsis:
1621      #include "petscsnes.h"
1622      PetscErrorCode SNESFunction(SNES snes,Vec x,Vec f,void *ctx);
1623 
1624      Input Parameters:
1625 +     snes - the SNES context
1626 .     x    - state at which to evaluate residual
1627 -     ctx     - optional user-defined function context, passed in with SNESSetFunction()
1628 
1629      Output Parameter:
1630 .     f  - vector to put residual (function value)
1631 
1632    Level: intermediate
1633 
1634 .seealso:   SNESSetFunction(), SNESGetFunction()
1635 M*/
1636 
1637 #undef __FUNCT__
1638 #define __FUNCT__ "SNESSetFunction"
1639 /*@C
1640    SNESSetFunction - Sets the function evaluation routine and function
1641    vector for use by the SNES routines in solving systems of nonlinear
1642    equations.
1643 
1644    Logically Collective on SNES
1645 
1646    Input Parameters:
1647 +  snes - the SNES context
1648 .  r - vector to store function value
1649 .  f - function evaluation routine; see SNESFunction for calling sequence details
1650 -  ctx - [optional] user-defined context for private data for the
1651          function evaluation routine (may be NULL)
1652 
1653    Notes:
1654    The Newton-like methods typically solve linear systems of the form
1655 $      f'(x) x = -f(x),
1656    where f'(x) denotes the Jacobian matrix and f(x) is the function.
1657 
1658    Level: beginner
1659 
1660 .keywords: SNES, nonlinear, set, function
1661 
1662 .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetPicard(), SNESFunction
1663 @*/
1664 PetscErrorCode  SNESSetFunction(SNES snes,Vec r,PetscErrorCode (*f)(SNES,Vec,Vec,void*),void *ctx)
1665 {
1666   PetscErrorCode ierr;
1667   DM             dm;
1668 
1669   PetscFunctionBegin;
1670   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1671   if (r) {
1672     PetscValidHeaderSpecific(r,VEC_CLASSID,2);
1673     PetscCheckSameComm(snes,1,r,2);
1674     ierr = PetscObjectReference((PetscObject)r);CHKERRQ(ierr);
1675     ierr = VecDestroy(&snes->vec_func);CHKERRQ(ierr);
1676 
1677     snes->vec_func = r;
1678   }
1679   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
1680   ierr = DMSNESSetFunction(dm,f,ctx);CHKERRQ(ierr);
1681   PetscFunctionReturn(0);
1682 }
1683 
1684 
1685 #undef __FUNCT__
1686 #define __FUNCT__ "SNESSetInitialFunction"
1687 /*@C
1688    SNESSetInitialFunction - Sets the function vector to be used as the
1689    function norm at the initialization of the method.  In some
1690    instances, the user has precomputed the function before calling
1691    SNESSolve.  This function allows one to avoid a redundant call
1692    to SNESComputeFunction in that case.
1693 
1694    Logically Collective on SNES
1695 
1696    Input Parameters:
1697 +  snes - the SNES context
1698 -  f - vector to store function value
1699 
1700    Notes:
1701    This should not be modified during the solution procedure.
1702 
1703    This is used extensively in the SNESFAS hierarchy and in nonlinear preconditioning.
1704 
1705    Level: developer
1706 
1707 .keywords: SNES, nonlinear, set, function
1708 
1709 .seealso: SNESSetFunction(), SNESComputeFunction(), SNESSetInitialFunctionNorm()
1710 @*/
1711 PetscErrorCode  SNESSetInitialFunction(SNES snes, Vec f)
1712 {
1713   PetscErrorCode ierr;
1714   Vec            vec_func;
1715 
1716   PetscFunctionBegin;
1717   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1718   PetscValidHeaderSpecific(f,VEC_CLASSID,2);
1719   PetscCheckSameComm(snes,1,f,2);
1720   if (snes->pcside == PC_LEFT && snes->functype == SNES_FUNCTION_PRECONDITIONED) {
1721     snes->vec_func_init_set = PETSC_FALSE;
1722     PetscFunctionReturn(0);
1723   }
1724   ierr = SNESGetFunction(snes,&vec_func,NULL,NULL);CHKERRQ(ierr);
1725   ierr = VecCopy(f, vec_func);CHKERRQ(ierr);
1726 
1727   snes->vec_func_init_set = PETSC_TRUE;
1728   PetscFunctionReturn(0);
1729 }
1730 
1731 #undef __FUNCT__
1732 #define __FUNCT__ "SNESSetNormSchedule"
1733 /*@
1734    SNESSetNormSchedule - Sets the SNESNormSchedule used in covergence and monitoring
1735    of the SNES method.
1736 
1737    Logically Collective on SNES
1738 
1739    Input Parameters:
1740 +  snes - the SNES context
1741 -  normschedule - the frequency of norm computation
1742 
1743    Options Database Key:
1744 .  -snes_norm_schedule <none, always, initialonly, finalonly, initalfinalonly>
1745 
1746    Notes:
1747    Only certain SNES methods support certain SNESNormSchedules.  Most require evaluation
1748    of the nonlinear function and the taking of its norm at every iteration to
1749    even ensure convergence at all.  However, methods such as custom Gauss-Seidel methods
1750    (SNESNGS) and the like do not require the norm of the function to be computed, and therfore
1751    may either be monitored for convergence or not.  As these are often used as nonlinear
1752    preconditioners, monitoring the norm of their error is not a useful enterprise within
1753    their solution.
1754 
1755    Level: developer
1756 
1757 .keywords: SNES, nonlinear, set, function, norm, type
1758 
1759 .seealso: SNESGetNormSchedule(), SNESComputeFunction(), VecNorm(), SNESSetFunction(), SNESSetInitialFunction(), SNESNormSchedule
1760 @*/
1761 PetscErrorCode  SNESSetNormSchedule(SNES snes, SNESNormSchedule normschedule)
1762 {
1763   PetscFunctionBegin;
1764   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1765   snes->normschedule = normschedule;
1766   PetscFunctionReturn(0);
1767 }
1768 
1769 
1770 #undef __FUNCT__
1771 #define __FUNCT__ "SNESGetNormSchedule"
1772 /*@
1773    SNESGetNormSchedule - Gets the SNESNormSchedule used in covergence and monitoring
1774    of the SNES method.
1775 
1776    Logically Collective on SNES
1777 
1778    Input Parameters:
1779 +  snes - the SNES context
1780 -  normschedule - the type of the norm used
1781 
1782    Level: advanced
1783 
1784 .keywords: SNES, nonlinear, set, function, norm, type
1785 
1786 .seealso: SNESSetNormSchedule(), SNESComputeFunction(), VecNorm(), SNESSetFunction(), SNESSetInitialFunction(), SNESNormSchedule
1787 @*/
1788 PetscErrorCode  SNESGetNormSchedule(SNES snes, SNESNormSchedule *normschedule)
1789 {
1790   PetscFunctionBegin;
1791   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1792   *normschedule = snes->normschedule;
1793   PetscFunctionReturn(0);
1794 }
1795 
1796 
1797 #undef __FUNCT__
1798 #define __FUNCT__ "SNESSetFunctionNorm"
1799 /*@
1800   SNESSetFunctionNorm - Sets the last computed residual norm.
1801 
1802   Logically Collective on SNES
1803 
1804   Input Parameters:
1805 + snes - the SNES context
1806 
1807 - normschedule - the frequency of norm computation
1808 
1809   Level: developer
1810 
1811 .keywords: SNES, nonlinear, set, function, norm, type
1812 .seealso: SNESGetNormSchedule(), SNESComputeFunction(), VecNorm(), SNESSetFunction(), SNESSetInitialFunction(), SNESNormSchedule
1813 @*/
1814 PetscErrorCode SNESSetFunctionNorm(SNES snes, PetscReal norm)
1815 {
1816   PetscFunctionBegin;
1817   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1818   snes->norm = norm;
1819   PetscFunctionReturn(0);
1820 }
1821 
1822 #undef __FUNCT__
1823 #define __FUNCT__ "SNESGetFunctionNorm"
1824 /*@
1825   SNESGetFunctionNorm - Gets the last computed norm of the residual
1826 
1827   Not Collective
1828 
1829   Input Parameter:
1830 . snes - the SNES context
1831 
1832   Output Parameter:
1833 . norm - the last computed residual norm
1834 
1835   Level: developer
1836 
1837 .keywords: SNES, nonlinear, set, function, norm, type
1838 .seealso: SNESSetNormSchedule(), SNESComputeFunction(), VecNorm(), SNESSetFunction(), SNESSetInitialFunction(), SNESNormSchedule
1839 @*/
1840 PetscErrorCode SNESGetFunctionNorm(SNES snes, PetscReal *norm)
1841 {
1842   PetscFunctionBegin;
1843   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1844   PetscValidPointer(norm, 2);
1845   *norm = snes->norm;
1846   PetscFunctionReturn(0);
1847 }
1848 
1849 #undef __FUNCT__
1850 #define __FUNCT__ "SNESSetFunctionType"
1851 /*@C
1852    SNESSetFunctionType - Sets the SNESNormSchedule used in covergence and monitoring
1853    of the SNES method.
1854 
1855    Logically Collective on SNES
1856 
1857    Input Parameters:
1858 +  snes - the SNES context
1859 -  normschedule - the frequency of norm computation
1860 
1861    Notes:
1862    Only certain SNES methods support certain SNESNormSchedules.  Most require evaluation
1863    of the nonlinear function and the taking of its norm at every iteration to
1864    even ensure convergence at all.  However, methods such as custom Gauss-Seidel methods
1865    (SNESNGS) and the like do not require the norm of the function to be computed, and therfore
1866    may either be monitored for convergence or not.  As these are often used as nonlinear
1867    preconditioners, monitoring the norm of their error is not a useful enterprise within
1868    their solution.
1869 
1870    Level: developer
1871 
1872 .keywords: SNES, nonlinear, set, function, norm, type
1873 
1874 .seealso: SNESGetNormSchedule(), SNESComputeFunction(), VecNorm(), SNESSetFunction(), SNESSetInitialFunction(), SNESNormSchedule
1875 @*/
1876 PetscErrorCode  SNESSetFunctionType(SNES snes, SNESFunctionType type)
1877 {
1878   PetscFunctionBegin;
1879   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1880   snes->functype = type;
1881   PetscFunctionReturn(0);
1882 }
1883 
1884 
1885 #undef __FUNCT__
1886 #define __FUNCT__ "SNESGetFunctionType"
1887 /*@C
1888    SNESGetFunctionType - Gets the SNESNormSchedule used in covergence and monitoring
1889    of the SNES method.
1890 
1891    Logically Collective on SNES
1892 
1893    Input Parameters:
1894 +  snes - the SNES context
1895 -  normschedule - the type of the norm used
1896 
1897    Level: advanced
1898 
1899 .keywords: SNES, nonlinear, set, function, norm, type
1900 
1901 .seealso: SNESSetNormSchedule(), SNESComputeFunction(), VecNorm(), SNESSetFunction(), SNESSetInitialFunction(), SNESNormSchedule
1902 @*/
1903 PetscErrorCode  SNESGetFunctionType(SNES snes, SNESFunctionType *type)
1904 {
1905   PetscFunctionBegin;
1906   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1907   *type = snes->functype;
1908   PetscFunctionReturn(0);
1909 }
1910 
1911 /*MC
1912     SNESNGSFunction - function used to convey a Gauss-Seidel sweep on the nonlinear function
1913 
1914      Synopsis:
1915      #include <petscsnes.h>
1916 $    SNESNGSFunction(SNES snes,Vec x,Vec b,void *ctx);
1917 
1918 +  X   - solution vector
1919 .  B   - RHS vector
1920 -  ctx - optional user-defined Gauss-Seidel context
1921 
1922    Level: intermediate
1923 
1924 .seealso:   SNESSetNGS(), SNESGetNGS()
1925 M*/
1926 
1927 #undef __FUNCT__
1928 #define __FUNCT__ "SNESSetNGS"
1929 /*@C
1930    SNESSetNGS - Sets the user nonlinear Gauss-Seidel routine for
1931    use with composed nonlinear solvers.
1932 
1933    Input Parameters:
1934 +  snes   - the SNES context
1935 .  f - function evaluation routine to apply Gauss-Seidel see SNESNGSFunction
1936 -  ctx    - [optional] user-defined context for private data for the
1937             smoother evaluation routine (may be NULL)
1938 
1939    Notes:
1940    The NGS routines are used by the composed nonlinear solver to generate
1941     a problem appropriate update to the solution, particularly FAS.
1942 
1943    Level: intermediate
1944 
1945 .keywords: SNES, nonlinear, set, Gauss-Seidel
1946 
1947 .seealso: SNESGetFunction(), SNESComputeNGS()
1948 @*/
1949 PetscErrorCode SNESSetNGS(SNES snes,PetscErrorCode (*f)(SNES,Vec,Vec,void*),void *ctx)
1950 {
1951   PetscErrorCode ierr;
1952   DM             dm;
1953 
1954   PetscFunctionBegin;
1955   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1956   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
1957   ierr = DMSNESSetNGS(dm,f,ctx);CHKERRQ(ierr);
1958   PetscFunctionReturn(0);
1959 }
1960 
1961 #undef __FUNCT__
1962 #define __FUNCT__ "SNESPicardComputeFunction"
1963 PETSC_EXTERN PetscErrorCode SNESPicardComputeFunction(SNES snes,Vec x,Vec f,void *ctx)
1964 {
1965   PetscErrorCode ierr;
1966   DM             dm;
1967   DMSNES         sdm;
1968 
1969   PetscFunctionBegin;
1970   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
1971   ierr = DMGetDMSNES(dm,&sdm);CHKERRQ(ierr);
1972   /*  A(x)*x - b(x) */
1973   if (sdm->ops->computepfunction) {
1974     ierr = (*sdm->ops->computepfunction)(snes,x,f,sdm->pctx);CHKERRQ(ierr);
1975   } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE, "Must call SNESSetPicard() to provide Picard function.");
1976 
1977   if (sdm->ops->computepjacobian) {
1978     ierr = (*sdm->ops->computepjacobian)(snes,x,snes->jacobian,snes->jacobian_pre,sdm->pctx);CHKERRQ(ierr);
1979   } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE, "Must call SNESSetPicard() to provide Picard matrix.");
1980   ierr = VecScale(f,-1.0);CHKERRQ(ierr);
1981   ierr = MatMultAdd(snes->jacobian,x,f,f);CHKERRQ(ierr);
1982   PetscFunctionReturn(0);
1983 }
1984 
1985 #undef __FUNCT__
1986 #define __FUNCT__ "SNESPicardComputeJacobian"
1987 PETSC_EXTERN PetscErrorCode SNESPicardComputeJacobian(SNES snes,Vec x1,Mat J,Mat B,void *ctx)
1988 {
1989   PetscFunctionBegin;
1990   /* the jacobian matrix should be pre-filled in SNESPicardComputeFunction */
1991   PetscFunctionReturn(0);
1992 }
1993 
1994 #undef __FUNCT__
1995 #define __FUNCT__ "SNESSetPicard"
1996 /*@C
1997    SNESSetPicard - Use SNES to solve the semilinear-system A(x) x = b(x) via a Picard type iteration (Picard linearization)
1998 
1999    Logically Collective on SNES
2000 
2001    Input Parameters:
2002 +  snes - the SNES context
2003 .  r - vector to store function value
2004 .  b - function evaluation routine
2005 .  Amat - matrix with which A(x) x - b(x) is to be computed
2006 .  Pmat - matrix from which preconditioner is computed (usually the same as Amat)
2007 .  J  - function to compute matrix value, see SNESJacobianFunction for details on its calling sequence
2008 -  ctx - [optional] user-defined context for private data for the
2009          function evaluation routine (may be NULL)
2010 
2011    Notes:
2012     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
2013     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.
2014 
2015     One can call SNESSetPicard() or SNESSetFunction() (and possibly SNESSetJacobian()) but cannot call both
2016 
2017 $     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}
2018 $     Note that when an exact solver is used this corresponds to the "classic" Picard A(x^{n}) x^{n+1} = b(x^{n}) iteration.
2019 
2020      Run with -snes_mf_operator to solve the system with Newton's method using A(x^{n}) to construct the preconditioner.
2021 
2022    We implement the defect correction form of the Picard iteration because it converges much more generally when inexact linear solvers are used then
2023    the direct Picard iteration A(x^n) x^{n+1} = b(x^n)
2024 
2025    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
2026    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
2027    different please contact us at petsc-dev@mcs.anl.gov and we'll have an entirely new argument :-).
2028 
2029    Level: intermediate
2030 
2031 .keywords: SNES, nonlinear, set, function
2032 
2033 .seealso: SNESGetFunction(), SNESSetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESGetPicard(), SNESLineSearchPreCheckPicard(), SNESJacobianFunction
2034 @*/
2035 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)
2036 {
2037   PetscErrorCode ierr;
2038   DM             dm;
2039 
2040   PetscFunctionBegin;
2041   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2042   ierr = SNESGetDM(snes, &dm);CHKERRQ(ierr);
2043   ierr = DMSNESSetPicard(dm,b,J,ctx);CHKERRQ(ierr);
2044   ierr = SNESSetFunction(snes,r,SNESPicardComputeFunction,ctx);CHKERRQ(ierr);
2045   ierr = SNESSetJacobian(snes,Amat,Pmat,SNESPicardComputeJacobian,ctx);CHKERRQ(ierr);
2046   PetscFunctionReturn(0);
2047 }
2048 
2049 #undef __FUNCT__
2050 #define __FUNCT__ "SNESGetPicard"
2051 /*@C
2052    SNESGetPicard - Returns the context for the Picard iteration
2053 
2054    Not Collective, but Vec is parallel if SNES is parallel. Collective if Vec is requested, but has not been created yet.
2055 
2056    Input Parameter:
2057 .  snes - the SNES context
2058 
2059    Output Parameter:
2060 +  r - the function (or NULL)
2061 .  f - the function (or NULL); see SNESFunction for calling sequence details
2062 .  Amat - the matrix used to defined the operation A(x) x - b(x) (or NULL)
2063 .  Pmat  - the matrix from which the preconditioner will be constructed (or NULL)
2064 .  J - the function for matrix evaluation (or NULL); see SNESJacobianFunction for calling sequence details
2065 -  ctx - the function context (or NULL)
2066 
2067    Level: advanced
2068 
2069 .keywords: SNES, nonlinear, get, function
2070 
2071 .seealso: SNESSetPicard(), SNESGetFunction(), SNESGetJacobian(), SNESGetDM(), SNESFunction, SNESJacobianFunction
2072 @*/
2073 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)
2074 {
2075   PetscErrorCode ierr;
2076   DM             dm;
2077 
2078   PetscFunctionBegin;
2079   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2080   ierr = SNESGetFunction(snes,r,NULL,NULL);CHKERRQ(ierr);
2081   ierr = SNESGetJacobian(snes,Amat,Pmat,NULL,NULL);CHKERRQ(ierr);
2082   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
2083   ierr = DMSNESGetPicard(dm,f,J,ctx);CHKERRQ(ierr);
2084   PetscFunctionReturn(0);
2085 }
2086 
2087 #undef __FUNCT__
2088 #define __FUNCT__ "SNESSetComputeInitialGuess"
2089 /*@C
2090    SNESSetComputeInitialGuess - Sets a routine used to compute an initial guess for the problem
2091 
2092    Logically Collective on SNES
2093 
2094    Input Parameters:
2095 +  snes - the SNES context
2096 .  func - function evaluation routine
2097 -  ctx - [optional] user-defined context for private data for the
2098          function evaluation routine (may be NULL)
2099 
2100    Calling sequence of func:
2101 $    func (SNES snes,Vec x,void *ctx);
2102 
2103 .  f - function vector
2104 -  ctx - optional user-defined function context
2105 
2106    Level: intermediate
2107 
2108 .keywords: SNES, nonlinear, set, function
2109 
2110 .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian()
2111 @*/
2112 PetscErrorCode  SNESSetComputeInitialGuess(SNES snes,PetscErrorCode (*func)(SNES,Vec,void*),void *ctx)
2113 {
2114   PetscFunctionBegin;
2115   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2116   if (func) snes->ops->computeinitialguess = func;
2117   if (ctx)  snes->initialguessP            = ctx;
2118   PetscFunctionReturn(0);
2119 }
2120 
2121 /* --------------------------------------------------------------- */
2122 #undef __FUNCT__
2123 #define __FUNCT__ "SNESGetRhs"
2124 /*@C
2125    SNESGetRhs - Gets the vector for solving F(x) = rhs. If rhs is not set
2126    it assumes a zero right hand side.
2127 
2128    Logically Collective on SNES
2129 
2130    Input Parameter:
2131 .  snes - the SNES context
2132 
2133    Output Parameter:
2134 .  rhs - the right hand side vector or NULL if the right hand side vector is null
2135 
2136    Level: intermediate
2137 
2138 .keywords: SNES, nonlinear, get, function, right hand side
2139 
2140 .seealso: SNESGetSolution(), SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction()
2141 @*/
2142 PetscErrorCode  SNESGetRhs(SNES snes,Vec *rhs)
2143 {
2144   PetscFunctionBegin;
2145   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2146   PetscValidPointer(rhs,2);
2147   *rhs = snes->vec_rhs;
2148   PetscFunctionReturn(0);
2149 }
2150 
2151 #undef __FUNCT__
2152 #define __FUNCT__ "SNESComputeFunction"
2153 /*@
2154    SNESComputeFunction - Calls the function that has been set with SNESSetFunction().
2155 
2156    Collective on SNES
2157 
2158    Input Parameters:
2159 +  snes - the SNES context
2160 -  x - input vector
2161 
2162    Output Parameter:
2163 .  y - function vector, as set by SNESSetFunction()
2164 
2165    Notes:
2166    SNESComputeFunction() is typically used within nonlinear solvers
2167    implementations, so most users would not generally call this routine
2168    themselves.
2169 
2170    Level: developer
2171 
2172 .keywords: SNES, nonlinear, compute, function
2173 
2174 .seealso: SNESSetFunction(), SNESGetFunction()
2175 @*/
2176 PetscErrorCode  SNESComputeFunction(SNES snes,Vec x,Vec y)
2177 {
2178   PetscErrorCode ierr;
2179   DM             dm;
2180   DMSNES         sdm;
2181 
2182   PetscFunctionBegin;
2183   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2184   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
2185   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
2186   PetscCheckSameComm(snes,1,x,2);
2187   PetscCheckSameComm(snes,1,y,3);
2188   ierr = VecValidValues(x,2,PETSC_TRUE);CHKERRQ(ierr);
2189 
2190   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
2191   ierr = DMGetDMSNES(dm,&sdm);CHKERRQ(ierr);
2192   if (sdm->ops->computefunction) {
2193     if (sdm->ops->computefunction != SNESObjectiveComputeFunctionDefaultFD) {
2194       ierr = PetscLogEventBegin(SNES_FunctionEval,snes,x,y,0);CHKERRQ(ierr);
2195     }
2196     ierr = VecLockPush(x);CHKERRQ(ierr);
2197     PetscStackPush("SNES user function");
2198     ierr = (*sdm->ops->computefunction)(snes,x,y,sdm->functionctx);CHKERRQ(ierr);
2199     PetscStackPop;
2200     ierr = VecLockPop(x);CHKERRQ(ierr);
2201     if (sdm->ops->computefunction != SNESObjectiveComputeFunctionDefaultFD) {
2202       ierr = PetscLogEventEnd(SNES_FunctionEval,snes,x,y,0);CHKERRQ(ierr);
2203     }
2204   } else if (snes->vec_rhs) {
2205     ierr = MatMult(snes->jacobian, x, y);CHKERRQ(ierr);
2206   } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE, "Must call SNESSetFunction() or SNESSetDM() before SNESComputeFunction(), likely called from SNESSolve().");
2207   if (snes->vec_rhs) {
2208     ierr = VecAXPY(y,-1.0,snes->vec_rhs);CHKERRQ(ierr);
2209   }
2210   snes->nfuncs++;
2211   /*
2212      domainerror might not be set on all processes; so we tag vector locally with Inf and the next inner product or norm will
2213      propagate the value to all processes
2214   */
2215   if (snes->domainerror) {
2216     ierr = VecSetInf(y);CHKERRQ(ierr);
2217   }
2218   PetscFunctionReturn(0);
2219 }
2220 
2221 #undef __FUNCT__
2222 #define __FUNCT__ "SNESComputeNGS"
2223 /*@
2224    SNESComputeNGS - Calls the Gauss-Seidel function that has been set with  SNESSetNGS().
2225 
2226    Collective on SNES
2227 
2228    Input Parameters:
2229 +  snes - the SNES context
2230 .  x - input vector
2231 -  b - rhs vector
2232 
2233    Output Parameter:
2234 .  x - new solution vector
2235 
2236    Notes:
2237    SNESComputeNGS() is typically used within composed nonlinear solver
2238    implementations, so most users would not generally call this routine
2239    themselves.
2240 
2241    Level: developer
2242 
2243 .keywords: SNES, nonlinear, compute, function
2244 
2245 .seealso: SNESSetNGS(), SNESComputeFunction()
2246 @*/
2247 PetscErrorCode  SNESComputeNGS(SNES snes,Vec b,Vec x)
2248 {
2249   PetscErrorCode ierr;
2250   DM             dm;
2251   DMSNES         sdm;
2252 
2253   PetscFunctionBegin;
2254   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2255   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
2256   if (b) PetscValidHeaderSpecific(b,VEC_CLASSID,3);
2257   PetscCheckSameComm(snes,1,x,2);
2258   if (b) PetscCheckSameComm(snes,1,b,3);
2259   if (b) {ierr = VecValidValues(b,2,PETSC_TRUE);CHKERRQ(ierr);}
2260   ierr = PetscLogEventBegin(SNES_NGSEval,snes,x,b,0);CHKERRQ(ierr);
2261   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
2262   ierr = DMGetDMSNES(dm,&sdm);CHKERRQ(ierr);
2263   if (sdm->ops->computegs) {
2264     if (b) {ierr = VecLockPush(b);CHKERRQ(ierr);}
2265     PetscStackPush("SNES user NGS");
2266     ierr = (*sdm->ops->computegs)(snes,x,b,sdm->gsctx);CHKERRQ(ierr);
2267     PetscStackPop;
2268     if (b) {ierr = VecLockPop(b);CHKERRQ(ierr);}
2269   } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE, "Must call SNESSetNGS() before SNESComputeNGS(), likely called from SNESSolve().");
2270   ierr = PetscLogEventEnd(SNES_NGSEval,snes,x,b,0);CHKERRQ(ierr);
2271   PetscFunctionReturn(0);
2272 }
2273 
2274 #undef __FUNCT__
2275 #define __FUNCT__ "SNESComputeJacobian"
2276 /*@
2277    SNESComputeJacobian - Computes the Jacobian matrix that has been set with SNESSetJacobian().
2278 
2279    Collective on SNES and Mat
2280 
2281    Input Parameters:
2282 +  snes - the SNES context
2283 -  x - input vector
2284 
2285    Output Parameters:
2286 +  A - Jacobian matrix
2287 -  B - optional preconditioning matrix
2288 
2289   Options Database Keys:
2290 +    -snes_lag_preconditioner <lag>
2291 .    -snes_lag_jacobian <lag>
2292 .    -snes_compare_explicit - Compare the computed Jacobian to the finite difference Jacobian and output the differences
2293 .    -snes_compare_explicit_draw  - Compare the computed Jacobian to the finite difference Jacobian and draw the result
2294 .    -snes_compare_explicit_contour  - Compare the computed Jacobian to the finite difference Jacobian and draw a contour plot with the result
2295 .    -snes_compare_operator  - Make the comparison options above use the operator instead of the preconditioning matrix
2296 .    -snes_compare_coloring - Compute the finite difference Jacobian using coloring and display norms of difference
2297 .    -snes_compare_coloring_display - Compute the finite differece Jacobian using coloring and display verbose differences
2298 .    -snes_compare_coloring_threshold - Display only those matrix entries that differ by more than a given threshold
2299 .    -snes_compare_coloring_threshold_atol - Absolute tolerance for difference in matrix entries to be displayed by -snes_compare_coloring_threshold
2300 .    -snes_compare_coloring_threshold_rtol - Relative tolerance for difference in matrix entries to be displayed by -snes_compare_coloring_threshold
2301 .    -snes_compare_coloring_draw - Compute the finite differece Jacobian using coloring and draw differences
2302 -    -snes_compare_coloring_draw_contour - Compute the finite differece Jacobian using coloring and show contours of matrices and differences
2303 
2304 
2305    Notes:
2306    Most users should not need to explicitly call this routine, as it
2307    is used internally within the nonlinear solvers.
2308 
2309    Level: developer
2310 
2311 .keywords: SNES, compute, Jacobian, matrix
2312 
2313 .seealso:  SNESSetJacobian(), KSPSetOperators(), MatStructure, SNESSetLagPreconditioner(), SNESSetLagJacobian()
2314 @*/
2315 PetscErrorCode  SNESComputeJacobian(SNES snes,Vec X,Mat A,Mat B)
2316 {
2317   PetscErrorCode ierr;
2318   PetscBool      flag;
2319   DM             dm;
2320   DMSNES         sdm;
2321   KSP            ksp;
2322 
2323   PetscFunctionBegin;
2324   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2325   PetscValidHeaderSpecific(X,VEC_CLASSID,2);
2326   PetscCheckSameComm(snes,1,X,2);
2327   ierr = VecValidValues(X,2,PETSC_TRUE);CHKERRQ(ierr);
2328   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
2329   ierr = DMGetDMSNES(dm,&sdm);CHKERRQ(ierr);
2330 
2331   if (!sdm->ops->computejacobian) SETERRQ(PetscObjectComm((PetscObject)snes),PETSC_ERR_USER,"Must call SNESSetJacobian(), DMSNESSetJacobian(), DMDASNESSetJacobianLocal(), etc");
2332 
2333   /* make sure that MatAssemblyBegin/End() is called on A matrix if it is matrix free */
2334 
2335   if (snes->lagjacobian == -2) {
2336     snes->lagjacobian = -1;
2337 
2338     ierr = PetscInfo(snes,"Recomputing Jacobian/preconditioner because lag is -2 (means compute Jacobian, but then never again) \n");CHKERRQ(ierr);
2339   } else if (snes->lagjacobian == -1) {
2340     ierr = PetscInfo(snes,"Reusing Jacobian/preconditioner because lag is -1\n");CHKERRQ(ierr);
2341     ierr = PetscObjectTypeCompare((PetscObject)A,MATMFFD,&flag);CHKERRQ(ierr);
2342     if (flag) {
2343       ierr = MatAssemblyBegin(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
2344       ierr = MatAssemblyEnd(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
2345     }
2346     PetscFunctionReturn(0);
2347   } else if (snes->lagjacobian > 1 && (snes->iter + snes->jac_iter) % snes->lagjacobian) {
2348     ierr = PetscInfo2(snes,"Reusing Jacobian/preconditioner because lag is %D and SNES iteration is %D\n",snes->lagjacobian,snes->iter);CHKERRQ(ierr);
2349     ierr = PetscObjectTypeCompare((PetscObject)A,MATMFFD,&flag);CHKERRQ(ierr);
2350     if (flag) {
2351       ierr = MatAssemblyBegin(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
2352       ierr = MatAssemblyEnd(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
2353     }
2354     PetscFunctionReturn(0);
2355   }
2356   if (snes->pc && snes->pcside == PC_LEFT) {
2357       ierr = MatAssemblyBegin(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
2358       ierr = MatAssemblyEnd(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
2359       PetscFunctionReturn(0);
2360   }
2361 
2362   ierr = PetscLogEventBegin(SNES_JacobianEval,snes,X,A,B);CHKERRQ(ierr);
2363   ierr = VecLockPush(X);CHKERRQ(ierr);
2364   PetscStackPush("SNES user Jacobian function");
2365   ierr = (*sdm->ops->computejacobian)(snes,X,A,B,sdm->jacobianctx);CHKERRQ(ierr);
2366   PetscStackPop;
2367   ierr = VecLockPop(X);CHKERRQ(ierr);
2368   ierr = PetscLogEventEnd(SNES_JacobianEval,snes,X,A,B);CHKERRQ(ierr);
2369 
2370   /* the next line ensures that snes->ksp exists */
2371   ierr = SNESGetKSP(snes,&ksp);CHKERRQ(ierr);
2372   if (snes->lagpreconditioner == -2) {
2373     ierr = PetscInfo(snes,"Rebuilding preconditioner exactly once since lag is -2\n");CHKERRQ(ierr);
2374     ierr = KSPSetReusePreconditioner(snes->ksp,PETSC_FALSE);CHKERRQ(ierr);
2375     snes->lagpreconditioner = -1;
2376   } else if (snes->lagpreconditioner == -1) {
2377     ierr = PetscInfo(snes,"Reusing preconditioner because lag is -1\n");CHKERRQ(ierr);
2378     ierr = KSPSetReusePreconditioner(snes->ksp,PETSC_TRUE);CHKERRQ(ierr);
2379   } else if (snes->lagpreconditioner > 1 && (snes->iter + snes->pre_iter) % snes->lagpreconditioner) {
2380     ierr = PetscInfo2(snes,"Reusing preconditioner because lag is %D and SNES iteration is %D\n",snes->lagpreconditioner,snes->iter);CHKERRQ(ierr);
2381     ierr = KSPSetReusePreconditioner(snes->ksp,PETSC_TRUE);CHKERRQ(ierr);
2382   } else {
2383     ierr = PetscInfo(snes,"Rebuilding preconditioner\n");CHKERRQ(ierr);
2384     ierr = KSPSetReusePreconditioner(snes->ksp,PETSC_FALSE);CHKERRQ(ierr);
2385   }
2386 
2387   /* make sure user returned a correct Jacobian and preconditioner */
2388   /* PetscValidHeaderSpecific(A,MAT_CLASSID,3);
2389     PetscValidHeaderSpecific(B,MAT_CLASSID,4);   */
2390   {
2391     PetscBool flag = PETSC_FALSE,flag_draw = PETSC_FALSE,flag_contour = PETSC_FALSE,flag_operator = PETSC_FALSE;
2392     ierr = PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes),((PetscObject)snes)->prefix,"-snes_compare_explicit",NULL,NULL,&flag);CHKERRQ(ierr);
2393     ierr = PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes),((PetscObject)snes)->prefix,"-snes_compare_explicit_draw",NULL,NULL,&flag_draw);CHKERRQ(ierr);
2394     ierr = PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes),((PetscObject)snes)->prefix,"-snes_compare_explicit_draw_contour",NULL,NULL,&flag_contour);CHKERRQ(ierr);
2395     ierr = PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes),((PetscObject)snes)->prefix,"-snes_compare_operator",NULL,NULL,&flag_operator);CHKERRQ(ierr);
2396     if (flag || flag_draw || flag_contour) {
2397       Mat          Bexp_mine = NULL,Bexp,FDexp;
2398       PetscViewer  vdraw,vstdout;
2399       PetscBool    flg;
2400       if (flag_operator) {
2401         ierr = MatComputeExplicitOperator(A,&Bexp_mine);CHKERRQ(ierr);
2402         Bexp = Bexp_mine;
2403       } else {
2404         /* See if the preconditioning matrix can be viewed and added directly */
2405         ierr = PetscObjectTypeCompareAny((PetscObject)B,&flg,MATSEQAIJ,MATMPIAIJ,MATSEQDENSE,MATMPIDENSE,MATSEQBAIJ,MATMPIBAIJ,MATSEQSBAIJ,MATMPIBAIJ,"");CHKERRQ(ierr);
2406         if (flg) Bexp = B;
2407         else {
2408           /* If the "preconditioning" matrix is itself MATSHELL or some other type without direct support */
2409           ierr = MatComputeExplicitOperator(B,&Bexp_mine);CHKERRQ(ierr);
2410           Bexp = Bexp_mine;
2411         }
2412       }
2413       ierr = MatConvert(Bexp,MATSAME,MAT_INITIAL_MATRIX,&FDexp);CHKERRQ(ierr);
2414       ierr = SNESComputeJacobianDefault(snes,X,FDexp,FDexp,NULL);CHKERRQ(ierr);
2415       ierr = PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)snes),&vstdout);CHKERRQ(ierr);
2416       if (flag_draw || flag_contour) {
2417         ierr = PetscViewerDrawOpen(PetscObjectComm((PetscObject)snes),0,"Explicit Jacobians",PETSC_DECIDE,PETSC_DECIDE,300,300,&vdraw);CHKERRQ(ierr);
2418         if (flag_contour) {ierr = PetscViewerPushFormat(vdraw,PETSC_VIEWER_DRAW_CONTOUR);CHKERRQ(ierr);}
2419       } else vdraw = NULL;
2420       ierr = PetscViewerASCIIPrintf(vstdout,"Explicit %s\n",flag_operator ? "Jacobian" : "preconditioning Jacobian");CHKERRQ(ierr);
2421       if (flag) {ierr = MatView(Bexp,vstdout);CHKERRQ(ierr);}
2422       if (vdraw) {ierr = MatView(Bexp,vdraw);CHKERRQ(ierr);}
2423       ierr = PetscViewerASCIIPrintf(vstdout,"Finite difference Jacobian\n");CHKERRQ(ierr);
2424       if (flag) {ierr = MatView(FDexp,vstdout);CHKERRQ(ierr);}
2425       if (vdraw) {ierr = MatView(FDexp,vdraw);CHKERRQ(ierr);}
2426       ierr = MatAYPX(FDexp,-1.0,Bexp,SAME_NONZERO_PATTERN);CHKERRQ(ierr);
2427       ierr = PetscViewerASCIIPrintf(vstdout,"User-provided matrix minus finite difference Jacobian\n");CHKERRQ(ierr);
2428       if (flag) {ierr = MatView(FDexp,vstdout);CHKERRQ(ierr);}
2429       if (vdraw) {              /* Always use contour for the difference */
2430         ierr = PetscViewerPushFormat(vdraw,PETSC_VIEWER_DRAW_CONTOUR);CHKERRQ(ierr);
2431         ierr = MatView(FDexp,vdraw);CHKERRQ(ierr);
2432         ierr = PetscViewerPopFormat(vdraw);CHKERRQ(ierr);
2433       }
2434       if (flag_contour) {ierr = PetscViewerPopFormat(vdraw);CHKERRQ(ierr);}
2435       ierr = PetscViewerDestroy(&vdraw);CHKERRQ(ierr);
2436       ierr = MatDestroy(&Bexp_mine);CHKERRQ(ierr);
2437       ierr = MatDestroy(&FDexp);CHKERRQ(ierr);
2438     }
2439   }
2440   {
2441     PetscBool flag = PETSC_FALSE,flag_display = PETSC_FALSE,flag_draw = PETSC_FALSE,flag_contour = PETSC_FALSE,flag_threshold = PETSC_FALSE;
2442     PetscReal threshold_atol = PETSC_SQRT_MACHINE_EPSILON,threshold_rtol = 10*PETSC_SQRT_MACHINE_EPSILON;
2443     ierr = PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes),((PetscObject)snes)->prefix,"-snes_compare_coloring",NULL,NULL,&flag);CHKERRQ(ierr);
2444     ierr = PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes),((PetscObject)snes)->prefix,"-snes_compare_coloring_display",NULL,NULL,&flag_display);CHKERRQ(ierr);
2445     ierr = PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes),((PetscObject)snes)->prefix,"-snes_compare_coloring_draw",NULL,NULL,&flag_draw);CHKERRQ(ierr);
2446     ierr = PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes),((PetscObject)snes)->prefix,"-snes_compare_coloring_draw_contour",NULL,NULL,&flag_contour);CHKERRQ(ierr);
2447     ierr = PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes),((PetscObject)snes)->prefix,"-snes_compare_coloring_threshold",NULL,NULL,&flag_threshold);CHKERRQ(ierr);
2448     if (flag_threshold) {
2449       ierr = PetscOptionsGetReal(((PetscObject)snes)->options,((PetscObject)snes)->prefix,"-snes_compare_coloring_threshold_rtol",&threshold_rtol,NULL);CHKERRQ(ierr);
2450       ierr = PetscOptionsGetReal(((PetscObject)snes)->options,((PetscObject)snes)->prefix,"-snes_compare_coloring_threshold_atol",&threshold_atol,NULL);CHKERRQ(ierr);
2451     }
2452     if (flag || flag_display || flag_draw || flag_contour || flag_threshold) {
2453       Mat            Bfd;
2454       PetscViewer    vdraw,vstdout;
2455       MatColoring    coloring;
2456       ISColoring     iscoloring;
2457       MatFDColoring  matfdcoloring;
2458       PetscErrorCode (*func)(SNES,Vec,Vec,void*);
2459       void           *funcctx;
2460       PetscReal      norm1,norm2,normmax;
2461 
2462       ierr = MatDuplicate(B,MAT_DO_NOT_COPY_VALUES,&Bfd);CHKERRQ(ierr);
2463       ierr = MatColoringCreate(Bfd,&coloring);CHKERRQ(ierr);
2464       ierr = MatColoringSetType(coloring,MATCOLORINGSL);CHKERRQ(ierr);
2465       ierr = MatColoringSetFromOptions(coloring);CHKERRQ(ierr);
2466       ierr = MatColoringApply(coloring,&iscoloring);CHKERRQ(ierr);
2467       ierr = MatColoringDestroy(&coloring);CHKERRQ(ierr);
2468       ierr = MatFDColoringCreate(Bfd,iscoloring,&matfdcoloring);CHKERRQ(ierr);
2469       ierr = MatFDColoringSetFromOptions(matfdcoloring);CHKERRQ(ierr);
2470       ierr = MatFDColoringSetUp(Bfd,iscoloring,matfdcoloring);CHKERRQ(ierr);
2471       ierr = ISColoringDestroy(&iscoloring);CHKERRQ(ierr);
2472 
2473       /* This method of getting the function is currently unreliable since it doesn't work for DM local functions. */
2474       ierr = SNESGetFunction(snes,NULL,&func,&funcctx);CHKERRQ(ierr);
2475       ierr = MatFDColoringSetFunction(matfdcoloring,(PetscErrorCode (*)(void))func,funcctx);CHKERRQ(ierr);
2476       ierr = PetscObjectSetOptionsPrefix((PetscObject)matfdcoloring,((PetscObject)snes)->prefix);CHKERRQ(ierr);
2477       ierr = PetscObjectAppendOptionsPrefix((PetscObject)matfdcoloring,"coloring_");CHKERRQ(ierr);
2478       ierr = MatFDColoringSetFromOptions(matfdcoloring);CHKERRQ(ierr);
2479       ierr = MatFDColoringApply(Bfd,matfdcoloring,X,snes);CHKERRQ(ierr);
2480       ierr = MatFDColoringDestroy(&matfdcoloring);CHKERRQ(ierr);
2481 
2482       ierr = PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)snes),&vstdout);CHKERRQ(ierr);
2483       if (flag_draw || flag_contour) {
2484         ierr = PetscViewerDrawOpen(PetscObjectComm((PetscObject)snes),0,"Colored Jacobians",PETSC_DECIDE,PETSC_DECIDE,300,300,&vdraw);CHKERRQ(ierr);
2485         if (flag_contour) {ierr = PetscViewerPushFormat(vdraw,PETSC_VIEWER_DRAW_CONTOUR);CHKERRQ(ierr);}
2486       } else vdraw = NULL;
2487       ierr = PetscViewerASCIIPrintf(vstdout,"Explicit preconditioning Jacobian\n");CHKERRQ(ierr);
2488       if (flag_display) {ierr = MatView(B,vstdout);CHKERRQ(ierr);}
2489       if (vdraw) {ierr = MatView(B,vdraw);CHKERRQ(ierr);}
2490       ierr = PetscViewerASCIIPrintf(vstdout,"Colored Finite difference Jacobian\n");CHKERRQ(ierr);
2491       if (flag_display) {ierr = MatView(Bfd,vstdout);CHKERRQ(ierr);}
2492       if (vdraw) {ierr = MatView(Bfd,vdraw);CHKERRQ(ierr);}
2493       ierr = MatAYPX(Bfd,-1.0,B,SAME_NONZERO_PATTERN);CHKERRQ(ierr);
2494       ierr = MatNorm(Bfd,NORM_1,&norm1);CHKERRQ(ierr);
2495       ierr = MatNorm(Bfd,NORM_FROBENIUS,&norm2);CHKERRQ(ierr);
2496       ierr = MatNorm(Bfd,NORM_MAX,&normmax);CHKERRQ(ierr);
2497       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);
2498       if (flag_display) {ierr = MatView(Bfd,vstdout);CHKERRQ(ierr);}
2499       if (vdraw) {              /* Always use contour for the difference */
2500         ierr = PetscViewerPushFormat(vdraw,PETSC_VIEWER_DRAW_CONTOUR);CHKERRQ(ierr);
2501         ierr = MatView(Bfd,vdraw);CHKERRQ(ierr);
2502         ierr = PetscViewerPopFormat(vdraw);CHKERRQ(ierr);
2503       }
2504       if (flag_contour) {ierr = PetscViewerPopFormat(vdraw);CHKERRQ(ierr);}
2505 
2506       if (flag_threshold) {
2507         PetscInt bs,rstart,rend,i;
2508         ierr = MatGetBlockSize(B,&bs);CHKERRQ(ierr);
2509         ierr = MatGetOwnershipRange(B,&rstart,&rend);CHKERRQ(ierr);
2510         for (i=rstart; i<rend; i++) {
2511           const PetscScalar *ba,*ca;
2512           const PetscInt    *bj,*cj;
2513           PetscInt          bn,cn,j,maxentrycol = -1,maxdiffcol = -1,maxrdiffcol = -1;
2514           PetscReal         maxentry = 0,maxdiff = 0,maxrdiff = 0;
2515           ierr = MatGetRow(B,i,&bn,&bj,&ba);CHKERRQ(ierr);
2516           ierr = MatGetRow(Bfd,i,&cn,&cj,&ca);CHKERRQ(ierr);
2517           if (bn != cn) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_PLIB,"Unexpected different nonzero pattern in -snes_compare_coloring_threshold");
2518           for (j=0; j<bn; j++) {
2519             PetscReal rdiff = PetscAbsScalar(ca[j]) / (threshold_atol + threshold_rtol*PetscAbsScalar(ba[j]));
2520             if (PetscAbsScalar(ba[j]) > PetscAbs(maxentry)) {
2521               maxentrycol = bj[j];
2522               maxentry    = PetscRealPart(ba[j]);
2523             }
2524             if (PetscAbsScalar(ca[j]) > PetscAbs(maxdiff)) {
2525               maxdiffcol = bj[j];
2526               maxdiff    = PetscRealPart(ca[j]);
2527             }
2528             if (rdiff > maxrdiff) {
2529               maxrdiffcol = bj[j];
2530               maxrdiff    = rdiff;
2531             }
2532           }
2533           if (maxrdiff > 1) {
2534             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);
2535             for (j=0; j<bn; j++) {
2536               PetscReal rdiff;
2537               rdiff = PetscAbsScalar(ca[j]) / (threshold_atol + threshold_rtol*PetscAbsScalar(ba[j]));
2538               if (rdiff > 1) {
2539                 ierr = PetscViewerASCIIPrintf(vstdout," (%D,%g:%g)",bj[j],(double)PetscRealPart(ba[j]),(double)PetscRealPart(ca[j]));CHKERRQ(ierr);
2540               }
2541             }
2542             ierr = PetscViewerASCIIPrintf(vstdout,"\n",i,maxentry,maxdiff,maxrdiff);CHKERRQ(ierr);
2543           }
2544           ierr = MatRestoreRow(B,i,&bn,&bj,&ba);CHKERRQ(ierr);
2545           ierr = MatRestoreRow(Bfd,i,&cn,&cj,&ca);CHKERRQ(ierr);
2546         }
2547       }
2548       ierr = PetscViewerDestroy(&vdraw);CHKERRQ(ierr);
2549       ierr = MatDestroy(&Bfd);CHKERRQ(ierr);
2550     }
2551   }
2552   PetscFunctionReturn(0);
2553 }
2554 
2555 /*MC
2556     SNESJacobianFunction - Function used to convey the nonlinear Jacobian of the function to be solved by SNES
2557 
2558      Synopsis:
2559      #include "petscsnes.h"
2560      PetscErrorCode SNESJacobianFunction(SNES snes,Vec x,Mat Amat,Mat Pmat,void *ctx);
2561 
2562 +  x - input vector
2563 .  Amat - the matrix that defines the (approximate) Jacobian
2564 .  Pmat - the matrix to be used in constructing the preconditioner, usually the same as Amat.
2565 -  ctx - [optional] user-defined Jacobian context
2566 
2567    Level: intermediate
2568 
2569 .seealso:   SNESSetFunction(), SNESGetFunction(), SNESSetJacobian(), SNESGetJacobian()
2570 M*/
2571 
2572 #undef __FUNCT__
2573 #define __FUNCT__ "SNESSetJacobian"
2574 /*@C
2575    SNESSetJacobian - Sets the function to compute Jacobian as well as the
2576    location to store the matrix.
2577 
2578    Logically Collective on SNES and Mat
2579 
2580    Input Parameters:
2581 +  snes - the SNES context
2582 .  Amat - the matrix that defines the (approximate) Jacobian
2583 .  Pmat - the matrix to be used in constructing the preconditioner, usually the same as Amat.
2584 .  J - Jacobian evaluation routine (if NULL then SNES retains any previously set value), see SNESJacobianFunction for details
2585 -  ctx - [optional] user-defined context for private data for the
2586          Jacobian evaluation routine (may be NULL) (if NULL then SNES retains any previously set value)
2587 
2588    Notes:
2589    If the Amat matrix and Pmat matrix are different you must call MatAssemblyBegin/End() on
2590    each matrix.
2591 
2592    If you know the operator Amat has a null space you can use MatSetNullSpace() and MatSetTransposeNullSpace() to supply the null
2593    space to Amat and the KSP solvers will automatically use that null space as needed during the solution process.
2594 
2595    If using SNESComputeJacobianDefaultColor() to assemble a Jacobian, the ctx argument
2596    must be a MatFDColoring.
2597 
2598    Other defect-correction schemes can be used by computing a different matrix in place of the Jacobian.  One common
2599    example is to use the "Picard linearization" which only differentiates through the highest order parts of each term.
2600 
2601    Level: beginner
2602 
2603 .keywords: SNES, nonlinear, set, Jacobian, matrix
2604 
2605 .seealso: KSPSetOperators(), SNESSetFunction(), MatMFFDComputeJacobian(), SNESComputeJacobianDefaultColor(), MatStructure, J,
2606           SNESSetPicard(), SNESJacobianFunction
2607 @*/
2608 PetscErrorCode  SNESSetJacobian(SNES snes,Mat Amat,Mat Pmat,PetscErrorCode (*J)(SNES,Vec,Mat,Mat,void*),void *ctx)
2609 {
2610   PetscErrorCode ierr;
2611   DM             dm;
2612 
2613   PetscFunctionBegin;
2614   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2615   if (Amat) PetscValidHeaderSpecific(Amat,MAT_CLASSID,2);
2616   if (Pmat) PetscValidHeaderSpecific(Pmat,MAT_CLASSID,3);
2617   if (Amat) PetscCheckSameComm(snes,1,Amat,2);
2618   if (Pmat) PetscCheckSameComm(snes,1,Pmat,3);
2619   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
2620   ierr = DMSNESSetJacobian(dm,J,ctx);CHKERRQ(ierr);
2621   if (Amat) {
2622     ierr = PetscObjectReference((PetscObject)Amat);CHKERRQ(ierr);
2623     ierr = MatDestroy(&snes->jacobian);CHKERRQ(ierr);
2624 
2625     snes->jacobian = Amat;
2626   }
2627   if (Pmat) {
2628     ierr = PetscObjectReference((PetscObject)Pmat);CHKERRQ(ierr);
2629     ierr = MatDestroy(&snes->jacobian_pre);CHKERRQ(ierr);
2630 
2631     snes->jacobian_pre = Pmat;
2632   }
2633   PetscFunctionReturn(0);
2634 }
2635 
2636 #undef __FUNCT__
2637 #define __FUNCT__ "SNESGetJacobian"
2638 /*@C
2639    SNESGetJacobian - Returns the Jacobian matrix and optionally the user
2640    provided context for evaluating the Jacobian.
2641 
2642    Not Collective, but Mat object will be parallel if SNES object is
2643 
2644    Input Parameter:
2645 .  snes - the nonlinear solver context
2646 
2647    Output Parameters:
2648 +  Amat - location to stash (approximate) Jacobian matrix (or NULL)
2649 .  Pmat - location to stash matrix used to compute the preconditioner (or NULL)
2650 .  J - location to put Jacobian function (or NULL), see SNESJacobianFunction for details on its calling sequence
2651 -  ctx - location to stash Jacobian ctx (or NULL)
2652 
2653    Level: advanced
2654 
2655 .seealso: SNESSetJacobian(), SNESComputeJacobian(), SNESJacobianFunction, SNESGetFunction()
2656 @*/
2657 PetscErrorCode SNESGetJacobian(SNES snes,Mat *Amat,Mat *Pmat,PetscErrorCode (**J)(SNES,Vec,Mat,Mat,void*),void **ctx)
2658 {
2659   PetscErrorCode ierr;
2660   DM             dm;
2661   DMSNES         sdm;
2662 
2663   PetscFunctionBegin;
2664   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2665   if (Amat) *Amat = snes->jacobian;
2666   if (Pmat) *Pmat = snes->jacobian_pre;
2667   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
2668   ierr = DMGetDMSNES(dm,&sdm);CHKERRQ(ierr);
2669   if (J) *J = sdm->ops->computejacobian;
2670   if (ctx) *ctx = sdm->jacobianctx;
2671   PetscFunctionReturn(0);
2672 }
2673 
2674 #undef __FUNCT__
2675 #define __FUNCT__ "SNESSetUp"
2676 /*@
2677    SNESSetUp - Sets up the internal data structures for the later use
2678    of a nonlinear solver.
2679 
2680    Collective on SNES
2681 
2682    Input Parameters:
2683 .  snes - the SNES context
2684 
2685    Notes:
2686    For basic use of the SNES solvers the user need not explicitly call
2687    SNESSetUp(), since these actions will automatically occur during
2688    the call to SNESSolve().  However, if one wishes to control this
2689    phase separately, SNESSetUp() should be called after SNESCreate()
2690    and optional routines of the form SNESSetXXX(), but before SNESSolve().
2691 
2692    Level: advanced
2693 
2694 .keywords: SNES, nonlinear, setup
2695 
2696 .seealso: SNESCreate(), SNESSolve(), SNESDestroy()
2697 @*/
2698 PetscErrorCode  SNESSetUp(SNES snes)
2699 {
2700   PetscErrorCode ierr;
2701   DM             dm;
2702   DMSNES         sdm;
2703   SNESLineSearch linesearch, pclinesearch;
2704   void           *lsprectx,*lspostctx;
2705   PetscErrorCode (*precheck)(SNESLineSearch,Vec,Vec,PetscBool*,void*);
2706   PetscErrorCode (*postcheck)(SNESLineSearch,Vec,Vec,Vec,PetscBool*,PetscBool*,void*);
2707   PetscErrorCode (*func)(SNES,Vec,Vec,void*);
2708   Vec            f,fpc;
2709   void           *funcctx;
2710   PetscErrorCode (*jac)(SNES,Vec,Mat,Mat,void*);
2711   void           *jacctx,*appctx;
2712   Mat            j,jpre;
2713 
2714   PetscFunctionBegin;
2715   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2716   if (snes->setupcalled) PetscFunctionReturn(0);
2717 
2718   if (!((PetscObject)snes)->type_name) {
2719     ierr = SNESSetType(snes,SNESNEWTONLS);CHKERRQ(ierr);
2720   }
2721 
2722   ierr = SNESGetFunction(snes,&snes->vec_func,NULL,NULL);CHKERRQ(ierr);
2723 
2724   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
2725   ierr = DMGetDMSNES(dm,&sdm);CHKERRQ(ierr);
2726   if (!sdm->ops->computefunction) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_WRONGSTATE,"Function never provided to SNES object");
2727   if (!sdm->ops->computejacobian) {
2728     ierr = DMSNESSetJacobian(dm,SNESComputeJacobianDefaultColor,NULL);CHKERRQ(ierr);
2729   }
2730   if (!snes->vec_func) {
2731     ierr = DMCreateGlobalVector(dm,&snes->vec_func);CHKERRQ(ierr);
2732   }
2733 
2734   if (!snes->ksp) {
2735     ierr = SNESGetKSP(snes, &snes->ksp);CHKERRQ(ierr);
2736   }
2737 
2738   if (!snes->linesearch) {
2739     ierr = SNESGetLineSearch(snes, &snes->linesearch);CHKERRQ(ierr);
2740   }
2741   ierr = SNESLineSearchSetFunction(snes->linesearch,SNESComputeFunction);CHKERRQ(ierr);
2742 
2743   if (snes->pc && (snes->pcside == PC_LEFT)) {
2744     snes->mf          = PETSC_TRUE;
2745     snes->mf_operator = PETSC_FALSE;
2746   }
2747 
2748   if (snes->pc) {
2749     /* copy the DM over */
2750     ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
2751     ierr = SNESSetDM(snes->pc,dm);CHKERRQ(ierr);
2752 
2753     ierr = SNESGetFunction(snes,&f,&func,&funcctx);CHKERRQ(ierr);
2754     ierr = VecDuplicate(f,&fpc);CHKERRQ(ierr);
2755     ierr = SNESSetFunction(snes->pc,fpc,func,funcctx);CHKERRQ(ierr);
2756     ierr = SNESGetJacobian(snes,&j,&jpre,&jac,&jacctx);CHKERRQ(ierr);
2757     ierr = SNESSetJacobian(snes->pc,j,jpre,jac,jacctx);CHKERRQ(ierr);
2758     ierr = SNESGetApplicationContext(snes,&appctx);CHKERRQ(ierr);
2759     ierr = SNESSetApplicationContext(snes->pc,appctx);CHKERRQ(ierr);
2760     ierr = VecDestroy(&fpc);CHKERRQ(ierr);
2761 
2762     /* copy the function pointers over */
2763     ierr = PetscObjectCopyFortranFunctionPointers((PetscObject)snes,(PetscObject)snes->pc);CHKERRQ(ierr);
2764 
2765     /* default to 1 iteration */
2766     ierr = SNESSetTolerances(snes->pc,0.0,0.0,0.0,1,snes->pc->max_funcs);CHKERRQ(ierr);
2767     if (snes->pcside==PC_RIGHT) {
2768       ierr = SNESSetNormSchedule(snes->pc,SNES_NORM_FINAL_ONLY);CHKERRQ(ierr);
2769     } else {
2770       ierr = SNESSetNormSchedule(snes->pc,SNES_NORM_NONE);CHKERRQ(ierr);
2771     }
2772     ierr = SNESSetFromOptions(snes->pc);CHKERRQ(ierr);
2773 
2774     /* copy the line search context over */
2775     ierr = SNESGetLineSearch(snes,&linesearch);CHKERRQ(ierr);
2776     ierr = SNESGetLineSearch(snes->pc,&pclinesearch);CHKERRQ(ierr);
2777     ierr = SNESLineSearchGetPreCheck(linesearch,&precheck,&lsprectx);CHKERRQ(ierr);
2778     ierr = SNESLineSearchGetPostCheck(linesearch,&postcheck,&lspostctx);CHKERRQ(ierr);
2779     ierr = SNESLineSearchSetPreCheck(pclinesearch,precheck,lsprectx);CHKERRQ(ierr);
2780     ierr = SNESLineSearchSetPostCheck(pclinesearch,postcheck,lspostctx);CHKERRQ(ierr);
2781     ierr = PetscObjectCopyFortranFunctionPointers((PetscObject)linesearch, (PetscObject)pclinesearch);CHKERRQ(ierr);
2782   }
2783   if (snes->mf) {
2784     ierr = SNESSetUpMatrixFree_Private(snes, snes->mf_operator, snes->mf_version);CHKERRQ(ierr);
2785   }
2786   if (snes->ops->usercompute && !snes->user) {
2787     ierr = (*snes->ops->usercompute)(snes,(void**)&snes->user);CHKERRQ(ierr);
2788   }
2789 
2790   snes->jac_iter = 0;
2791   snes->pre_iter = 0;
2792 
2793   if (snes->ops->setup) {
2794     ierr = (*snes->ops->setup)(snes);CHKERRQ(ierr);
2795   }
2796 
2797   if (snes->pc && (snes->pcside == PC_LEFT)) {
2798     if (snes->functype == SNES_FUNCTION_PRECONDITIONED) {
2799       ierr = SNESGetLineSearch(snes,&linesearch);CHKERRQ(ierr);
2800       ierr = SNESLineSearchSetFunction(linesearch,SNESComputeFunctionDefaultNPC);CHKERRQ(ierr);
2801     }
2802   }
2803 
2804   snes->setupcalled = PETSC_TRUE;
2805   PetscFunctionReturn(0);
2806 }
2807 
2808 #undef __FUNCT__
2809 #define __FUNCT__ "SNESReset"
2810 /*@
2811    SNESReset - Resets a SNES context to the snessetupcalled = 0 state and removes any allocated Vecs and Mats
2812 
2813    Collective on SNES
2814 
2815    Input Parameter:
2816 .  snes - iterative context obtained from SNESCreate()
2817 
2818    Level: intermediate
2819 
2820    Notes: Also calls the application context destroy routine set with SNESSetComputeApplicationContext()
2821 
2822 .keywords: SNES, destroy
2823 
2824 .seealso: SNESCreate(), SNESSetUp(), SNESSolve()
2825 @*/
2826 PetscErrorCode  SNESReset(SNES snes)
2827 {
2828   PetscErrorCode ierr;
2829 
2830   PetscFunctionBegin;
2831   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2832   if (snes->ops->userdestroy && snes->user) {
2833     ierr       = (*snes->ops->userdestroy)((void**)&snes->user);CHKERRQ(ierr);
2834     snes->user = NULL;
2835   }
2836   if (snes->pc) {
2837     ierr = SNESReset(snes->pc);CHKERRQ(ierr);
2838   }
2839 
2840   if (snes->ops->reset) {
2841     ierr = (*snes->ops->reset)(snes);CHKERRQ(ierr);
2842   }
2843   if (snes->ksp) {
2844     ierr = KSPReset(snes->ksp);CHKERRQ(ierr);
2845   }
2846 
2847   if (snes->linesearch) {
2848     ierr = SNESLineSearchReset(snes->linesearch);CHKERRQ(ierr);
2849   }
2850 
2851   ierr = VecDestroy(&snes->vec_rhs);CHKERRQ(ierr);
2852   ierr = VecDestroy(&snes->vec_sol);CHKERRQ(ierr);
2853   ierr = VecDestroy(&snes->vec_sol_update);CHKERRQ(ierr);
2854   ierr = VecDestroy(&snes->vec_func);CHKERRQ(ierr);
2855   ierr = MatDestroy(&snes->jacobian);CHKERRQ(ierr);
2856   ierr = MatDestroy(&snes->jacobian_pre);CHKERRQ(ierr);
2857   ierr = VecDestroyVecs(snes->nwork,&snes->work);CHKERRQ(ierr);
2858   ierr = VecDestroyVecs(snes->nvwork,&snes->vwork);CHKERRQ(ierr);
2859 
2860   snes->alwayscomputesfinalresidual = PETSC_FALSE;
2861 
2862   snes->nwork       = snes->nvwork = 0;
2863   snes->setupcalled = PETSC_FALSE;
2864   PetscFunctionReturn(0);
2865 }
2866 
2867 #undef __FUNCT__
2868 #define __FUNCT__ "SNESDestroy"
2869 /*@
2870    SNESDestroy - Destroys the nonlinear solver context that was created
2871    with SNESCreate().
2872 
2873    Collective on SNES
2874 
2875    Input Parameter:
2876 .  snes - the SNES context
2877 
2878    Level: beginner
2879 
2880 .keywords: SNES, nonlinear, destroy
2881 
2882 .seealso: SNESCreate(), SNESSolve()
2883 @*/
2884 PetscErrorCode  SNESDestroy(SNES *snes)
2885 {
2886   PetscErrorCode ierr;
2887 
2888   PetscFunctionBegin;
2889   if (!*snes) PetscFunctionReturn(0);
2890   PetscValidHeaderSpecific((*snes),SNES_CLASSID,1);
2891   if (--((PetscObject)(*snes))->refct > 0) {*snes = 0; PetscFunctionReturn(0);}
2892 
2893   ierr = SNESReset((*snes));CHKERRQ(ierr);
2894   ierr = SNESDestroy(&(*snes)->pc);CHKERRQ(ierr);
2895 
2896   /* if memory was published with SAWs then destroy it */
2897   ierr = PetscObjectSAWsViewOff((PetscObject)*snes);CHKERRQ(ierr);
2898   if ((*snes)->ops->destroy) {ierr = (*((*snes))->ops->destroy)((*snes));CHKERRQ(ierr);}
2899 
2900   ierr = DMDestroy(&(*snes)->dm);CHKERRQ(ierr);
2901   ierr = KSPDestroy(&(*snes)->ksp);CHKERRQ(ierr);
2902   ierr = SNESLineSearchDestroy(&(*snes)->linesearch);CHKERRQ(ierr);
2903 
2904   ierr = PetscFree((*snes)->kspconvctx);CHKERRQ(ierr);
2905   if ((*snes)->ops->convergeddestroy) {
2906     ierr = (*(*snes)->ops->convergeddestroy)((*snes)->cnvP);CHKERRQ(ierr);
2907   }
2908   if ((*snes)->conv_malloc) {
2909     ierr = PetscFree((*snes)->conv_hist);CHKERRQ(ierr);
2910     ierr = PetscFree((*snes)->conv_hist_its);CHKERRQ(ierr);
2911   }
2912   ierr = SNESMonitorCancel((*snes));CHKERRQ(ierr);
2913   ierr = PetscHeaderDestroy(snes);CHKERRQ(ierr);
2914   PetscFunctionReturn(0);
2915 }
2916 
2917 /* ----------- Routines to set solver parameters ---------- */
2918 
2919 #undef __FUNCT__
2920 #define __FUNCT__ "SNESSetLagPreconditioner"
2921 /*@
2922    SNESSetLagPreconditioner - Determines when the preconditioner is rebuilt in the nonlinear solve.
2923 
2924    Logically Collective on SNES
2925 
2926    Input Parameters:
2927 +  snes - the SNES context
2928 -  lag - -1 indicates NEVER rebuild, 1 means rebuild every time the Jacobian is computed within a single nonlinear solve, 2 means every second time
2929          the Jacobian is built etc. -2 indicates rebuild preconditioner at next chance but then never rebuild after that
2930 
2931    Options Database Keys:
2932 .    -snes_lag_preconditioner <lag>
2933 
2934    Notes:
2935    The default is 1
2936    The preconditioner is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1
2937    If  -1 is used before the very first nonlinear solve the preconditioner is still built because there is no previous preconditioner to use
2938 
2939    Level: intermediate
2940 
2941 .keywords: SNES, nonlinear, set, convergence, tolerances
2942 
2943 .seealso: SNESSetTrustRegionTolerance(), SNESGetLagPreconditioner(), SNESSetLagJacobian(), SNESGetLagJacobian()
2944 
2945 @*/
2946 PetscErrorCode  SNESSetLagPreconditioner(SNES snes,PetscInt lag)
2947 {
2948   PetscFunctionBegin;
2949   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2950   if (lag < -2) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag must be -2, -1, 1 or greater");
2951   if (!lag) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag cannot be 0");
2952   PetscValidLogicalCollectiveInt(snes,lag,2);
2953   snes->lagpreconditioner = lag;
2954   PetscFunctionReturn(0);
2955 }
2956 
2957 #undef __FUNCT__
2958 #define __FUNCT__ "SNESSetGridSequence"
2959 /*@
2960    SNESSetGridSequence - sets the number of steps of grid sequencing that SNES does
2961 
2962    Logically Collective on SNES
2963 
2964    Input Parameters:
2965 +  snes - the SNES context
2966 -  steps - the number of refinements to do, defaults to 0
2967 
2968    Options Database Keys:
2969 .    -snes_grid_sequence <steps>
2970 
2971    Level: intermediate
2972 
2973    Notes:
2974    Use SNESGetSolution() to extract the fine grid solution after grid sequencing.
2975 
2976 .keywords: SNES, nonlinear, set, convergence, tolerances
2977 
2978 .seealso: SNESSetTrustRegionTolerance(), SNESGetLagPreconditioner(), SNESSetLagJacobian(), SNESGetLagJacobian(), SNESGetGridSequence()
2979 
2980 @*/
2981 PetscErrorCode  SNESSetGridSequence(SNES snes,PetscInt steps)
2982 {
2983   PetscFunctionBegin;
2984   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2985   PetscValidLogicalCollectiveInt(snes,steps,2);
2986   snes->gridsequence = steps;
2987   PetscFunctionReturn(0);
2988 }
2989 
2990 #undef __FUNCT__
2991 #define __FUNCT__ "SNESGetGridSequence"
2992 /*@
2993    SNESGetGridSequence - gets the number of steps of grid sequencing that SNES does
2994 
2995    Logically Collective on SNES
2996 
2997    Input Parameter:
2998 .  snes - the SNES context
2999 
3000    Output Parameter:
3001 .  steps - the number of refinements to do, defaults to 0
3002 
3003    Options Database Keys:
3004 .    -snes_grid_sequence <steps>
3005 
3006    Level: intermediate
3007 
3008    Notes:
3009    Use SNESGetSolution() to extract the fine grid solution after grid sequencing.
3010 
3011 .keywords: SNES, nonlinear, set, convergence, tolerances
3012 
3013 .seealso: SNESSetTrustRegionTolerance(), SNESGetLagPreconditioner(), SNESSetLagJacobian(), SNESGetLagJacobian(), SNESSetGridSequence()
3014 
3015 @*/
3016 PetscErrorCode  SNESGetGridSequence(SNES snes,PetscInt *steps)
3017 {
3018   PetscFunctionBegin;
3019   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3020   *steps = snes->gridsequence;
3021   PetscFunctionReturn(0);
3022 }
3023 
3024 #undef __FUNCT__
3025 #define __FUNCT__ "SNESGetLagPreconditioner"
3026 /*@
3027    SNESGetLagPreconditioner - Indicates how often the preconditioner is rebuilt
3028 
3029    Not Collective
3030 
3031    Input Parameter:
3032 .  snes - the SNES context
3033 
3034    Output Parameter:
3035 .   lag - -1 indicates NEVER rebuild, 1 means rebuild every time the Jacobian is computed within a single nonlinear solve, 2 means every second time
3036          the Jacobian is built etc. -2 indicates rebuild preconditioner at next chance but then never rebuild after that
3037 
3038    Options Database Keys:
3039 .    -snes_lag_preconditioner <lag>
3040 
3041    Notes:
3042    The default is 1
3043    The preconditioner is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1
3044 
3045    Level: intermediate
3046 
3047 .keywords: SNES, nonlinear, set, convergence, tolerances
3048 
3049 .seealso: SNESSetTrustRegionTolerance(), SNESSetLagPreconditioner()
3050 
3051 @*/
3052 PetscErrorCode  SNESGetLagPreconditioner(SNES snes,PetscInt *lag)
3053 {
3054   PetscFunctionBegin;
3055   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3056   *lag = snes->lagpreconditioner;
3057   PetscFunctionReturn(0);
3058 }
3059 
3060 #undef __FUNCT__
3061 #define __FUNCT__ "SNESSetLagJacobian"
3062 /*@
3063    SNESSetLagJacobian - Determines when the Jacobian is rebuilt in the nonlinear solve. See SNESSetLagPreconditioner() for determining how
3064      often the preconditioner is rebuilt.
3065 
3066    Logically Collective on SNES
3067 
3068    Input Parameters:
3069 +  snes - the SNES context
3070 -  lag - -1 indicates NEVER rebuild, 1 means rebuild every time the Jacobian is computed within a single nonlinear solve, 2 means every second time
3071          the Jacobian is built etc. -2 means rebuild at next chance but then never again
3072 
3073    Options Database Keys:
3074 .    -snes_lag_jacobian <lag>
3075 
3076    Notes:
3077    The default is 1
3078    The Jacobian is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1
3079    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
3080    at the next Newton step but never again (unless it is reset to another value)
3081 
3082    Level: intermediate
3083 
3084 .keywords: SNES, nonlinear, set, convergence, tolerances
3085 
3086 .seealso: SNESSetTrustRegionTolerance(), SNESGetLagPreconditioner(), SNESSetLagPreconditioner(), SNESGetLagJacobian()
3087 
3088 @*/
3089 PetscErrorCode  SNESSetLagJacobian(SNES snes,PetscInt lag)
3090 {
3091   PetscFunctionBegin;
3092   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3093   if (lag < -2) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag must be -2, -1, 1 or greater");
3094   if (!lag) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag cannot be 0");
3095   PetscValidLogicalCollectiveInt(snes,lag,2);
3096   snes->lagjacobian = lag;
3097   PetscFunctionReturn(0);
3098 }
3099 
3100 #undef __FUNCT__
3101 #define __FUNCT__ "SNESGetLagJacobian"
3102 /*@
3103    SNESGetLagJacobian - Indicates how often the Jacobian is rebuilt. See SNESGetLagPreconditioner() to determine when the preconditioner is rebuilt
3104 
3105    Not Collective
3106 
3107    Input Parameter:
3108 .  snes - the SNES context
3109 
3110    Output Parameter:
3111 .   lag - -1 indicates NEVER rebuild, 1 means rebuild every time the Jacobian is computed within a single nonlinear solve, 2 means every second time
3112          the Jacobian is built etc.
3113 
3114    Options Database Keys:
3115 .    -snes_lag_jacobian <lag>
3116 
3117    Notes:
3118    The default is 1
3119    The jacobian is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1
3120 
3121    Level: intermediate
3122 
3123 .keywords: SNES, nonlinear, set, convergence, tolerances
3124 
3125 .seealso: SNESSetTrustRegionTolerance(), SNESSetLagJacobian(), SNESSetLagPreconditioner(), SNESGetLagPreconditioner()
3126 
3127 @*/
3128 PetscErrorCode  SNESGetLagJacobian(SNES snes,PetscInt *lag)
3129 {
3130   PetscFunctionBegin;
3131   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3132   *lag = snes->lagjacobian;
3133   PetscFunctionReturn(0);
3134 }
3135 
3136 #undef __FUNCT__
3137 #define __FUNCT__ "SNESSetLagJacobianPersists"
3138 /*@
3139    SNESSetLagJacobianPersists - Set whether or not the Jacobian lagging persists through multiple solves
3140 
3141    Logically collective on SNES
3142 
3143    Input Parameter:
3144 +  snes - the SNES context
3145 -   flg - jacobian lagging persists if true
3146 
3147    Options Database Keys:
3148 .    -snes_lag_jacobian_persists <flg>
3149 
3150    Notes: This is useful both for nonlinear preconditioning, where it's appropriate to have the Jacobian be stale by
3151    several solves, and for implicit time-stepping, where Jacobian lagging in the inner nonlinear solve over several
3152    timesteps may present huge efficiency gains.
3153 
3154    Level: developer
3155 
3156 .keywords: SNES, nonlinear, lag
3157 
3158 .seealso: SNESSetLagPreconditionerPersists(), SNESSetLagJacobian(), SNESGetLagJacobian(), SNESGetNPC()
3159 
3160 @*/
3161 PetscErrorCode  SNESSetLagJacobianPersists(SNES snes,PetscBool flg)
3162 {
3163   PetscFunctionBegin;
3164   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3165   PetscValidLogicalCollectiveBool(snes,flg,2);
3166   snes->lagjac_persist = flg;
3167   PetscFunctionReturn(0);
3168 }
3169 
3170 #undef __FUNCT__
3171 #define __FUNCT__ "SNESSetLagPreconditionerPersists"
3172 /*@
3173    SNESSetLagPreconditionerPersists - Set whether or not the preconditioner lagging persists through multiple solves
3174 
3175    Logically Collective on SNES
3176 
3177    Input Parameter:
3178 +  snes - the SNES context
3179 -   flg - preconditioner lagging persists if true
3180 
3181    Options Database Keys:
3182 .    -snes_lag_jacobian_persists <flg>
3183 
3184    Notes: This is useful both for nonlinear preconditioning, where it's appropriate to have the preconditioner be stale
3185    by several solves, and for implicit time-stepping, where preconditioner lagging in the inner nonlinear solve over
3186    several timesteps may present huge efficiency gains.
3187 
3188    Level: developer
3189 
3190 .keywords: SNES, nonlinear, lag
3191 
3192 .seealso: SNESSetLagJacobianPersists(), SNESSetLagJacobian(), SNESGetLagJacobian(), SNESGetNPC()
3193 
3194 @*/
3195 PetscErrorCode  SNESSetLagPreconditionerPersists(SNES snes,PetscBool flg)
3196 {
3197   PetscFunctionBegin;
3198   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3199   PetscValidLogicalCollectiveBool(snes,flg,2);
3200   snes->lagpre_persist = flg;
3201   PetscFunctionReturn(0);
3202 }
3203 
3204 #undef __FUNCT__
3205 #define __FUNCT__ "SNESSetTolerances"
3206 /*@
3207    SNESSetTolerances - Sets various parameters used in convergence tests.
3208 
3209    Logically Collective on SNES
3210 
3211    Input Parameters:
3212 +  snes - the SNES context
3213 .  abstol - absolute convergence tolerance
3214 .  rtol - relative convergence tolerance
3215 .  stol -  convergence tolerance in terms of the norm of the change in the solution between steps,  || delta x || < stol*|| x ||
3216 .  maxit - maximum number of iterations
3217 -  maxf - maximum number of function evaluations
3218 
3219    Options Database Keys:
3220 +    -snes_atol <abstol> - Sets abstol
3221 .    -snes_rtol <rtol> - Sets rtol
3222 .    -snes_stol <stol> - Sets stol
3223 .    -snes_max_it <maxit> - Sets maxit
3224 -    -snes_max_funcs <maxf> - Sets maxf
3225 
3226    Notes:
3227    The default maximum number of iterations is 50.
3228    The default maximum number of function evaluations is 1000.
3229 
3230    Level: intermediate
3231 
3232 .keywords: SNES, nonlinear, set, convergence, tolerances
3233 
3234 .seealso: SNESSetTrustRegionTolerance()
3235 @*/
3236 PetscErrorCode  SNESSetTolerances(SNES snes,PetscReal abstol,PetscReal rtol,PetscReal stol,PetscInt maxit,PetscInt maxf)
3237 {
3238   PetscFunctionBegin;
3239   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3240   PetscValidLogicalCollectiveReal(snes,abstol,2);
3241   PetscValidLogicalCollectiveReal(snes,rtol,3);
3242   PetscValidLogicalCollectiveReal(snes,stol,4);
3243   PetscValidLogicalCollectiveInt(snes,maxit,5);
3244   PetscValidLogicalCollectiveInt(snes,maxf,6);
3245 
3246   if (abstol != PETSC_DEFAULT) {
3247     if (abstol < 0.0) SETERRQ1(PetscObjectComm((PetscObject)snes),PETSC_ERR_ARG_OUTOFRANGE,"Absolute tolerance %g must be non-negative",(double)abstol);
3248     snes->abstol = abstol;
3249   }
3250   if (rtol != PETSC_DEFAULT) {
3251     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);
3252     snes->rtol = rtol;
3253   }
3254   if (stol != PETSC_DEFAULT) {
3255     if (stol < 0.0) SETERRQ1(PetscObjectComm((PetscObject)snes),PETSC_ERR_ARG_OUTOFRANGE,"Step tolerance %g must be non-negative",(double)stol);
3256     snes->stol = stol;
3257   }
3258   if (maxit != PETSC_DEFAULT) {
3259     if (maxit < 0) SETERRQ1(PetscObjectComm((PetscObject)snes),PETSC_ERR_ARG_OUTOFRANGE,"Maximum number of iterations %D must be non-negative",maxit);
3260     snes->max_its = maxit;
3261   }
3262   if (maxf != PETSC_DEFAULT) {
3263     if (maxf < 0) SETERRQ1(PetscObjectComm((PetscObject)snes),PETSC_ERR_ARG_OUTOFRANGE,"Maximum number of function evaluations %D must be non-negative",maxf);
3264     snes->max_funcs = maxf;
3265   }
3266   snes->tolerancesset = PETSC_TRUE;
3267   PetscFunctionReturn(0);
3268 }
3269 
3270 #undef __FUNCT__
3271 #define __FUNCT__ "SNESGetTolerances"
3272 /*@
3273    SNESGetTolerances - Gets various parameters used in convergence tests.
3274 
3275    Not Collective
3276 
3277    Input Parameters:
3278 +  snes - the SNES context
3279 .  atol - absolute convergence tolerance
3280 .  rtol - relative convergence tolerance
3281 .  stol -  convergence tolerance in terms of the norm
3282            of the change in the solution between steps
3283 .  maxit - maximum number of iterations
3284 -  maxf - maximum number of function evaluations
3285 
3286    Notes:
3287    The user can specify NULL for any parameter that is not needed.
3288 
3289    Level: intermediate
3290 
3291 .keywords: SNES, nonlinear, get, convergence, tolerances
3292 
3293 .seealso: SNESSetTolerances()
3294 @*/
3295 PetscErrorCode  SNESGetTolerances(SNES snes,PetscReal *atol,PetscReal *rtol,PetscReal *stol,PetscInt *maxit,PetscInt *maxf)
3296 {
3297   PetscFunctionBegin;
3298   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3299   if (atol)  *atol  = snes->abstol;
3300   if (rtol)  *rtol  = snes->rtol;
3301   if (stol)  *stol  = snes->stol;
3302   if (maxit) *maxit = snes->max_its;
3303   if (maxf)  *maxf  = snes->max_funcs;
3304   PetscFunctionReturn(0);
3305 }
3306 
3307 #undef __FUNCT__
3308 #define __FUNCT__ "SNESSetTrustRegionTolerance"
3309 /*@
3310    SNESSetTrustRegionTolerance - Sets the trust region parameter tolerance.
3311 
3312    Logically Collective on SNES
3313 
3314    Input Parameters:
3315 +  snes - the SNES context
3316 -  tol - tolerance
3317 
3318    Options Database Key:
3319 .  -snes_trtol <tol> - Sets tol
3320 
3321    Level: intermediate
3322 
3323 .keywords: SNES, nonlinear, set, trust region, tolerance
3324 
3325 .seealso: SNESSetTolerances()
3326 @*/
3327 PetscErrorCode  SNESSetTrustRegionTolerance(SNES snes,PetscReal tol)
3328 {
3329   PetscFunctionBegin;
3330   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3331   PetscValidLogicalCollectiveReal(snes,tol,2);
3332   snes->deltatol = tol;
3333   PetscFunctionReturn(0);
3334 }
3335 
3336 /*
3337    Duplicate the lg monitors for SNES from KSP; for some reason with
3338    dynamic libraries things don't work under Sun4 if we just use
3339    macros instead of functions
3340 */
3341 #undef __FUNCT__
3342 #define __FUNCT__ "SNESMonitorLGResidualNorm"
3343 PetscErrorCode  SNESMonitorLGResidualNorm(SNES snes,PetscInt it,PetscReal norm,void *ctx)
3344 {
3345   PetscErrorCode ierr;
3346 
3347   PetscFunctionBegin;
3348   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3349   ierr = KSPMonitorLGResidualNorm((KSP)snes,it,norm,ctx);CHKERRQ(ierr);
3350   PetscFunctionReturn(0);
3351 }
3352 
3353 #undef __FUNCT__
3354 #define __FUNCT__ "SNESMonitorLGCreate"
3355 PetscErrorCode  SNESMonitorLGCreate(MPI_Comm comm,const char host[],const char label[],int x,int y,int m,int n,PetscDrawLG *lgctx)
3356 {
3357   PetscErrorCode ierr;
3358 
3359   PetscFunctionBegin;
3360   ierr = KSPMonitorLGResidualNormCreate(comm,host,label,x,y,m,n,lgctx);CHKERRQ(ierr);
3361   PetscFunctionReturn(0);
3362 }
3363 
3364 PETSC_INTERN PetscErrorCode  SNESMonitorRange_Private(SNES,PetscInt,PetscReal*);
3365 
3366 #undef __FUNCT__
3367 #define __FUNCT__ "SNESMonitorLGRange"
3368 PetscErrorCode  SNESMonitorLGRange(SNES snes,PetscInt n,PetscReal rnorm,void *monctx)
3369 {
3370   PetscDrawLG      lg;
3371   PetscErrorCode   ierr;
3372   PetscReal        x,y,per;
3373   PetscViewer      v = (PetscViewer)monctx;
3374   static PetscReal prev; /* should be in the context */
3375   PetscDraw        draw;
3376 
3377   PetscFunctionBegin;
3378   PetscValidHeaderSpecific(v,PETSC_VIEWER_CLASSID,4);
3379   ierr = PetscViewerDrawGetDrawLG(v,0,&lg);CHKERRQ(ierr);
3380   if (!n) {ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);}
3381   ierr = PetscDrawLGGetDraw(lg,&draw);CHKERRQ(ierr);
3382   ierr = PetscDrawSetTitle(draw,"Residual norm");CHKERRQ(ierr);
3383   x    = (PetscReal)n;
3384   if (rnorm > 0.0) y = PetscLog10Real(rnorm);
3385   else y = -15.0;
3386   ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr);
3387   if (n < 20 || !(n % 5) || snes->reason) {
3388     ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr);
3389     ierr = PetscDrawLGSave(lg);CHKERRQ(ierr);
3390   }
3391 
3392   ierr = PetscViewerDrawGetDrawLG(v,1,&lg);CHKERRQ(ierr);
3393   if (!n) {ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);}
3394   ierr = PetscDrawLGGetDraw(lg,&draw);CHKERRQ(ierr);
3395   ierr = PetscDrawSetTitle(draw,"% elemts > .2*max elemt");CHKERRQ(ierr);
3396   ierr =  SNESMonitorRange_Private(snes,n,&per);CHKERRQ(ierr);
3397   x    = (PetscReal)n;
3398   y    = 100.0*per;
3399   ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr);
3400   if (n < 20 || !(n % 5) || snes->reason) {
3401     ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr);
3402     ierr = PetscDrawLGSave(lg);CHKERRQ(ierr);
3403   }
3404 
3405   ierr = PetscViewerDrawGetDrawLG(v,2,&lg);CHKERRQ(ierr);
3406   if (!n) {prev = rnorm;ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);}
3407   ierr = PetscDrawLGGetDraw(lg,&draw);CHKERRQ(ierr);
3408   ierr = PetscDrawSetTitle(draw,"(norm -oldnorm)/oldnorm");CHKERRQ(ierr);
3409   x    = (PetscReal)n;
3410   y    = (prev - rnorm)/prev;
3411   ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr);
3412   if (n < 20 || !(n % 5) || snes->reason) {
3413     ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr);
3414     ierr = PetscDrawLGSave(lg);CHKERRQ(ierr);
3415   }
3416 
3417   ierr = PetscViewerDrawGetDrawLG(v,3,&lg);CHKERRQ(ierr);
3418   if (!n) {ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);}
3419   ierr = PetscDrawLGGetDraw(lg,&draw);CHKERRQ(ierr);
3420   ierr = PetscDrawSetTitle(draw,"(norm -oldnorm)/oldnorm*(% > .2 max)");CHKERRQ(ierr);
3421   x    = (PetscReal)n;
3422   y    = (prev - rnorm)/(prev*per);
3423   if (n > 2) { /*skip initial crazy value */
3424     ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr);
3425   }
3426   if (n < 20 || !(n % 5) || snes->reason) {
3427     ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr);
3428     ierr = PetscDrawLGSave(lg);CHKERRQ(ierr);
3429   }
3430   prev = rnorm;
3431   PetscFunctionReturn(0);
3432 }
3433 
3434 #undef __FUNCT__
3435 #define __FUNCT__ "SNESMonitor"
3436 /*@
3437    SNESMonitor - runs the user provided monitor routines, if they exist
3438 
3439    Collective on SNES
3440 
3441    Input Parameters:
3442 +  snes - nonlinear solver context obtained from SNESCreate()
3443 .  iter - iteration number
3444 -  rnorm - relative norm of the residual
3445 
3446    Notes:
3447    This routine is called by the SNES implementations.
3448    It does not typically need to be called by the user.
3449 
3450    Level: developer
3451 
3452 .seealso: SNESMonitorSet()
3453 @*/
3454 PetscErrorCode  SNESMonitor(SNES snes,PetscInt iter,PetscReal rnorm)
3455 {
3456   PetscErrorCode ierr;
3457   PetscInt       i,n = snes->numbermonitors;
3458 
3459   PetscFunctionBegin;
3460   ierr = VecLockPush(snes->vec_sol);CHKERRQ(ierr);
3461   for (i=0; i<n; i++) {
3462     ierr = (*snes->monitor[i])(snes,iter,rnorm,snes->monitorcontext[i]);CHKERRQ(ierr);
3463   }
3464   ierr = VecLockPop(snes->vec_sol);CHKERRQ(ierr);
3465   PetscFunctionReturn(0);
3466 }
3467 
3468 /* ------------ Routines to set performance monitoring options ----------- */
3469 
3470 /*MC
3471     SNESMonitorFunction - functional form passed to SNESMonitorSet() to monitor convergence of nonlinear solver
3472 
3473      Synopsis:
3474      #include <petscsnes.h>
3475 $    PetscErrorCode SNESMonitorFunction(SNES snes,PetscInt its, PetscReal norm,void *mctx)
3476 
3477 +    snes - the SNES context
3478 .    its - iteration number
3479 .    norm - 2-norm function value (may be estimated)
3480 -    mctx - [optional] monitoring context
3481 
3482    Level: advanced
3483 
3484 .seealso:   SNESMonitorSet(), SNESMonitorGet()
3485 M*/
3486 
3487 #undef __FUNCT__
3488 #define __FUNCT__ "SNESMonitorSet"
3489 /*@C
3490    SNESMonitorSet - Sets an ADDITIONAL function that is to be used at every
3491    iteration of the nonlinear solver to display the iteration's
3492    progress.
3493 
3494    Logically Collective on SNES
3495 
3496    Input Parameters:
3497 +  snes - the SNES context
3498 .  f - the monitor function, see SNESMonitorFunction for the calling sequence
3499 .  mctx - [optional] user-defined context for private data for the
3500           monitor routine (use NULL if no context is desired)
3501 -  monitordestroy - [optional] routine that frees monitor context
3502           (may be NULL)
3503 
3504    Options Database Keys:
3505 +    -snes_monitor        - sets SNESMonitorDefault()
3506 .    -snes_monitor_lg_residualnorm    - sets line graph monitor,
3507                             uses SNESMonitorLGCreate()
3508 -    -snes_monitor_cancel - cancels all monitors that have
3509                             been hardwired into a code by
3510                             calls to SNESMonitorSet(), but
3511                             does not cancel those set via
3512                             the options database.
3513 
3514    Notes:
3515    Several different monitoring routines may be set by calling
3516    SNESMonitorSet() multiple times; all will be called in the
3517    order in which they were set.
3518 
3519    Fortran notes: Only a single monitor function can be set for each SNES object
3520 
3521    Level: intermediate
3522 
3523 .keywords: SNES, nonlinear, set, monitor
3524 
3525 .seealso: SNESMonitorDefault(), SNESMonitorCancel(), SNESMonitorFunction
3526 @*/
3527 PetscErrorCode  SNESMonitorSet(SNES snes,PetscErrorCode (*f)(SNES,PetscInt,PetscReal,void*),void *mctx,PetscErrorCode (*monitordestroy)(void**))
3528 {
3529   PetscInt       i;
3530   PetscErrorCode ierr;
3531   PetscBool      identical;
3532 
3533   PetscFunctionBegin;
3534   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3535   for (i=0; i<snes->numbermonitors;i++) {
3536     ierr = PetscMonitorCompare((PetscErrorCode (*)(void))f,mctx,monitordestroy,(PetscErrorCode (*)(void))snes->monitor[i],snes->monitorcontext[i],snes->monitordestroy[i],&identical);CHKERRQ(ierr);
3537     if (identical) PetscFunctionReturn(0);
3538   }
3539   if (snes->numbermonitors >= MAXSNESMONITORS) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Too many monitors set");
3540   snes->monitor[snes->numbermonitors]          = f;
3541   snes->monitordestroy[snes->numbermonitors]   = monitordestroy;
3542   snes->monitorcontext[snes->numbermonitors++] = (void*)mctx;
3543   PetscFunctionReturn(0);
3544 }
3545 
3546 #undef __FUNCT__
3547 #define __FUNCT__ "SNESMonitorCancel"
3548 /*@
3549    SNESMonitorCancel - Clears all the monitor functions for a SNES object.
3550 
3551    Logically Collective on SNES
3552 
3553    Input Parameters:
3554 .  snes - the SNES context
3555 
3556    Options Database Key:
3557 .  -snes_monitor_cancel - cancels all monitors that have been hardwired
3558     into a code by calls to SNESMonitorSet(), but does not cancel those
3559     set via the options database
3560 
3561    Notes:
3562    There is no way to clear one specific monitor from a SNES object.
3563 
3564    Level: intermediate
3565 
3566 .keywords: SNES, nonlinear, set, monitor
3567 
3568 .seealso: SNESMonitorDefault(), SNESMonitorSet()
3569 @*/
3570 PetscErrorCode  SNESMonitorCancel(SNES snes)
3571 {
3572   PetscErrorCode ierr;
3573   PetscInt       i;
3574 
3575   PetscFunctionBegin;
3576   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3577   for (i=0; i<snes->numbermonitors; i++) {
3578     if (snes->monitordestroy[i]) {
3579       ierr = (*snes->monitordestroy[i])(&snes->monitorcontext[i]);CHKERRQ(ierr);
3580     }
3581   }
3582   snes->numbermonitors = 0;
3583   PetscFunctionReturn(0);
3584 }
3585 
3586 /*MC
3587     SNESConvergenceTestFunction - functional form used for testing of convergence of nonlinear solver
3588 
3589      Synopsis:
3590      #include <petscsnes.h>
3591 $     PetscErrorCode SNESConvergenceTest(SNES snes,PetscInt it,PetscReal xnorm,PetscReal gnorm,PetscReal f,SNESConvergedReason *reason,void *cctx)
3592 
3593 +    snes - the SNES context
3594 .    it - current iteration (0 is the first and is before any Newton step)
3595 .    cctx - [optional] convergence context
3596 .    reason - reason for convergence/divergence
3597 .    xnorm - 2-norm of current iterate
3598 .    gnorm - 2-norm of current step
3599 -    f - 2-norm of function
3600 
3601    Level: intermediate
3602 
3603 .seealso:   SNESSetConvergenceTest(), SNESGetConvergenceTest()
3604 M*/
3605 
3606 #undef __FUNCT__
3607 #define __FUNCT__ "SNESSetConvergenceTest"
3608 /*@C
3609    SNESSetConvergenceTest - Sets the function that is to be used
3610    to test for convergence of the nonlinear iterative solution.
3611 
3612    Logically Collective on SNES
3613 
3614    Input Parameters:
3615 +  snes - the SNES context
3616 .  SNESConvergenceTestFunction - routine to test for convergence
3617 .  cctx - [optional] context for private data for the convergence routine  (may be NULL)
3618 -  destroy - [optional] destructor for the context (may be NULL; NULL_FUNCTION in Fortran)
3619 
3620    Level: advanced
3621 
3622 .keywords: SNES, nonlinear, set, convergence, test
3623 
3624 .seealso: SNESConvergedDefault(), SNESConvergedSkip(), SNESConvergenceTestFunction
3625 @*/
3626 PetscErrorCode  SNESSetConvergenceTest(SNES snes,PetscErrorCode (*SNESConvergenceTestFunction)(SNES,PetscInt,PetscReal,PetscReal,PetscReal,SNESConvergedReason*,void*),void *cctx,PetscErrorCode (*destroy)(void*))
3627 {
3628   PetscErrorCode ierr;
3629 
3630   PetscFunctionBegin;
3631   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3632   if (!SNESConvergenceTestFunction) SNESConvergenceTestFunction = SNESConvergedSkip;
3633   if (snes->ops->convergeddestroy) {
3634     ierr = (*snes->ops->convergeddestroy)(snes->cnvP);CHKERRQ(ierr);
3635   }
3636   snes->ops->converged        = SNESConvergenceTestFunction;
3637   snes->ops->convergeddestroy = destroy;
3638   snes->cnvP                  = cctx;
3639   PetscFunctionReturn(0);
3640 }
3641 
3642 #undef __FUNCT__
3643 #define __FUNCT__ "SNESGetConvergedReason"
3644 /*@
3645    SNESGetConvergedReason - Gets the reason the SNES iteration was stopped.
3646 
3647    Not Collective
3648 
3649    Input Parameter:
3650 .  snes - the SNES context
3651 
3652    Output Parameter:
3653 .  reason - negative value indicates diverged, positive value converged, see SNESConvergedReason or the
3654             manual pages for the individual convergence tests for complete lists
3655 
3656    Options Database:
3657 .   -snes_converged_reason - prints the reason to standard out
3658 
3659    Level: intermediate
3660 
3661    Notes: Should only be called after the call the SNESSolve() is complete, if it is called earlier it returns the value SNES__CONVERGED_ITERATING.
3662 
3663 .keywords: SNES, nonlinear, set, convergence, test
3664 
3665 .seealso: SNESSetConvergenceTest(), SNESSetConvergedReason(), SNESConvergedReason
3666 @*/
3667 PetscErrorCode SNESGetConvergedReason(SNES snes,SNESConvergedReason *reason)
3668 {
3669   PetscFunctionBegin;
3670   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3671   PetscValidPointer(reason,2);
3672   *reason = snes->reason;
3673   PetscFunctionReturn(0);
3674 }
3675 
3676 #undef __FUNCT__
3677 #define __FUNCT__ "SNESSetConvergedReason"
3678 /*@
3679    SNESSetConvergedReason - Sets the reason the SNES iteration was stopped.
3680 
3681    Not Collective
3682 
3683    Input Parameters:
3684 +  snes - the SNES context
3685 -  reason - negative value indicates diverged, positive value converged, see SNESConvergedReason or the
3686             manual pages for the individual convergence tests for complete lists
3687 
3688    Level: intermediate
3689 
3690 .keywords: SNES, nonlinear, set, convergence, test
3691 .seealso: SNESGetConvergedReason(), SNESSetConvergenceTest(), SNESConvergedReason
3692 @*/
3693 PetscErrorCode SNESSetConvergedReason(SNES snes,SNESConvergedReason reason)
3694 {
3695   PetscFunctionBegin;
3696   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3697   snes->reason = reason;
3698   PetscFunctionReturn(0);
3699 }
3700 
3701 #undef __FUNCT__
3702 #define __FUNCT__ "SNESSetConvergenceHistory"
3703 /*@
3704    SNESSetConvergenceHistory - Sets the array used to hold the convergence history.
3705 
3706    Logically Collective on SNES
3707 
3708    Input Parameters:
3709 +  snes - iterative context obtained from SNESCreate()
3710 .  a   - array to hold history, this array will contain the function norms computed at each step
3711 .  its - integer array holds the number of linear iterations for each solve.
3712 .  na  - size of a and its
3713 -  reset - PETSC_TRUE indicates each new nonlinear solve resets the history counter to zero,
3714            else it continues storing new values for new nonlinear solves after the old ones
3715 
3716    Notes:
3717    If 'a' and 'its' are NULL then space is allocated for the history. If 'na' PETSC_DECIDE or PETSC_DEFAULT then a
3718    default array of length 10000 is allocated.
3719 
3720    This routine is useful, e.g., when running a code for purposes
3721    of accurate performance monitoring, when no I/O should be done
3722    during the section of code that is being timed.
3723 
3724    Level: intermediate
3725 
3726 .keywords: SNES, set, convergence, history
3727 
3728 .seealso: SNESGetConvergenceHistory()
3729 
3730 @*/
3731 PetscErrorCode  SNESSetConvergenceHistory(SNES snes,PetscReal a[],PetscInt its[],PetscInt na,PetscBool reset)
3732 {
3733   PetscErrorCode ierr;
3734 
3735   PetscFunctionBegin;
3736   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3737   if (a) PetscValidScalarPointer(a,2);
3738   if (its) PetscValidIntPointer(its,3);
3739   if (!a) {
3740     if (na == PETSC_DECIDE || na == PETSC_DEFAULT) na = 1000;
3741     ierr = PetscCalloc1(na,&a);CHKERRQ(ierr);
3742     ierr = PetscCalloc1(na,&its);CHKERRQ(ierr);
3743 
3744     snes->conv_malloc = PETSC_TRUE;
3745   }
3746   snes->conv_hist       = a;
3747   snes->conv_hist_its   = its;
3748   snes->conv_hist_max   = na;
3749   snes->conv_hist_len   = 0;
3750   snes->conv_hist_reset = reset;
3751   PetscFunctionReturn(0);
3752 }
3753 
3754 #if defined(PETSC_HAVE_MATLAB_ENGINE)
3755 #include <engine.h>   /* MATLAB include file */
3756 #include <mex.h>      /* MATLAB include file */
3757 
3758 #undef __FUNCT__
3759 #define __FUNCT__ "SNESGetConvergenceHistoryMatlab"
3760 PETSC_EXTERN mxArray *SNESGetConvergenceHistoryMatlab(SNES snes)
3761 {
3762   mxArray   *mat;
3763   PetscInt  i;
3764   PetscReal *ar;
3765 
3766   PetscFunctionBegin;
3767   mat = mxCreateDoubleMatrix(snes->conv_hist_len,1,mxREAL);
3768   ar  = (PetscReal*) mxGetData(mat);
3769   for (i=0; i<snes->conv_hist_len; i++) ar[i] = snes->conv_hist[i];
3770   PetscFunctionReturn(mat);
3771 }
3772 #endif
3773 
3774 #undef __FUNCT__
3775 #define __FUNCT__ "SNESGetConvergenceHistory"
3776 /*@C
3777    SNESGetConvergenceHistory - Gets the array used to hold the convergence history.
3778 
3779    Not Collective
3780 
3781    Input Parameter:
3782 .  snes - iterative context obtained from SNESCreate()
3783 
3784    Output Parameters:
3785 .  a   - array to hold history
3786 .  its - integer array holds the number of linear iterations (or
3787          negative if not converged) for each solve.
3788 -  na  - size of a and its
3789 
3790    Notes:
3791     The calling sequence for this routine in Fortran is
3792 $   call SNESGetConvergenceHistory(SNES snes, integer na, integer ierr)
3793 
3794    This routine is useful, e.g., when running a code for purposes
3795    of accurate performance monitoring, when no I/O should be done
3796    during the section of code that is being timed.
3797 
3798    Level: intermediate
3799 
3800 .keywords: SNES, get, convergence, history
3801 
3802 .seealso: SNESSetConvergencHistory()
3803 
3804 @*/
3805 PetscErrorCode  SNESGetConvergenceHistory(SNES snes,PetscReal *a[],PetscInt *its[],PetscInt *na)
3806 {
3807   PetscFunctionBegin;
3808   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3809   if (a)   *a   = snes->conv_hist;
3810   if (its) *its = snes->conv_hist_its;
3811   if (na)  *na  = snes->conv_hist_len;
3812   PetscFunctionReturn(0);
3813 }
3814 
3815 #undef __FUNCT__
3816 #define __FUNCT__ "SNESSetUpdate"
3817 /*@C
3818   SNESSetUpdate - Sets the general-purpose update function called
3819   at the beginning of every iteration of the nonlinear solve. Specifically
3820   it is called just before the Jacobian is "evaluated".
3821 
3822   Logically Collective on SNES
3823 
3824   Input Parameters:
3825 . snes - The nonlinear solver context
3826 . func - The function
3827 
3828   Calling sequence of func:
3829 . func (SNES snes, PetscInt step);
3830 
3831 . step - The current step of the iteration
3832 
3833   Level: advanced
3834 
3835   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()
3836         This is not used by most users.
3837 
3838 .keywords: SNES, update
3839 
3840 .seealso SNESSetJacobian(), SNESSolve()
3841 @*/
3842 PetscErrorCode  SNESSetUpdate(SNES snes, PetscErrorCode (*func)(SNES, PetscInt))
3843 {
3844   PetscFunctionBegin;
3845   PetscValidHeaderSpecific(snes, SNES_CLASSID,1);
3846   snes->ops->update = func;
3847   PetscFunctionReturn(0);
3848 }
3849 
3850 #undef __FUNCT__
3851 #define __FUNCT__ "SNESScaleStep_Private"
3852 /*
3853    SNESScaleStep_Private - Scales a step so that its length is less than the
3854    positive parameter delta.
3855 
3856     Input Parameters:
3857 +   snes - the SNES context
3858 .   y - approximate solution of linear system
3859 .   fnorm - 2-norm of current function
3860 -   delta - trust region size
3861 
3862     Output Parameters:
3863 +   gpnorm - predicted function norm at the new point, assuming local
3864     linearization.  The value is zero if the step lies within the trust
3865     region, and exceeds zero otherwise.
3866 -   ynorm - 2-norm of the step
3867 
3868     Note:
3869     For non-trust region methods such as SNESNEWTONLS, the parameter delta
3870     is set to be the maximum allowable step size.
3871 
3872 .keywords: SNES, nonlinear, scale, step
3873 */
3874 PetscErrorCode SNESScaleStep_Private(SNES snes,Vec y,PetscReal *fnorm,PetscReal *delta,PetscReal *gpnorm,PetscReal *ynorm)
3875 {
3876   PetscReal      nrm;
3877   PetscScalar    cnorm;
3878   PetscErrorCode ierr;
3879 
3880   PetscFunctionBegin;
3881   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3882   PetscValidHeaderSpecific(y,VEC_CLASSID,2);
3883   PetscCheckSameComm(snes,1,y,2);
3884 
3885   ierr = VecNorm(y,NORM_2,&nrm);CHKERRQ(ierr);
3886   if (nrm > *delta) {
3887     nrm     = *delta/nrm;
3888     *gpnorm = (1.0 - nrm)*(*fnorm);
3889     cnorm   = nrm;
3890     ierr    = VecScale(y,cnorm);CHKERRQ(ierr);
3891     *ynorm  = *delta;
3892   } else {
3893     *gpnorm = 0.0;
3894     *ynorm  = nrm;
3895   }
3896   PetscFunctionReturn(0);
3897 }
3898 
3899 #undef __FUNCT__
3900 #define __FUNCT__ "SNESReasonView"
3901 /*@
3902    SNESReasonView - Displays the reason a SNES solve converged or diverged to a viewer
3903 
3904    Collective on SNES
3905 
3906    Parameter:
3907 +  snes - iterative context obtained from SNESCreate()
3908 -  viewer - the viewer to display the reason
3909 
3910 
3911    Options Database Keys:
3912 .  -snes_converged_reason - print reason for converged or diverged, also prints number of iterations
3913 
3914    Level: beginner
3915 
3916 .keywords: SNES, solve, linear system
3917 
3918 .seealso: SNESCreate(), SNESSetUp(), SNESDestroy(), SNESSetTolerances(), SNESConvergedDefault()
3919 
3920 @*/
3921 PetscErrorCode  SNESReasonView(SNES snes,PetscViewer viewer)
3922 {
3923   PetscErrorCode ierr;
3924   PetscBool      isAscii;
3925 
3926   PetscFunctionBegin;
3927   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&isAscii);CHKERRQ(ierr);
3928   if (isAscii) {
3929     ierr = PetscViewerASCIIAddTab(viewer,((PetscObject)snes)->tablevel);CHKERRQ(ierr);
3930     if (snes->reason > 0) {
3931       if (((PetscObject) snes)->prefix) {
3932         ierr = PetscViewerASCIIPrintf(viewer,"Nonlinear %s solve converged due to %s iterations %D\n",((PetscObject) snes)->prefix,SNESConvergedReasons[snes->reason],snes->iter);CHKERRQ(ierr);
3933       } else {
3934         ierr = PetscViewerASCIIPrintf(viewer,"Nonlinear solve converged due to %s iterations %D\n",SNESConvergedReasons[snes->reason],snes->iter);CHKERRQ(ierr);
3935       }
3936     } else {
3937       if (((PetscObject) snes)->prefix) {
3938         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);
3939       } else {
3940         ierr = PetscViewerASCIIPrintf(viewer,"Nonlinear solve did not converge due to %s iterations %D\n",SNESConvergedReasons[snes->reason],snes->iter);CHKERRQ(ierr);
3941       }
3942     }
3943     ierr = PetscViewerASCIISubtractTab(viewer,((PetscObject)snes)->tablevel);CHKERRQ(ierr);
3944   }
3945   PetscFunctionReturn(0);
3946 }
3947 
3948 #undef __FUNCT__
3949 #define __FUNCT__ "SNESReasonViewFromOptions"
3950 /*@C
3951   SNESReasonViewFromOptions - Processes command line options to determine if/how a SNESReason is to be viewed.
3952 
3953   Collective on SNES
3954 
3955   Input Parameters:
3956 . snes   - the SNES object
3957 
3958   Level: intermediate
3959 
3960 @*/
3961 PetscErrorCode SNESReasonViewFromOptions(SNES snes)
3962 {
3963   PetscErrorCode    ierr;
3964   PetscViewer       viewer;
3965   PetscBool         flg;
3966   static PetscBool  incall = PETSC_FALSE;
3967   PetscViewerFormat format;
3968 
3969   PetscFunctionBegin;
3970   if (incall) PetscFunctionReturn(0);
3971   incall = PETSC_TRUE;
3972   ierr   = PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes),((PetscObject)snes)->prefix,"-snes_converged_reason",&viewer,&format,&flg);CHKERRQ(ierr);
3973   if (flg) {
3974     ierr = PetscViewerPushFormat(viewer,format);CHKERRQ(ierr);
3975     ierr = SNESReasonView(snes,viewer);CHKERRQ(ierr);
3976     ierr = PetscViewerPopFormat(viewer);CHKERRQ(ierr);
3977     ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr);
3978   }
3979   incall = PETSC_FALSE;
3980   PetscFunctionReturn(0);
3981 }
3982 
3983 #undef __FUNCT__
3984 #define __FUNCT__ "SNESSolve"
3985 /*@C
3986    SNESSolve - Solves a nonlinear system F(x) = b.
3987    Call SNESSolve() after calling SNESCreate() and optional routines of the form SNESSetXXX().
3988 
3989    Collective on SNES
3990 
3991    Input Parameters:
3992 +  snes - the SNES context
3993 .  b - the constant part of the equation F(x) = b, or NULL to use zero.
3994 -  x - the solution vector.
3995 
3996    Notes:
3997    The user should initialize the vector,x, with the initial guess
3998    for the nonlinear solve prior to calling SNESSolve.  In particular,
3999    to employ an initial guess of zero, the user should explicitly set
4000    this vector to zero by calling VecSet().
4001 
4002    Level: beginner
4003 
4004 .keywords: SNES, nonlinear, solve
4005 
4006 .seealso: SNESCreate(), SNESDestroy(), SNESSetFunction(), SNESSetJacobian(), SNESSetGridSequence(), SNESGetSolution()
4007 @*/
4008 PetscErrorCode  SNESSolve(SNES snes,Vec b,Vec x)
4009 {
4010   PetscErrorCode    ierr;
4011   PetscBool         flg;
4012   PetscInt          grid;
4013   Vec               xcreated = NULL;
4014   DM                dm;
4015 
4016   PetscFunctionBegin;
4017   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
4018   if (x) PetscValidHeaderSpecific(x,VEC_CLASSID,3);
4019   if (x) PetscCheckSameComm(snes,1,x,3);
4020   if (b) PetscValidHeaderSpecific(b,VEC_CLASSID,2);
4021   if (b) PetscCheckSameComm(snes,1,b,2);
4022 
4023   if (!x) {
4024     ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
4025     ierr = DMCreateGlobalVector(dm,&xcreated);CHKERRQ(ierr);
4026     x    = xcreated;
4027   }
4028   ierr = SNESViewFromOptions(snes,NULL,"-snes_view_pre");CHKERRQ(ierr);
4029 
4030   for (grid=0; grid<snes->gridsequence; grid++) {ierr = PetscViewerASCIIPushTab(PETSC_VIEWER_STDOUT_(PetscObjectComm((PetscObject)snes)));CHKERRQ(ierr);}
4031   for (grid=0; grid<snes->gridsequence+1; grid++) {
4032 
4033     /* set solution vector */
4034     if (!grid) {ierr = PetscObjectReference((PetscObject)x);CHKERRQ(ierr);}
4035     ierr          = VecDestroy(&snes->vec_sol);CHKERRQ(ierr);
4036     snes->vec_sol = x;
4037     ierr          = SNESGetDM(snes,&dm);CHKERRQ(ierr);
4038 
4039     /* set affine vector if provided */
4040     if (b) { ierr = PetscObjectReference((PetscObject)b);CHKERRQ(ierr); }
4041     ierr          = VecDestroy(&snes->vec_rhs);CHKERRQ(ierr);
4042     snes->vec_rhs = b;
4043 
4044     if (snes->vec_func == snes->vec_sol) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_IDN,"Solution vector cannot be function vector");
4045     if (snes->vec_rhs  == snes->vec_sol) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_IDN,"Solution vector cannot be right hand side vector");
4046     if (!snes->vec_sol_update /* && snes->vec_sol */) {
4047       ierr = VecDuplicate(snes->vec_sol,&snes->vec_sol_update);CHKERRQ(ierr);
4048       ierr = PetscLogObjectParent((PetscObject)snes,(PetscObject)snes->vec_sol_update);CHKERRQ(ierr);
4049     }
4050     ierr = DMShellSetGlobalVector(dm,snes->vec_sol);CHKERRQ(ierr);
4051     ierr = SNESSetUp(snes);CHKERRQ(ierr);
4052 
4053     if (!grid) {
4054       if (snes->ops->computeinitialguess) {
4055         ierr = (*snes->ops->computeinitialguess)(snes,snes->vec_sol,snes->initialguessP);CHKERRQ(ierr);
4056       }
4057     }
4058 
4059     if (snes->conv_hist_reset) snes->conv_hist_len = 0;
4060     if (snes->counters_reset) {snes->nfuncs = 0; snes->linear_its = 0; snes->numFailures = 0;}
4061 
4062     ierr = PetscLogEventBegin(SNES_Solve,snes,0,0,0);CHKERRQ(ierr);
4063     ierr = (*snes->ops->solve)(snes);CHKERRQ(ierr);
4064     ierr = PetscLogEventEnd(SNES_Solve,snes,0,0,0);CHKERRQ(ierr);
4065     if (!snes->reason) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Internal error, solver returned without setting converged reason");
4066     snes->domainerror = PETSC_FALSE; /* clear the flag if it has been set */
4067 
4068     if (snes->lagjac_persist) snes->jac_iter += snes->iter;
4069     if (snes->lagpre_persist) snes->pre_iter += snes->iter;
4070 
4071     ierr   = PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes),((PetscObject)snes)->prefix,"-snes_test_local_min",NULL,NULL,&flg);CHKERRQ(ierr);
4072     if (flg && !PetscPreLoadingOn) { ierr = SNESTestLocalMin(snes);CHKERRQ(ierr); }
4073     ierr = SNESReasonViewFromOptions(snes);CHKERRQ(ierr);
4074 
4075     if (snes->errorifnotconverged && snes->reason < 0) SETERRQ(PetscObjectComm((PetscObject)snes),PETSC_ERR_NOT_CONVERGED,"SNESSolve has not converged");
4076     if (snes->reason < 0) break;
4077     if (grid <  snes->gridsequence) {
4078       DM  fine;
4079       Vec xnew;
4080       Mat interp;
4081 
4082       ierr = DMRefine(snes->dm,PetscObjectComm((PetscObject)snes),&fine);CHKERRQ(ierr);
4083       if (!fine) SETERRQ(PetscObjectComm((PetscObject)snes),PETSC_ERR_ARG_INCOMP,"DMRefine() did not perform any refinement, cannot continue grid sequencing");
4084       ierr = DMCreateInterpolation(snes->dm,fine,&interp,NULL);CHKERRQ(ierr);
4085       ierr = DMCreateGlobalVector(fine,&xnew);CHKERRQ(ierr);
4086       ierr = MatInterpolate(interp,x,xnew);CHKERRQ(ierr);
4087       ierr = DMInterpolate(snes->dm,interp,fine);CHKERRQ(ierr);
4088       ierr = MatDestroy(&interp);CHKERRQ(ierr);
4089       x    = xnew;
4090 
4091       ierr = SNESReset(snes);CHKERRQ(ierr);
4092       ierr = SNESSetDM(snes,fine);CHKERRQ(ierr);
4093       ierr = DMDestroy(&fine);CHKERRQ(ierr);
4094       ierr = PetscViewerASCIIPopTab(PETSC_VIEWER_STDOUT_(PetscObjectComm((PetscObject)snes)));CHKERRQ(ierr);
4095     }
4096   }
4097   ierr = SNESViewFromOptions(snes,NULL,"-snes_view");CHKERRQ(ierr);
4098   ierr = VecViewFromOptions(snes->vec_sol,(PetscObject)snes,"-snes_view_solution");CHKERRQ(ierr);
4099 
4100   ierr = VecDestroy(&xcreated);CHKERRQ(ierr);
4101   ierr = PetscObjectSAWsBlock((PetscObject)snes);CHKERRQ(ierr);
4102   PetscFunctionReturn(0);
4103 }
4104 
4105 /* --------- Internal routines for SNES Package --------- */
4106 
4107 #undef __FUNCT__
4108 #define __FUNCT__ "SNESSetType"
4109 /*@C
4110    SNESSetType - Sets the method for the nonlinear solver.
4111 
4112    Collective on SNES
4113 
4114    Input Parameters:
4115 +  snes - the SNES context
4116 -  type - a known method
4117 
4118    Options Database Key:
4119 .  -snes_type <type> - Sets the method; use -help for a list
4120    of available methods (for instance, newtonls or newtontr)
4121 
4122    Notes:
4123    See "petsc/include/petscsnes.h" for available methods (for instance)
4124 +    SNESNEWTONLS - Newton's method with line search
4125      (systems of nonlinear equations)
4126 .    SNESNEWTONTR - Newton's method with trust region
4127      (systems of nonlinear equations)
4128 
4129   Normally, it is best to use the SNESSetFromOptions() command and then
4130   set the SNES solver type from the options database rather than by using
4131   this routine.  Using the options database provides the user with
4132   maximum flexibility in evaluating the many nonlinear solvers.
4133   The SNESSetType() routine is provided for those situations where it
4134   is necessary to set the nonlinear solver independently of the command
4135   line or options database.  This might be the case, for example, when
4136   the choice of solver changes during the execution of the program,
4137   and the user's application is taking responsibility for choosing the
4138   appropriate method.
4139 
4140     Developer Notes: SNESRegister() adds a constructor for a new SNESType to SNESList, SNESSetType() locates
4141     the constructor in that list and calls it to create the spexific object.
4142 
4143   Level: intermediate
4144 
4145 .keywords: SNES, set, type
4146 
4147 .seealso: SNESType, SNESCreate(), SNESDestroy(), SNESGetType(), SNESSetFromOptions()
4148 
4149 @*/
4150 PetscErrorCode  SNESSetType(SNES snes,SNESType type)
4151 {
4152   PetscErrorCode ierr,(*r)(SNES);
4153   PetscBool      match;
4154 
4155   PetscFunctionBegin;
4156   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
4157   PetscValidCharPointer(type,2);
4158 
4159   ierr = PetscObjectTypeCompare((PetscObject)snes,type,&match);CHKERRQ(ierr);
4160   if (match) PetscFunctionReturn(0);
4161 
4162   ierr =  PetscFunctionListFind(SNESList,type,&r);CHKERRQ(ierr);
4163   if (!r) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_UNKNOWN_TYPE,"Unable to find requested SNES type %s",type);
4164   /* Destroy the previous private SNES context */
4165   if (snes->ops->destroy) {
4166     ierr               = (*(snes)->ops->destroy)(snes);CHKERRQ(ierr);
4167     snes->ops->destroy = NULL;
4168   }
4169   /* Reinitialize function pointers in SNESOps structure */
4170   snes->ops->setup          = 0;
4171   snes->ops->solve          = 0;
4172   snes->ops->view           = 0;
4173   snes->ops->setfromoptions = 0;
4174   snes->ops->destroy        = 0;
4175   /* Call the SNESCreate_XXX routine for this particular Nonlinear solver */
4176   snes->setupcalled = PETSC_FALSE;
4177 
4178   ierr = PetscObjectChangeTypeName((PetscObject)snes,type);CHKERRQ(ierr);
4179   ierr = (*r)(snes);CHKERRQ(ierr);
4180   PetscFunctionReturn(0);
4181 }
4182 
4183 #undef __FUNCT__
4184 #define __FUNCT__ "SNESGetType"
4185 /*@C
4186    SNESGetType - Gets the SNES method type and name (as a string).
4187 
4188    Not Collective
4189 
4190    Input Parameter:
4191 .  snes - nonlinear solver context
4192 
4193    Output Parameter:
4194 .  type - SNES method (a character string)
4195 
4196    Level: intermediate
4197 
4198 .keywords: SNES, nonlinear, get, type, name
4199 @*/
4200 PetscErrorCode  SNESGetType(SNES snes,SNESType *type)
4201 {
4202   PetscFunctionBegin;
4203   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
4204   PetscValidPointer(type,2);
4205   *type = ((PetscObject)snes)->type_name;
4206   PetscFunctionReturn(0);
4207 }
4208 
4209 #undef __FUNCT__
4210 #define __FUNCT__ "SNESSetSolution"
4211 /*@
4212   SNESSetSolution - Sets the solution vector for use by the SNES routines.
4213 
4214   Logically Collective on SNES and Vec
4215 
4216   Input Parameters:
4217 + snes - the SNES context obtained from SNESCreate()
4218 - u    - the solution vector
4219 
4220   Level: beginner
4221 
4222 .keywords: SNES, set, solution
4223 @*/
4224 PetscErrorCode SNESSetSolution(SNES snes, Vec u)
4225 {
4226   DM             dm;
4227   PetscErrorCode ierr;
4228 
4229   PetscFunctionBegin;
4230   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
4231   PetscValidHeaderSpecific(u, VEC_CLASSID, 2);
4232   ierr = PetscObjectReference((PetscObject) u);CHKERRQ(ierr);
4233   ierr = VecDestroy(&snes->vec_sol);CHKERRQ(ierr);
4234 
4235   snes->vec_sol = u;
4236 
4237   ierr = SNESGetDM(snes, &dm);CHKERRQ(ierr);
4238   ierr = DMShellSetGlobalVector(dm, u);CHKERRQ(ierr);
4239   PetscFunctionReturn(0);
4240 }
4241 
4242 #undef __FUNCT__
4243 #define __FUNCT__ "SNESGetSolution"
4244 /*@
4245    SNESGetSolution - Returns the vector where the approximate solution is
4246    stored. This is the fine grid solution when using SNESSetGridSequence().
4247 
4248    Not Collective, but Vec is parallel if SNES is parallel
4249 
4250    Input Parameter:
4251 .  snes - the SNES context
4252 
4253    Output Parameter:
4254 .  x - the solution
4255 
4256    Level: intermediate
4257 
4258 .keywords: SNES, nonlinear, get, solution
4259 
4260 .seealso:  SNESGetSolutionUpdate(), SNESGetFunction()
4261 @*/
4262 PetscErrorCode  SNESGetSolution(SNES snes,Vec *x)
4263 {
4264   PetscFunctionBegin;
4265   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
4266   PetscValidPointer(x,2);
4267   *x = snes->vec_sol;
4268   PetscFunctionReturn(0);
4269 }
4270 
4271 #undef __FUNCT__
4272 #define __FUNCT__ "SNESGetSolutionUpdate"
4273 /*@
4274    SNESGetSolutionUpdate - Returns the vector where the solution update is
4275    stored.
4276 
4277    Not Collective, but Vec is parallel if SNES is parallel
4278 
4279    Input Parameter:
4280 .  snes - the SNES context
4281 
4282    Output Parameter:
4283 .  x - the solution update
4284 
4285    Level: advanced
4286 
4287 .keywords: SNES, nonlinear, get, solution, update
4288 
4289 .seealso: SNESGetSolution(), SNESGetFunction()
4290 @*/
4291 PetscErrorCode  SNESGetSolutionUpdate(SNES snes,Vec *x)
4292 {
4293   PetscFunctionBegin;
4294   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
4295   PetscValidPointer(x,2);
4296   *x = snes->vec_sol_update;
4297   PetscFunctionReturn(0);
4298 }
4299 
4300 #undef __FUNCT__
4301 #define __FUNCT__ "SNESGetFunction"
4302 /*@C
4303    SNESGetFunction - Returns the vector where the function is stored.
4304 
4305    Not Collective, but Vec is parallel if SNES is parallel. Collective if Vec is requested, but has not been created yet.
4306 
4307    Input Parameter:
4308 .  snes - the SNES context
4309 
4310    Output Parameter:
4311 +  r - the vector that is used to store residuals (or NULL if you don't want it)
4312 .  f - the function (or NULL if you don't want it); see SNESFunction for calling sequence details
4313 -  ctx - the function context (or NULL if you don't want it)
4314 
4315    Level: advanced
4316 
4317 .keywords: SNES, nonlinear, get, function
4318 
4319 .seealso: SNESSetFunction(), SNESGetSolution(), SNESFunction
4320 @*/
4321 PetscErrorCode  SNESGetFunction(SNES snes,Vec *r,PetscErrorCode (**f)(SNES,Vec,Vec,void*),void **ctx)
4322 {
4323   PetscErrorCode ierr;
4324   DM             dm;
4325 
4326   PetscFunctionBegin;
4327   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
4328   if (r) {
4329     if (!snes->vec_func) {
4330       if (snes->vec_rhs) {
4331         ierr = VecDuplicate(snes->vec_rhs,&snes->vec_func);CHKERRQ(ierr);
4332       } else if (snes->vec_sol) {
4333         ierr = VecDuplicate(snes->vec_sol,&snes->vec_func);CHKERRQ(ierr);
4334       } else if (snes->dm) {
4335         ierr = DMCreateGlobalVector(snes->dm,&snes->vec_func);CHKERRQ(ierr);
4336       }
4337     }
4338     *r = snes->vec_func;
4339   }
4340   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
4341   ierr = DMSNESGetFunction(dm,f,ctx);CHKERRQ(ierr);
4342   PetscFunctionReturn(0);
4343 }
4344 
4345 /*@C
4346    SNESGetNGS - Returns the NGS function and context.
4347 
4348    Input Parameter:
4349 .  snes - the SNES context
4350 
4351    Output Parameter:
4352 +  f - the function (or NULL) see SNESNGSFunction for details
4353 -  ctx    - the function context (or NULL)
4354 
4355    Level: advanced
4356 
4357 .keywords: SNES, nonlinear, get, function
4358 
4359 .seealso: SNESSetNGS(), SNESGetFunction()
4360 @*/
4361 
4362 #undef __FUNCT__
4363 #define __FUNCT__ "SNESGetNGS"
4364 PetscErrorCode SNESGetNGS (SNES snes, PetscErrorCode (**f)(SNES, Vec, Vec, void*), void ** ctx)
4365 {
4366   PetscErrorCode ierr;
4367   DM             dm;
4368 
4369   PetscFunctionBegin;
4370   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
4371   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
4372   ierr = DMSNESGetNGS(dm,f,ctx);CHKERRQ(ierr);
4373   PetscFunctionReturn(0);
4374 }
4375 
4376 #undef __FUNCT__
4377 #define __FUNCT__ "SNESSetOptionsPrefix"
4378 /*@C
4379    SNESSetOptionsPrefix - Sets the prefix used for searching for all
4380    SNES options in the database.
4381 
4382    Logically Collective on SNES
4383 
4384    Input Parameter:
4385 +  snes - the SNES context
4386 -  prefix - the prefix to prepend to all option names
4387 
4388    Notes:
4389    A hyphen (-) must NOT be given at the beginning of the prefix name.
4390    The first character of all runtime options is AUTOMATICALLY the hyphen.
4391 
4392    Level: advanced
4393 
4394 .keywords: SNES, set, options, prefix, database
4395 
4396 .seealso: SNESSetFromOptions()
4397 @*/
4398 PetscErrorCode  SNESSetOptionsPrefix(SNES snes,const char prefix[])
4399 {
4400   PetscErrorCode ierr;
4401 
4402   PetscFunctionBegin;
4403   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
4404   ierr = PetscObjectSetOptionsPrefix((PetscObject)snes,prefix);CHKERRQ(ierr);
4405   if (!snes->ksp) {ierr = SNESGetKSP(snes,&snes->ksp);CHKERRQ(ierr);}
4406   if (snes->linesearch) {
4407     ierr = SNESGetLineSearch(snes,&snes->linesearch);CHKERRQ(ierr);
4408     ierr = PetscObjectSetOptionsPrefix((PetscObject)snes->linesearch,prefix);CHKERRQ(ierr);
4409   }
4410   ierr = KSPSetOptionsPrefix(snes->ksp,prefix);CHKERRQ(ierr);
4411   PetscFunctionReturn(0);
4412 }
4413 
4414 #undef __FUNCT__
4415 #define __FUNCT__ "SNESAppendOptionsPrefix"
4416 /*@C
4417    SNESAppendOptionsPrefix - Appends to the prefix used for searching for all
4418    SNES options in the database.
4419 
4420    Logically Collective on SNES
4421 
4422    Input Parameters:
4423 +  snes - the SNES context
4424 -  prefix - the prefix to prepend to all option names
4425 
4426    Notes:
4427    A hyphen (-) must NOT be given at the beginning of the prefix name.
4428    The first character of all runtime options is AUTOMATICALLY the hyphen.
4429 
4430    Level: advanced
4431 
4432 .keywords: SNES, append, options, prefix, database
4433 
4434 .seealso: SNESGetOptionsPrefix()
4435 @*/
4436 PetscErrorCode  SNESAppendOptionsPrefix(SNES snes,const char prefix[])
4437 {
4438   PetscErrorCode ierr;
4439 
4440   PetscFunctionBegin;
4441   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
4442   ierr = PetscObjectAppendOptionsPrefix((PetscObject)snes,prefix);CHKERRQ(ierr);
4443   if (!snes->ksp) {ierr = SNESGetKSP(snes,&snes->ksp);CHKERRQ(ierr);}
4444   if (snes->linesearch) {
4445     ierr = SNESGetLineSearch(snes,&snes->linesearch);CHKERRQ(ierr);
4446     ierr = PetscObjectAppendOptionsPrefix((PetscObject)snes->linesearch,prefix);CHKERRQ(ierr);
4447   }
4448   ierr = KSPAppendOptionsPrefix(snes->ksp,prefix);CHKERRQ(ierr);
4449   PetscFunctionReturn(0);
4450 }
4451 
4452 #undef __FUNCT__
4453 #define __FUNCT__ "SNESGetOptionsPrefix"
4454 /*@C
4455    SNESGetOptionsPrefix - Sets the prefix used for searching for all
4456    SNES options in the database.
4457 
4458    Not Collective
4459 
4460    Input Parameter:
4461 .  snes - the SNES context
4462 
4463    Output Parameter:
4464 .  prefix - pointer to the prefix string used
4465 
4466    Notes: On the fortran side, the user should pass in a string 'prefix' of
4467    sufficient length to hold the prefix.
4468 
4469    Level: advanced
4470 
4471 .keywords: SNES, get, options, prefix, database
4472 
4473 .seealso: SNESAppendOptionsPrefix()
4474 @*/
4475 PetscErrorCode  SNESGetOptionsPrefix(SNES snes,const char *prefix[])
4476 {
4477   PetscErrorCode ierr;
4478 
4479   PetscFunctionBegin;
4480   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
4481   ierr = PetscObjectGetOptionsPrefix((PetscObject)snes,prefix);CHKERRQ(ierr);
4482   PetscFunctionReturn(0);
4483 }
4484 
4485 
4486 #undef __FUNCT__
4487 #define __FUNCT__ "SNESRegister"
4488 /*@C
4489   SNESRegister - Adds a method to the nonlinear solver package.
4490 
4491    Not collective
4492 
4493    Input Parameters:
4494 +  name_solver - name of a new user-defined solver
4495 -  routine_create - routine to create method context
4496 
4497    Notes:
4498    SNESRegister() may be called multiple times to add several user-defined solvers.
4499 
4500    Sample usage:
4501 .vb
4502    SNESRegister("my_solver",MySolverCreate);
4503 .ve
4504 
4505    Then, your solver can be chosen with the procedural interface via
4506 $     SNESSetType(snes,"my_solver")
4507    or at runtime via the option
4508 $     -snes_type my_solver
4509 
4510    Level: advanced
4511 
4512     Note: If your function is not being put into a shared library then use SNESRegister() instead
4513 
4514 .keywords: SNES, nonlinear, register
4515 
4516 .seealso: SNESRegisterAll(), SNESRegisterDestroy()
4517 
4518   Level: advanced
4519 @*/
4520 PetscErrorCode  SNESRegister(const char sname[],PetscErrorCode (*function)(SNES))
4521 {
4522   PetscErrorCode ierr;
4523 
4524   PetscFunctionBegin;
4525   ierr = PetscFunctionListAdd(&SNESList,sname,function);CHKERRQ(ierr);
4526   PetscFunctionReturn(0);
4527 }
4528 
4529 #undef __FUNCT__
4530 #define __FUNCT__ "SNESTestLocalMin"
4531 PetscErrorCode  SNESTestLocalMin(SNES snes)
4532 {
4533   PetscErrorCode ierr;
4534   PetscInt       N,i,j;
4535   Vec            u,uh,fh;
4536   PetscScalar    value;
4537   PetscReal      norm;
4538 
4539   PetscFunctionBegin;
4540   ierr = SNESGetSolution(snes,&u);CHKERRQ(ierr);
4541   ierr = VecDuplicate(u,&uh);CHKERRQ(ierr);
4542   ierr = VecDuplicate(u,&fh);CHKERRQ(ierr);
4543 
4544   /* currently only works for sequential */
4545   ierr = PetscPrintf(PETSC_COMM_WORLD,"Testing FormFunction() for local min\n");CHKERRQ(ierr);
4546   ierr = VecGetSize(u,&N);CHKERRQ(ierr);
4547   for (i=0; i<N; i++) {
4548     ierr = VecCopy(u,uh);CHKERRQ(ierr);
4549     ierr = PetscPrintf(PETSC_COMM_WORLD,"i = %D\n",i);CHKERRQ(ierr);
4550     for (j=-10; j<11; j++) {
4551       value = PetscSign(j)*PetscExpReal(PetscAbs(j)-10.0);
4552       ierr  = VecSetValue(uh,i,value,ADD_VALUES);CHKERRQ(ierr);
4553       ierr  = SNESComputeFunction(snes,uh,fh);CHKERRQ(ierr);
4554       ierr  = VecNorm(fh,NORM_2,&norm);CHKERRQ(ierr);
4555       ierr  = PetscPrintf(PETSC_COMM_WORLD,"       j norm %D %18.16e\n",j,norm);CHKERRQ(ierr);
4556       value = -value;
4557       ierr  = VecSetValue(uh,i,value,ADD_VALUES);CHKERRQ(ierr);
4558     }
4559   }
4560   ierr = VecDestroy(&uh);CHKERRQ(ierr);
4561   ierr = VecDestroy(&fh);CHKERRQ(ierr);
4562   PetscFunctionReturn(0);
4563 }
4564 
4565 #undef __FUNCT__
4566 #define __FUNCT__ "SNESKSPSetUseEW"
4567 /*@
4568    SNESKSPSetUseEW - Sets SNES use Eisenstat-Walker method for
4569    computing relative tolerance for linear solvers within an inexact
4570    Newton method.
4571 
4572    Logically Collective on SNES
4573 
4574    Input Parameters:
4575 +  snes - SNES context
4576 -  flag - PETSC_TRUE or PETSC_FALSE
4577 
4578     Options Database:
4579 +  -snes_ksp_ew - use Eisenstat-Walker method for determining linear system convergence
4580 .  -snes_ksp_ew_version ver - version of  Eisenstat-Walker method
4581 .  -snes_ksp_ew_rtol0 <rtol0> - Sets rtol0
4582 .  -snes_ksp_ew_rtolmax <rtolmax> - Sets rtolmax
4583 .  -snes_ksp_ew_gamma <gamma> - Sets gamma
4584 .  -snes_ksp_ew_alpha <alpha> - Sets alpha
4585 .  -snes_ksp_ew_alpha2 <alpha2> - Sets alpha2
4586 -  -snes_ksp_ew_threshold <threshold> - Sets threshold
4587 
4588    Notes:
4589    Currently, the default is to use a constant relative tolerance for
4590    the inner linear solvers.  Alternatively, one can use the
4591    Eisenstat-Walker method, where the relative convergence tolerance
4592    is reset at each Newton iteration according progress of the nonlinear
4593    solver.
4594 
4595    Level: advanced
4596 
4597    Reference:
4598    S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an
4599    inexact Newton method", SISC 17 (1), pp.16-32, 1996.
4600 
4601 .keywords: SNES, KSP, Eisenstat, Walker, convergence, test, inexact, Newton
4602 
4603 .seealso: SNESKSPGetUseEW(), SNESKSPGetParametersEW(), SNESKSPSetParametersEW()
4604 @*/
4605 PetscErrorCode  SNESKSPSetUseEW(SNES snes,PetscBool flag)
4606 {
4607   PetscFunctionBegin;
4608   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
4609   PetscValidLogicalCollectiveBool(snes,flag,2);
4610   snes->ksp_ewconv = flag;
4611   PetscFunctionReturn(0);
4612 }
4613 
4614 #undef __FUNCT__
4615 #define __FUNCT__ "SNESKSPGetUseEW"
4616 /*@
4617    SNESKSPGetUseEW - Gets if SNES is using Eisenstat-Walker method
4618    for computing relative tolerance for linear solvers within an
4619    inexact Newton method.
4620 
4621    Not Collective
4622 
4623    Input Parameter:
4624 .  snes - SNES context
4625 
4626    Output Parameter:
4627 .  flag - PETSC_TRUE or PETSC_FALSE
4628 
4629    Notes:
4630    Currently, the default is to use a constant relative tolerance for
4631    the inner linear solvers.  Alternatively, one can use the
4632    Eisenstat-Walker method, where the relative convergence tolerance
4633    is reset at each Newton iteration according progress of the nonlinear
4634    solver.
4635 
4636    Level: advanced
4637 
4638    Reference:
4639    S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an
4640    inexact Newton method", SISC 17 (1), pp.16-32, 1996.
4641 
4642 .keywords: SNES, KSP, Eisenstat, Walker, convergence, test, inexact, Newton
4643 
4644 .seealso: SNESKSPSetUseEW(), SNESKSPGetParametersEW(), SNESKSPSetParametersEW()
4645 @*/
4646 PetscErrorCode  SNESKSPGetUseEW(SNES snes, PetscBool  *flag)
4647 {
4648   PetscFunctionBegin;
4649   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
4650   PetscValidPointer(flag,2);
4651   *flag = snes->ksp_ewconv;
4652   PetscFunctionReturn(0);
4653 }
4654 
4655 #undef __FUNCT__
4656 #define __FUNCT__ "SNESKSPSetParametersEW"
4657 /*@
4658    SNESKSPSetParametersEW - Sets parameters for Eisenstat-Walker
4659    convergence criteria for the linear solvers within an inexact
4660    Newton method.
4661 
4662    Logically Collective on SNES
4663 
4664    Input Parameters:
4665 +    snes - SNES context
4666 .    version - version 1, 2 (default is 2) or 3
4667 .    rtol_0 - initial relative tolerance (0 <= rtol_0 < 1)
4668 .    rtol_max - maximum relative tolerance (0 <= rtol_max < 1)
4669 .    gamma - multiplicative factor for version 2 rtol computation
4670              (0 <= gamma2 <= 1)
4671 .    alpha - power for version 2 rtol computation (1 < alpha <= 2)
4672 .    alpha2 - power for safeguard
4673 -    threshold - threshold for imposing safeguard (0 < threshold < 1)
4674 
4675    Note:
4676    Version 3 was contributed by Luis Chacon, June 2006.
4677 
4678    Use PETSC_DEFAULT to retain the default for any of the parameters.
4679 
4680    Level: advanced
4681 
4682    Reference:
4683    S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an
4684    inexact Newton method", Utah State University Math. Stat. Dept. Res.
4685    Report 6/94/75, June, 1994, to appear in SIAM J. Sci. Comput.
4686 
4687 .keywords: SNES, KSP, Eisenstat, Walker, set, parameters
4688 
4689 .seealso: SNESKSPSetUseEW(), SNESKSPGetUseEW(), SNESKSPGetParametersEW()
4690 @*/
4691 PetscErrorCode  SNESKSPSetParametersEW(SNES snes,PetscInt version,PetscReal rtol_0,PetscReal rtol_max,PetscReal gamma,PetscReal alpha,PetscReal alpha2,PetscReal threshold)
4692 {
4693   SNESKSPEW *kctx;
4694 
4695   PetscFunctionBegin;
4696   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
4697   kctx = (SNESKSPEW*)snes->kspconvctx;
4698   if (!kctx) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context existing");
4699   PetscValidLogicalCollectiveInt(snes,version,2);
4700   PetscValidLogicalCollectiveReal(snes,rtol_0,3);
4701   PetscValidLogicalCollectiveReal(snes,rtol_max,4);
4702   PetscValidLogicalCollectiveReal(snes,gamma,5);
4703   PetscValidLogicalCollectiveReal(snes,alpha,6);
4704   PetscValidLogicalCollectiveReal(snes,alpha2,7);
4705   PetscValidLogicalCollectiveReal(snes,threshold,8);
4706 
4707   if (version != PETSC_DEFAULT)   kctx->version   = version;
4708   if (rtol_0 != PETSC_DEFAULT)    kctx->rtol_0    = rtol_0;
4709   if (rtol_max != PETSC_DEFAULT)  kctx->rtol_max  = rtol_max;
4710   if (gamma != PETSC_DEFAULT)     kctx->gamma     = gamma;
4711   if (alpha != PETSC_DEFAULT)     kctx->alpha     = alpha;
4712   if (alpha2 != PETSC_DEFAULT)    kctx->alpha2    = alpha2;
4713   if (threshold != PETSC_DEFAULT) kctx->threshold = threshold;
4714 
4715   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);
4716   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);
4717   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);
4718   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);
4719   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);
4720   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);
4721   PetscFunctionReturn(0);
4722 }
4723 
4724 #undef __FUNCT__
4725 #define __FUNCT__ "SNESKSPGetParametersEW"
4726 /*@
4727    SNESKSPGetParametersEW - Gets parameters for Eisenstat-Walker
4728    convergence criteria for the linear solvers within an inexact
4729    Newton method.
4730 
4731    Not Collective
4732 
4733    Input Parameters:
4734      snes - SNES context
4735 
4736    Output Parameters:
4737 +    version - version 1, 2 (default is 2) or 3
4738 .    rtol_0 - initial relative tolerance (0 <= rtol_0 < 1)
4739 .    rtol_max - maximum relative tolerance (0 <= rtol_max < 1)
4740 .    gamma - multiplicative factor for version 2 rtol computation (0 <= gamma2 <= 1)
4741 .    alpha - power for version 2 rtol computation (1 < alpha <= 2)
4742 .    alpha2 - power for safeguard
4743 -    threshold - threshold for imposing safeguard (0 < threshold < 1)
4744 
4745    Level: advanced
4746 
4747 .keywords: SNES, KSP, Eisenstat, Walker, get, parameters
4748 
4749 .seealso: SNESKSPSetUseEW(), SNESKSPGetUseEW(), SNESKSPSetParametersEW()
4750 @*/
4751 PetscErrorCode  SNESKSPGetParametersEW(SNES snes,PetscInt *version,PetscReal *rtol_0,PetscReal *rtol_max,PetscReal *gamma,PetscReal *alpha,PetscReal *alpha2,PetscReal *threshold)
4752 {
4753   SNESKSPEW *kctx;
4754 
4755   PetscFunctionBegin;
4756   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
4757   kctx = (SNESKSPEW*)snes->kspconvctx;
4758   if (!kctx) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context existing");
4759   if (version)   *version   = kctx->version;
4760   if (rtol_0)    *rtol_0    = kctx->rtol_0;
4761   if (rtol_max)  *rtol_max  = kctx->rtol_max;
4762   if (gamma)     *gamma     = kctx->gamma;
4763   if (alpha)     *alpha     = kctx->alpha;
4764   if (alpha2)    *alpha2    = kctx->alpha2;
4765   if (threshold) *threshold = kctx->threshold;
4766   PetscFunctionReturn(0);
4767 }
4768 
4769 #undef __FUNCT__
4770 #define __FUNCT__ "KSPPreSolve_SNESEW"
4771  PetscErrorCode KSPPreSolve_SNESEW(KSP ksp, Vec b, Vec x, SNES snes)
4772 {
4773   PetscErrorCode ierr;
4774   SNESKSPEW      *kctx = (SNESKSPEW*)snes->kspconvctx;
4775   PetscReal      rtol  = PETSC_DEFAULT,stol;
4776 
4777   PetscFunctionBegin;
4778   if (!snes->ksp_ewconv) PetscFunctionReturn(0);
4779   if (!snes->iter) {
4780     rtol = kctx->rtol_0; /* first time in, so use the original user rtol */
4781     ierr = VecNorm(snes->vec_func,NORM_2,&kctx->norm_first);CHKERRQ(ierr);
4782   }
4783   else {
4784     if (kctx->version == 1) {
4785       rtol = (snes->norm - kctx->lresid_last)/kctx->norm_last;
4786       if (rtol < 0.0) rtol = -rtol;
4787       stol = PetscPowReal(kctx->rtol_last,kctx->alpha2);
4788       if (stol > kctx->threshold) rtol = PetscMax(rtol,stol);
4789     } else if (kctx->version == 2) {
4790       rtol = kctx->gamma * PetscPowReal(snes->norm/kctx->norm_last,kctx->alpha);
4791       stol = kctx->gamma * PetscPowReal(kctx->rtol_last,kctx->alpha);
4792       if (stol > kctx->threshold) rtol = PetscMax(rtol,stol);
4793     } else if (kctx->version == 3) { /* contributed by Luis Chacon, June 2006. */
4794       rtol = kctx->gamma * PetscPowReal(snes->norm/kctx->norm_last,kctx->alpha);
4795       /* safeguard: avoid sharp decrease of rtol */
4796       stol = kctx->gamma*PetscPowReal(kctx->rtol_last,kctx->alpha);
4797       stol = PetscMax(rtol,stol);
4798       rtol = PetscMin(kctx->rtol_0,stol);
4799       /* safeguard: avoid oversolving */
4800       stol = kctx->gamma*(kctx->norm_first*snes->rtol)/snes->norm;
4801       stol = PetscMax(rtol,stol);
4802       rtol = PetscMin(kctx->rtol_0,stol);
4803     } else SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Only versions 1, 2 or 3 are supported: %D",kctx->version);
4804   }
4805   /* safeguard: avoid rtol greater than one */
4806   rtol = PetscMin(rtol,kctx->rtol_max);
4807   ierr = KSPSetTolerances(ksp,rtol,PETSC_DEFAULT,PETSC_DEFAULT,PETSC_DEFAULT);CHKERRQ(ierr);
4808   ierr = PetscInfo3(snes,"iter %D, Eisenstat-Walker (version %D) KSP rtol=%g\n",snes->iter,kctx->version,(double)rtol);CHKERRQ(ierr);
4809   PetscFunctionReturn(0);
4810 }
4811 
4812 #undef __FUNCT__
4813 #define __FUNCT__ "KSPPostSolve_SNESEW"
4814 PetscErrorCode KSPPostSolve_SNESEW(KSP ksp, Vec b, Vec x, SNES snes)
4815 {
4816   PetscErrorCode ierr;
4817   SNESKSPEW      *kctx = (SNESKSPEW*)snes->kspconvctx;
4818   PCSide         pcside;
4819   Vec            lres;
4820 
4821   PetscFunctionBegin;
4822   if (!snes->ksp_ewconv) PetscFunctionReturn(0);
4823   ierr = KSPGetTolerances(ksp,&kctx->rtol_last,0,0,0);CHKERRQ(ierr);
4824   kctx->norm_last = snes->norm;
4825   if (kctx->version == 1) {
4826     PC        pc;
4827     PetscBool isNone;
4828 
4829     ierr = KSPGetPC(ksp, &pc);CHKERRQ(ierr);
4830     ierr = PetscObjectTypeCompare((PetscObject) pc, PCNONE, &isNone);CHKERRQ(ierr);
4831     ierr = KSPGetPCSide(ksp,&pcside);CHKERRQ(ierr);
4832      if (pcside == PC_RIGHT || isNone) { /* XXX Should we also test KSP_UNPRECONDITIONED_NORM ? */
4833       /* KSP residual is true linear residual */
4834       ierr = KSPGetResidualNorm(ksp,&kctx->lresid_last);CHKERRQ(ierr);
4835     } else {
4836       /* KSP residual is preconditioned residual */
4837       /* compute true linear residual norm */
4838       ierr = VecDuplicate(b,&lres);CHKERRQ(ierr);
4839       ierr = MatMult(snes->jacobian,x,lres);CHKERRQ(ierr);
4840       ierr = VecAYPX(lres,-1.0,b);CHKERRQ(ierr);
4841       ierr = VecNorm(lres,NORM_2,&kctx->lresid_last);CHKERRQ(ierr);
4842       ierr = VecDestroy(&lres);CHKERRQ(ierr);
4843     }
4844   }
4845   PetscFunctionReturn(0);
4846 }
4847 
4848 #undef __FUNCT__
4849 #define __FUNCT__ "SNESGetKSP"
4850 /*@
4851    SNESGetKSP - Returns the KSP context for a SNES solver.
4852 
4853    Not Collective, but if SNES object is parallel, then KSP object is parallel
4854 
4855    Input Parameter:
4856 .  snes - the SNES context
4857 
4858    Output Parameter:
4859 .  ksp - the KSP context
4860 
4861    Notes:
4862    The user can then directly manipulate the KSP context to set various
4863    options, etc.  Likewise, the user can then extract and manipulate the
4864    PC contexts as well.
4865 
4866    Level: beginner
4867 
4868 .keywords: SNES, nonlinear, get, KSP, context
4869 
4870 .seealso: KSPGetPC(), SNESCreate(), KSPCreate(), SNESSetKSP()
4871 @*/
4872 PetscErrorCode  SNESGetKSP(SNES snes,KSP *ksp)
4873 {
4874   PetscErrorCode ierr;
4875 
4876   PetscFunctionBegin;
4877   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
4878   PetscValidPointer(ksp,2);
4879 
4880   if (!snes->ksp) {
4881     PetscBool monitor = PETSC_FALSE;
4882 
4883     ierr = KSPCreate(PetscObjectComm((PetscObject)snes),&snes->ksp);CHKERRQ(ierr);
4884     ierr = PetscObjectIncrementTabLevel((PetscObject)snes->ksp,(PetscObject)snes,1);CHKERRQ(ierr);
4885     ierr = PetscLogObjectParent((PetscObject)snes,(PetscObject)snes->ksp);CHKERRQ(ierr);
4886 
4887     ierr = KSPSetPreSolve(snes->ksp,(PetscErrorCode (*)(KSP,Vec,Vec,void*))KSPPreSolve_SNESEW,snes);CHKERRQ(ierr);
4888     ierr = KSPSetPostSolve(snes->ksp,(PetscErrorCode (*)(KSP,Vec,Vec,void*))KSPPostSolve_SNESEW,snes);CHKERRQ(ierr);
4889 
4890     ierr = PetscOptionsGetBool(((PetscObject)snes)->options,((PetscObject)snes)->prefix,"-ksp_monitor_snes",&monitor,NULL);CHKERRQ(ierr);
4891     if (monitor) {
4892       ierr = KSPMonitorSet(snes->ksp,KSPMonitorSNES,snes,NULL);CHKERRQ(ierr);
4893     }
4894     monitor = PETSC_FALSE;
4895     ierr = PetscOptionsGetBool(((PetscObject)snes)->options,((PetscObject)snes)->prefix,"-ksp_monitor_snes_lg",&monitor,NULL);CHKERRQ(ierr);
4896     if (monitor) {
4897       PetscObject *objs;
4898       ierr = KSPMonitorSNESLGResidualNormCreate(PetscObjectComm((PetscObject)snes),NULL,NULL,PETSC_DECIDE,PETSC_DECIDE,600,600,&objs);CHKERRQ(ierr);
4899       objs[0] = (PetscObject) snes;
4900       ierr = KSPMonitorSet(snes->ksp,(PetscErrorCode (*)(KSP,PetscInt,PetscReal,void*))KSPMonitorSNESLGResidualNorm,objs,(PetscErrorCode (*)(void**))KSPMonitorSNESLGResidualNormDestroy);CHKERRQ(ierr);
4901     }
4902   }
4903   *ksp = snes->ksp;
4904   PetscFunctionReturn(0);
4905 }
4906 
4907 
4908 #include <petsc/private/dmimpl.h>
4909 #undef __FUNCT__
4910 #define __FUNCT__ "SNESSetDM"
4911 /*@
4912    SNESSetDM - Sets the DM that may be used by some nonlinear solvers or their underlying preconditioners
4913 
4914    Logically Collective on SNES
4915 
4916    Input Parameters:
4917 +  snes - the nonlinear solver context
4918 -  dm - the dm, cannot be NULL
4919 
4920    Level: intermediate
4921 
4922 .seealso: SNESGetDM(), KSPSetDM(), KSPGetDM()
4923 @*/
4924 PetscErrorCode  SNESSetDM(SNES snes,DM dm)
4925 {
4926   PetscErrorCode ierr;
4927   KSP            ksp;
4928   DMSNES         sdm;
4929 
4930   PetscFunctionBegin;
4931   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
4932   PetscValidHeaderSpecific(dm,DM_CLASSID,2);
4933   ierr = PetscObjectReference((PetscObject)dm);CHKERRQ(ierr);
4934   if (snes->dm) {               /* Move the DMSNES context over to the new DM unless the new DM already has one */
4935     if (snes->dm->dmsnes && !dm->dmsnes) {
4936       ierr = DMCopyDMSNES(snes->dm,dm);CHKERRQ(ierr);
4937       ierr = DMGetDMSNES(snes->dm,&sdm);CHKERRQ(ierr);
4938       if (sdm->originaldm == snes->dm) sdm->originaldm = dm; /* Grant write privileges to the replacement DM */
4939     }
4940     ierr = DMDestroy(&snes->dm);CHKERRQ(ierr);
4941   }
4942   snes->dm     = dm;
4943   snes->dmAuto = PETSC_FALSE;
4944 
4945   ierr = SNESGetKSP(snes,&ksp);CHKERRQ(ierr);
4946   ierr = KSPSetDM(ksp,dm);CHKERRQ(ierr);
4947   ierr = KSPSetDMActive(ksp,PETSC_FALSE);CHKERRQ(ierr);
4948   if (snes->pc) {
4949     ierr = SNESSetDM(snes->pc, snes->dm);CHKERRQ(ierr);
4950     ierr = SNESSetNPCSide(snes,snes->pcside);CHKERRQ(ierr);
4951   }
4952   PetscFunctionReturn(0);
4953 }
4954 
4955 #undef __FUNCT__
4956 #define __FUNCT__ "SNESGetDM"
4957 /*@
4958    SNESGetDM - Gets the DM that may be used by some preconditioners
4959 
4960    Not Collective but DM obtained is parallel on SNES
4961 
4962    Input Parameter:
4963 . snes - the preconditioner context
4964 
4965    Output Parameter:
4966 .  dm - the dm
4967 
4968    Level: intermediate
4969 
4970 .seealso: SNESSetDM(), KSPSetDM(), KSPGetDM()
4971 @*/
4972 PetscErrorCode  SNESGetDM(SNES snes,DM *dm)
4973 {
4974   PetscErrorCode ierr;
4975 
4976   PetscFunctionBegin;
4977   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
4978   if (!snes->dm) {
4979     ierr         = DMShellCreate(PetscObjectComm((PetscObject)snes),&snes->dm);CHKERRQ(ierr);
4980     snes->dmAuto = PETSC_TRUE;
4981   }
4982   *dm = snes->dm;
4983   PetscFunctionReturn(0);
4984 }
4985 
4986 #undef __FUNCT__
4987 #define __FUNCT__ "SNESSetNPC"
4988 /*@
4989   SNESSetNPC - Sets the nonlinear preconditioner to be used.
4990 
4991   Collective on SNES
4992 
4993   Input Parameters:
4994 + snes - iterative context obtained from SNESCreate()
4995 - pc   - the preconditioner object
4996 
4997   Notes:
4998   Use SNESGetNPC() to retrieve the preconditioner context (for example,
4999   to configure it using the API).
5000 
5001   Level: developer
5002 
5003 .keywords: SNES, set, precondition
5004 .seealso: SNESGetNPC(), SNESHasNPC()
5005 @*/
5006 PetscErrorCode SNESSetNPC(SNES snes, SNES pc)
5007 {
5008   PetscErrorCode ierr;
5009 
5010   PetscFunctionBegin;
5011   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
5012   PetscValidHeaderSpecific(pc, SNES_CLASSID, 2);
5013   PetscCheckSameComm(snes, 1, pc, 2);
5014   ierr     = PetscObjectReference((PetscObject) pc);CHKERRQ(ierr);
5015   ierr     = SNESDestroy(&snes->pc);CHKERRQ(ierr);
5016   snes->pc = pc;
5017   ierr     = PetscLogObjectParent((PetscObject)snes, (PetscObject)snes->pc);CHKERRQ(ierr);
5018   PetscFunctionReturn(0);
5019 }
5020 
5021 #undef __FUNCT__
5022 #define __FUNCT__ "SNESGetNPC"
5023 /*@
5024   SNESGetNPC - Creates a nonlinear preconditioning solver (SNES) to be used to precondition the nonlinear solver.
5025 
5026   Not Collective
5027 
5028   Input Parameter:
5029 . snes - iterative context obtained from SNESCreate()
5030 
5031   Output Parameter:
5032 . pc - preconditioner context
5033 
5034   Notes: If a SNES was previously set with SNESSetNPC() then that SNES is returned.
5035 
5036   Level: developer
5037 
5038 .keywords: SNES, get, preconditioner
5039 .seealso: SNESSetNPC(), SNESHasNPC()
5040 @*/
5041 PetscErrorCode SNESGetNPC(SNES snes, SNES *pc)
5042 {
5043   PetscErrorCode ierr;
5044   const char     *optionsprefix;
5045 
5046   PetscFunctionBegin;
5047   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
5048   PetscValidPointer(pc, 2);
5049   if (!snes->pc) {
5050     ierr = SNESCreate(PetscObjectComm((PetscObject)snes),&snes->pc);CHKERRQ(ierr);
5051     ierr = PetscObjectIncrementTabLevel((PetscObject)snes->pc,(PetscObject)snes,1);CHKERRQ(ierr);
5052     ierr = PetscLogObjectParent((PetscObject)snes,(PetscObject)snes->pc);CHKERRQ(ierr);
5053     ierr = SNESGetOptionsPrefix(snes,&optionsprefix);CHKERRQ(ierr);
5054     ierr = SNESSetOptionsPrefix(snes->pc,optionsprefix);CHKERRQ(ierr);
5055     ierr = SNESAppendOptionsPrefix(snes->pc,"npc_");CHKERRQ(ierr);
5056     ierr = SNESSetCountersReset(snes->pc,PETSC_FALSE);CHKERRQ(ierr);
5057   }
5058   *pc = snes->pc;
5059   PetscFunctionReturn(0);
5060 }
5061 
5062 #undef __FUNCT__
5063 #define __FUNCT__ "SNESHasNPC"
5064 /*@
5065   SNESHasNPC - Returns whether a nonlinear preconditioner exists
5066 
5067   Not Collective
5068 
5069   Input Parameter:
5070 . snes - iterative context obtained from SNESCreate()
5071 
5072   Output Parameter:
5073 . has_npc - whether the SNES has an NPC or not
5074 
5075   Level: developer
5076 
5077 .keywords: SNES, has, preconditioner
5078 .seealso: SNESSetNPC(), SNESGetNPC()
5079 @*/
5080 PetscErrorCode SNESHasNPC(SNES snes, PetscBool *has_npc)
5081 {
5082   PetscFunctionBegin;
5083   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
5084   *has_npc = (PetscBool) (snes->pc ? PETSC_TRUE : PETSC_FALSE);
5085   PetscFunctionReturn(0);
5086 }
5087 
5088 #undef __FUNCT__
5089 #define __FUNCT__ "SNESSetNPCSide"
5090 /*@
5091     SNESSetNPCSide - Sets the preconditioning side.
5092 
5093     Logically Collective on SNES
5094 
5095     Input Parameter:
5096 .   snes - iterative context obtained from SNESCreate()
5097 
5098     Output Parameter:
5099 .   side - the preconditioning side, where side is one of
5100 .vb
5101       PC_LEFT - left preconditioning
5102       PC_RIGHT - right preconditioning (default for most nonlinear solvers)
5103 .ve
5104 
5105     Options Database Keys:
5106 .   -snes_pc_side <right,left>
5107 
5108     Notes: SNESNRICHARDSON and SNESNCG only support left preconditioning.
5109 
5110     Level: intermediate
5111 
5112 .keywords: SNES, set, right, left, side, preconditioner, flag
5113 
5114 .seealso: SNESGetNPCSide(), KSPSetPCSide()
5115 @*/
5116 PetscErrorCode  SNESSetNPCSide(SNES snes,PCSide side)
5117 {
5118   PetscFunctionBegin;
5119   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
5120   PetscValidLogicalCollectiveEnum(snes,side,2);
5121   snes->pcside = side;
5122   PetscFunctionReturn(0);
5123 }
5124 
5125 #undef __FUNCT__
5126 #define __FUNCT__ "SNESGetNPCSide"
5127 /*@
5128     SNESGetNPCSide - Gets the preconditioning side.
5129 
5130     Not Collective
5131 
5132     Input Parameter:
5133 .   snes - iterative context obtained from SNESCreate()
5134 
5135     Output Parameter:
5136 .   side - the preconditioning side, where side is one of
5137 .vb
5138       PC_LEFT - left preconditioning
5139       PC_RIGHT - right preconditioning (default for most nonlinear solvers)
5140 .ve
5141 
5142     Level: intermediate
5143 
5144 .keywords: SNES, get, right, left, side, preconditioner, flag
5145 
5146 .seealso: SNESSetNPCSide(), KSPGetPCSide()
5147 @*/
5148 PetscErrorCode  SNESGetNPCSide(SNES snes,PCSide *side)
5149 {
5150   PetscFunctionBegin;
5151   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
5152   PetscValidPointer(side,2);
5153   *side = snes->pcside;
5154   PetscFunctionReturn(0);
5155 }
5156 
5157 #undef __FUNCT__
5158 #define __FUNCT__ "SNESSetLineSearch"
5159 /*@
5160   SNESSetLineSearch - Sets the linesearch on the SNES instance.
5161 
5162   Collective on SNES
5163 
5164   Input Parameters:
5165 + snes - iterative context obtained from SNESCreate()
5166 - linesearch   - the linesearch object
5167 
5168   Notes:
5169   Use SNESGetLineSearch() to retrieve the preconditioner context (for example,
5170   to configure it using the API).
5171 
5172   Level: developer
5173 
5174 .keywords: SNES, set, linesearch
5175 .seealso: SNESGetLineSearch()
5176 @*/
5177 PetscErrorCode SNESSetLineSearch(SNES snes, SNESLineSearch linesearch)
5178 {
5179   PetscErrorCode ierr;
5180 
5181   PetscFunctionBegin;
5182   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
5183   PetscValidHeaderSpecific(linesearch, SNESLINESEARCH_CLASSID, 2);
5184   PetscCheckSameComm(snes, 1, linesearch, 2);
5185   ierr = PetscObjectReference((PetscObject) linesearch);CHKERRQ(ierr);
5186   ierr = SNESLineSearchDestroy(&snes->linesearch);CHKERRQ(ierr);
5187 
5188   snes->linesearch = linesearch;
5189 
5190   ierr = PetscLogObjectParent((PetscObject)snes, (PetscObject)snes->linesearch);CHKERRQ(ierr);
5191   PetscFunctionReturn(0);
5192 }
5193 
5194 #undef __FUNCT__
5195 #define __FUNCT__ "SNESGetLineSearch"
5196 /*@
5197   SNESGetLineSearch - Returns a pointer to the line search context set with SNESSetLineSearch()
5198   or creates a default line search instance associated with the SNES and returns it.
5199 
5200   Not Collective
5201 
5202   Input Parameter:
5203 . snes - iterative context obtained from SNESCreate()
5204 
5205   Output Parameter:
5206 . linesearch - linesearch context
5207 
5208   Level: beginner
5209 
5210 .keywords: SNES, get, linesearch
5211 .seealso: SNESSetLineSearch(), SNESLineSearchCreate()
5212 @*/
5213 PetscErrorCode SNESGetLineSearch(SNES snes, SNESLineSearch *linesearch)
5214 {
5215   PetscErrorCode ierr;
5216   const char     *optionsprefix;
5217 
5218   PetscFunctionBegin;
5219   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
5220   PetscValidPointer(linesearch, 2);
5221   if (!snes->linesearch) {
5222     ierr = SNESGetOptionsPrefix(snes, &optionsprefix);CHKERRQ(ierr);
5223     ierr = SNESLineSearchCreate(PetscObjectComm((PetscObject)snes), &snes->linesearch);CHKERRQ(ierr);
5224     ierr = SNESLineSearchSetSNES(snes->linesearch, snes);CHKERRQ(ierr);
5225     ierr = SNESLineSearchAppendOptionsPrefix(snes->linesearch, optionsprefix);CHKERRQ(ierr);
5226     ierr = PetscObjectIncrementTabLevel((PetscObject) snes->linesearch, (PetscObject) snes, 1);CHKERRQ(ierr);
5227     ierr = PetscLogObjectParent((PetscObject)snes, (PetscObject)snes->linesearch);CHKERRQ(ierr);
5228   }
5229   *linesearch = snes->linesearch;
5230   PetscFunctionReturn(0);
5231 }
5232 
5233 #if defined(PETSC_HAVE_MATLAB_ENGINE)
5234 #include <mex.h>
5235 
5236 typedef struct {char *funcname; mxArray *ctx;} SNESMatlabContext;
5237 
5238 #undef __FUNCT__
5239 #define __FUNCT__ "SNESComputeFunction_Matlab"
5240 /*
5241    SNESComputeFunction_Matlab - Calls the function that has been set with SNESSetFunctionMatlab().
5242 
5243    Collective on SNES
5244 
5245    Input Parameters:
5246 +  snes - the SNES context
5247 -  x - input vector
5248 
5249    Output Parameter:
5250 .  y - function vector, as set by SNESSetFunction()
5251 
5252    Notes:
5253    SNESComputeFunction() is typically used within nonlinear solvers
5254    implementations, so most users would not generally call this routine
5255    themselves.
5256 
5257    Level: developer
5258 
5259 .keywords: SNES, nonlinear, compute, function
5260 
5261 .seealso: SNESSetFunction(), SNESGetFunction()
5262 */
5263 PetscErrorCode  SNESComputeFunction_Matlab(SNES snes,Vec x,Vec y, void *ctx)
5264 {
5265   PetscErrorCode    ierr;
5266   SNESMatlabContext *sctx = (SNESMatlabContext*)ctx;
5267   int               nlhs  = 1,nrhs = 5;
5268   mxArray           *plhs[1],*prhs[5];
5269   long long int     lx = 0,ly = 0,ls = 0;
5270 
5271   PetscFunctionBegin;
5272   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
5273   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
5274   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
5275   PetscCheckSameComm(snes,1,x,2);
5276   PetscCheckSameComm(snes,1,y,3);
5277 
5278   /* call Matlab function in ctx with arguments x and y */
5279 
5280   ierr    = PetscMemcpy(&ls,&snes,sizeof(snes));CHKERRQ(ierr);
5281   ierr    = PetscMemcpy(&lx,&x,sizeof(x));CHKERRQ(ierr);
5282   ierr    = PetscMemcpy(&ly,&y,sizeof(x));CHKERRQ(ierr);
5283   prhs[0] = mxCreateDoubleScalar((double)ls);
5284   prhs[1] = mxCreateDoubleScalar((double)lx);
5285   prhs[2] = mxCreateDoubleScalar((double)ly);
5286   prhs[3] = mxCreateString(sctx->funcname);
5287   prhs[4] = sctx->ctx;
5288   ierr    = mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscSNESComputeFunctionInternal");CHKERRQ(ierr);
5289   ierr    = mxGetScalar(plhs[0]);CHKERRQ(ierr);
5290   mxDestroyArray(prhs[0]);
5291   mxDestroyArray(prhs[1]);
5292   mxDestroyArray(prhs[2]);
5293   mxDestroyArray(prhs[3]);
5294   mxDestroyArray(plhs[0]);
5295   PetscFunctionReturn(0);
5296 }
5297 
5298 #undef __FUNCT__
5299 #define __FUNCT__ "SNESSetFunctionMatlab"
5300 /*
5301    SNESSetFunctionMatlab - Sets the function evaluation routine and function
5302    vector for use by the SNES routines in solving systems of nonlinear
5303    equations from MATLAB. Here the function is a string containing the name of a MATLAB function
5304 
5305    Logically Collective on SNES
5306 
5307    Input Parameters:
5308 +  snes - the SNES context
5309 .  r - vector to store function value
5310 -  f - function evaluation routine
5311 
5312    Notes:
5313    The Newton-like methods typically solve linear systems of the form
5314 $      f'(x) x = -f(x),
5315    where f'(x) denotes the Jacobian matrix and f(x) is the function.
5316 
5317    Level: beginner
5318 
5319    Developer Note:  This bleeds the allocated memory SNESMatlabContext *sctx;
5320 
5321 .keywords: SNES, nonlinear, set, function
5322 
5323 .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction()
5324 */
5325 PetscErrorCode  SNESSetFunctionMatlab(SNES snes,Vec r,const char *f,mxArray *ctx)
5326 {
5327   PetscErrorCode    ierr;
5328   SNESMatlabContext *sctx;
5329 
5330   PetscFunctionBegin;
5331   /* currently sctx is memory bleed */
5332   ierr = PetscNew(&sctx);CHKERRQ(ierr);
5333   ierr = PetscStrallocpy(f,&sctx->funcname);CHKERRQ(ierr);
5334   /*
5335      This should work, but it doesn't
5336   sctx->ctx = ctx;
5337   mexMakeArrayPersistent(sctx->ctx);
5338   */
5339   sctx->ctx = mxDuplicateArray(ctx);
5340   ierr      = SNESSetFunction(snes,r,SNESComputeFunction_Matlab,sctx);CHKERRQ(ierr);
5341   PetscFunctionReturn(0);
5342 }
5343 
5344 #undef __FUNCT__
5345 #define __FUNCT__ "SNESComputeJacobian_Matlab"
5346 /*
5347    SNESComputeJacobian_Matlab - Calls the function that has been set with SNESSetJacobianMatlab().
5348 
5349    Collective on SNES
5350 
5351    Input Parameters:
5352 +  snes - the SNES context
5353 .  x - input vector
5354 .  A, B - the matrices
5355 -  ctx - user context
5356 
5357    Level: developer
5358 
5359 .keywords: SNES, nonlinear, compute, function
5360 
5361 .seealso: SNESSetFunction(), SNESGetFunction()
5362 @*/
5363 PetscErrorCode  SNESComputeJacobian_Matlab(SNES snes,Vec x,Mat A,Mat B,void *ctx)
5364 {
5365   PetscErrorCode    ierr;
5366   SNESMatlabContext *sctx = (SNESMatlabContext*)ctx;
5367   int               nlhs  = 2,nrhs = 6;
5368   mxArray           *plhs[2],*prhs[6];
5369   long long int     lx = 0,lA = 0,ls = 0, lB = 0;
5370 
5371   PetscFunctionBegin;
5372   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
5373   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
5374 
5375   /* call Matlab function in ctx with arguments x and y */
5376 
5377   ierr    = PetscMemcpy(&ls,&snes,sizeof(snes));CHKERRQ(ierr);
5378   ierr    = PetscMemcpy(&lx,&x,sizeof(x));CHKERRQ(ierr);
5379   ierr    = PetscMemcpy(&lA,A,sizeof(x));CHKERRQ(ierr);
5380   ierr    = PetscMemcpy(&lB,B,sizeof(x));CHKERRQ(ierr);
5381   prhs[0] = mxCreateDoubleScalar((double)ls);
5382   prhs[1] = mxCreateDoubleScalar((double)lx);
5383   prhs[2] = mxCreateDoubleScalar((double)lA);
5384   prhs[3] = mxCreateDoubleScalar((double)lB);
5385   prhs[4] = mxCreateString(sctx->funcname);
5386   prhs[5] = sctx->ctx;
5387   ierr    = mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscSNESComputeJacobianInternal");CHKERRQ(ierr);
5388   ierr    = mxGetScalar(plhs[0]);CHKERRQ(ierr);
5389   mxDestroyArray(prhs[0]);
5390   mxDestroyArray(prhs[1]);
5391   mxDestroyArray(prhs[2]);
5392   mxDestroyArray(prhs[3]);
5393   mxDestroyArray(prhs[4]);
5394   mxDestroyArray(plhs[0]);
5395   mxDestroyArray(plhs[1]);
5396   PetscFunctionReturn(0);
5397 }
5398 
5399 #undef __FUNCT__
5400 #define __FUNCT__ "SNESSetJacobianMatlab"
5401 /*
5402    SNESSetJacobianMatlab - Sets the Jacobian function evaluation routine and two empty Jacobian matrices
5403    vector for use by the SNES routines in solving systems of nonlinear
5404    equations from MATLAB. Here the function is a string containing the name of a MATLAB function
5405 
5406    Logically Collective on SNES
5407 
5408    Input Parameters:
5409 +  snes - the SNES context
5410 .  A,B - Jacobian matrices
5411 .  J - function evaluation routine
5412 -  ctx - user context
5413 
5414    Level: developer
5415 
5416    Developer Note:  This bleeds the allocated memory SNESMatlabContext *sctx;
5417 
5418 .keywords: SNES, nonlinear, set, function
5419 
5420 .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction(), J
5421 */
5422 PetscErrorCode  SNESSetJacobianMatlab(SNES snes,Mat A,Mat B,const char *J,mxArray *ctx)
5423 {
5424   PetscErrorCode    ierr;
5425   SNESMatlabContext *sctx;
5426 
5427   PetscFunctionBegin;
5428   /* currently sctx is memory bleed */
5429   ierr = PetscNew(&sctx);CHKERRQ(ierr);
5430   ierr = PetscStrallocpy(J,&sctx->funcname);CHKERRQ(ierr);
5431   /*
5432      This should work, but it doesn't
5433   sctx->ctx = ctx;
5434   mexMakeArrayPersistent(sctx->ctx);
5435   */
5436   sctx->ctx = mxDuplicateArray(ctx);
5437   ierr      = SNESSetJacobian(snes,A,B,SNESComputeJacobian_Matlab,sctx);CHKERRQ(ierr);
5438   PetscFunctionReturn(0);
5439 }
5440 
5441 #undef __FUNCT__
5442 #define __FUNCT__ "SNESMonitor_Matlab"
5443 /*
5444    SNESMonitor_Matlab - Calls the function that has been set with SNESMonitorSetMatlab().
5445 
5446    Collective on SNES
5447 
5448 .seealso: SNESSetFunction(), SNESGetFunction()
5449 @*/
5450 PetscErrorCode  SNESMonitor_Matlab(SNES snes,PetscInt it, PetscReal fnorm, void *ctx)
5451 {
5452   PetscErrorCode    ierr;
5453   SNESMatlabContext *sctx = (SNESMatlabContext*)ctx;
5454   int               nlhs  = 1,nrhs = 6;
5455   mxArray           *plhs[1],*prhs[6];
5456   long long int     lx = 0,ls = 0;
5457   Vec               x  = snes->vec_sol;
5458 
5459   PetscFunctionBegin;
5460   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
5461 
5462   ierr    = PetscMemcpy(&ls,&snes,sizeof(snes));CHKERRQ(ierr);
5463   ierr    = PetscMemcpy(&lx,&x,sizeof(x));CHKERRQ(ierr);
5464   prhs[0] = mxCreateDoubleScalar((double)ls);
5465   prhs[1] = mxCreateDoubleScalar((double)it);
5466   prhs[2] = mxCreateDoubleScalar((double)fnorm);
5467   prhs[3] = mxCreateDoubleScalar((double)lx);
5468   prhs[4] = mxCreateString(sctx->funcname);
5469   prhs[5] = sctx->ctx;
5470   ierr    = mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscSNESMonitorInternal");CHKERRQ(ierr);
5471   ierr    = mxGetScalar(plhs[0]);CHKERRQ(ierr);
5472   mxDestroyArray(prhs[0]);
5473   mxDestroyArray(prhs[1]);
5474   mxDestroyArray(prhs[2]);
5475   mxDestroyArray(prhs[3]);
5476   mxDestroyArray(prhs[4]);
5477   mxDestroyArray(plhs[0]);
5478   PetscFunctionReturn(0);
5479 }
5480 
5481 #undef __FUNCT__
5482 #define __FUNCT__ "SNESMonitorSetMatlab"
5483 /*
5484    SNESMonitorSetMatlab - Sets the monitor function from MATLAB
5485 
5486    Level: developer
5487 
5488    Developer Note:  This bleeds the allocated memory SNESMatlabContext *sctx;
5489 
5490 .keywords: SNES, nonlinear, set, function
5491 
5492 .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction()
5493 */
5494 PetscErrorCode  SNESMonitorSetMatlab(SNES snes,const char *f,mxArray *ctx)
5495 {
5496   PetscErrorCode    ierr;
5497   SNESMatlabContext *sctx;
5498 
5499   PetscFunctionBegin;
5500   /* currently sctx is memory bleed */
5501   ierr = PetscNew(&sctx);CHKERRQ(ierr);
5502   ierr = PetscStrallocpy(f,&sctx->funcname);CHKERRQ(ierr);
5503   /*
5504      This should work, but it doesn't
5505   sctx->ctx = ctx;
5506   mexMakeArrayPersistent(sctx->ctx);
5507   */
5508   sctx->ctx = mxDuplicateArray(ctx);
5509   ierr      = SNESMonitorSet(snes,SNESMonitor_Matlab,sctx,NULL);CHKERRQ(ierr);
5510   PetscFunctionReturn(0);
5511 }
5512 
5513 #endif
5514