xref: /petsc/src/snes/interface/snes.c (revision fae171e0928a68051052473fbd80ecaec6ec1e7e)
1 #ifndef lint
2 static char vcid[] = "$Id: snes.c,v 1.69 1996/03/24 22:11:36 curfman Exp curfman $";
3 #endif
4 
5 #include "draw.h"          /*I "draw.h"  I*/
6 #include "snesimpl.h"      /*I "snes.h"  I*/
7 #include "sys/nreg.h"
8 #include "pinclude/pviewer.h"
9 #include <math.h>
10 
11 extern int SNESGetTypeFromOptions_Private(SNES,SNESType*,int*);
12 extern int SNESPrintTypes_Private(MPI_Comm,char*,char*);
13 
14 /*@
15    SNESView - Prints the SNES data structure.
16 
17    Input Parameters:
18 .  SNES - the SNES context
19 .  viewer - visualization context
20 
21    Options Database Key:
22 $  -snes_view : calls SNESView() at end of SNESSolve()
23 
24    Notes:
25    The available visualization contexts include
26 $     STDOUT_VIEWER_SELF - standard output (default)
27 $     STDOUT_VIEWER_WORLD - synchronized standard
28 $       output where only the first processor opens
29 $       the file.  All other processors send their
30 $       data to the first processor to print.
31 
32    The user can open alternative vistualization contexts with
33 $    ViewerFileOpenASCII() - output to a specified file
34 
35 .keywords: SNES, view
36 
37 .seealso: ViewerFileOpenASCII()
38 @*/
39 int SNESView(SNES snes,Viewer viewer)
40 {
41   SNES_KSP_EW_ConvCtx *kctx;
42   FILE                *fd;
43   int                 ierr;
44   SLES                sles;
45   char                *method;
46   ViewerType          vtype;
47 
48   ierr = ViewerGetType(viewer,&vtype); CHKERRQ(ierr);
49   if (vtype == ASCII_FILE_VIEWER || vtype == ASCII_FILES_VIEWER) {
50     ierr = ViewerASCIIGetPointer(viewer,&fd); CHKERRQ(ierr);
51     PetscFPrintf(snes->comm,fd,"SNES Object:\n");
52     SNESGetType(snes,PETSC_NULL,&method);
53     PetscFPrintf(snes->comm,fd,"  method: %s\n",method);
54     if (snes->view) (*snes->view)((PetscObject)snes,viewer);
55     PetscFPrintf(snes->comm,fd,
56       "  maximum iterations=%d, maximum function evaluations=%d\n",
57       snes->max_its,snes->max_funcs);
58     PetscFPrintf(snes->comm,fd,
59     "  tolerances: relative=%g, absolute=%g, truncation=%g, solution=%g\n",
60       snes->rtol, snes->atol, snes->trunctol, snes->xtol);
61     if (snes->method_class == SNES_UNCONSTRAINED_MINIMIZATION)
62       PetscFPrintf(snes->comm,fd,"  min function tolerance=%g\n",snes->fmin);
63     if (snes->ksp_ewconv) {
64       kctx = (SNES_KSP_EW_ConvCtx *)snes->kspconvctx;
65       if (kctx) {
66         PetscFPrintf(snes->comm,fd,
67      "  Eisenstat-Walker computation of KSP relative tolerance (version %d)\n",
68         kctx->version);
69         PetscFPrintf(snes->comm,fd,
70           "    rtol_0=%g, rtol_max=%g, threshold=%g\n",kctx->rtol_0,
71           kctx->rtol_max,kctx->threshold);
72         PetscFPrintf(snes->comm,fd,"    gamma=%g, alpha=%g, alpha2=%g\n",
73           kctx->gamma,kctx->alpha,kctx->alpha2);
74       }
75     }
76   } else if (vtype == STRING_VIEWER) {
77     SNESGetType(snes,PETSC_NULL,&method);
78     ViewerStringSPrintf(viewer," %-3.3s",method);
79   }
80   SNESGetSLES(snes,&sles);
81   ierr = SLESView(sles,viewer); CHKERRQ(ierr);
82   return 0;
83 }
84 
85 /*@
86    SNESSetFromOptions - Sets various SNES and SLES parameters from user options.
87 
88    Input Parameter:
89 .  snes - the SNES context
90 
91 .keywords: SNES, nonlinear, set, options, database
92 
93 .seealso: SNESPrintHelp(), SNESSetOptionsPrefix()
94 @*/
95 int SNESSetFromOptions(SNES snes)
96 {
97   SNESType method;
98   double   tmp;
99   SLES     sles;
100   int      ierr, flg;
101   int      version   = PETSC_DEFAULT;
102   double   rtol_0    = PETSC_DEFAULT;
103   double   rtol_max  = PETSC_DEFAULT;
104   double   gamma2    = PETSC_DEFAULT;
105   double   alpha     = PETSC_DEFAULT;
106   double   alpha2    = PETSC_DEFAULT;
107   double   threshold = PETSC_DEFAULT;
108 
109   PetscValidHeaderSpecific(snes,SNES_COOKIE);
110   if (snes->setup_called)SETERRQ(1,"SNESSetFromOptions:Must call prior to SNESSetUp!");
111   ierr = SNESGetTypeFromOptions_Private(snes,&method,&flg); CHKERRQ(ierr);
112   if (flg) {
113     ierr = SNESSetType(snes,method); CHKERRQ(ierr);
114   }
115   else if (!snes->set_method_called) {
116     if (snes->method_class == SNES_NONLINEAR_EQUATIONS) {
117       ierr = SNESSetType(snes,SNES_EQ_LS); CHKERRQ(ierr);
118     }
119     else {
120       ierr = SNESSetType(snes,SNES_UM_TR); CHKERRQ(ierr);
121     }
122   }
123 
124   ierr = OptionsHasName(PETSC_NULL,"-help", &flg); CHKERRQ(ierr);
125   if (flg) { SNESPrintHelp(snes); }
126   ierr = OptionsGetDouble(snes->prefix,"-snes_stol",&tmp, &flg); CHKERRQ(ierr);
127   if (flg) { SNESSetTolerances(snes,PETSC_DEFAULT,PETSC_DEFAULT,tmp,PETSC_DEFAULT,PETSC_DEFAULT); }
128   ierr = OptionsGetDouble(snes->prefix,"-snes_atol",&tmp, &flg); CHKERRQ(ierr);
129   if (flg) { SNESSetTolerances(snes,tmp,PETSC_DEFAULT,PETSC_DEFAULT,PETSC_DEFAULT,PETSC_DEFAULT); }
130   ierr = OptionsGetDouble(snes->prefix,"-snes_rtol",&tmp, &flg);  CHKERRQ(ierr);
131   if (flg) { SNESSetTolerances(snes,PETSC_DEFAULT,tmp,PETSC_DEFAULT,PETSC_DEFAULT,PETSC_DEFAULT); }
132   ierr = OptionsGetInt(snes->prefix,"-snes_max_it",&snes->max_its, &flg); CHKERRQ(ierr);
133   ierr = OptionsGetInt(snes->prefix,"-snes_max_funcs",&snes->max_funcs, &flg);CHKERRQ(ierr);
134   ierr = OptionsGetDouble(snes->prefix,"-snes_trtol",&tmp, &flg); CHKERRQ(ierr);
135   if (flg) { SNESSetTrustRegionTolerance(snes,tmp); }
136   ierr = OptionsGetDouble(snes->prefix,"-snes_fmin",&tmp, &flg); CHKERRQ(ierr);
137   if (flg) { SNESSetMinimizationFunctionTolerance(snes,tmp); }
138   ierr = OptionsHasName(snes->prefix,"-snes_ksp_ew_conv", &flg); CHKERRQ(ierr);
139   if (flg) { snes->ksp_ewconv = 1; }
140   ierr = OptionsGetInt(snes->prefix,"-snes_ksp_ew_version",&version,&flg); CHKERRQ(ierr);
141   ierr = OptionsGetDouble(snes->prefix,"-snes_ksp_ew_rtol0",&rtol_0,&flg); CHKERRQ(ierr);
142   ierr = OptionsGetDouble(snes->prefix,"-snes_ksp_ew_rtolmax",&rtol_max,&flg); CHKERRQ(ierr);
143   ierr = OptionsGetDouble(snes->prefix,"-snes_ksp_ew_gamma",&gamma2,&flg); CHKERRQ(ierr);
144   ierr = OptionsGetDouble(snes->prefix,"-snes_ksp_ew_alpha",&alpha,&flg); CHKERRQ(ierr);
145   ierr = OptionsGetDouble(snes->prefix,"-snes_ksp_ew_alpha2",&alpha2,&flg); CHKERRQ(ierr);
146   ierr = OptionsGetDouble(snes->prefix,"-snes_ksp_ew_threshold",&threshold,&flg);  CHKERRQ(ierr);
147   ierr = SNES_KSP_SetParametersEW(snes,version,rtol_0,rtol_max,gamma2,alpha,
148                                   alpha2,threshold); CHKERRQ(ierr);
149   ierr = OptionsHasName(snes->prefix,"-snes_monitor", &flg);  CHKERRQ(ierr);
150   if (flg) { SNESSetMonitor(snes,SNESDefaultMonitor,0); }
151   ierr = OptionsHasName(snes->prefix,"-snes_smonitor", &flg);  CHKERRQ(ierr);
152    if (flg) { SNESSetMonitor(snes,SNESDefaultSMonitor,0); }
153   ierr = OptionsHasName(snes->prefix,"-snes_xmonitor", &flg);  CHKERRQ(ierr);
154   if (flg) {
155     int       rank = 0;
156     DrawLG lg;
157     MPI_Initialized(&rank);
158     if (rank) MPI_Comm_rank(snes->comm,&rank);
159     if (!rank) {
160       ierr = SNESLGMonitorCreate(0,0,0,0,300,300,&lg); CHKERRQ(ierr);
161       ierr = SNESSetMonitor(snes,SNESLGMonitor,(void *)lg); CHKERRQ(ierr);
162       snes->xmonitor = lg;
163       PLogObjectParent(snes,lg);
164     }
165   }
166   ierr = OptionsHasName(snes->prefix,"-snes_fd", &flg);  CHKERRQ(ierr);
167   if (flg && snes->method_class == SNES_NONLINEAR_EQUATIONS) {
168     ierr = SNESSetJacobian(snes,snes->jacobian,snes->jacobian_pre,
169                  SNESDefaultComputeJacobian,snes->funP); CHKERRQ(ierr);
170     PLogInfo(snes,
171       "SNESSetFromOptions: Setting default finite difference Jacobian matrix\n");
172   }
173   else if (flg && snes->method_class == SNES_UNCONSTRAINED_MINIMIZATION) {
174     ierr = SNESSetHessian(snes,snes->jacobian,snes->jacobian_pre,
175                  SNESDefaultComputeHessian,snes->funP); CHKERRQ(ierr);
176     PLogInfo(snes,
177       "SNESSetFromOptions: Setting default finite difference Hessian matrix\n");
178   }
179   ierr = SNESGetSLES(snes,&sles); CHKERRQ(ierr);
180   ierr = SLESSetFromOptions(sles); CHKERRQ(ierr);
181   if (!snes->setfromoptions) return 0;
182   return (*snes->setfromoptions)(snes);
183 }
184 
185 /*@
186    SNESPrintHelp - Prints all options for the SNES component.
187 
188    Input Parameter:
189 .  snes - the SNES context
190 
191    Options Database Keys:
192 $  -help, -h
193 
194 .keywords: SNES, nonlinear, help
195 
196 .seealso: SNESSetFromOptions()
197 @*/
198 int SNESPrintHelp(SNES snes)
199 {
200   char                p[64];
201   SNES_KSP_EW_ConvCtx *kctx;
202 
203   PetscValidHeaderSpecific(snes,SNES_COOKIE);
204 
205   PetscStrcpy(p,"-");
206   if (snes->prefix) PetscStrcat(p, snes->prefix);
207 
208   kctx = (SNES_KSP_EW_ConvCtx *)snes->kspconvctx;
209 
210   PetscPrintf(snes->comm,"SNES options ----------------------------\n");
211   SNESPrintTypes_Private(snes->comm,p,"snes_type");
212   PetscPrintf(snes->comm," %ssnes_monitor: use default SNES monitor\n",p);
213   PetscPrintf(snes->comm," %ssnes_view: view SNES info after each nonlinear solve\n",p);
214   PetscPrintf(snes->comm," %ssnes_max_it <its>: max iterations (default %d)\n",p,snes->max_its);
215   PetscPrintf(snes->comm," %ssnes_max_funcs <maxf>: max function evals (default %d)\n",p,snes->max_funcs);
216   PetscPrintf(snes->comm," %ssnes_stol <stol>: successive step tolerance (default %g)\n",p,snes->xtol);
217   PetscPrintf(snes->comm," %ssnes_atol <atol>: absolute tolerance (default %g)\n",p,snes->atol);
218   PetscPrintf(snes->comm," %ssnes_rtol <rtol>: relative tolerance (default %g)\n",p,snes->rtol);
219   PetscPrintf(snes->comm," %ssnes_trtol <trtol>: trust region parameter tolerance (default %g)\n",p,snes->deltatol);
220   if (snes->type == SNES_NONLINEAR_EQUATIONS) {
221     PetscPrintf(snes->comm,
222      " options for solving systems of nonlinear equations only:\n");
223     PetscPrintf(snes->comm,"   %ssnes_fd: use finite differences for Jacobian\n",p);
224     PetscPrintf(snes->comm,"   %ssnes_mf: use matrix-free Jacobian\n",p);
225     PetscPrintf(snes->comm,"   %ssnes_ksp_ew_conv: use Eisenstat-Walker computation of KSP rtol. Params are:\n",p);
226     PetscPrintf(snes->comm,
227      "     %ssnes_ksp_ew_version <version> (1 or 2, default is %d)\n",p,kctx->version);
228     PetscPrintf(snes->comm,
229      "     %ssnes_ksp_ew_rtol0 <rtol0> (0 <= rtol0 < 1, default %g)\n",p,kctx->rtol_0);
230     PetscPrintf(snes->comm,
231      "     %ssnes_ksp_ew_rtolmax <rtolmax> (0 <= rtolmax < 1, default %g)\n",p,kctx->rtol_max);
232     PetscPrintf(snes->comm,
233      "     %ssnes_ksp_ew_gamma <gamma> (0 <= gamma <= 1, default %g)\n",p,kctx->gamma);
234     PetscPrintf(snes->comm,
235      "     %ssnes_ksp_ew_alpha <alpha> (1 < alpha <= 2, default %g)\n",p,kctx->alpha);
236     PetscPrintf(snes->comm,
237      "     %ssnes_ksp_ew_alpha2 <alpha2> (default %g)\n",p,kctx->alpha2);
238     PetscPrintf(snes->comm,
239      "     %ssnes_ksp_ew_threshold <threshold> (0 < threshold < 1, default %g)\n",p,kctx->threshold);
240   }
241   else if (snes->type == SNES_UNCONSTRAINED_MINIMIZATION) {
242     PetscPrintf(snes->comm,
243      " options for solving unconstrained minimization problems only:\n");
244     PetscPrintf(snes->comm,"   %ssnes_fmin <ftol>: minimum function tolerance (default %g)\n",p,snes->fmin);
245     PetscPrintf(snes->comm,"   %ssnes_fd: use finite differences for Hessian\n",p);
246     PetscPrintf(snes->comm,"   %ssnes_mf: use matrix-free Hessian\n",p);
247   }
248   PetscPrintf(snes->comm," Run program with %ssnes_type method -help for help on ",p);
249   PetscPrintf(snes->comm,"a particular method\n");
250   if (snes->printhelp) (*snes->printhelp)(snes,p);
251   return 0;
252 }
253 /*@
254    SNESSetApplicationContext - Sets the optional user-defined context for
255    the nonlinear solvers.
256 
257    Input Parameters:
258 .  snes - the SNES context
259 .  usrP - optional user context
260 
261 .keywords: SNES, nonlinear, set, application, context
262 
263 .seealso: SNESGetApplicationContext()
264 @*/
265 int SNESSetApplicationContext(SNES snes,void *usrP)
266 {
267   PetscValidHeaderSpecific(snes,SNES_COOKIE);
268   snes->user		= usrP;
269   return 0;
270 }
271 /*@C
272    SNESGetApplicationContext - Gets the user-defined context for the
273    nonlinear solvers.
274 
275    Input Parameter:
276 .  snes - SNES context
277 
278    Output Parameter:
279 .  usrP - user context
280 
281 .keywords: SNES, nonlinear, get, application, context
282 
283 .seealso: SNESSetApplicationContext()
284 @*/
285 int SNESGetApplicationContext( SNES snes,  void **usrP )
286 {
287   PetscValidHeaderSpecific(snes,SNES_COOKIE);
288   *usrP = snes->user;
289   return 0;
290 }
291 /*@
292    SNESGetIterationNumber - Gets the current iteration number of the
293    nonlinear solver.
294 
295    Input Parameter:
296 .  snes - SNES context
297 
298    Output Parameter:
299 .  iter - iteration number
300 
301 .keywords: SNES, nonlinear, get, iteration, number
302 @*/
303 int SNESGetIterationNumber(SNES snes,int* iter)
304 {
305   PetscValidHeaderSpecific(snes,SNES_COOKIE);
306   *iter = snes->iter;
307   return 0;
308 }
309 /*@
310    SNESGetFunctionNorm - Gets the norm of the current function that was set
311    with SNESSSetFunction().
312 
313    Input Parameter:
314 .  snes - SNES context
315 
316    Output Parameter:
317 .  fnorm - 2-norm of function
318 
319    Note:
320    SNESGetFunctionNorm() is valid for SNES_NONLINEAR_EQUATIONS methods only.
321    A related routine for SNES_UNCONSTRAINED_MINIMIZATION methods is
322    SNESGetGradientNorm().
323 
324 .keywords: SNES, nonlinear, get, function, norm
325 
326 .seealso: SNESSetFunction()
327 @*/
328 int SNESGetFunctionNorm(SNES snes,Scalar *fnorm)
329 {
330   PetscValidHeaderSpecific(snes,SNES_COOKIE);
331   if (snes->method_class != SNES_NONLINEAR_EQUATIONS) SETERRQ(1,
332     "SNESGetFunctionNorm:For SNES_NONLINEAR_EQUATIONS only");
333   *fnorm = snes->norm;
334   return 0;
335 }
336 /*@
337    SNESGetGradientNorm - Gets the norm of the current gradient that was set
338    with SNESSSetGradient().
339 
340    Input Parameter:
341 .  snes - SNES context
342 
343    Output Parameter:
344 .  fnorm - 2-norm of gradient
345 
346    Note:
347    SNESGetGradientNorm() is valid for SNES_UNCONSTRAINED_MINIMIZATION
348    methods only.  A related routine for SNES_NONLINEAR_EQUATIONS methods
349    is SNESGetFunctionNorm().
350 
351 .keywords: SNES, nonlinear, get, gradient, norm
352 
353 .seelso: SNESSetGradient()
354 @*/
355 int SNESGetGradientNorm(SNES snes,Scalar *gnorm)
356 {
357   PetscValidHeaderSpecific(snes,SNES_COOKIE);
358   if (snes->method_class != SNES_UNCONSTRAINED_MINIMIZATION) SETERRQ(1,
359     "SNESGetGradientNorm:For SNES_UNCONSTRAINED_MINIMIZATION only");
360   *gnorm = snes->norm;
361   return 0;
362 }
363 /*@
364    SNESGetNumberUnsuccessfulSteps - Gets the number of unsuccessful steps
365    attempted by the nonlinear solver.
366 
367    Input Parameter:
368 .  snes - SNES context
369 
370    Output Parameter:
371 .  nfails - number of unsuccessful steps attempted
372 
373 .keywords: SNES, nonlinear, get, number, unsuccessful, steps
374 @*/
375 int SNESGetNumberUnsuccessfulSteps(SNES snes,int* nfails)
376 {
377   PetscValidHeaderSpecific(snes,SNES_COOKIE);
378   *nfails = snes->nfailures;
379   return 0;
380 }
381 /*@C
382    SNESGetSLES - Returns the SLES context for a SNES solver.
383 
384    Input Parameter:
385 .  snes - the SNES context
386 
387    Output Parameter:
388 .  sles - the SLES context
389 
390    Notes:
391    The user can then directly manipulate the SLES context to set various
392    options, etc.  Likewise, the user can then extract and manipulate the
393    KSP and PC contexts as well.
394 
395 .keywords: SNES, nonlinear, get, SLES, context
396 
397 .seealso: SLESGetPC(), SLESGetKSP()
398 @*/
399 int SNESGetSLES(SNES snes,SLES *sles)
400 {
401   PetscValidHeaderSpecific(snes,SNES_COOKIE);
402   *sles = snes->sles;
403   return 0;
404 }
405 /* -----------------------------------------------------------*/
406 /*@C
407    SNESCreate - Creates a nonlinear solver context.
408 
409    Input Parameter:
410 .  comm - MPI communicator
411 .  type - type of method, one of
412 $    SNES_NONLINEAR_EQUATIONS
413 $      (for systems of nonlinear equations)
414 $    SNES_UNCONSTRAINED_MINIMIZATION
415 $      (for unconstrained minimization)
416 
417    Output Parameter:
418 .  outsnes - the new SNES context
419 
420 .keywords: SNES, nonlinear, create, context
421 
422 .seealso: SNESSolve(), SNESDestroy()
423 @*/
424 int SNESCreate(MPI_Comm comm,SNESProblemType type,SNES *outsnes)
425 {
426   int                 ierr;
427   SNES                snes;
428   SNES_KSP_EW_ConvCtx *kctx;
429 
430   *outsnes = 0;
431   if (type != SNES_UNCONSTRAINED_MINIMIZATION && type != SNES_NONLINEAR_EQUATIONS)
432     SETERRQ(1,"SNESCreate:incorrect method type");
433   PetscHeaderCreate(snes,_SNES,SNES_COOKIE,SNES_UNKNOWN_METHOD,comm);
434   PLogObjectCreate(snes);
435   snes->max_its           = 50;
436   snes->max_funcs	  = 1000;
437   snes->norm		  = 0.0;
438   if (type == SNES_UNCONSTRAINED_MINIMIZATION) {
439     snes->rtol		  = 1.e-8;
440     snes->ttol            = 0.0;
441     snes->atol		  = 1.e-10;
442   }
443   else {
444     snes->rtol		  = 1.e-8;
445     snes->ttol            = 0.0;
446     snes->atol		  = 1.e-50;
447   }
448   snes->xtol		  = 1.e-8;
449   snes->trunctol	  = 1.e-12; /* no longer used */
450   snes->nfuncs            = 0;
451   snes->nfailures         = 0;
452   snes->monitor           = 0;
453   snes->data              = 0;
454   snes->view              = 0;
455   snes->computeumfunction = 0;
456   snes->umfunP            = 0;
457   snes->fc                = 0;
458   snes->deltatol          = 1.e-12;
459   snes->fmin              = -1.e30;
460   snes->method_class      = type;
461   snes->set_method_called = 0;
462   snes->setup_called      = 0;
463   snes->ksp_ewconv        = 0;
464 
465   /* Create context to compute Eisenstat-Walker relative tolerance for KSP */
466   kctx = PetscNew(SNES_KSP_EW_ConvCtx); CHKPTRQ(kctx);
467   snes->kspconvctx  = (void*)kctx;
468   kctx->version     = 2;
469   kctx->rtol_0      = .3; /* Eisenstat and Walker suggest rtol_0=.5, but
470                              this was too large for some test cases */
471   kctx->rtol_last   = 0;
472   kctx->rtol_max    = .9;
473   kctx->gamma       = 1.0;
474   kctx->alpha2      = .5*(1.0 + sqrt(5.0));
475   kctx->alpha       = kctx->alpha2;
476   kctx->threshold   = .1;
477   kctx->lresid_last = 0;
478   kctx->norm_last   = 0;
479 
480   ierr = SLESCreate(comm,&snes->sles); CHKERRQ(ierr);
481   PLogObjectParent(snes,snes->sles)
482 
483   *outsnes = snes;
484   return 0;
485 }
486 
487 /* --------------------------------------------------------------- */
488 /*@C
489    SNESSetFunction - Sets the function evaluation routine and function
490    vector for use by the SNES routines in solving systems of nonlinear
491    equations.
492 
493    Input Parameters:
494 .  snes - the SNES context
495 .  func - function evaluation routine
496 .  ctx - optional user-defined function context
497 .  r - vector to store function value
498 
499    Calling sequence of func:
500 .  func (SNES, Vec x, Vec f, void *ctx);
501 
502 .  x - input vector
503 .  f - vector function
504 .  ctx - optional user-defined context for private data for the
505          function evaluation routine (may be null)
506 
507    Notes:
508    The Newton-like methods typically solve linear systems of the form
509 $      f'(x) x = -f(x),
510 $  where f'(x) denotes the Jacobian matrix and f(x) is the function.
511 
512    SNESSetFunction() is valid for SNES_NONLINEAR_EQUATIONS methods only.
513    Analogous routines for SNES_UNCONSTRAINED_MINIMIZATION methods are
514    SNESSetMinimizationFunction() and SNESSetGradient();
515 
516 .keywords: SNES, nonlinear, set, function
517 
518 .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian()
519 @*/
520 int SNESSetFunction( SNES snes, Vec r, int (*func)(SNES,Vec,Vec,void*),void *ctx)
521 {
522   PetscValidHeaderSpecific(snes,SNES_COOKIE);
523   if (snes->method_class != SNES_NONLINEAR_EQUATIONS) SETERRQ(1,
524     "SNESSetFunction:For SNES_NONLINEAR_EQUATIONS only");
525   snes->computefunction     = func;
526   snes->vec_func            = snes->vec_func_always = r;
527   snes->funP                = ctx;
528   return 0;
529 }
530 
531 /*@
532    SNESComputeFunction - Computes the function that has been set with
533    SNESSetFunction().
534 
535    Input Parameters:
536 .  snes - the SNES context
537 .  x - input vector
538 
539    Output Parameter:
540 .  y - function vector, as set by SNESSetFunction()
541 
542 n   Notes:
543    SNESComputeFunction() is valid for SNES_NONLINEAR_EQUATIONS methods only.
544    Analogous routines for SNES_UNCONSTRAINED_MINIMIZATION methods are
545    SNESComputeMinimizationFunction() and SNESComputeGradient();
546 
547 .keywords: SNES, nonlinear, compute, function
548 
549 .seealso: SNESSetFunction(), SNESGetFunction()
550 @*/
551 int SNESComputeFunction(SNES snes,Vec x, Vec y)
552 {
553   int    ierr;
554 
555   if (snes->method_class != SNES_NONLINEAR_EQUATIONS) SETERRQ(1,
556     "SNESComputeFunction: For SNES_NONLINEAR_EQUATIONS only");
557   PLogEventBegin(SNES_FunctionEval,snes,x,y,0);
558   ierr = (*snes->computefunction)(snes,x,y,snes->funP); CHKERRQ(ierr);
559   PLogEventEnd(SNES_FunctionEval,snes,x,y,0);
560   return 0;
561 }
562 
563 /*@C
564    SNESSetMinimizationFunction - Sets the function evaluation routine for
565    unconstrained minimization.
566 
567    Input Parameters:
568 .  snes - the SNES context
569 .  func - function evaluation routine
570 .  ctx - optional user-defined function context
571 
572    Calling sequence of func:
573 .  func (SNES snes,Vec x,double *f,void *ctx);
574 
575 .  x - input vector
576 .  f - function
577 .  ctx - optional user-defined context for private data for the
578          function evaluation routine (may be null)
579 
580    Notes:
581    SNESSetMinimizationFunction() is valid for SNES_UNCONSTRAINED_MINIMIZATION
582    methods only. An analogous routine for SNES_NONLINEAR_EQUATIONS methods is
583    SNESSetFunction().
584 
585 .keywords: SNES, nonlinear, set, minimization, function
586 
587 .seealso:  SNESGetMinimizationFunction(), SNESComputeMinimizationFunction(),
588            SNESSetHessian(), SNESSetGradient()
589 @*/
590 int SNESSetMinimizationFunction(SNES snes,int (*func)(SNES,Vec,double*,void*),
591                       void *ctx)
592 {
593   PetscValidHeaderSpecific(snes,SNES_COOKIE);
594   if (snes->method_class != SNES_UNCONSTRAINED_MINIMIZATION) SETERRQ(1,
595     "SNESSetMinimizationFunction:Only for SNES_UNCONSTRAINED_MINIMIZATION");
596   snes->computeumfunction   = func;
597   snes->umfunP              = ctx;
598   return 0;
599 }
600 
601 /*@
602    SNESComputeMinimizationFunction - Computes the function that has been
603    set with SNESSetMinimizationFunction().
604 
605    Input Parameters:
606 .  snes - the SNES context
607 .  x - input vector
608 
609    Output Parameter:
610 .  y - function value
611 
612    Notes:
613    SNESComputeMinimizationFunction() is valid only for
614    SNES_UNCONSTRAINED_MINIMIZATION methods. An analogous routine for
615    SNES_NONLINEAR_EQUATIONS methods is SNESComputeFunction().
616 
617 .keywords: SNES, nonlinear, compute, minimization, function
618 
619 .seealso: SNESSetMinimizationFunction(), SNESGetMinimizationFunction(),
620           SNESComputeGradient(), SNESComputeHessian()
621 @*/
622 int SNESComputeMinimizationFunction(SNES snes,Vec x,double *y)
623 {
624   int    ierr;
625   if (snes->method_class != SNES_UNCONSTRAINED_MINIMIZATION) SETERRQ(1,
626     "SNESComputeMinimizationFunction:Only for SNES_UNCONSTRAINED_MINIMIZATION");
627   PLogEventBegin(SNES_MinimizationFunctionEval,snes,x,y,0);
628   ierr = (*snes->computeumfunction)(snes,x,y,snes->umfunP); CHKERRQ(ierr);
629   PLogEventEnd(SNES_MinimizationFunctionEval,snes,x,y,0);
630   return 0;
631 }
632 
633 /*@C
634    SNESSetGradient - Sets the gradient evaluation routine and gradient
635    vector for use by the SNES routines.
636 
637    Input Parameters:
638 .  snes - the SNES context
639 .  func - function evaluation routine
640 .  ctx - optional user-defined function context
641 .  r - vector to store gradient value
642 
643    Calling sequence of func:
644 .  func (SNES, Vec x, Vec g, void *ctx);
645 
646 .  x - input vector
647 .  g - gradient vector
648 .  ctx - optional user-defined context for private data for the
649          function evaluation routine (may be null)
650 
651    Notes:
652    SNESSetMinimizationFunction() is valid for SNES_UNCONSTRAINED_MINIMIZATION
653    methods only. An analogous routine for SNES_NONLINEAR_EQUATIONS methods is
654    SNESSetFunction().
655 
656 .keywords: SNES, nonlinear, set, function
657 
658 .seealso: SNESGetGradient(), SNESComputeGradient(), SNESSetHessian(),
659           SNESSetMinimizationFunction(),
660 @*/
661 int SNESSetGradient(SNES snes,Vec r,int (*func)(SNES,Vec,Vec,void*),
662                      void *ctx)
663 {
664   PetscValidHeaderSpecific(snes,SNES_COOKIE);
665   if (snes->method_class != SNES_UNCONSTRAINED_MINIMIZATION) SETERRQ(1,
666     "SNESSetGradient:For SNES_UNCONSTRAINED_MINIMIZATION only");
667   snes->computefunction     = func;
668   snes->vec_func            = snes->vec_func_always = r;
669   snes->funP                = ctx;
670   return 0;
671 }
672 
673 /*@
674    SNESComputeGradient - Computes the gradient that has been set with
675    SNESSetGradient().
676 
677    Input Parameters:
678 .  snes - the SNES context
679 .  x - input vector
680 
681    Output Parameter:
682 .  y - gradient vector
683 
684    Notes:
685    SNESComputeGradient() is valid only for
686    SNES_UNCONSTRAINED_MINIMIZATION methods. An analogous routine for
687    SNES_NONLINEAR_EQUATIONS methods is SNESComputeFunction().
688 
689 .keywords: SNES, nonlinear, compute, gradient
690 
691 .seealso:  SNESSetGradient(), SNESGetGradient(),
692            SNESComputeMinimizationFunction(), SNESComputeHessian()
693 @*/
694 int SNESComputeGradient(SNES snes,Vec x, Vec y)
695 {
696   int    ierr;
697   if (snes->method_class != SNES_UNCONSTRAINED_MINIMIZATION) SETERRQ(1,
698     "SNESComputeGradient:For SNES_UNCONSTRAINED_MINIMIZATION only");
699   PLogEventBegin(SNES_GradientEval,snes,x,y,0);
700   ierr = (*snes->computefunction)(snes,x,y,snes->funP); CHKERRQ(ierr);
701   PLogEventEnd(SNES_GradientEval,snes,x,y,0);
702   return 0;
703 }
704 
705 /*@
706    SNESComputeJacobian - Computes the Jacobian matrix that has been
707    set with SNESSetJacobian().
708 
709    Input Parameters:
710 .  snes - the SNES context
711 .  x - input vector
712 
713    Output Parameters:
714 .  A - Jacobian matrix
715 .  B - optional preconditioning matrix
716 .  flag - flag indicating matrix structure
717 
718    Notes:
719    Most users should not need to explicitly call this routine, as it
720    is used internally within the nonlinear solvers.
721 
722    See SLESSetOperators() for information about setting the flag parameter.
723 
724    SNESComputeJacobian() is valid only for SNES_NONLINEAR_EQUATIONS
725    methods. An analogous routine for SNES_UNCONSTRAINED_MINIMIZATION
726    methods is SNESComputeJacobian().
727 
728 .keywords: SNES, compute, Jacobian, matrix
729 
730 .seealso:  SNESSetJacobian(), SLESSetOperators()
731 @*/
732 int SNESComputeJacobian(SNES snes,Vec X,Mat *A,Mat *B,MatStructure *flg)
733 {
734   int    ierr;
735   if (snes->method_class != SNES_NONLINEAR_EQUATIONS) SETERRQ(1,
736     "SNESComputeJacobian: For SNES_NONLINEAR_EQUATIONS only");
737   if (!snes->computejacobian) return 0;
738   PLogEventBegin(SNES_JacobianEval,snes,X,*A,*B);
739   *flg = DIFFERENT_NONZERO_PATTERN;
740   ierr = (*snes->computejacobian)(snes,X,A,B,flg,snes->jacP); CHKERRQ(ierr);
741   PLogEventEnd(SNES_JacobianEval,snes,X,*A,*B);
742   /* make sure user returned a correct Jacobian and preconditioner */
743   PetscValidHeaderSpecific(*A,MAT_COOKIE);
744   PetscValidHeaderSpecific(*B,MAT_COOKIE);
745   return 0;
746 }
747 
748 /*@
749    SNESComputeHessian - Computes the Hessian matrix that has been
750    set with SNESSetHessian().
751 
752    Input Parameters:
753 .  snes - the SNES context
754 .  x - input vector
755 
756    Output Parameters:
757 .  A - Hessian matrix
758 .  B - optional preconditioning matrix
759 .  flag - flag indicating matrix structure
760 
761    Notes:
762    Most users should not need to explicitly call this routine, as it
763    is used internally within the nonlinear solvers.
764 
765    See SLESSetOperators() for information about setting the flag parameter.
766 
767    SNESComputeHessian() is valid only for
768    SNES_UNCONSTRAINED_MINIMIZATION methods. An analogous routine for
769    SNES_NONLINEAR_EQUATIONS methods is SNESComputeJacobian().
770 
771 .keywords: SNES, compute, Hessian, matrix
772 
773 .seealso:  SNESSetHessian(), SLESSetOperators(), SNESComputeGradient(),
774            SNESComputeMinimizationFunction()
775 @*/
776 int SNESComputeHessian(SNES snes,Vec x,Mat *A,Mat *B,MatStructure *flag)
777 {
778   int    ierr;
779   if (snes->method_class != SNES_UNCONSTRAINED_MINIMIZATION) SETERRQ(1,
780     "SNESComputeHessian:For SNES_UNCONSTRAINED_MINIMIZATION only");
781   if (!snes->computejacobian) return 0;
782   PLogEventBegin(SNES_HessianEval,snes,x,*A,*B);
783   *flag = DIFFERENT_NONZERO_PATTERN;
784   ierr = (*snes->computejacobian)(snes,x,A,B,flag,snes->jacP); CHKERRQ(ierr);
785   PLogEventEnd(SNES_HessianEval,snes,x,*A,*B);
786   /* make sure user returned a correct Jacobian and preconditioner */
787   PetscValidHeaderSpecific(*A,MAT_COOKIE);
788   PetscValidHeaderSpecific(*B,MAT_COOKIE);
789   return 0;
790 }
791 
792 /*@C
793    SNESSetJacobian - Sets the function to compute Jacobian as well as the
794    location to store it.
795 
796    Input Parameters:
797 .  snes - the SNES context
798 .  A - Jacobian matrix
799 .  B - preconditioner matrix (usually same as the Jacobian)
800 .  func - Jacobian evaluation routine
801 .  ctx - optional user-defined context for private data for the
802          Jacobian evaluation routine (may be null)
803 
804    Calling sequence of func:
805 .  func (SNES,Vec x,Mat *A,Mat *B,int *flag,void *ctx);
806 
807 .  x - input vector
808 .  A - Jacobian matrix
809 .  B - preconditioner matrix, usually the same as A
810 .  flag - flag indicating information about the preconditioner matrix
811    structure (same as flag in SLESSetOperators())
812 .  ctx - optional user-defined Jacobian context
813 
814    Notes:
815    See SLESSetOperators() for information about setting the flag input
816    parameter in the routine func().  Be sure to read this information!
817 
818    The routine func() takes Mat * as the matrix arguments rather than Mat.
819    This allows the Jacobian evaluation routine to replace A and/or B with a
820    completely new new matrix structure (not just different matrix elements)
821    when appropriate, for instance, if the nonzero structure is changing
822    throughout the global iterations.
823 
824 .keywords: SNES, nonlinear, set, Jacobian, matrix
825 
826 .seealso: SLESSetOperators(), SNESSetFunction()
827 @*/
828 int SNESSetJacobian(SNES snes,Mat A,Mat B,int (*func)(SNES,Vec,Mat*,Mat*,
829                     MatStructure*,void*),void *ctx)
830 {
831   PetscValidHeaderSpecific(snes,SNES_COOKIE);
832   if (snes->method_class != SNES_NONLINEAR_EQUATIONS) SETERRQ(1,
833     "SNESSetJacobian:For SNES_NONLINEAR_EQUATIONS only");
834   snes->computejacobian = func;
835   snes->jacP            = ctx;
836   snes->jacobian        = A;
837   snes->jacobian_pre    = B;
838   return 0;
839 }
840 
841 /*@
842    SNESGetJacobian - Returns the Jacobian matrix and optionally the user
843    provided context for evaluating the Jacobian.
844 
845    Input Parameter:
846 .  snes - the nonlinear solver context
847 
848    Output Parameters:
849 .  A - location to stash Jacobian matrix (or PETSC_NULL)
850 .  B - location to stash preconditioner matrix (or PETSC_NULL)
851 .  ctx - location to stash Jacobian ctx (or PETSC_NULL)
852 
853 .seealso: SNESSetJacobian(), SNESComputeJacobian()
854 @*/
855 int SNESGetJacobian(SNES snes,Mat *A,Mat *B, void **ctx)
856 {
857   if (snes->method_class != SNES_NONLINEAR_EQUATIONS) SETERRQ(1,
858     "SNESSetJacobian:For SNES_NONLINEAR_EQUATIONS only");
859   if (A)   *A = snes->jacobian;
860   if (B)   *B = snes->jacobian_pre;
861   if (ctx) *ctx = snes->jacP;
862   return 0;
863 }
864 
865 /*@C
866    SNESSetHessian - Sets the function to compute Hessian as well as the
867    location to store it.
868 
869    Input Parameters:
870 .  snes - the SNES context
871 .  A - Hessian matrix
872 .  B - preconditioner matrix (usually same as the Hessian)
873 .  func - Jacobian evaluation routine
874 .  ctx - optional user-defined context for private data for the
875          Hessian evaluation routine (may be null)
876 
877    Calling sequence of func:
878 .  func (SNES,Vec x,Mat *A,Mat *B,int *flag,void *ctx);
879 
880 .  x - input vector
881 .  A - Hessian matrix
882 .  B - preconditioner matrix, usually the same as A
883 .  flag - flag indicating information about the preconditioner matrix
884    structure (same as flag in SLESSetOperators())
885 .  ctx - optional user-defined Hessian context
886 
887    Notes:
888    See SLESSetOperators() for information about setting the flag input
889    parameter in the routine func().  Be sure to read this information!
890 
891    The function func() takes Mat * as the matrix arguments rather than Mat.
892    This allows the Hessian evaluation routine to replace A and/or B with a
893    completely new new matrix structure (not just different matrix elements)
894    when appropriate, for instance, if the nonzero structure is changing
895    throughout the global iterations.
896 
897 .keywords: SNES, nonlinear, set, Hessian, matrix
898 
899 .seealso: SNESSetMinimizationFunction(), SNESSetGradient(), SLESSetOperators()
900 @*/
901 int SNESSetHessian(SNES snes,Mat A,Mat B,int (*func)(SNES,Vec,Mat*,Mat*,
902                     MatStructure*,void*),void *ctx)
903 {
904   PetscValidHeaderSpecific(snes,SNES_COOKIE);
905   if (snes->method_class != SNES_UNCONSTRAINED_MINIMIZATION) SETERRQ(1,
906     "SNESSetHessian:For SNES_UNCONSTRAINED_MINIMIZATION only");
907   snes->computejacobian = func;
908   snes->jacP            = ctx;
909   snes->jacobian        = A;
910   snes->jacobian_pre    = B;
911   return 0;
912 }
913 
914 /*@
915    SNESGetHessian - Returns the Hessian matrix and optionally the user
916    provided context for evaluating the Hessian.
917 
918    Input Parameter:
919 .  snes - the nonlinear solver context
920 
921    Output Parameters:
922 .  A - location to stash Hessian matrix (or PETSC_NULL)
923 .  B - location to stash preconditioner matrix (or PETSC_NULL)
924 .  ctx - location to stash Hessian ctx (or PETSC_NULL)
925 
926 .seealso: SNESSetHessian(), SNESComputeHessian()
927 @*/
928 int SNESGetHessian(SNES snes,Mat *A,Mat *B, void **ctx)
929 {
930   if (snes->method_class != SNES_UNCONSTRAINED_MINIMIZATION) SETERRQ(1,
931     "SNESSetHessian:For SNES_UNCONSTRAINED_MINIMIZATION only");
932   if (A)   *A = snes->jacobian;
933   if (B)   *B = snes->jacobian_pre;
934   if (ctx) *ctx = snes->jacP;
935   return 0;
936 }
937 
938 /* ----- Routines to initialize and destroy a nonlinear solver ---- */
939 
940 /*@
941    SNESSetUp - Sets up the internal data structures for the later use
942    of a nonlinear solver.
943 
944    Input Parameter:
945 .  snes - the SNES context
946 .  x - the solution vector
947 
948    Notes:
949    For basic use of the SNES solvers the user need not explicitly call
950    SNESSetUp(), since these actions will automatically occur during
951    the call to SNESSolve().  However, if one wishes to control this
952    phase separately, SNESSetUp() should be called after SNESCreate()
953    and optional routines of the form SNESSetXXX(), but before SNESSolve().
954 
955 .keywords: SNES, nonlinear, setup
956 
957 .seealso: SNESCreate(), SNESSolve(), SNESDestroy()
958 @*/
959 int SNESSetUp(SNES snes,Vec x)
960 {
961   int ierr, flg;
962   PetscValidHeaderSpecific(snes,SNES_COOKIE);
963   PetscValidHeaderSpecific(x,VEC_COOKIE);
964   snes->vec_sol = snes->vec_sol_always = x;
965 
966   ierr = OptionsHasName(snes->prefix,"-snes_mf", &flg);  CHKERRQ(ierr);
967   if (flg) {
968     Mat J;
969     ierr = SNESDefaultMatrixFreeMatCreate(snes,snes->vec_sol,&J);CHKERRQ(ierr);
970     PLogObjectParent(snes,J);
971     snes->mfshell = J;
972     if (snes->method_class == SNES_NONLINEAR_EQUATIONS) {
973       ierr = SNESSetJacobian(snes,J,J,0,snes->funP); CHKERRQ(ierr);
974       PLogInfo(snes,"SNESSetUp: Setting default matrix-free Jacobian routines\n");
975     }
976     else if (snes->method_class == SNES_UNCONSTRAINED_MINIMIZATION) {
977       ierr = SNESSetHessian(snes,J,J,0,snes->funP); CHKERRQ(ierr);
978       PLogInfo(snes,"SNESSetUp: Setting default matrix-free Hessian routines\n");
979     } else SETERRQ(1,"SNESSetUp:Method class doesn't support matrix-free option");
980   }
981   if ((snes->method_class == SNES_NONLINEAR_EQUATIONS)) {
982     if (!snes->vec_func) SETERRQ(1,"SNESSetUp:Must call SNESSetFunction() first");
983     if (!snes->computefunction) SETERRQ(1,"SNESSetUp:Must call SNESSetFunction() first");
984     if (!snes->jacobian) SETERRQ(1,"SNESSetUp:Must call SNESSetJacobian() first");
985     if (snes->vec_func == snes->vec_sol) SETERRQ(1,"SNESSetUp:Solution vector cannot be function vector");
986 
987     /* Set the KSP stopping criterion to use the Eisenstat-Walker method */
988     if (snes->ksp_ewconv && snes->type != SNES_EQ_TR) {
989       SLES sles; KSP ksp;
990       ierr = SNESGetSLES(snes,&sles); CHKERRQ(ierr);
991       ierr = SLESGetKSP(sles,&ksp); CHKERRQ(ierr);
992       ierr = KSPSetConvergenceTest(ksp,SNES_KSP_EW_Converged_Private,
993              (void *)snes); CHKERRQ(ierr);
994     }
995   } else if ((snes->method_class == SNES_UNCONSTRAINED_MINIMIZATION)) {
996     if (!snes->vec_func) SETERRQ(1,"SNESSetUp:Must call SNESSetGradient() first");
997     if (!snes->computefunction) SETERRQ(1,"SNESSetUp:Must call SNESSetGradient() first");
998     if (!snes->computeumfunction)
999       SETERRQ(1,"SNESSetUp:Must call SNESSetMinimizationFunction() first");
1000     if (!snes->jacobian) SETERRQ(1,"SNESSetUp:Must call SNESSetHessian() first");
1001   } else SETERRQ(1,"SNESSetUp:Unknown method class");
1002   if (snes->setup) {ierr = (*snes->setup)(snes); CHKERRQ(ierr);}
1003   snes->setup_called = 1;
1004   return 0;
1005 }
1006 
1007 /*@C
1008    SNESDestroy - Destroys the nonlinear solver context that was created
1009    with SNESCreate().
1010 
1011    Input Parameter:
1012 .  snes - the SNES context
1013 
1014 .keywords: SNES, nonlinear, destroy
1015 
1016 .seealso: SNESCreate(), SNESSolve()
1017 @*/
1018 int SNESDestroy(SNES snes)
1019 {
1020   int ierr;
1021   PetscValidHeaderSpecific(snes,SNES_COOKIE);
1022   ierr = (*(snes)->destroy)((PetscObject)snes); CHKERRQ(ierr);
1023   if (snes->kspconvctx) PetscFree(snes->kspconvctx);
1024   if (snes->mfshell) MatDestroy(snes->mfshell);
1025   ierr = SLESDestroy(snes->sles); CHKERRQ(ierr);
1026   if (snes->xmonitor) SNESLGMonitorDestroy(snes->xmonitor);
1027   PLogObjectDestroy((PetscObject)snes);
1028   PetscHeaderDestroy((PetscObject)snes);
1029   return 0;
1030 }
1031 
1032 /* ----------- Routines to set solver parameters ---------- */
1033 
1034 /*@
1035    SNESSetTolerances - Sets various parameters used in convergence tests.
1036 
1037    Input Parameters:
1038 .  snes - the SNES context
1039 .  atol - tolerance
1040 
1041    Options Database Key:
1042 $    -snes_atol <atol> - absolute convergence tolerance
1043 $    -snes_rtol <rtol> - relative convergence tolerance
1044 $    -snes_stol <stol> - convergence tolerance in terms of
1045 $          the norm of the change in the solution between steps
1046 $    -snes_max_it <maxit> - maximum number of iterations
1047 $    -snes_max_funcs <maxf> - maximum number of function evaluations
1048 
1049    Notes:
1050    The default maximum number of iterations is 50.
1051    The default maximum number of function evaluations is 1000.
1052 
1053 .keywords: SNES, nonlinear, set, absolute, convergence, tolerance
1054 
1055 .seealso: SNESSetTrustRegionTolerance(), SNESSetMinimizationFunctionTolerance()
1056 @*/
1057 int SNESSetTolerances(SNES snes,double atol,double rtol,double stol,int maxit,int maxf)
1058 {
1059   PetscValidHeaderSpecific(snes,SNES_COOKIE);
1060   if (atol != PETSC_DEFAULT)  snes->atol      = atol;
1061   if (rtol != PETSC_DEFAULT)  snes->rtol      = rtol;
1062   if (stol != PETSC_DEFAULT)  snes->xtol      = stol;
1063   if (maxit != PETSC_DEFAULT) snes->max_its   = maxit;
1064   if (maxf != PETSC_DEFAULT)  snes->max_funcs = maxf;
1065   return 0;
1066 }
1067 
1068 /*@
1069    SNESSetTrustRegionTolerance - Sets the trust region parameter tolerance.
1070 
1071    Input Parameters:
1072 .  snes - the SNES context
1073 .  tol - tolerance
1074 
1075    Options Database Key:
1076 $    -snes_trtol <tol>
1077 
1078 .keywords: SNES, nonlinear, set, trust region, tolerance
1079 
1080 .seealso: SNESSetTolerances(), SNESSetMinimizationFunctionTolerance()
1081 @*/
1082 int SNESSetTrustRegionTolerance(SNES snes,double tol)
1083 {
1084   PetscValidHeaderSpecific(snes,SNES_COOKIE);
1085   snes->deltatol = tol;
1086   return 0;
1087 }
1088 
1089 /*@
1090    SNESSetMinimizationFunctionTolerance - Sets the minimum allowable function tolerance
1091    for unconstrained minimization solvers.
1092 
1093    Input Parameters:
1094 .  snes - the SNES context
1095 .  ftol - minimum function tolerance
1096 
1097    Options Database Key:
1098 $    -snes_fmin <ftol>
1099 
1100    Note:
1101    SNESSetMinimizationFunctionTolerance() is valid for SNES_UNCONSTRAINED_MINIMIZATION
1102    methods only.
1103 
1104 .keywords: SNES, nonlinear, set, minimum, convergence, function, tolerance
1105 
1106 .seealso: SNESSetTolerances(), SNESSetTrustRegionTolerance()
1107 @*/
1108 int SNESSetMinimizationFunctionTolerance(SNES snes,double ftol)
1109 {
1110   PetscValidHeaderSpecific(snes,SNES_COOKIE);
1111   snes->fmin = ftol;
1112   return 0;
1113 }
1114 
1115 /* ------------ Routines to set performance monitoring options ----------- */
1116 
1117 /*@C
1118    SNESSetMonitor - Sets the function that is to be used at every
1119    iteration of the nonlinear solver to display the iteration's
1120    progress.
1121 
1122    Input Parameters:
1123 .  snes - the SNES context
1124 .  func - monitoring routine
1125 .  mctx - optional user-defined context for private data for the
1126           monitor routine (may be null)
1127 
1128    Calling sequence of func:
1129    int func(SNES snes,int its, Vec x,Vec f,double norm,void *mctx)
1130 
1131 $    snes - the SNES context
1132 $    its - iteration number
1133 $    mctx - optional monitoring context
1134 $
1135 $ SNES_NONLINEAR_EQUATIONS methods:
1136 $    norm - 2-norm function value (may be estimated)
1137 $
1138 $ SNES_UNCONSTRAINED_MINIMIZATION methods:
1139 $    norm - 2-norm gradient value (may be estimated)
1140 
1141 .keywords: SNES, nonlinear, set, monitor
1142 
1143 .seealso: SNESDefaultMonitor()
1144 @*/
1145 int SNESSetMonitor( SNES snes, int (*func)(SNES,int,double,void*),
1146                     void *mctx )
1147 {
1148   snes->monitor = func;
1149   snes->monP    = (void*)mctx;
1150   return 0;
1151 }
1152 
1153 /*@C
1154    SNESSetConvergenceTest - Sets the function that is to be used
1155    to test for convergence of the nonlinear iterative solution.
1156 
1157    Input Parameters:
1158 .  snes - the SNES context
1159 .  func - routine to test for convergence
1160 .  cctx - optional context for private data for the convergence routine
1161           (may be null)
1162 
1163    Calling sequence of func:
1164    int func (SNES snes,double xnorm,double gnorm,
1165              double f,void *cctx)
1166 
1167 $    snes - the SNES context
1168 $    cctx - optional convergence context
1169 $    xnorm - 2-norm of current iterate
1170 $
1171 $ SNES_NONLINEAR_EQUATIONS methods:
1172 $    gnorm - 2-norm of current step
1173 $    f - 2-norm of function
1174 $
1175 $ SNES_UNCONSTRAINED_MINIMIZATION methods:
1176 $    gnorm - 2-norm of current gradient
1177 $    f - function value
1178 
1179 .keywords: SNES, nonlinear, set, convergence, test
1180 
1181 .seealso: SNESConverged_EQ_LS(), SNESConverged_EQ_TR(),
1182           SNESConverged_UM_LS(), SNESConverged_UM_TR()
1183 @*/
1184 int SNESSetConvergenceTest(SNES snes,
1185           int (*func)(SNES,double,double,double,void*),void *cctx)
1186 {
1187   (snes)->converged = func;
1188   (snes)->cnvP      = cctx;
1189   return 0;
1190 }
1191 
1192 /*
1193    SNESScaleStep_Private - Scales a step so that its length is less than the
1194    positive parameter delta.
1195 
1196     Input Parameters:
1197 .   snes - the SNES context
1198 .   y - approximate solution of linear system
1199 .   fnorm - 2-norm of current function
1200 .   delta - trust region size
1201 
1202     Output Parameters:
1203 .   gpnorm - predicted function norm at the new point, assuming local
1204     linearization.  The value is zero if the step lies within the trust
1205     region, and exceeds zero otherwise.
1206 .   ynorm - 2-norm of the step
1207 
1208     Note:
1209     For non-trust region methods such as SNES_EQ_LS, the parameter delta
1210     is set to be the maximum allowable step size.
1211 
1212 .keywords: SNES, nonlinear, scale, step
1213 */
1214 int SNESScaleStep_Private(SNES snes,Vec y,double *fnorm,double *delta,
1215                   double *gpnorm,double *ynorm)
1216 {
1217   double norm;
1218   Scalar cnorm;
1219   VecNorm(y,NORM_2, &norm );
1220   if (norm > *delta) {
1221      norm = *delta/norm;
1222      *gpnorm = (1.0 - norm)*(*fnorm);
1223      cnorm = norm;
1224      VecScale( &cnorm, y );
1225      *ynorm = *delta;
1226   } else {
1227      *gpnorm = 0.0;
1228      *ynorm = norm;
1229   }
1230   return 0;
1231 }
1232 
1233 /*@
1234    SNESSolve - Solves a nonlinear system.  Call SNESSolve after calling
1235    SNESCreate() and optional routines of the form SNESSetXXX().
1236 
1237    Input Parameter:
1238 .  snes - the SNES context
1239 .  x - the solution vector
1240 
1241    Output Parameter:
1242    its - number of iterations until termination
1243 
1244    Note:
1245    The user should initialize the vector, x, with the initial guess
1246    for the nonlinear solve prior to calling SNESSolve.  In particular,
1247    to employ an initial guess of zero, the user should explicitly set
1248    this vector to zero by calling VecSet().
1249 
1250 .keywords: SNES, nonlinear, solve
1251 
1252 .seealso: SNESCreate(), SNESDestroy()
1253 @*/
1254 int SNESSolve(SNES snes,Vec x,int *its)
1255 {
1256   int ierr, flg;
1257 
1258   PetscValidHeaderSpecific(snes,SNES_COOKIE);
1259   if (!snes->setup_called) {ierr = SNESSetUp(snes,x); CHKERRQ(ierr);}
1260   else {snes->vec_sol = snes->vec_sol_always = x;}
1261   PLogEventBegin(SNES_Solve,snes,0,0,0);
1262   ierr = (*(snes)->solve)(snes,its); CHKERRQ(ierr);
1263   PLogEventEnd(SNES_Solve,snes,0,0,0);
1264   ierr = OptionsHasName(PETSC_NULL,"-snes_view", &flg); CHKERRQ(ierr);
1265   if (flg) { ierr = SNESView(snes,STDOUT_VIEWER_WORLD); CHKERRQ(ierr); }
1266   return 0;
1267 }
1268 
1269 /* --------- Internal routines for SNES Package --------- */
1270 static NRList *__SNESList = 0;
1271 
1272 /*@
1273    SNESSetType - Sets the method for the nonlinear solver.
1274 
1275    Input Parameters:
1276 .  snes - the SNES context
1277 .  method - a known method
1278 
1279    Notes:
1280    See "petsc/include/snes.h" for available methods (for instance)
1281 $  Systems of nonlinear equations:
1282 $    SNES_EQ_LS - Newton's method with line search
1283 $    SNES_EQ_TR - Newton's method with trust region
1284 $  Unconstrained minimization:
1285 $    SNES_UM_TR - Newton's method with trust region
1286 $    SNES_UM_LS - Newton's method with line search
1287 
1288   Options Database Command:
1289 $ -snes_type  <method>
1290 $    Use -help for a list of available methods
1291 $    (for instance, ls or tr)
1292 
1293 .keysords: SNES, set, method
1294 @*/
1295 int SNESSetType(SNES snes,SNESType method)
1296 {
1297   int (*r)(SNES);
1298   PetscValidHeaderSpecific(snes,SNES_COOKIE);
1299   /* Get the function pointers for the iterative method requested */
1300   if (!__SNESList) {SNESRegisterAll();}
1301   if (!__SNESList) {SETERRQ(1,"SNESSetType:Could not get methods");}
1302   r =  (int (*)(SNES))NRFindRoutine( __SNESList, (int)method, (char *)0 );
1303   if (!r) {SETERRQ(1,"SNESSetType:Unknown method");}
1304   if (snes->data) PetscFree(snes->data);
1305   snes->set_method_called = 1;
1306   return (*r)(snes);
1307 }
1308 
1309 /* --------------------------------------------------------------------- */
1310 /*@C
1311    SNESRegister - Adds the method to the nonlinear solver package, given
1312    a function pointer and a nonlinear solver name of the type SNESType.
1313 
1314    Input Parameters:
1315 .  name - for instance SNES_EQ_LS, SNES_EQ_TR, ...
1316 .  sname - corresponding string for name
1317 .  create - routine to create method context
1318 
1319 .keywords: SNES, nonlinear, register
1320 
1321 .seealso: SNESRegisterAll(), SNESRegisterDestroy()
1322 @*/
1323 int SNESRegister(int name, char *sname, int (*create)(SNES))
1324 {
1325   int ierr;
1326   if (!__SNESList) {ierr = NRCreate(&__SNESList); CHKERRQ(ierr);}
1327   NRRegister( __SNESList, name, sname, (int (*)(void*))create );
1328   return 0;
1329 }
1330 /* --------------------------------------------------------------------- */
1331 /*@C
1332    SNESRegisterDestroy - Frees the list of nonlinear solvers that were
1333    registered by SNESRegister().
1334 
1335 .keywords: SNES, nonlinear, register, destroy
1336 
1337 .seealso: SNESRegisterAll(), SNESRegisterAll()
1338 @*/
1339 int SNESRegisterDestroy()
1340 {
1341   if (__SNESList) {
1342     NRDestroy( __SNESList );
1343     __SNESList = 0;
1344   }
1345   return 0;
1346 }
1347 
1348 /*
1349    SNESGetTypeFromOptions_Private - Sets the selected method from the
1350    options database.
1351 
1352    Input Parameter:
1353 .  ctx - the SNES context
1354 
1355    Output Parameter:
1356 .  method -  solver method
1357 
1358    Returns:
1359    Returns 1 if the method is found; 0 otherwise.
1360 
1361    Options Database Key:
1362 $  -snes_type  method
1363 */
1364 int SNESGetTypeFromOptions_Private(SNES ctx,SNESType *method,int *flg)
1365 {
1366   int ierr;
1367   char sbuf[50];
1368   ierr = OptionsGetString(ctx->prefix,"-snes_type", sbuf, 50, flg); CHKERRQ(ierr);
1369   if (*flg) {
1370     if (!__SNESList) {ierr = SNESRegisterAll(); CHKERRQ(ierr);}
1371     *method = (SNESType)NRFindID( __SNESList, sbuf );
1372   }
1373   return 0;
1374 }
1375 
1376 /*@C
1377    SNESGetType - Gets the SNES method type and name (as a string).
1378 
1379    Input Parameter:
1380 .  snes - nonlinear solver context
1381 
1382    Output Parameter:
1383 .  method - SNES method (or use PETSC_NULL)
1384 .  name - name of SNES method (or use PETSC_NULL)
1385 
1386 .keywords: SNES, nonlinear, get, method, name
1387 @*/
1388 int SNESGetType(SNES snes, SNESType *method,char **name)
1389 {
1390   int ierr;
1391   if (!__SNESList) {ierr = SNESRegisterAll(); CHKERRQ(ierr);}
1392   if (method) *method = (SNESType) snes->type;
1393   if (name)  *name = NRFindName( __SNESList, (int) snes->type );
1394   return 0;
1395 }
1396 
1397 #include <stdio.h>
1398 /*
1399    SNESPrintTypes_Private - Prints the SNES methods available from the
1400    options database.
1401 
1402    Input Parameters:
1403 .  comm   - communicator (usually MPI_COMM_WORLD)
1404 .  prefix - prefix (usually "-")
1405 .  name   - the options database name (by default "snes_type")
1406 */
1407 int SNESPrintTypes_Private(MPI_Comm comm,char* prefix,char *name)
1408 {
1409   FuncList *entry;
1410   if (!__SNESList) {SNESRegisterAll();}
1411   entry = __SNESList->head;
1412   PetscPrintf(comm," %s%s (one of)",prefix,name);
1413   while (entry) {
1414     PetscPrintf(comm," %s",entry->name);
1415     entry = entry->next;
1416   }
1417   PetscPrintf(comm,"\n");
1418   return 0;
1419 }
1420 
1421 /*@C
1422    SNESGetSolution - Returns the vector where the approximate solution is
1423    stored.
1424 
1425    Input Parameter:
1426 .  snes - the SNES context
1427 
1428    Output Parameter:
1429 .  x - the solution
1430 
1431 .keywords: SNES, nonlinear, get, solution
1432 
1433 .seealso: SNESGetFunction(), SNESGetGradient(), SNESGetSolutionUpdate()
1434 @*/
1435 int SNESGetSolution(SNES snes,Vec *x)
1436 {
1437   PetscValidHeaderSpecific(snes,SNES_COOKIE);
1438   *x = snes->vec_sol_always;
1439   return 0;
1440 }
1441 
1442 /*@C
1443    SNESGetSolutionUpdate - Returns the vector where the solution update is
1444    stored.
1445 
1446    Input Parameter:
1447 .  snes - the SNES context
1448 
1449    Output Parameter:
1450 .  x - the solution update
1451 
1452    Notes:
1453    This vector is implementation dependent.
1454 
1455 .keywords: SNES, nonlinear, get, solution, update
1456 
1457 .seealso: SNESGetSolution(), SNESGetFunction
1458 @*/
1459 int SNESGetSolutionUpdate(SNES snes,Vec *x)
1460 {
1461   PetscValidHeaderSpecific(snes,SNES_COOKIE);
1462   *x = snes->vec_sol_update_always;
1463   return 0;
1464 }
1465 
1466 /*@C
1467    SNESGetFunction - Returns the vector where the function is stored.
1468 
1469    Input Parameter:
1470 .  snes - the SNES context
1471 
1472    Output Parameter:
1473 .  r - the function
1474 
1475    Notes:
1476    SNESGetFunction() is valid for SNES_NONLINEAR_EQUATIONS methods only
1477    Analogous routines for SNES_UNCONSTRAINED_MINIMIZATION methods are
1478    SNESGetMinimizationFunction() and SNESGetGradient();
1479 
1480 .keywords: SNES, nonlinear, get, function
1481 
1482 .seealso: SNESSetFunction(), SNESGetSolution(), SNESGetMinimizationFunction(),
1483           SNESGetGradient()
1484 @*/
1485 int SNESGetFunction(SNES snes,Vec *r)
1486 {
1487   PetscValidHeaderSpecific(snes,SNES_COOKIE);
1488   if (snes->method_class != SNES_NONLINEAR_EQUATIONS) SETERRQ(1,
1489     "SNESGetFunction:For SNES_NONLINEAR_EQUATIONS only");
1490   *r = snes->vec_func_always;
1491   return 0;
1492 }
1493 
1494 /*@C
1495    SNESGetGradient - Returns the vector where the gradient is stored.
1496 
1497    Input Parameter:
1498 .  snes - the SNES context
1499 
1500    Output Parameter:
1501 .  r - the gradient
1502 
1503    Notes:
1504    SNESGetGradient() is valid for SNES_UNCONSTRAINED_MINIMIZATION methods
1505    only.  An analogous routine for SNES_NONLINEAR_EQUATIONS methods is
1506    SNESGetFunction().
1507 
1508 .keywords: SNES, nonlinear, get, gradient
1509 
1510 .seealso: SNESGetMinimizationFunction(), SNESGetSolution(), SNESGetFunction()
1511 @*/
1512 int SNESGetGradient(SNES snes,Vec *r)
1513 {
1514   PetscValidHeaderSpecific(snes,SNES_COOKIE);
1515   if (snes->method_class != SNES_UNCONSTRAINED_MINIMIZATION) SETERRQ(1,
1516     "SNESGetGradient:For SNES_UNCONSTRAINED_MINIMIZATION only");
1517   *r = snes->vec_func_always;
1518   return 0;
1519 }
1520 
1521 /*@
1522    SNESGetMinimizationFunction - Returns the scalar function value for
1523    unconstrained minimization problems.
1524 
1525    Input Parameter:
1526 .  snes - the SNES context
1527 
1528    Output Parameter:
1529 .  r - the function
1530 
1531    Notes:
1532    SNESGetMinimizationFunction() is valid for SNES_UNCONSTRAINED_MINIMIZATION
1533    methods only.  An analogous routine for SNES_NONLINEAR_EQUATIONS methods is
1534    SNESGetFunction().
1535 
1536 .keywords: SNES, nonlinear, get, function
1537 
1538 .seealso: SNESGetGradient(), SNESGetSolution(), SNESGetFunction()
1539 @*/
1540 int SNESGetMinimizationFunction(SNES snes,double *r)
1541 {
1542   PetscValidHeaderSpecific(snes,SNES_COOKIE);
1543   if (snes->method_class != SNES_UNCONSTRAINED_MINIMIZATION) SETERRQ(1,
1544     "SNESGetMinimizationFunction:For SNES_UNCONSTRAINED_MINIMIZATION only");
1545   *r = snes->fc;
1546   return 0;
1547 }
1548 
1549 /*@C
1550    SNESSetOptionsPrefix - Sets the prefix used for searching for all
1551    SNES options in the database.
1552 
1553    Input Parameter:
1554 .  snes - the SNES context
1555 .  prefix - the prefix to prepend to all option names
1556 
1557 .keywords: SNES, set, options, prefix, database
1558 
1559 .seealso: SNESSetFromOptions()
1560 @*/
1561 int SNESSetOptionsPrefix(SNES snes,char *prefix)
1562 {
1563   int ierr;
1564 
1565   PetscValidHeaderSpecific(snes,SNES_COOKIE);
1566   ierr = PetscObjectSetPrefix((PetscObject)snes, prefix); CHKERRQ(ierr);
1567   ierr = SLESSetOptionsPrefix(snes->sles,prefix);CHKERRQ(ierr);
1568   return 0;
1569 }
1570 
1571 /*@C
1572    SNESAppendOptionsPrefix - Append to the prefix used for searching for all
1573    SNES options in the database.
1574 
1575    Input Parameter:
1576 .  snes - the SNES context
1577 .  prefix - the prefix to prepend to all option names
1578 
1579 .keywords: SNES, append, options, prefix, database
1580 
1581 .seealso: SNESGetOptionsPrefix()
1582 @*/
1583 int SNESAppendOptionsPrefix(SNES snes,char *prefix)
1584 {
1585   int ierr;
1586 
1587   PetscValidHeaderSpecific(snes,SNES_COOKIE);
1588   ierr = PetscObjectAppendPrefix((PetscObject)snes, prefix); CHKERRQ(ierr);
1589   ierr = SLESAppendOptionsPrefix(snes->sles,prefix);CHKERRQ(ierr);
1590   return 0;
1591 }
1592 
1593 /*@
1594    SNESGetOptionsPrefix - Sets the prefix used for searching for all
1595    SNES options in the database.
1596 
1597    Input Parameter:
1598 .  snes - the SNES context
1599 
1600    Output Parameter:
1601 .  prefix - pointer to the prefix string used
1602 
1603 .keywords: SNES, get, options, prefix, database
1604 
1605 .seealso: SNESAppendOptionsPrefix()
1606 @*/
1607 int SNESGetOptionsPrefix(SNES snes,char **prefix)
1608 {
1609   int ierr;
1610 
1611   PetscValidHeaderSpecific(snes,SNES_COOKIE);
1612   ierr = PetscObjectGetPrefix((PetscObject)snes, prefix); CHKERRQ(ierr);
1613   return 0;
1614 }
1615 
1616 
1617 
1618 
1619 
1620