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