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