xref: /petsc/src/snes/interface/snes.c (revision 3e1910f1ab6113d8365e15c6b8c907ccce7ce4ea)
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();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();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(SNESList,type,&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 SNESRegister().
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 - Adds a method to the nonlinear solver package.
4061 
4062    Not collective
4063 
4064    Input Parameters:
4065 +  name_solver - name of a new user-defined solver
4066 -  routine_create - routine to create method context
4067 
4068    Notes:
4069    SNESRegister() may be called multiple times to add several user-defined solvers.
4070 
4071    Sample usage:
4072 .vb
4073    SNESRegister("my_solver",MySolverCreate);
4074 .ve
4075 
4076    Then, your solver can be chosen with the procedural interface via
4077 $     SNESSetType(snes,"my_solver")
4078    or at runtime via the option
4079 $     -snes_type my_solver
4080 
4081    Level: advanced
4082 
4083     Note: If your function is not being put into a shared library then use SNESRegister() instead
4084 
4085 .keywords: SNES, nonlinear, register
4086 
4087 .seealso: SNESRegisterAll(), SNESRegisterDestroy()
4088 
4089   Level: advanced
4090 @*/
4091 PetscErrorCode  SNESRegister(const char sname[],PetscErrorCode (*function)(SNES))
4092 {
4093   PetscErrorCode ierr;
4094 
4095   PetscFunctionBegin;
4096   ierr = PetscFunctionListAdd(&SNESList,sname,function);CHKERRQ(ierr);
4097   PetscFunctionReturn(0);
4098 }
4099 
4100 #undef __FUNCT__
4101 #define __FUNCT__ "SNESTestLocalMin"
4102 PetscErrorCode  SNESTestLocalMin(SNES snes)
4103 {
4104   PetscErrorCode ierr;
4105   PetscInt       N,i,j;
4106   Vec            u,uh,fh;
4107   PetscScalar    value;
4108   PetscReal      norm;
4109 
4110   PetscFunctionBegin;
4111   ierr = SNESGetSolution(snes,&u);CHKERRQ(ierr);
4112   ierr = VecDuplicate(u,&uh);CHKERRQ(ierr);
4113   ierr = VecDuplicate(u,&fh);CHKERRQ(ierr);
4114 
4115   /* currently only works for sequential */
4116   ierr = PetscPrintf(PETSC_COMM_WORLD,"Testing FormFunction() for local min\n");CHKERRQ(ierr);
4117   ierr = VecGetSize(u,&N);CHKERRQ(ierr);
4118   for (i=0; i<N; i++) {
4119     ierr = VecCopy(u,uh);CHKERRQ(ierr);
4120     ierr = PetscPrintf(PETSC_COMM_WORLD,"i = %D\n",i);CHKERRQ(ierr);
4121     for (j=-10; j<11; j++) {
4122       value = PetscSign(j)*exp(PetscAbs(j)-10.0);
4123       ierr  = VecSetValue(uh,i,value,ADD_VALUES);CHKERRQ(ierr);
4124       ierr  = SNESComputeFunction(snes,uh,fh);CHKERRQ(ierr);
4125       ierr  = VecNorm(fh,NORM_2,&norm);CHKERRQ(ierr);
4126       ierr  = PetscPrintf(PETSC_COMM_WORLD,"       j norm %D %18.16e\n",j,norm);CHKERRQ(ierr);
4127       value = -value;
4128       ierr  = VecSetValue(uh,i,value,ADD_VALUES);CHKERRQ(ierr);
4129     }
4130   }
4131   ierr = VecDestroy(&uh);CHKERRQ(ierr);
4132   ierr = VecDestroy(&fh);CHKERRQ(ierr);
4133   PetscFunctionReturn(0);
4134 }
4135 
4136 #undef __FUNCT__
4137 #define __FUNCT__ "SNESKSPSetUseEW"
4138 /*@
4139    SNESKSPSetUseEW - Sets SNES use Eisenstat-Walker method for
4140    computing relative tolerance for linear solvers within an inexact
4141    Newton method.
4142 
4143    Logically Collective on SNES
4144 
4145    Input Parameters:
4146 +  snes - SNES context
4147 -  flag - PETSC_TRUE or PETSC_FALSE
4148 
4149     Options Database:
4150 +  -snes_ksp_ew - use Eisenstat-Walker method for determining linear system convergence
4151 .  -snes_ksp_ew_version ver - version of  Eisenstat-Walker method
4152 .  -snes_ksp_ew_rtol0 <rtol0> - Sets rtol0
4153 .  -snes_ksp_ew_rtolmax <rtolmax> - Sets rtolmax
4154 .  -snes_ksp_ew_gamma <gamma> - Sets gamma
4155 .  -snes_ksp_ew_alpha <alpha> - Sets alpha
4156 .  -snes_ksp_ew_alpha2 <alpha2> - Sets alpha2
4157 -  -snes_ksp_ew_threshold <threshold> - Sets threshold
4158 
4159    Notes:
4160    Currently, the default is to use a constant relative tolerance for
4161    the inner linear solvers.  Alternatively, one can use the
4162    Eisenstat-Walker method, where the relative convergence tolerance
4163    is reset at each Newton iteration according progress of the nonlinear
4164    solver.
4165 
4166    Level: advanced
4167 
4168    Reference:
4169    S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an
4170    inexact Newton method", SISC 17 (1), pp.16-32, 1996.
4171 
4172 .keywords: SNES, KSP, Eisenstat, Walker, convergence, test, inexact, Newton
4173 
4174 .seealso: SNESKSPGetUseEW(), SNESKSPGetParametersEW(), SNESKSPSetParametersEW()
4175 @*/
4176 PetscErrorCode  SNESKSPSetUseEW(SNES snes,PetscBool flag)
4177 {
4178   PetscFunctionBegin;
4179   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
4180   PetscValidLogicalCollectiveBool(snes,flag,2);
4181   snes->ksp_ewconv = flag;
4182   PetscFunctionReturn(0);
4183 }
4184 
4185 #undef __FUNCT__
4186 #define __FUNCT__ "SNESKSPGetUseEW"
4187 /*@
4188    SNESKSPGetUseEW - Gets if SNES is using Eisenstat-Walker method
4189    for computing relative tolerance for linear solvers within an
4190    inexact Newton method.
4191 
4192    Not Collective
4193 
4194    Input Parameter:
4195 .  snes - SNES context
4196 
4197    Output Parameter:
4198 .  flag - PETSC_TRUE or PETSC_FALSE
4199 
4200    Notes:
4201    Currently, the default is to use a constant relative tolerance for
4202    the inner linear solvers.  Alternatively, one can use the
4203    Eisenstat-Walker method, where the relative convergence tolerance
4204    is reset at each Newton iteration according progress of the nonlinear
4205    solver.
4206 
4207    Level: advanced
4208 
4209    Reference:
4210    S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an
4211    inexact Newton method", SISC 17 (1), pp.16-32, 1996.
4212 
4213 .keywords: SNES, KSP, Eisenstat, Walker, convergence, test, inexact, Newton
4214 
4215 .seealso: SNESKSPSetUseEW(), SNESKSPGetParametersEW(), SNESKSPSetParametersEW()
4216 @*/
4217 PetscErrorCode  SNESKSPGetUseEW(SNES snes, PetscBool  *flag)
4218 {
4219   PetscFunctionBegin;
4220   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
4221   PetscValidPointer(flag,2);
4222   *flag = snes->ksp_ewconv;
4223   PetscFunctionReturn(0);
4224 }
4225 
4226 #undef __FUNCT__
4227 #define __FUNCT__ "SNESKSPSetParametersEW"
4228 /*@
4229    SNESKSPSetParametersEW - Sets parameters for Eisenstat-Walker
4230    convergence criteria for the linear solvers within an inexact
4231    Newton method.
4232 
4233    Logically Collective on SNES
4234 
4235    Input Parameters:
4236 +    snes - SNES context
4237 .    version - version 1, 2 (default is 2) or 3
4238 .    rtol_0 - initial relative tolerance (0 <= rtol_0 < 1)
4239 .    rtol_max - maximum relative tolerance (0 <= rtol_max < 1)
4240 .    gamma - multiplicative factor for version 2 rtol computation
4241              (0 <= gamma2 <= 1)
4242 .    alpha - power for version 2 rtol computation (1 < alpha <= 2)
4243 .    alpha2 - power for safeguard
4244 -    threshold - threshold for imposing safeguard (0 < threshold < 1)
4245 
4246    Note:
4247    Version 3 was contributed by Luis Chacon, June 2006.
4248 
4249    Use PETSC_DEFAULT to retain the default for any of the parameters.
4250 
4251    Level: advanced
4252 
4253    Reference:
4254    S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an
4255    inexact Newton method", Utah State University Math. Stat. Dept. Res.
4256    Report 6/94/75, June, 1994, to appear in SIAM J. Sci. Comput.
4257 
4258 .keywords: SNES, KSP, Eisenstat, Walker, set, parameters
4259 
4260 .seealso: SNESKSPSetUseEW(), SNESKSPGetUseEW(), SNESKSPGetParametersEW()
4261 @*/
4262 PetscErrorCode  SNESKSPSetParametersEW(SNES snes,PetscInt version,PetscReal rtol_0,PetscReal rtol_max,PetscReal gamma,PetscReal alpha,PetscReal alpha2,PetscReal threshold)
4263 {
4264   SNESKSPEW *kctx;
4265 
4266   PetscFunctionBegin;
4267   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
4268   kctx = (SNESKSPEW*)snes->kspconvctx;
4269   if (!kctx) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context existing");
4270   PetscValidLogicalCollectiveInt(snes,version,2);
4271   PetscValidLogicalCollectiveReal(snes,rtol_0,3);
4272   PetscValidLogicalCollectiveReal(snes,rtol_max,4);
4273   PetscValidLogicalCollectiveReal(snes,gamma,5);
4274   PetscValidLogicalCollectiveReal(snes,alpha,6);
4275   PetscValidLogicalCollectiveReal(snes,alpha2,7);
4276   PetscValidLogicalCollectiveReal(snes,threshold,8);
4277 
4278   if (version != PETSC_DEFAULT)   kctx->version   = version;
4279   if (rtol_0 != PETSC_DEFAULT)    kctx->rtol_0    = rtol_0;
4280   if (rtol_max != PETSC_DEFAULT)  kctx->rtol_max  = rtol_max;
4281   if (gamma != PETSC_DEFAULT)     kctx->gamma     = gamma;
4282   if (alpha != PETSC_DEFAULT)     kctx->alpha     = alpha;
4283   if (alpha2 != PETSC_DEFAULT)    kctx->alpha2    = alpha2;
4284   if (threshold != PETSC_DEFAULT) kctx->threshold = threshold;
4285 
4286   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);
4287   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);
4288   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);
4289   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);
4290   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);
4291   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);
4292   PetscFunctionReturn(0);
4293 }
4294 
4295 #undef __FUNCT__
4296 #define __FUNCT__ "SNESKSPGetParametersEW"
4297 /*@
4298    SNESKSPGetParametersEW - Gets parameters for Eisenstat-Walker
4299    convergence criteria for the linear solvers within an inexact
4300    Newton method.
4301 
4302    Not Collective
4303 
4304    Input Parameters:
4305      snes - SNES context
4306 
4307    Output Parameters:
4308 +    version - version 1, 2 (default is 2) or 3
4309 .    rtol_0 - initial relative tolerance (0 <= rtol_0 < 1)
4310 .    rtol_max - maximum relative tolerance (0 <= rtol_max < 1)
4311 .    gamma - multiplicative factor for version 2 rtol computation (0 <= gamma2 <= 1)
4312 .    alpha - power for version 2 rtol computation (1 < alpha <= 2)
4313 .    alpha2 - power for safeguard
4314 -    threshold - threshold for imposing safeguard (0 < threshold < 1)
4315 
4316    Level: advanced
4317 
4318 .keywords: SNES, KSP, Eisenstat, Walker, get, parameters
4319 
4320 .seealso: SNESKSPSetUseEW(), SNESKSPGetUseEW(), SNESKSPSetParametersEW()
4321 @*/
4322 PetscErrorCode  SNESKSPGetParametersEW(SNES snes,PetscInt *version,PetscReal *rtol_0,PetscReal *rtol_max,PetscReal *gamma,PetscReal *alpha,PetscReal *alpha2,PetscReal *threshold)
4323 {
4324   SNESKSPEW *kctx;
4325 
4326   PetscFunctionBegin;
4327   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
4328   kctx = (SNESKSPEW*)snes->kspconvctx;
4329   if (!kctx) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context existing");
4330   if (version)   *version   = kctx->version;
4331   if (rtol_0)    *rtol_0    = kctx->rtol_0;
4332   if (rtol_max)  *rtol_max  = kctx->rtol_max;
4333   if (gamma)     *gamma     = kctx->gamma;
4334   if (alpha)     *alpha     = kctx->alpha;
4335   if (alpha2)    *alpha2    = kctx->alpha2;
4336   if (threshold) *threshold = kctx->threshold;
4337   PetscFunctionReturn(0);
4338 }
4339 
4340 #undef __FUNCT__
4341 #define __FUNCT__ "SNESKSPEW_PreSolve"
4342  PetscErrorCode SNESKSPEW_PreSolve(KSP ksp, Vec b, Vec x, SNES snes)
4343 {
4344   PetscErrorCode ierr;
4345   SNESKSPEW      *kctx = (SNESKSPEW*)snes->kspconvctx;
4346   PetscReal      rtol  = PETSC_DEFAULT,stol;
4347 
4348   PetscFunctionBegin;
4349   if (!snes->ksp_ewconv) PetscFunctionReturn(0);
4350   if (!snes->iter) rtol = kctx->rtol_0; /* first time in, so use the original user rtol */
4351   else {
4352     if (kctx->version == 1) {
4353       rtol = (snes->norm - kctx->lresid_last)/kctx->norm_last;
4354       if (rtol < 0.0) rtol = -rtol;
4355       stol = PetscPowReal(kctx->rtol_last,kctx->alpha2);
4356       if (stol > kctx->threshold) rtol = PetscMax(rtol,stol);
4357     } else if (kctx->version == 2) {
4358       rtol = kctx->gamma * PetscPowReal(snes->norm/kctx->norm_last,kctx->alpha);
4359       stol = kctx->gamma * PetscPowReal(kctx->rtol_last,kctx->alpha);
4360       if (stol > kctx->threshold) rtol = PetscMax(rtol,stol);
4361     } else if (kctx->version == 3) { /* contributed by Luis Chacon, June 2006. */
4362       rtol = kctx->gamma * PetscPowReal(snes->norm/kctx->norm_last,kctx->alpha);
4363       /* safeguard: avoid sharp decrease of rtol */
4364       stol = kctx->gamma*PetscPowReal(kctx->rtol_last,kctx->alpha);
4365       stol = PetscMax(rtol,stol);
4366       rtol = PetscMin(kctx->rtol_0,stol);
4367       /* safeguard: avoid oversolving */
4368       stol = kctx->gamma*(snes->ttol)/snes->norm;
4369       stol = PetscMax(rtol,stol);
4370       rtol = PetscMin(kctx->rtol_0,stol);
4371     } else SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Only versions 1, 2 or 3 are supported: %D",kctx->version);
4372   }
4373   /* safeguard: avoid rtol greater than one */
4374   rtol = PetscMin(rtol,kctx->rtol_max);
4375   ierr = KSPSetTolerances(ksp,rtol,PETSC_DEFAULT,PETSC_DEFAULT,PETSC_DEFAULT);CHKERRQ(ierr);
4376   ierr = PetscInfo3(snes,"iter %D, Eisenstat-Walker (version %D) KSP rtol=%G\n",snes->iter,kctx->version,rtol);CHKERRQ(ierr);
4377   PetscFunctionReturn(0);
4378 }
4379 
4380 #undef __FUNCT__
4381 #define __FUNCT__ "SNESKSPEW_PostSolve"
4382 PetscErrorCode SNESKSPEW_PostSolve(KSP ksp, Vec b, Vec x, SNES snes)
4383 {
4384   PetscErrorCode ierr;
4385   SNESKSPEW      *kctx = (SNESKSPEW*)snes->kspconvctx;
4386   PCSide         pcside;
4387   Vec            lres;
4388 
4389   PetscFunctionBegin;
4390   if (!snes->ksp_ewconv) PetscFunctionReturn(0);
4391   ierr = KSPGetTolerances(ksp,&kctx->rtol_last,0,0,0);CHKERRQ(ierr);
4392   ierr = SNESGetFunctionNorm(snes,&kctx->norm_last);CHKERRQ(ierr);
4393   if (kctx->version == 1) {
4394     ierr = KSPGetPCSide(ksp,&pcside);CHKERRQ(ierr);
4395     if (pcside == PC_RIGHT) { /* XXX Should we also test KSP_UNPRECONDITIONED_NORM ? */
4396       /* KSP residual is true linear residual */
4397       ierr = KSPGetResidualNorm(ksp,&kctx->lresid_last);CHKERRQ(ierr);
4398     } else {
4399       /* KSP residual is preconditioned residual */
4400       /* compute true linear residual norm */
4401       ierr = VecDuplicate(b,&lres);CHKERRQ(ierr);
4402       ierr = MatMult(snes->jacobian,x,lres);CHKERRQ(ierr);
4403       ierr = VecAYPX(lres,-1.0,b);CHKERRQ(ierr);
4404       ierr = VecNorm(lres,NORM_2,&kctx->lresid_last);CHKERRQ(ierr);
4405       ierr = VecDestroy(&lres);CHKERRQ(ierr);
4406     }
4407   }
4408   PetscFunctionReturn(0);
4409 }
4410 
4411 #undef __FUNCT__
4412 #define __FUNCT__ "SNESGetKSP"
4413 /*@
4414    SNESGetKSP - Returns the KSP context for a SNES solver.
4415 
4416    Not Collective, but if SNES object is parallel, then KSP object is parallel
4417 
4418    Input Parameter:
4419 .  snes - the SNES context
4420 
4421    Output Parameter:
4422 .  ksp - the KSP context
4423 
4424    Notes:
4425    The user can then directly manipulate the KSP context to set various
4426    options, etc.  Likewise, the user can then extract and manipulate the
4427    PC contexts as well.
4428 
4429    Level: beginner
4430 
4431 .keywords: SNES, nonlinear, get, KSP, context
4432 
4433 .seealso: KSPGetPC(), SNESCreate(), KSPCreate(), SNESSetKSP()
4434 @*/
4435 PetscErrorCode  SNESGetKSP(SNES snes,KSP *ksp)
4436 {
4437   PetscErrorCode ierr;
4438 
4439   PetscFunctionBegin;
4440   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
4441   PetscValidPointer(ksp,2);
4442 
4443   if (!snes->ksp) {
4444     ierr = KSPCreate(PetscObjectComm((PetscObject)snes),&snes->ksp);CHKERRQ(ierr);
4445     ierr = PetscObjectIncrementTabLevel((PetscObject)snes->ksp,(PetscObject)snes,1);CHKERRQ(ierr);
4446     ierr = PetscLogObjectParent(snes,snes->ksp);CHKERRQ(ierr);
4447 
4448     ierr = KSPSetPreSolve(snes->ksp,(PetscErrorCode (*)(KSP,Vec,Vec,void*))SNESKSPEW_PreSolve,snes);CHKERRQ(ierr);
4449     ierr = KSPSetPostSolve(snes->ksp,(PetscErrorCode (*)(KSP,Vec,Vec,void*))SNESKSPEW_PostSolve,snes);CHKERRQ(ierr);
4450   }
4451   *ksp = snes->ksp;
4452   PetscFunctionReturn(0);
4453 }
4454 
4455 
4456 #include <petsc-private/dmimpl.h>
4457 #undef __FUNCT__
4458 #define __FUNCT__ "SNESSetDM"
4459 /*@
4460    SNESSetDM - Sets the DM that may be used by some preconditioners
4461 
4462    Logically Collective on SNES
4463 
4464    Input Parameters:
4465 +  snes - the preconditioner context
4466 -  dm - the dm
4467 
4468    Level: intermediate
4469 
4470 .seealso: SNESGetDM(), KSPSetDM(), KSPGetDM()
4471 @*/
4472 PetscErrorCode  SNESSetDM(SNES snes,DM dm)
4473 {
4474   PetscErrorCode ierr;
4475   KSP            ksp;
4476   DMSNES         sdm;
4477 
4478   PetscFunctionBegin;
4479   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
4480   if (dm) {ierr = PetscObjectReference((PetscObject)dm);CHKERRQ(ierr);}
4481   if (snes->dm) {               /* Move the DMSNES context over to the new DM unless the new DM already has one */
4482     if (snes->dm->dmsnes && snes->dmAuto && !dm->dmsnes) {
4483       ierr = DMCopyDMSNES(snes->dm,dm);CHKERRQ(ierr);
4484       ierr = DMGetDMSNES(snes->dm,&sdm);CHKERRQ(ierr);
4485       if (sdm->originaldm == snes->dm) sdm->originaldm = dm; /* Grant write privileges to the replacement DM */
4486     }
4487     ierr = DMDestroy(&snes->dm);CHKERRQ(ierr);
4488   }
4489   snes->dm     = dm;
4490   snes->dmAuto = PETSC_FALSE;
4491 
4492   ierr = SNESGetKSP(snes,&ksp);CHKERRQ(ierr);
4493   ierr = KSPSetDM(ksp,dm);CHKERRQ(ierr);
4494   ierr = KSPSetDMActive(ksp,PETSC_FALSE);CHKERRQ(ierr);
4495   if (snes->pc) {
4496     ierr = SNESSetDM(snes->pc, snes->dm);CHKERRQ(ierr);
4497     ierr = SNESSetPCSide(snes,snes->pcside);CHKERRQ(ierr);
4498   }
4499   PetscFunctionReturn(0);
4500 }
4501 
4502 #undef __FUNCT__
4503 #define __FUNCT__ "SNESGetDM"
4504 /*@
4505    SNESGetDM - Gets the DM that may be used by some preconditioners
4506 
4507    Not Collective but DM obtained is parallel on SNES
4508 
4509    Input Parameter:
4510 . snes - the preconditioner context
4511 
4512    Output Parameter:
4513 .  dm - the dm
4514 
4515    Level: intermediate
4516 
4517 .seealso: SNESSetDM(), KSPSetDM(), KSPGetDM()
4518 @*/
4519 PetscErrorCode  SNESGetDM(SNES snes,DM *dm)
4520 {
4521   PetscErrorCode ierr;
4522 
4523   PetscFunctionBegin;
4524   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
4525   if (!snes->dm) {
4526     ierr         = DMShellCreate(PetscObjectComm((PetscObject)snes),&snes->dm);CHKERRQ(ierr);
4527     snes->dmAuto = PETSC_TRUE;
4528   }
4529   *dm = snes->dm;
4530   PetscFunctionReturn(0);
4531 }
4532 
4533 #undef __FUNCT__
4534 #define __FUNCT__ "SNESSetPC"
4535 /*@
4536   SNESSetPC - Sets the nonlinear preconditioner to be used.
4537 
4538   Collective on SNES
4539 
4540   Input Parameters:
4541 + snes - iterative context obtained from SNESCreate()
4542 - pc   - the preconditioner object
4543 
4544   Notes:
4545   Use SNESGetPC() to retrieve the preconditioner context (for example,
4546   to configure it using the API).
4547 
4548   Level: developer
4549 
4550 .keywords: SNES, set, precondition
4551 .seealso: SNESGetPC()
4552 @*/
4553 PetscErrorCode SNESSetPC(SNES snes, SNES pc)
4554 {
4555   PetscErrorCode ierr;
4556 
4557   PetscFunctionBegin;
4558   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
4559   PetscValidHeaderSpecific(pc, SNES_CLASSID, 2);
4560   PetscCheckSameComm(snes, 1, pc, 2);
4561   ierr     = PetscObjectReference((PetscObject) pc);CHKERRQ(ierr);
4562   ierr     = SNESDestroy(&snes->pc);CHKERRQ(ierr);
4563   snes->pc = pc;
4564   ierr     = PetscLogObjectParent(snes, snes->pc);CHKERRQ(ierr);
4565   PetscFunctionReturn(0);
4566 }
4567 
4568 #undef __FUNCT__
4569 #define __FUNCT__ "SNESGetPC"
4570 /*@
4571   SNESGetPC - Returns a pointer to the nonlinear preconditioning context set with SNESSetPC().
4572 
4573   Not Collective
4574 
4575   Input Parameter:
4576 . snes - iterative context obtained from SNESCreate()
4577 
4578   Output Parameter:
4579 . pc - preconditioner context
4580 
4581   Level: developer
4582 
4583 .keywords: SNES, get, preconditioner
4584 .seealso: SNESSetPC()
4585 @*/
4586 PetscErrorCode SNESGetPC(SNES snes, SNES *pc)
4587 {
4588   PetscErrorCode ierr;
4589   const char     *optionsprefix;
4590 
4591   PetscFunctionBegin;
4592   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
4593   PetscValidPointer(pc, 2);
4594   if (!snes->pc) {
4595     ierr = SNESCreate(PetscObjectComm((PetscObject)snes),&snes->pc);CHKERRQ(ierr);
4596     ierr = PetscObjectIncrementTabLevel((PetscObject)snes->pc,(PetscObject)snes,1);CHKERRQ(ierr);
4597     ierr = PetscLogObjectParent(snes,snes->pc);CHKERRQ(ierr);
4598     ierr = SNESGetOptionsPrefix(snes,&optionsprefix);CHKERRQ(ierr);
4599     ierr = SNESSetOptionsPrefix(snes->pc,optionsprefix);CHKERRQ(ierr);
4600     ierr = SNESAppendOptionsPrefix(snes->pc,"npc_");CHKERRQ(ierr);
4601   }
4602   *pc = snes->pc;
4603   PetscFunctionReturn(0);
4604 }
4605 
4606 #undef __FUNCT__
4607 #define __FUNCT__ "SNESSetPCSide"
4608 /*@
4609     SNESSetPCSide - Sets the preconditioning side.
4610 
4611     Logically Collective on SNES
4612 
4613     Input Parameter:
4614 .   snes - iterative context obtained from SNESCreate()
4615 
4616     Output Parameter:
4617 .   side - the preconditioning side, where side is one of
4618 .vb
4619       PC_LEFT - left preconditioning (default)
4620       PC_RIGHT - right preconditioning
4621 .ve
4622 
4623     Options Database Keys:
4624 .   -snes_pc_side <right,left>
4625 
4626     Level: intermediate
4627 
4628 .keywords: SNES, set, right, left, side, preconditioner, flag
4629 
4630 .seealso: SNESGetPCSide(), KSPSetPCSide()
4631 @*/
4632 PetscErrorCode  SNESSetPCSide(SNES snes,PCSide side)
4633 {
4634   PetscFunctionBegin;
4635   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
4636   PetscValidLogicalCollectiveEnum(snes,side,2);
4637   snes->pcside = side;
4638   PetscFunctionReturn(0);
4639 }
4640 
4641 #undef __FUNCT__
4642 #define __FUNCT__ "SNESGetPCSide"
4643 /*@
4644     SNESGetPCSide - Gets the preconditioning side.
4645 
4646     Not Collective
4647 
4648     Input Parameter:
4649 .   snes - iterative context obtained from SNESCreate()
4650 
4651     Output Parameter:
4652 .   side - the preconditioning side, where side is one of
4653 .vb
4654       PC_LEFT - left preconditioning (default)
4655       PC_RIGHT - right preconditioning
4656 .ve
4657 
4658     Level: intermediate
4659 
4660 .keywords: SNES, get, right, left, side, preconditioner, flag
4661 
4662 .seealso: SNESSetPCSide(), KSPGetPCSide()
4663 @*/
4664 PetscErrorCode  SNESGetPCSide(SNES snes,PCSide *side)
4665 {
4666   PetscFunctionBegin;
4667   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
4668   PetscValidPointer(side,2);
4669   *side = snes->pcside;
4670   PetscFunctionReturn(0);
4671 }
4672 
4673 #undef __FUNCT__
4674 #define __FUNCT__ "SNESSetSNESLineSearch"
4675 /*@
4676   SNESSetSNESLineSearch - Sets the linesearch on the SNES instance.
4677 
4678   Collective on SNES
4679 
4680   Input Parameters:
4681 + snes - iterative context obtained from SNESCreate()
4682 - linesearch   - the linesearch object
4683 
4684   Notes:
4685   Use SNESGetSNESLineSearch() to retrieve the preconditioner context (for example,
4686   to configure it using the API).
4687 
4688   Level: developer
4689 
4690 .keywords: SNES, set, linesearch
4691 .seealso: SNESGetSNESLineSearch()
4692 @*/
4693 PetscErrorCode SNESSetSNESLineSearch(SNES snes, SNESLineSearch linesearch)
4694 {
4695   PetscErrorCode ierr;
4696 
4697   PetscFunctionBegin;
4698   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
4699   PetscValidHeaderSpecific(linesearch, SNESLINESEARCH_CLASSID, 2);
4700   PetscCheckSameComm(snes, 1, linesearch, 2);
4701   ierr = PetscObjectReference((PetscObject) linesearch);CHKERRQ(ierr);
4702   ierr = SNESLineSearchDestroy(&snes->linesearch);CHKERRQ(ierr);
4703 
4704   snes->linesearch = linesearch;
4705 
4706   ierr = PetscLogObjectParent(snes, snes->linesearch);CHKERRQ(ierr);
4707   PetscFunctionReturn(0);
4708 }
4709 
4710 #undef __FUNCT__
4711 #define __FUNCT__ "SNESGetSNESLineSearch"
4712 /*@C
4713   SNESGetSNESLineSearch - Returns a pointer to the line search context set with SNESSetLineSearch()
4714   or creates a default line search instance associated with the SNES and returns it.
4715 
4716   Not Collective
4717 
4718   Input Parameter:
4719 . snes - iterative context obtained from SNESCreate()
4720 
4721   Output Parameter:
4722 . linesearch - linesearch context
4723 
4724   Level: developer
4725 
4726 .keywords: SNES, get, linesearch
4727 .seealso: SNESSetSNESLineSearch()
4728 @*/
4729 PetscErrorCode SNESGetSNESLineSearch(SNES snes, SNESLineSearch *linesearch)
4730 {
4731   PetscErrorCode ierr;
4732   const char     *optionsprefix;
4733 
4734   PetscFunctionBegin;
4735   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
4736   PetscValidPointer(linesearch, 2);
4737   if (!snes->linesearch) {
4738     ierr = SNESGetOptionsPrefix(snes, &optionsprefix);CHKERRQ(ierr);
4739     ierr = SNESLineSearchCreate(PetscObjectComm((PetscObject)snes), &snes->linesearch);CHKERRQ(ierr);
4740     ierr = SNESLineSearchSetSNES(snes->linesearch, snes);CHKERRQ(ierr);
4741     ierr = SNESLineSearchAppendOptionsPrefix(snes->linesearch, optionsprefix);CHKERRQ(ierr);
4742     ierr = PetscObjectIncrementTabLevel((PetscObject) snes->linesearch, (PetscObject) snes, 1);CHKERRQ(ierr);
4743     ierr = PetscLogObjectParent(snes, snes->linesearch);CHKERRQ(ierr);
4744   }
4745   *linesearch = snes->linesearch;
4746   PetscFunctionReturn(0);
4747 }
4748 
4749 #if defined(PETSC_HAVE_MATLAB_ENGINE)
4750 #include <mex.h>
4751 
4752 typedef struct {char *funcname; mxArray *ctx;} SNESMatlabContext;
4753 
4754 #undef __FUNCT__
4755 #define __FUNCT__ "SNESComputeFunction_Matlab"
4756 /*
4757    SNESComputeFunction_Matlab - Calls the function that has been set with SNESSetFunctionMatlab().
4758 
4759    Collective on SNES
4760 
4761    Input Parameters:
4762 +  snes - the SNES context
4763 -  x - input vector
4764 
4765    Output Parameter:
4766 .  y - function vector, as set by SNESSetFunction()
4767 
4768    Notes:
4769    SNESComputeFunction() is typically used within nonlinear solvers
4770    implementations, so most users would not generally call this routine
4771    themselves.
4772 
4773    Level: developer
4774 
4775 .keywords: SNES, nonlinear, compute, function
4776 
4777 .seealso: SNESSetFunction(), SNESGetFunction()
4778 */
4779 PetscErrorCode  SNESComputeFunction_Matlab(SNES snes,Vec x,Vec y, void *ctx)
4780 {
4781   PetscErrorCode    ierr;
4782   SNESMatlabContext *sctx = (SNESMatlabContext*)ctx;
4783   int               nlhs  = 1,nrhs = 5;
4784   mxArray           *plhs[1],*prhs[5];
4785   long long int     lx = 0,ly = 0,ls = 0;
4786 
4787   PetscFunctionBegin;
4788   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
4789   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
4790   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
4791   PetscCheckSameComm(snes,1,x,2);
4792   PetscCheckSameComm(snes,1,y,3);
4793 
4794   /* call Matlab function in ctx with arguments x and y */
4795 
4796   ierr    = PetscMemcpy(&ls,&snes,sizeof(snes));CHKERRQ(ierr);
4797   ierr    = PetscMemcpy(&lx,&x,sizeof(x));CHKERRQ(ierr);
4798   ierr    = PetscMemcpy(&ly,&y,sizeof(x));CHKERRQ(ierr);
4799   prhs[0] = mxCreateDoubleScalar((double)ls);
4800   prhs[1] = mxCreateDoubleScalar((double)lx);
4801   prhs[2] = mxCreateDoubleScalar((double)ly);
4802   prhs[3] = mxCreateString(sctx->funcname);
4803   prhs[4] = sctx->ctx;
4804   ierr    = mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscSNESComputeFunctionInternal");CHKERRQ(ierr);
4805   ierr    = mxGetScalar(plhs[0]);CHKERRQ(ierr);
4806   mxDestroyArray(prhs[0]);
4807   mxDestroyArray(prhs[1]);
4808   mxDestroyArray(prhs[2]);
4809   mxDestroyArray(prhs[3]);
4810   mxDestroyArray(plhs[0]);
4811   PetscFunctionReturn(0);
4812 }
4813 
4814 #undef __FUNCT__
4815 #define __FUNCT__ "SNESSetFunctionMatlab"
4816 /*
4817    SNESSetFunctionMatlab - Sets the function evaluation routine and function
4818    vector for use by the SNES routines in solving systems of nonlinear
4819    equations from MATLAB. Here the function is a string containing the name of a MATLAB function
4820 
4821    Logically Collective on SNES
4822 
4823    Input Parameters:
4824 +  snes - the SNES context
4825 .  r - vector to store function value
4826 -  SNESFunction - function evaluation routine
4827 
4828    Notes:
4829    The Newton-like methods typically solve linear systems of the form
4830 $      f'(x) x = -f(x),
4831    where f'(x) denotes the Jacobian matrix and f(x) is the function.
4832 
4833    Level: beginner
4834 
4835    Developer Note:  This bleeds the allocated memory SNESMatlabContext *sctx;
4836 
4837 .keywords: SNES, nonlinear, set, function
4838 
4839 .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction()
4840 */
4841 PetscErrorCode  SNESSetFunctionMatlab(SNES snes,Vec r,const char *SNESFunction,mxArray *ctx)
4842 {
4843   PetscErrorCode    ierr;
4844   SNESMatlabContext *sctx;
4845 
4846   PetscFunctionBegin;
4847   /* currently sctx is memory bleed */
4848   ierr = PetscMalloc(sizeof(SNESMatlabContext),&sctx);CHKERRQ(ierr);
4849   ierr = PetscStrallocpy(SNESFunction,&sctx->funcname);CHKERRQ(ierr);
4850   /*
4851      This should work, but it doesn't
4852   sctx->ctx = ctx;
4853   mexMakeArrayPersistent(sctx->ctx);
4854   */
4855   sctx->ctx = mxDuplicateArray(ctx);
4856   ierr      = SNESSetFunction(snes,r,SNESComputeFunction_Matlab,sctx);CHKERRQ(ierr);
4857   PetscFunctionReturn(0);
4858 }
4859 
4860 #undef __FUNCT__
4861 #define __FUNCT__ "SNESComputeJacobian_Matlab"
4862 /*
4863    SNESComputeJacobian_Matlab - Calls the function that has been set with SNESSetJacobianMatlab().
4864 
4865    Collective on SNES
4866 
4867    Input Parameters:
4868 +  snes - the SNES context
4869 .  x - input vector
4870 .  A, B - the matrices
4871 -  ctx - user context
4872 
4873    Output Parameter:
4874 .  flag - structure of the matrix
4875 
4876    Level: developer
4877 
4878 .keywords: SNES, nonlinear, compute, function
4879 
4880 .seealso: SNESSetFunction(), SNESGetFunction()
4881 @*/
4882 PetscErrorCode  SNESComputeJacobian_Matlab(SNES snes,Vec x,Mat *A,Mat *B,MatStructure *flag, void *ctx)
4883 {
4884   PetscErrorCode    ierr;
4885   SNESMatlabContext *sctx = (SNESMatlabContext*)ctx;
4886   int               nlhs  = 2,nrhs = 6;
4887   mxArray           *plhs[2],*prhs[6];
4888   long long int     lx = 0,lA = 0,ls = 0, lB = 0;
4889 
4890   PetscFunctionBegin;
4891   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
4892   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
4893 
4894   /* call Matlab function in ctx with arguments x and y */
4895 
4896   ierr    = PetscMemcpy(&ls,&snes,sizeof(snes));CHKERRQ(ierr);
4897   ierr    = PetscMemcpy(&lx,&x,sizeof(x));CHKERRQ(ierr);
4898   ierr    = PetscMemcpy(&lA,A,sizeof(x));CHKERRQ(ierr);
4899   ierr    = PetscMemcpy(&lB,B,sizeof(x));CHKERRQ(ierr);
4900   prhs[0] = mxCreateDoubleScalar((double)ls);
4901   prhs[1] = mxCreateDoubleScalar((double)lx);
4902   prhs[2] = mxCreateDoubleScalar((double)lA);
4903   prhs[3] = mxCreateDoubleScalar((double)lB);
4904   prhs[4] = mxCreateString(sctx->funcname);
4905   prhs[5] = sctx->ctx;
4906   ierr    = mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscSNESComputeJacobianInternal");CHKERRQ(ierr);
4907   ierr    = mxGetScalar(plhs[0]);CHKERRQ(ierr);
4908   *flag   = (MatStructure) mxGetScalar(plhs[1]);CHKERRQ(ierr);
4909   mxDestroyArray(prhs[0]);
4910   mxDestroyArray(prhs[1]);
4911   mxDestroyArray(prhs[2]);
4912   mxDestroyArray(prhs[3]);
4913   mxDestroyArray(prhs[4]);
4914   mxDestroyArray(plhs[0]);
4915   mxDestroyArray(plhs[1]);
4916   PetscFunctionReturn(0);
4917 }
4918 
4919 #undef __FUNCT__
4920 #define __FUNCT__ "SNESSetJacobianMatlab"
4921 /*
4922    SNESSetJacobianMatlab - Sets the Jacobian function evaluation routine and two empty Jacobian matrices
4923    vector for use by the SNES routines in solving systems of nonlinear
4924    equations from MATLAB. Here the function is a string containing the name of a MATLAB function
4925 
4926    Logically Collective on SNES
4927 
4928    Input Parameters:
4929 +  snes - the SNES context
4930 .  A,B - Jacobian matrices
4931 .  SNESJacobianFunction - function evaluation routine
4932 -  ctx - user context
4933 
4934    Level: developer
4935 
4936    Developer Note:  This bleeds the allocated memory SNESMatlabContext *sctx;
4937 
4938 .keywords: SNES, nonlinear, set, function
4939 
4940 .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction(), SNESJacobianFunction
4941 */
4942 PetscErrorCode  SNESSetJacobianMatlab(SNES snes,Mat A,Mat B,const char *SNESJacobianFunction,mxArray *ctx)
4943 {
4944   PetscErrorCode    ierr;
4945   SNESMatlabContext *sctx;
4946 
4947   PetscFunctionBegin;
4948   /* currently sctx is memory bleed */
4949   ierr = PetscMalloc(sizeof(SNESMatlabContext),&sctx);CHKERRQ(ierr);
4950   ierr = PetscStrallocpy(SNESJacobianFunction,&sctx->funcname);CHKERRQ(ierr);
4951   /*
4952      This should work, but it doesn't
4953   sctx->ctx = ctx;
4954   mexMakeArrayPersistent(sctx->ctx);
4955   */
4956   sctx->ctx = mxDuplicateArray(ctx);
4957   ierr      = SNESSetJacobian(snes,A,B,SNESComputeJacobian_Matlab,sctx);CHKERRQ(ierr);
4958   PetscFunctionReturn(0);
4959 }
4960 
4961 #undef __FUNCT__
4962 #define __FUNCT__ "SNESMonitor_Matlab"
4963 /*
4964    SNESMonitor_Matlab - Calls the function that has been set with SNESMonitorSetMatlab().
4965 
4966    Collective on SNES
4967 
4968 .seealso: SNESSetFunction(), SNESGetFunction()
4969 @*/
4970 PetscErrorCode  SNESMonitor_Matlab(SNES snes,PetscInt it, PetscReal fnorm, void *ctx)
4971 {
4972   PetscErrorCode    ierr;
4973   SNESMatlabContext *sctx = (SNESMatlabContext*)ctx;
4974   int               nlhs  = 1,nrhs = 6;
4975   mxArray           *plhs[1],*prhs[6];
4976   long long int     lx = 0,ls = 0;
4977   Vec               x  = snes->vec_sol;
4978 
4979   PetscFunctionBegin;
4980   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
4981 
4982   ierr    = PetscMemcpy(&ls,&snes,sizeof(snes));CHKERRQ(ierr);
4983   ierr    = PetscMemcpy(&lx,&x,sizeof(x));CHKERRQ(ierr);
4984   prhs[0] = mxCreateDoubleScalar((double)ls);
4985   prhs[1] = mxCreateDoubleScalar((double)it);
4986   prhs[2] = mxCreateDoubleScalar((double)fnorm);
4987   prhs[3] = mxCreateDoubleScalar((double)lx);
4988   prhs[4] = mxCreateString(sctx->funcname);
4989   prhs[5] = sctx->ctx;
4990   ierr    = mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscSNESMonitorInternal");CHKERRQ(ierr);
4991   ierr    = mxGetScalar(plhs[0]);CHKERRQ(ierr);
4992   mxDestroyArray(prhs[0]);
4993   mxDestroyArray(prhs[1]);
4994   mxDestroyArray(prhs[2]);
4995   mxDestroyArray(prhs[3]);
4996   mxDestroyArray(prhs[4]);
4997   mxDestroyArray(plhs[0]);
4998   PetscFunctionReturn(0);
4999 }
5000 
5001 #undef __FUNCT__
5002 #define __FUNCT__ "SNESMonitorSetMatlab"
5003 /*
5004    SNESMonitorSetMatlab - Sets the monitor function from MATLAB
5005 
5006    Level: developer
5007 
5008    Developer Note:  This bleeds the allocated memory SNESMatlabContext *sctx;
5009 
5010 .keywords: SNES, nonlinear, set, function
5011 
5012 .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction()
5013 */
5014 PetscErrorCode  SNESMonitorSetMatlab(SNES snes,const char *SNESMonitorFunction,mxArray *ctx)
5015 {
5016   PetscErrorCode    ierr;
5017   SNESMatlabContext *sctx;
5018 
5019   PetscFunctionBegin;
5020   /* currently sctx is memory bleed */
5021   ierr = PetscMalloc(sizeof(SNESMatlabContext),&sctx);CHKERRQ(ierr);
5022   ierr = PetscStrallocpy(SNESMonitorFunction,&sctx->funcname);CHKERRQ(ierr);
5023   /*
5024      This should work, but it doesn't
5025   sctx->ctx = ctx;
5026   mexMakeArrayPersistent(sctx->ctx);
5027   */
5028   sctx->ctx = mxDuplicateArray(ctx);
5029   ierr      = SNESMonitorSet(snes,SNESMonitor_Matlab,sctx,NULL);CHKERRQ(ierr);
5030   PetscFunctionReturn(0);
5031 }
5032 
5033 #endif
5034