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