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