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