xref: /petsc/src/snes/interface/snes.c (revision 227d817a37c50a73d88aa8c031007e5b1fb2e4ec)
1 #ifndef lint
2 static char vcid[] = "$Id: snes.c,v 1.44 1996/01/24 04:16:11 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(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   if (type != SNES_UNCONSTRAINED_MINIMIZATION && type != SNES_NONLINEAR_EQUATIONS)
430     SETERRQ(1,"SNESCreate:incorrect method type");
431   PetscHeaderCreate(snes,_SNES,SNES_COOKIE,SNES_UNKNOWN_METHOD,comm);
432   PLogObjectCreate(snes);
433   snes->max_its           = 50;
434   snes->max_funcs	  = 1000;
435   snes->norm		  = 0.0;
436   if (type == SNES_UNCONSTRAINED_MINIMIZATION) {
437     snes->rtol		  = 1.e-08;
438     snes->atol		  = 1.e-10;
439   }
440   else {
441     snes->rtol		  = 1.e-8;
442     snes->ttol            = 0.0;
443     snes->atol		  = 1.e-50;
444   }
445   snes->xtol		  = 1.e-8;
446   snes->trunctol	  = 1.e-12;
447   snes->nfuncs            = 0;
448   snes->nfailures         = 0;
449   snes->monitor           = 0;
450   snes->data              = 0;
451   snes->view              = 0;
452   snes->computeumfunction = 0;
453   snes->umfunP            = 0;
454   snes->fc                = 0;
455   snes->deltatol          = 1.e-12;
456   snes->fmin              = -1.e30;
457   snes->method_class      = type;
458   snes->set_method_called = 0;
459   snes->setup_called      = 0;
460   snes->ksp_ewconv        = 0;
461 
462   /* Create context to compute Eisenstat-Walker relative tolerance for KSP */
463   kctx = PetscNew(SNES_KSP_EW_ConvCtx); CHKPTRQ(kctx);
464   snes->kspconvctx  = (void*)kctx;
465   kctx->version     = 2;
466   kctx->rtol_0      = .3; /* Eisenstat and Walker suggest rtol_0=.5, but
467                              this was too large for some test cases */
468   kctx->rtol_last   = 0;
469   kctx->rtol_max    = .9;
470   kctx->gamma       = 1.0;
471   kctx->alpha2      = .5*(1.0 + sqrt(5.0));
472   kctx->alpha       = kctx->alpha2;
473   kctx->threshold   = .1;
474   kctx->lresid_last = 0;
475   kctx->norm_last   = 0;
476 
477   ierr = SLESCreate(comm,&snes->sles); CHKERRQ(ierr);
478   PLogObjectParent(snes,snes->sles)
479 
480   *outsnes = snes;
481   return 0;
482 }
483 
484 /* --------------------------------------------------------------- */
485 /*@C
486    SNESSetFunction - Sets the function evaluation routine and function
487    vector for use by the SNES routines in solving systems of nonlinear
488    equations.
489 
490    Input Parameters:
491 .  snes - the SNES context
492 .  func - function evaluation routine
493 .  ctx - optional user-defined function context
494 .  r - vector to store function value
495 
496    Calling sequence of func:
497 .  func (SNES, Vec x, Vec f, void *ctx);
498 
499 .  x - input vector
500 .  f - vector function
501 .  ctx - optional user-defined context for private data for the
502          function evaluation routine (may be null)
503 
504    Notes:
505    The Newton-like methods typically solve linear systems of the form
506 $      f'(x) x = -f(x),
507 $  where f'(x) denotes the Jacobian matrix and f(x) is the function.
508 
509    SNESSetFunction() is valid for SNES_NONLINEAR_EQUATIONS methods only.
510    Analogous routines for SNES_UNCONSTRAINED_MINIMIZATION methods are
511    SNESSetMinimizationFunction() and SNESSetGradient();
512 
513 .keywords: SNES, nonlinear, set, function
514 
515 .seealso: SNESGetFunction(), SNESSetJacobian(), SNESSetSolution()
516 @*/
517 int SNESSetFunction( SNES snes, Vec r, int (*func)(SNES,Vec,Vec,void*),void *ctx)
518 {
519   PETSCVALIDHEADERSPECIFIC(snes,SNES_COOKIE);
520   if (snes->method_class != SNES_NONLINEAR_EQUATIONS) SETERRQ(1,
521     "SNESSetFunction:For SNES_NONLINEAR_EQUATIONS only");
522   snes->computefunction     = func;
523   snes->vec_func            = snes->vec_func_always = r;
524   snes->funP                = ctx;
525   return 0;
526 }
527 
528 /*@
529    SNESComputeFunction - Computes the function that has been set with
530    SNESSetFunction().
531 
532    Input Parameters:
533 .  snes - the SNES context
534 .  x - input vector
535 
536    Output Parameter:
537 .  y - function vector or its negative, as set by SNESSetFunction()
538 
539    Notes:
540    SNESComputeFunction() is valid for SNES_NONLINEAR_EQUATIONS methods only.
541    Analogous routines for SNES_UNCONSTRAINED_MINIMIZATION methods are
542    SNESComputeMinimizationFunction() and SNESComputeGradient();
543 
544 .keywords: SNES, nonlinear, compute, function
545 
546 .seealso: SNESSetFunction()
547 @*/
548 int SNESComputeFunction(SNES snes,Vec x, Vec y)
549 {
550   int    ierr;
551 
552   PLogEventBegin(SNES_FunctionEval,snes,x,y,0);
553   ierr = (*snes->computefunction)(snes,x,y,snes->funP); CHKERRQ(ierr);
554   PLogEventEnd(SNES_FunctionEval,snes,x,y,0);
555   return 0;
556 }
557 
558 /*@C
559    SNESSetMinimizationFunction - Sets the function evaluation routine for
560    unconstrained minimization.
561 
562    Input Parameters:
563 .  snes - the SNES context
564 .  func - function evaluation routine
565 .  ctx - optional user-defined function context
566 
567    Calling sequence of func:
568 .  func (SNES snes,Vec x,double *f,void *ctx);
569 
570 .  x - input vector
571 .  f - function
572 .  ctx - optional user-defined context for private data for the
573          function evaluation routine (may be null)
574 
575    Notes:
576    SNESSetMinimizationFunction() is valid for SNES_UNCONSTRAINED_MINIMIZATION
577    methods only. An analogous routine for SNES_NONLINEAR_EQUATIONS methods is
578    SNESSetFunction().
579 
580 .keywords: SNES, nonlinear, set, minimization, function
581 
582 .seealso:  SNESGetMinimizationFunction(), SNESSetHessian(), SNESSetGradient(),
583            SNESSetSolution()
584 @*/
585 int SNESSetMinimizationFunction(SNES snes,int (*func)(SNES,Vec,double*,void*),
586                       void *ctx)
587 {
588   PETSCVALIDHEADERSPECIFIC(snes,SNES_COOKIE);
589   if (snes->method_class != SNES_UNCONSTRAINED_MINIMIZATION) SETERRQ(1,
590     "SNESSetMinimizationFunction:Only for SNES_UNCONSTRAINED_MINIMIZATION");
591   snes->computeumfunction   = func;
592   snes->umfunP              = ctx;
593   return 0;
594 }
595 
596 /*@
597    SNESComputeMinimizationFunction - Computes the function that has been
598    set with SNESSetMinimizationFunction().
599 
600    Input Parameters:
601 .  snes - the SNES context
602 .  x - input vector
603 
604    Output Parameter:
605 .  y - function value
606 
607    Notes:
608    SNESComputeMinimizationFunction() is valid only for
609    SNES_UNCONSTRAINED_MINIMIZATION methods. An analogous routine for
610    SNES_NONLINEAR_EQUATIONS methods is SNESComputeFunction().
611 @*/
612 int SNESComputeMinimizationFunction(SNES snes,Vec x,double *y)
613 {
614   int    ierr;
615   if (snes->method_class != SNES_UNCONSTRAINED_MINIMIZATION) SETERRQ(1,
616     "SNESComputeMinimizationFunction:Only for SNES_UNCONSTRAINED_MINIMIZATION");
617   PLogEventBegin(SNES_MinimizationFunctionEval,snes,x,y,0);
618   ierr = (*snes->computeumfunction)(snes,x,y,snes->umfunP); CHKERRQ(ierr);
619   PLogEventEnd(SNES_MinimizationFunctionEval,snes,x,y,0);
620   return 0;
621 }
622 
623 /*@C
624    SNESSetGradient - Sets the gradient evaluation routine and gradient
625    vector for use by the SNES routines.
626 
627    Input Parameters:
628 .  snes - the SNES context
629 .  func - function evaluation routine
630 .  ctx - optional user-defined function context
631 .  r - vector to store gradient value
632 
633    Calling sequence of func:
634 .  func (SNES, Vec x, Vec g, void *ctx);
635 
636 .  x - input vector
637 .  g - gradient vector
638 .  ctx - optional user-defined context for private data for the
639          function evaluation routine (may be null)
640 
641    Notes:
642    SNESSetMinimizationFunction() is valid for SNES_UNCONSTRAINED_MINIMIZATION
643    methods only. An analogous routine for SNES_NONLINEAR_EQUATIONS methods is
644    SNESSetFunction().
645 
646 .keywords: SNES, nonlinear, set, function
647 
648 .seealso: SNESGetGradient(), SNESSetHessian(), SNESSetMinimizationFunction(),
649           SNESSetSolution()
650 @*/
651 int SNESSetGradient(SNES snes,Vec r,int (*func)(SNES,Vec,Vec,void*),
652                      void *ctx)
653 {
654   PETSCVALIDHEADERSPECIFIC(snes,SNES_COOKIE);
655   if (snes->method_class != SNES_UNCONSTRAINED_MINIMIZATION) SETERRQ(1,
656     "SNESSetGradient:For SNES_UNCONSTRAINED_MINIMIZATION only");
657   snes->computefunction     = func;
658   snes->vec_func            = snes->vec_func_always = r;
659   snes->funP                = ctx;
660   return 0;
661 }
662 
663 /*@
664    SNESComputeGradient - Computes the gradient that has been
665    set with SNESSetGradient().
666 
667    Input Parameters:
668 .  snes - the SNES context
669 .  x - input vector
670 
671    Output Parameter:
672 .  y - gradient vector
673 
674    Notes:
675    SNESComputeGradient() is valid only for
676    SNES_UNCONSTRAINED_MINIMIZATION methods. An analogous routine for
677    SNES_NONLINEAR_EQUATIONS methods is SNESComputeFunction().
678 @*/
679 int SNESComputeGradient(SNES snes,Vec x, Vec y)
680 {
681   int    ierr;
682   if (snes->method_class != SNES_UNCONSTRAINED_MINIMIZATION) SETERRQ(1,
683     "SNESComputeGradient:For SNES_UNCONSTRAINED_MINIMIZATION only");
684   PLogEventBegin(SNES_GradientEval,snes,x,y,0);
685   ierr = (*snes->computefunction)(snes,x,y,snes->funP); CHKERRQ(ierr);
686   PLogEventEnd(SNES_GradientEval,snes,x,y,0);
687   return 0;
688 }
689 
690 int SNESComputeJacobian(SNES snes,Vec X,Mat *A,Mat *B,MatStructure *flg)
691 {
692   int    ierr;
693   if (snes->method_class != SNES_NONLINEAR_EQUATIONS) SETERRQ(1,
694     "SNESComputeJacobian: For SNES_NONLINEAR_EQUATIONS only");
695   if (!snes->computejacobian) return 0;
696   PLogEventBegin(SNES_JacobianEval,snes,X,*A,*B);
697   *flg = ALLMAT_DIFFERENT_NONZERO_PATTERN;
698   ierr = (*snes->computejacobian)(snes,X,A,B,flg,snes->jacP); CHKERRQ(ierr);
699   PLogEventEnd(SNES_JacobianEval,snes,X,*A,*B);
700   return 0;
701 }
702 
703 int SNESComputeHessian(SNES snes,Vec X,Mat *A,Mat *B,MatStructure *flg)
704 {
705   int    ierr;
706   if (snes->method_class != SNES_UNCONSTRAINED_MINIMIZATION) SETERRQ(1,
707     "SNESComputeHessian:For SNES_UNCONSTRAINED_MINIMIZATION only");
708   if (!snes->computejacobian) return 0;
709   PLogEventBegin(SNES_HessianEval,snes,X,*A,*B);
710   ierr = (*snes->computejacobian)(snes,X,A,B,flg,snes->jacP); CHKERRQ(ierr);
711   PLogEventEnd(SNES_HessianEval,snes,X,*A,*B);
712   return 0;
713 }
714 
715 /*@C
716    SNESSetJacobian - Sets the function to compute Jacobian as well as the
717    location to store it.
718 
719    Input Parameters:
720 .  snes - the SNES context
721 .  A - Jacobian matrix
722 .  B - preconditioner matrix (usually same as the Jacobian)
723 .  func - Jacobian evaluation routine
724 .  ctx - optional user-defined context for private data for the
725          Jacobian evaluation routine (may be null)
726 
727    Calling sequence of func:
728 .  func (SNES,Vec x,Mat *A,Mat *B,int *flag,void *ctx);
729 
730 .  x - input vector
731 .  A - Jacobian matrix
732 .  B - preconditioner matrix, usually the same as A
733 .  flag - flag indicating information about matrix structure,
734    same as flag in SLESSetOperators()
735 .  ctx - optional user-defined Jacobian context
736 
737    Notes:
738    The function func() takes Mat * as the matrix arguments rather than Mat.
739    This allows the Jacobian evaluation routine to replace A and/or B with a
740    completely new new matrix structure (not just different matrix elements)
741    when appropriate, for instance, if the nonzero structure is changing
742    throughout the global iterations.
743 
744 .keywords: SNES, nonlinear, set, Jacobian, matrix
745 
746 .seealso: SNESSetFunction(), SNESSetSolution()
747 @*/
748 int SNESSetJacobian(SNES snes,Mat A,Mat B,int (*func)(SNES,Vec,Mat*,Mat*,
749                     MatStructure*,void*),void *ctx)
750 {
751   PETSCVALIDHEADERSPECIFIC(snes,SNES_COOKIE);
752   if (snes->method_class != SNES_NONLINEAR_EQUATIONS) SETERRQ(1,
753     "SNESSetJacobian:For SNES_NONLINEAR_EQUATIONS only");
754   snes->computejacobian = func;
755   snes->jacP            = ctx;
756   snes->jacobian        = A;
757   snes->jacobian_pre    = B;
758   return 0;
759 }
760 /*@
761      SNESGetJacobian - Returns the Jacobian matrix and optionally the user
762           provided context for evaluating the Jacobian.
763 
764   Input Parameter:
765 .  snes - the nonlinear solver context
766 
767   Output Parameters:
768 .  A - location to stash Jacobian matrix (or PETSC_NULL)
769 .  B - location to stash preconditioner matrix (or PETSC_NULL)
770 .  ctx - location to stash Jacobian ctx (or PETSC_NULL)
771 
772 .seealso: SNESSetJacobian(), SNESComputeJacobian()
773 @*/
774 int SNESGetJacobian(SNES snes,Mat *A,Mat *B, void **ctx)
775 {
776   if (A)   *A = snes->jacobian;
777   if (B)   *B = snes->jacobian_pre;
778   if (ctx) *ctx = snes->jacP;
779   return 0;
780 }
781 
782 /*@C
783    SNESSetHessian - Sets the function to compute Hessian as well as the
784    location to store it.
785 
786    Input Parameters:
787 .  snes - the SNES context
788 .  A - Hessian matrix
789 .  B - preconditioner matrix (usually same as the Hessian)
790 .  func - Jacobian evaluation routine
791 .  ctx - optional user-defined context for private data for the
792          Hessian evaluation routine (may be null)
793 
794    Calling sequence of func:
795 .  func (SNES,Vec x,Mat *A,Mat *B,int *flag,void *ctx);
796 
797 .  x - input vector
798 .  A - Hessian matrix
799 .  B - preconditioner matrix, usually the same as A
800 .  flag - flag indicating information about matrix structure,
801    same as flag in SLESSetOperators()
802 .  ctx - optional user-defined Hessian context
803 
804    Notes:
805    The function func() takes Mat * as the matrix arguments rather than Mat.
806    This allows the Hessian evaluation routine to replace A and/or B with a
807    completely new new matrix structure (not just different matrix elements)
808    when appropriate, for instance, if the nonzero structure is changing
809    throughout the global iterations.
810 
811 .keywords: SNES, nonlinear, set, Hessian, matrix
812 
813 .seealso: SNESSetMinimizationFunction(), SNESSetSolution(), SNESSetGradient()
814 @*/
815 int SNESSetHessian(SNES snes,Mat A,Mat B,int (*func)(SNES,Vec,Mat*,Mat*,
816                     MatStructure*,void*),void *ctx)
817 {
818   PETSCVALIDHEADERSPECIFIC(snes,SNES_COOKIE);
819   if (snes->method_class != SNES_UNCONSTRAINED_MINIMIZATION) SETERRQ(1,
820     "SNESSetHessian:For SNES_UNCONSTRAINED_MINIMIZATION only");
821   snes->computejacobian = func;
822   snes->jacP            = ctx;
823   snes->jacobian        = A;
824   snes->jacobian_pre    = B;
825   return 0;
826 }
827 
828 /* ----- Routines to initialize and destroy a nonlinear solver ---- */
829 
830 /*@
831    SNESSetUp - Sets up the internal data structures for the later use
832    of a nonlinear solver.  Call SNESSetUp() after calling SNESCreate()
833    and optional routines of the form SNESSetXXX(), but before calling
834    SNESSolve().
835 
836    Input Parameter:
837 .  snes - the SNES context
838 
839 .keywords: SNES, nonlinear, setup
840 
841 .seealso: SNESCreate(), SNESSolve(), SNESDestroy()
842 @*/
843 int SNESSetUp(SNES snes)
844 {
845   int ierr;
846   PETSCVALIDHEADERSPECIFIC(snes,SNES_COOKIE);
847   if (!snes->vec_sol) SETERRQ(1,"SNESSetUp:Must call SNESSetSolution() first");
848 
849   if ((snes->method_class == SNES_NONLINEAR_EQUATIONS)) {
850     if (!snes->vec_func) SETERRQ(1,"SNESSetUp:Must call SNESSetFunction() first");
851     if (!snes->computefunction) SETERRQ(1,"SNESSetUp:Must call SNESSetFunction() first");
852     if (!snes->jacobian) SETERRQ(1,"SNESSetUp:Must call SNESSetJacobian() first");
853 
854     /* Set the KSP stopping criterion to use the Eisenstat-Walker method */
855     if (snes->ksp_ewconv && snes->type != SNES_EQ_NTR) {
856       SLES sles; KSP ksp;
857       ierr = SNESGetSLES(snes,&sles); CHKERRQ(ierr);
858       ierr = SLESGetKSP(sles,&ksp); CHKERRQ(ierr);
859       ierr = KSPSetConvergenceTest(ksp,SNES_KSP_EW_Converged_Private,
860              (void *)snes); CHKERRQ(ierr);
861     }
862   } else if ((snes->method_class == SNES_UNCONSTRAINED_MINIMIZATION)) {
863     if (!snes->vec_func) SETERRQ(1,"SNESSetUp:Must call SNESSetGradient() first");
864     if (!snes->computefunction) SETERRQ(1,"SNESSetUp:Must call SNESSetGradient() first");
865     if (!snes->computeumfunction)
866       SETERRQ(1,"SNESSetUp:Must call SNESSetMinimizationFunction() first");
867     if (!snes->jacobian) SETERRQ(1,"SNESSetUp:Must call SNESSetHessian() first");
868   } else SETERRQ(1,"SNESSetUp:Unknown method class");
869   if (snes->setup) {ierr = (*snes->setup)(snes); CHKERRQ(ierr);}
870   snes->setup_called = 1;
871   return 0;
872 }
873 
874 /*@C
875    SNESDestroy - Destroys the nonlinear solver context that was created
876    with SNESCreate().
877 
878    Input Parameter:
879 .  snes - the SNES context
880 
881 .keywords: SNES, nonlinear, destroy
882 
883 .seealso: SNESCreate(), SNESSetUp(), SNESSolve()
884 @*/
885 int SNESDestroy(SNES snes)
886 {
887   int ierr;
888   PETSCVALIDHEADERSPECIFIC(snes,SNES_COOKIE);
889   ierr = (*(snes)->destroy)((PetscObject)snes); CHKERRQ(ierr);
890   if (snes->kspconvctx) PetscFree(snes->kspconvctx);
891   if (snes->mfshell) MatDestroy(snes->mfshell);
892   ierr = SLESDestroy(snes->sles); CHKERRQ(ierr);
893   PLogObjectDestroy((PetscObject)snes);
894   PetscHeaderDestroy((PetscObject)snes);
895   return 0;
896 }
897 
898 /* ----------- Routines to set solver parameters ---------- */
899 
900 /*@
901    SNESSetMaxIterations - Sets the maximum number of global iterations to use.
902 
903    Input Parameters:
904 .  snes - the SNES context
905 .  maxits - maximum number of iterations to use
906 
907    Options Database Key:
908 $  -snes_max_it  maxits
909 
910    Note:
911    The default maximum number of iterations is 50.
912 
913 .keywords: SNES, nonlinear, set, maximum, iterations
914 
915 .seealso: SNESSetMaxFunctionEvaluations()
916 @*/
917 int SNESSetMaxIterations(SNES snes,int maxits)
918 {
919   PETSCVALIDHEADERSPECIFIC(snes,SNES_COOKIE);
920   snes->max_its = maxits;
921   return 0;
922 }
923 
924 /*@
925    SNESSetMaxFunctionEvaluations - Sets the maximum number of function
926    evaluations to use.
927 
928    Input Parameters:
929 .  snes - the SNES context
930 .  maxf - maximum number of function evaluations
931 
932    Options Database Key:
933 $  -snes_max_funcs maxf
934 
935    Note:
936    The default maximum number of function evaluations is 1000.
937 
938 .keywords: SNES, nonlinear, set, maximum, function, evaluations
939 
940 .seealso: SNESSetMaxIterations()
941 @*/
942 int SNESSetMaxFunctionEvaluations(SNES snes,int maxf)
943 {
944   PETSCVALIDHEADERSPECIFIC(snes,SNES_COOKIE);
945   snes->max_funcs = maxf;
946   return 0;
947 }
948 
949 /*@
950    SNESSetRelativeTolerance - Sets the relative convergence tolerance.
951 
952    Input Parameters:
953 .  snes - the SNES context
954 .  rtol - tolerance
955 
956    Options Database Key:
957 $    -snes_rtol tol
958 
959 .keywords: SNES, nonlinear, set, relative, convergence, tolerance
960 
961 .seealso: SNESSetAbsoluteTolerance(), SNESSetSolutionTolerance(),
962            SNESSetTruncationTolerance()
963 @*/
964 int SNESSetRelativeTolerance(SNES snes,double rtol)
965 {
966   PETSCVALIDHEADERSPECIFIC(snes,SNES_COOKIE);
967   snes->rtol = rtol;
968   return 0;
969 }
970 
971 /*@
972    SNESSetTrustRegionTolerance - Sets the trust region parameter tolerance.
973 
974    Input Parameters:
975 .  snes - the SNES context
976 .  tol - tolerance
977 
978    Options Database Key:
979 $    -snes_trtol tol
980 
981 .keywords: SNES, nonlinear, set, trust region, tolerance
982 
983 .seealso: SNESSetAbsoluteTolerance(), SNESSetSolutionTolerance(),
984            SNESSetTruncationTolerance()
985 @*/
986 int SNESSetTrustRegionTolerance(SNES snes,double tol)
987 {
988   PETSCVALIDHEADERSPECIFIC(snes,SNES_COOKIE);
989   snes->deltatol = tol;
990   return 0;
991 }
992 
993 /*@
994    SNESSetAbsoluteTolerance - Sets the absolute convergence tolerance.
995 
996    Input Parameters:
997 .  snes - the SNES context
998 .  atol - tolerance
999 
1000    Options Database Key:
1001 $    -snes_atol tol
1002 
1003 .keywords: SNES, nonlinear, set, absolute, convergence, tolerance
1004 
1005 .seealso: SNESSetRelativeTolerance(), SNESSetSolutionTolerance(),
1006            SNESSetTruncationTolerance()
1007 @*/
1008 int SNESSetAbsoluteTolerance(SNES snes,double atol)
1009 {
1010   PETSCVALIDHEADERSPECIFIC(snes,SNES_COOKIE);
1011   snes->atol = atol;
1012   return 0;
1013 }
1014 
1015 /*@
1016    SNESSetTruncationTolerance - Sets the tolerance that may be used by the
1017    step routines to control the accuracy of the step computation.
1018 
1019    Input Parameters:
1020 .  snes - the SNES context
1021 .  tol - tolerance
1022 
1023    Options Database Key:
1024 $    -snes_ttol tol
1025 
1026    Notes:
1027    If the step computation involves an application of the inverse
1028    Jacobian (or Hessian), this parameter may be used to control the
1029    accuracy of that application.
1030 
1031 .keywords: SNES, nonlinear, set, truncation, tolerance
1032 
1033 .seealso: SNESSetRelativeTolerance(), SNESSetSolutionTolerance(),
1034           SNESSetAbsoluteTolerance()
1035 @*/
1036 int SNESSetTruncationTolerance(SNES snes,double tol)
1037 {
1038   PETSCVALIDHEADERSPECIFIC(snes,SNES_COOKIE);
1039   snes->trunctol = tol;
1040   return 0;
1041 }
1042 
1043 /*@
1044    SNESSetSolutionTolerance - Sets the convergence tolerance in terms of
1045    the norm of the change in the solution between steps.
1046 
1047    Input Parameters:
1048 .  snes - the SNES context
1049 .  tol - tolerance
1050 
1051    Options Database Key:
1052 $    -snes_stol tol
1053 
1054 .keywords: SNES, nonlinear, set, solution, tolerance
1055 
1056 .seealso: SNESSetTruncationTolerance(), SNESSetRelativeTolerance(),
1057           SNESSetAbsoluteTolerance()
1058 @*/
1059 int SNESSetSolutionTolerance( SNES snes, double tol )
1060 {
1061   PETSCVALIDHEADERSPECIFIC(snes,SNES_COOKIE);
1062   snes->xtol = tol;
1063   return 0;
1064 }
1065 
1066 /*@
1067    SNESSetMinFunctionTolerance - Sets the minimum allowable function tolerance
1068    for unconstrained minimization solvers.
1069 
1070    Input Parameters:
1071 .  snes - the SNES context
1072 .  ftol - minimum function tolerance
1073 
1074    Options Database Key:
1075 $    -snes_fmin ftol
1076 
1077    Note:
1078    SNESSetMinFunctionTolerance() is valid for SNES_UNCONSTRAINED_MINIMIZATION
1079    methods only.
1080 
1081 .keywords: SNES, nonlinear, set, minimum, convergence, function, tolerance
1082 
1083 .seealso: SNESSetRelativeTolerance(), SNESSetSolutionTolerance(),
1084            SNESSetTruncationTolerance()
1085 @*/
1086 int SNESSetMinFunctionTolerance(SNES snes,double ftol)
1087 {
1088   PETSCVALIDHEADERSPECIFIC(snes,SNES_COOKIE);
1089   snes->fmin = ftol;
1090   return 0;
1091 }
1092 
1093 
1094 
1095 /* ---------- Routines to set various aspects of nonlinear solver --------- */
1096 
1097 /*@C
1098    SNESSetSolution - Sets the solution vector for use by the SNES routines.
1099 
1100    Input Parameters:
1101 .  snes - the SNES context
1102 .  x - the solution vector
1103 
1104 
1105 .keywords: SNES, nonlinear, set, solution, initial guess
1106 
1107 .seealso: SNESGetSolution(), SNESSetJacobian(), SNESSetFunction()
1108 @*/
1109 int SNESSetSolution(SNES snes,Vec x)
1110 {
1111   PETSCVALIDHEADERSPECIFIC(snes,SNES_COOKIE);
1112   snes->vec_sol             = snes->vec_sol_always = x;
1113   return 0;
1114 }
1115 
1116 /* ------------ Routines to set performance monitoring options ----------- */
1117 
1118 /*@C
1119    SNESSetMonitor - Sets the function that is to be used at every
1120    iteration of the nonlinear solver to display the iteration's
1121    progress.
1122 
1123    Input Parameters:
1124 .  snes - the SNES context
1125 .  func - monitoring routine
1126 .  mctx - optional user-defined context for private data for the
1127           monitor routine (may be null)
1128 
1129    Calling sequence of func:
1130    int func(SNES snes,int its, Vec x,Vec f,double norm,void *mctx)
1131 
1132 $    snes - the SNES context
1133 $    its - iteration number
1134 $    mctx - optional monitoring context
1135 $
1136 $ SNES_NONLINEAR_EQUATIONS methods:
1137 $    norm - 2-norm function value (may be estimated)
1138 $
1139 $ SNES_UNCONSTRAINED_MINIMIZATION methods:
1140 $    norm - 2-norm gradient value (may be estimated)
1141 
1142 .keywords: SNES, nonlinear, set, monitor
1143 
1144 .seealso: SNESDefaultMonitor()
1145 @*/
1146 int SNESSetMonitor( SNES snes, int (*func)(SNES,int,double,void*),
1147                     void *mctx )
1148 {
1149   snes->monitor = func;
1150   snes->monP    = (void*)mctx;
1151   return 0;
1152 }
1153 
1154 /*@C
1155    SNESSetConvergenceTest - Sets the function that is to be used
1156    to test for convergence of the nonlinear iterative solution.
1157 
1158    Input Parameters:
1159 .  snes - the SNES context
1160 .  func - routine to test for convergence
1161 .  cctx - optional context for private data for the convergence routine
1162           (may be null)
1163 
1164    Calling sequence of func:
1165    int func (SNES snes,double xnorm,double gnorm,
1166              double f,void *cctx)
1167 
1168 $    snes - the SNES context
1169 $    cctx - optional convergence context
1170 $    xnorm - 2-norm of current iterate
1171 $
1172 $ SNES_NONLINEAR_EQUATIONS methods:
1173 $    gnorm - 2-norm of current step
1174 $    f - 2-norm of function
1175 $
1176 $ SNES_UNCONSTRAINED_MINIMIZATION methods:
1177 $    gnorm - 2-norm of current gradient
1178 $    f - function value
1179 
1180 .keywords: SNES, nonlinear, set, convergence, test
1181 
1182 .seealso: SNESDefaultConverged()
1183 @*/
1184 int SNESSetConvergenceTest(SNES snes,
1185           int (*func)(SNES,double,double,double,void*),void *cctx)
1186 {
1187   (snes)->converged = func;
1188   (snes)->cnvP      = cctx;
1189   return 0;
1190 }
1191 
1192 /*
1193    SNESScaleStep_Private - Scales a step so that its length is less than the
1194    positive parameter delta.
1195 
1196     Input Parameters:
1197 .   snes - the SNES context
1198 .   y - approximate solution of linear system
1199 .   fnorm - 2-norm of current function
1200 .   delta - trust region size
1201 
1202     Output Parameters:
1203 .   gpnorm - predicted function norm at the new point, assuming local
1204     linearization.  The value is zero if the step lies within the trust
1205     region, and exceeds zero otherwise.
1206 .   ynorm - 2-norm of the step
1207 
1208     Note:
1209     For non-trust region methods such as SNES_EQ_NLS, the parameter delta
1210     is set to be the maximum allowable step size.
1211 
1212 .keywords: SNES, nonlinear, scale, step
1213 */
1214 int SNESScaleStep_Private(SNES snes,Vec y,double *fnorm,double *delta,
1215                   double *gpnorm,double *ynorm)
1216 {
1217   double norm;
1218   Scalar cnorm;
1219   VecNorm(y,NORM_2, &norm );
1220   if (norm > *delta) {
1221      norm = *delta/norm;
1222      *gpnorm = (1.0 - norm)*(*fnorm);
1223      cnorm = norm;
1224      VecScale( &cnorm, y );
1225      *ynorm = *delta;
1226   } else {
1227      *gpnorm = 0.0;
1228      *ynorm = norm;
1229   }
1230   return 0;
1231 }
1232 
1233 /*@
1234    SNESSolve - Solves a nonlinear system.  Call SNESSolve after calling
1235    SNESCreate(), optional routines of the form SNESSetXXX(), and SNESSetUp().
1236 
1237    Input Parameter:
1238 .  snes - the SNES context
1239 
1240    Output Parameter:
1241    its - number of iterations until termination
1242 
1243 .keywords: SNES, nonlinear, solve
1244 
1245 .seealso: SNESCreate(), SNESSetUp(), SNESDestroy()
1246 @*/
1247 int SNESSolve(SNES snes,int *its)
1248 {
1249   int ierr, flg;
1250 
1251   if (!snes->setup_called) {ierr = SNESSetUp(snes); CHKERRQ(ierr);}
1252   PETSCVALIDHEADERSPECIFIC(snes,SNES_COOKIE);
1253   PLogEventBegin(SNES_Solve,snes,0,0,0);
1254   ierr = (*(snes)->solve)(snes,its); CHKERRQ(ierr);
1255   PLogEventEnd(SNES_Solve,snes,0,0,0);
1256   ierr = OptionsHasName(PETSC_NULL,"-snes_view", &flg); CHKERRQ(ierr);
1257   if (flg) { ierr = SNESView(snes,STDOUT_VIEWER_WORLD); CHKERRQ(ierr); }
1258   return 0;
1259 }
1260 
1261 /* --------- Internal routines for SNES Package --------- */
1262 static NRList *__SNESList = 0;
1263 
1264 /*@
1265    SNESSetType - Sets the method for the nonlinear solver.
1266 
1267    Input Parameters:
1268 .  snes - the SNES context
1269 .  method - a known method
1270 
1271    Notes:
1272    See "petsc/include/snes.h" for available methods (for instance)
1273 $  Systems of nonlinear equations:
1274 $    SNES_EQ_NLS - Newton's method with line search
1275 $    SNES_EQ_NTR - Newton's method with trust region
1276 $  Unconstrained minimization:
1277 $    SNES_UM_NTR - Newton's method with trust region
1278 $    SNES_UM_NLS - Newton's method with line search
1279 
1280   Options Database Command:
1281 $ -snes_type  <method>
1282 $    Use -help for a list of available methods
1283 $    (for instance, ls or tr)
1284 
1285 .keysords: SNES, set, method
1286 @*/
1287 int SNESSetType(SNES snes,SNESType method)
1288 {
1289   int (*r)(SNES);
1290   PETSCVALIDHEADERSPECIFIC(snes,SNES_COOKIE);
1291   /* Get the function pointers for the iterative method requested */
1292   if (!__SNESList) {SNESRegisterAll();}
1293   if (!__SNESList) {SETERRQ(1,"SNESSetType:Could not get methods");}
1294   r =  (int (*)(SNES))NRFindRoutine( __SNESList, (int)method, (char *)0 );
1295   if (!r) {SETERRQ(1,"SNESSetType:Unknown method");}
1296   if (snes->data) PetscFree(snes->data);
1297   snes->set_method_called = 1;
1298   return (*r)(snes);
1299 }
1300 
1301 /* --------------------------------------------------------------------- */
1302 /*@C
1303    SNESRegister - Adds the method to the nonlinear solver package, given
1304    a function pointer and a nonlinear solver name of the type SNESType.
1305 
1306    Input Parameters:
1307 .  name - for instance SNES_EQ_NLS, SNES_EQ_NTR, ...
1308 .  sname - corfunPonding string for name
1309 .  create - routine to create method context
1310 
1311 .keywords: SNES, nonlinear, register
1312 
1313 .seealso: SNESRegisterAll(), SNESRegisterDestroy()
1314 @*/
1315 int SNESRegister(int name, char *sname, int (*create)(SNES))
1316 {
1317   int ierr;
1318   if (!__SNESList) {ierr = NRCreate(&__SNESList); CHKERRQ(ierr);}
1319   NRRegister( __SNESList, name, sname, (int (*)(void*))create );
1320   return 0;
1321 }
1322 /* --------------------------------------------------------------------- */
1323 /*@C
1324    SNESRegisterDestroy - Frees the list of nonlinear solvers that were
1325    registered by SNESRegister().
1326 
1327 .keywords: SNES, nonlinear, register, destroy
1328 
1329 .seealso: SNESRegisterAll(), SNESRegisterAll()
1330 @*/
1331 int SNESRegisterDestroy()
1332 {
1333   if (__SNESList) {
1334     NRDestroy( __SNESList );
1335     __SNESList = 0;
1336   }
1337   return 0;
1338 }
1339 
1340 /*
1341    SNESGetTypeFromOptions_Private - Sets the selected method from the
1342    options database.
1343 
1344    Input Parameter:
1345 .  ctx - the SNES context
1346 
1347    Output Parameter:
1348 .  method -  solver method
1349 
1350    Returns:
1351    Returns 1 if the method is found; 0 otherwise.
1352 
1353    Options Database Key:
1354 $  -snes_type  method
1355 */
1356 int SNESGetTypeFromOptions_Private(SNES ctx,SNESType *method,int *flg)
1357 {
1358   int ierr;
1359   char sbuf[50];
1360   ierr = OptionsGetString(ctx->prefix,"-snes_type", sbuf, 50, flg); CHKERRQ(ierr);
1361   if (*flg) {
1362     if (!__SNESList) {ierr = SNESRegisterAll(); CHKERRQ(ierr);}
1363     *method = (SNESType)NRFindID( __SNESList, sbuf );
1364   }
1365   return 0;
1366 }
1367 
1368 /*@C
1369    SNESGetType - Gets the SNES method type and name (as a string).
1370 
1371    Input Parameter:
1372 .  snes - nonlinear solver context
1373 
1374    Output Parameter:
1375 .  method - SNES method (or use PETSC_NULL)
1376 .  name - name of SNES method (or use PETSC_NULL)
1377 
1378 .keywords: SNES, nonlinear, get, method, name
1379 @*/
1380 int SNESGetType(SNES snes, SNESType *method,char **name)
1381 {
1382   int ierr;
1383   if (!__SNESList) {ierr = SNESRegisterAll(); CHKERRQ(ierr);}
1384   if (method) *method = (SNESType) snes->type;
1385   if (name)  *name = NRFindName( __SNESList, (int) snes->type );
1386   return 0;
1387 }
1388 
1389 #include <stdio.h>
1390 /*
1391    SNESPrintTypes_Private - Prints the SNES methods available from the
1392    options database.
1393 
1394    Input Parameters:
1395 .  prefix - prefix (usually "-")
1396 .  name - the options database name (by default "snes_type")
1397 */
1398 int SNESPrintTypes_Private(char* prefix,char *name)
1399 {
1400   FuncList *entry;
1401   if (!__SNESList) {SNESRegisterAll();}
1402   entry = __SNESList->head;
1403   fprintf(stderr," %s%s (one of)",prefix,name);
1404   while (entry) {
1405     fprintf(stderr," %s",entry->name);
1406     entry = entry->next;
1407   }
1408   fprintf(stderr,"\n");
1409   return 0;
1410 }
1411 
1412 /*@C
1413    SNESGetSolution - Returns the vector where the approximate solution is
1414    stored.
1415 
1416    Input Parameter:
1417 .  snes - the SNES context
1418 
1419    Output Parameter:
1420 .  x - the solution
1421 
1422 .keywords: SNES, nonlinear, get, solution
1423 
1424 .seealso: SNESSetSolution(), SNESGetFunction(), SNESGetSolutionUpdate()
1425 @*/
1426 int SNESGetSolution(SNES snes,Vec *x)
1427 {
1428   PETSCVALIDHEADERSPECIFIC(snes,SNES_COOKIE);
1429   *x = snes->vec_sol_always;
1430   return 0;
1431 }
1432 
1433 /*@C
1434    SNESGetSolutionUpdate - Returns the vector where the solution update is
1435    stored.
1436 
1437    Input Parameter:
1438 .  snes - the SNES context
1439 
1440    Output Parameter:
1441 .  x - the solution update
1442 
1443    Notes:
1444    This vector is implementation dependent.
1445 
1446 .keywords: SNES, nonlinear, get, solution, update
1447 
1448 .seealso: SNESGetSolution(), SNESGetFunction
1449 @*/
1450 int SNESGetSolutionUpdate(SNES snes,Vec *x)
1451 {
1452   PETSCVALIDHEADERSPECIFIC(snes,SNES_COOKIE);
1453   *x = snes->vec_sol_update_always;
1454   return 0;
1455 }
1456 
1457 /*@C
1458    SNESGetFunction - Returns the vector where the function is
1459    stored.  Actually usually returns the vector where the negative of
1460    the function is stored.
1461 
1462    Input Parameter:
1463 .  snes - the SNES context
1464 
1465    Output Parameter:
1466 .  r - the function (or its negative)
1467 
1468    Notes:
1469    SNESGetFunction() is valid for SNES_NONLINEAR_EQUATIONS methods only
1470    Analogous routines for SNES_UNCONSTRAINED_MINIMIZATION methods are
1471    SNESGetMinimizationFunction() and SNESGetGradient();
1472 
1473 .keywords: SNES, nonlinear, get function
1474 
1475 .seealso: SNESSetFunction(), SNESGetSolution()
1476 @*/
1477 int SNESGetFunction(SNES snes,Vec *r)
1478 {
1479   PETSCVALIDHEADERSPECIFIC(snes,SNES_COOKIE);
1480   if (snes->method_class != SNES_NONLINEAR_EQUATIONS) SETERRQ(1,
1481     "SNESGetFunction:For SNES_NONLINEAR_EQUATIONS only");
1482   *r = snes->vec_func_always;
1483   return 0;
1484 }
1485 
1486 /*@C
1487    SNESGetGradient - Returns the vector where the gradient is
1488    stored.  Actually usually returns the vector where the negative of
1489    the function is stored.
1490 
1491    Input Parameter:
1492 .  snes - the SNES context
1493 
1494    Output Parameter:
1495 .  r - the gradient
1496 
1497    Notes:
1498    SNESGetGradient() is valid for SNES_UNCONSTRAINED_MINIMIZATION methods
1499    only.  An analogous routine for SNES_NONLINEAR_EQUATIONS methods is
1500    SNESGetFunction().
1501 
1502 .keywords: SNES, nonlinear, get, gradient
1503 
1504 .seealso: SNESGetMinimizationFunction(), SNESGetSolution()
1505 @*/
1506 int SNESGetGradient(SNES snes,Vec *r)
1507 {
1508   PETSCVALIDHEADERSPECIFIC(snes,SNES_COOKIE);
1509   if (snes->method_class != SNES_UNCONSTRAINED_MINIMIZATION) SETERRQ(1,
1510     "SNESGetGradient:For SNES_UNCONSTRAINED_MINIMIZATION only");
1511   *r = snes->vec_func_always;
1512   return 0;
1513 }
1514 
1515 /*@
1516    SNESGetMinimizationFunction - Returns the scalar function value for
1517    unconstrained minimization problems.
1518 
1519    Input Parameter:
1520 .  snes - the SNES context
1521 
1522    Output Parameter:
1523 .  r - the function
1524 
1525    Notes:
1526    SNESGetMinimizationFunction() is valid for SNES_UNCONSTRAINED_MINIMIZATION
1527    methods only.  An analogous routine for SNES_NONLINEAR_EQUATIONS methods is
1528    SNESGetFunction().
1529 
1530 .keywords: SNES, nonlinear, get, function
1531 
1532 .seealso: SNESGetGradient(), SNESGetSolution()
1533 @*/
1534 int SNESGetMinimizationFunction(SNES snes,double *r)
1535 {
1536   PETSCVALIDHEADERSPECIFIC(snes,SNES_COOKIE);
1537   if (snes->method_class != SNES_UNCONSTRAINED_MINIMIZATION) SETERRQ(1,
1538     "SNESGetMinimizationFunction:For SNES_UNCONSTRAINED_MINIMIZATION only");
1539   *r = snes->fc;
1540   return 0;
1541 }
1542 
1543 
1544 /*@C
1545    SNESSetOptionsPrefix - Sets the prefix used for searching for all
1546    SNES options in the database.
1547 
1548    Input Parameter:
1549 .  snes - the SNES context
1550 .  prefix - the prefix to prepend to all option names
1551 
1552 .keywords: SNES, set, options, prefix, database
1553 @*/
1554 int SNESSetOptionsPrefix(SNES snes,char *prefix)
1555 {
1556   int ierr;
1557 
1558   PETSCVALIDHEADERSPECIFIC(snes,SNES_COOKIE);
1559   ierr = PetscObjectSetPrefix((PetscObject)snes, prefix); CHKERRQ(ierr);
1560   ierr = SLESSetOptionsPrefix(snes->sles,prefix);CHKERRQ(ierr);
1561   return 0;
1562 }
1563 
1564 /*@C
1565    SNESAppendOptionsPrefix - Append to the prefix used for searching for all
1566    SNES options in the database.
1567 
1568    Input Parameter:
1569 .  snes - the SNES context
1570 .  prefix - the prefix to prepend to all option names
1571 
1572 .keywords: SNES, append, options, prefix, database
1573 @*/
1574 int SNESAppendOptionsPrefix(SNES snes,char *prefix)
1575 {
1576   int ierr;
1577 
1578   PETSCVALIDHEADERSPECIFIC(snes,SNES_COOKIE);
1579   ierr = PetscObjectAppendPrefix((PetscObject)snes, prefix); CHKERRQ(ierr);
1580   ierr = SLESAppendOptionsPrefix(snes->sles,prefix);CHKERRQ(ierr);
1581   return 0;
1582 }
1583 
1584 /*@
1585    SNESGetOptionsPrefix - Sets the prefix used for searching for all
1586    SNES options in the database.
1587 
1588    Input Parameter:
1589 .  snes - the SNES context
1590 
1591    Output Parameter:
1592 .  prefix - pointer to the prefix string used
1593 
1594 .keywords: SNES, get, options, prefix, database
1595 @*/
1596 int SNESGetOptionsPrefix(SNES snes,char **prefix)
1597 {
1598   int ierr;
1599 
1600   PETSCVALIDHEADERSPECIFIC(snes,SNES_COOKIE);
1601   ierr = PetscObjectGetPrefix((PetscObject)snes, prefix); CHKERRQ(ierr);
1602   return 0;
1603 }
1604 
1605 
1606 
1607 
1608 
1609