xref: /petsc/src/snes/interface/snesj.c (revision 11320018864f6641ac52ace117d4bf1606b1b45c)
1*11320018SBarry Smith 
2*11320018SBarry Smith #ifndef lint
3*11320018SBarry Smith static char vcid[] = "$Id: snes.c,v 1.11 1995/04/27 20:17:07 bsmith Exp bsmith $";
4*11320018SBarry Smith #endif
5*11320018SBarry Smith 
6*11320018SBarry Smith #include "draw.h"
7*11320018SBarry Smith #include "snesimpl.h"
8*11320018SBarry Smith #include "options.h"
9*11320018SBarry Smith 
10*11320018SBarry Smith /*@
11*11320018SBarry Smith    SNESSetFromOptions - Sets various SLES parameters from user options.
12*11320018SBarry Smith 
13*11320018SBarry Smith    Input Parameter:
14*11320018SBarry Smith .  snes - the SNES context
15*11320018SBarry Smith 
16*11320018SBarry Smith .keywords: SNES, nonlinear, set, options, database
17*11320018SBarry Smith 
18*11320018SBarry Smith .seealso: SNESPrintHelp()
19*11320018SBarry Smith @*/
20*11320018SBarry Smith int SNESSetFromOptions(SNES snes)
21*11320018SBarry Smith {
22*11320018SBarry Smith   SNESMETHOD method;
23*11320018SBarry Smith   double tmp;
24*11320018SBarry Smith   SLES   sles;
25*11320018SBarry Smith   VALIDHEADER(snes,SNES_COOKIE);
26*11320018SBarry Smith   if (SNESGetMethodFromOptions(snes,&method)) {
27*11320018SBarry Smith     SNESSetMethod(snes,method);
28*11320018SBarry Smith   }
29*11320018SBarry Smith   if (OptionsHasName(0,0,"-help"))  SNESPrintHelp(snes);
30*11320018SBarry Smith   if (OptionsGetDouble(0,snes->prefix,"-snes_stol",&tmp)) {
31*11320018SBarry Smith     SNESSetSolutionTolerance(snes,tmp);
32*11320018SBarry Smith   }
33*11320018SBarry Smith   if (OptionsGetDouble(0,snes->prefix,"-snes_ttol",&tmp)) {
34*11320018SBarry Smith     SNESSetTruncationTolerance(snes,tmp);
35*11320018SBarry Smith   }
36*11320018SBarry Smith   if (OptionsGetDouble(0,snes->prefix,"-snes_atol",&tmp)) {
37*11320018SBarry Smith     SNESSetAbsoluteTolerance(snes,tmp);
38*11320018SBarry Smith   }
39*11320018SBarry Smith   if (OptionsGetDouble(0,snes->prefix,"-snes_rtol",&tmp)) {
40*11320018SBarry Smith     SNESSetRelativeTolerance(snes,tmp);
41*11320018SBarry Smith   }
42*11320018SBarry Smith   OptionsGetInt(0,snes->prefix,"-snes_max_it",&snes->max_its);
43*11320018SBarry Smith   OptionsGetInt(0,snes->prefix,"-snes_max_resid",&snes->max_resids);
44*11320018SBarry Smith   if (OptionsHasName(0,snes->prefix,"-snes_monitor")) {
45*11320018SBarry Smith     SNESSetMonitor(snes,SNESDefaultMonitor,0);
46*11320018SBarry Smith   }
47*11320018SBarry Smith   if (OptionsHasName(0,snes->prefix,"-snes_xmonitor")){
48*11320018SBarry Smith     int       ierr,mytid = 0;
49*11320018SBarry Smith     DrawLGCtx lg;
50*11320018SBarry Smith     MPI_Initialized(&mytid);
51*11320018SBarry Smith     if (mytid) MPI_Comm_rank(snes->comm,&mytid);
52*11320018SBarry Smith     if (!mytid) {
53*11320018SBarry Smith       ierr = SNESLGMonitorCreate(0,0,0,0,300,300,&lg); CHKERR(ierr);
54*11320018SBarry Smith       SNESSetMonitor(snes,SNESLGMonitor,(void *)lg);
55*11320018SBarry Smith     }
56*11320018SBarry Smith   }
57*11320018SBarry Smith   SNESGetSLES(snes,&sles);
58*11320018SBarry Smith   SLESSetFromOptions(sles);
59*11320018SBarry Smith   if (!snes->SetFromOptions) return 0;
60*11320018SBarry Smith   return (*snes->SetFromOptions)(snes);
61*11320018SBarry Smith }
62*11320018SBarry Smith 
63*11320018SBarry Smith /*@
64*11320018SBarry Smith    SNESPrintHelp - Prints all options for the SNES component.
65*11320018SBarry Smith 
66*11320018SBarry Smith    Input Parameter:
67*11320018SBarry Smith .  snes - the SNES context
68*11320018SBarry Smith 
69*11320018SBarry Smith .keywords: SNES, nonlinear, help
70*11320018SBarry Smith 
71*11320018SBarry Smith .seealso: SLESSetFromOptions()
72*11320018SBarry Smith @*/
73*11320018SBarry Smith int SNESPrintHelp(SNES snes)
74*11320018SBarry Smith {
75*11320018SBarry Smith   int     rank;
76*11320018SBarry Smith   char    *prefix = "-";
77*11320018SBarry Smith   if (snes->prefix) prefix = snes->prefix;
78*11320018SBarry Smith   VALIDHEADER(snes,SNES_COOKIE);
79*11320018SBarry Smith   if (!snes->PrintHelp) return 0;
80*11320018SBarry Smith   MPI_Comm_rank(snes->comm,&rank); if (rank) return 0;
81*11320018SBarry Smith   fprintf(stderr,"SNES options ----------------------------\n");
82*11320018SBarry Smith   fprintf(stderr,"%ssnes_method [ls] \n",prefix);
83*11320018SBarry Smith   fprintf(stderr,"%ssnes_stol tol (default %g)\n",prefix,snes->xtol);
84*11320018SBarry Smith   fprintf(stderr,"%ssnes_atol tol (default %g)\n",prefix,snes->atol);
85*11320018SBarry Smith   fprintf(stderr,"%ssnes_rtol tol (default %g)\n",prefix,snes->rtol);
86*11320018SBarry Smith   fprintf(stderr,"%ssnes_ttol tol (default %g)\n",prefix,snes->trunctol);
87*11320018SBarry Smith   fprintf(stderr,"%ssnes_max_it its (default %d)\n",prefix,snes->max_its);
88*11320018SBarry Smith   fprintf(stderr,"%ssnes_monitor\n",prefix);
89*11320018SBarry Smith   return (*snes->PrintHelp)(snes);
90*11320018SBarry Smith }
91*11320018SBarry Smith /*@
92*11320018SBarry Smith    SNESSetApplicationContext - Sets the optional user-defined context for
93*11320018SBarry Smith    the nonlinear solvers.
94*11320018SBarry Smith 
95*11320018SBarry Smith    Input Parameters:
96*11320018SBarry Smith .  snes - the SNES context
97*11320018SBarry Smith .  usrP - optional user context
98*11320018SBarry Smith 
99*11320018SBarry Smith .keywords: SNES, nonlinear, set, application, context
100*11320018SBarry Smith 
101*11320018SBarry Smith .seealso: SNESGetApplicationContext()
102*11320018SBarry Smith @*/
103*11320018SBarry Smith int SNESSetApplicationContext(SNES snes,void *usrP)
104*11320018SBarry Smith {
105*11320018SBarry Smith    VALIDHEADER(snes,SNES_COOKIE);
106*11320018SBarry Smith    snes->user		= usrP;
107*11320018SBarry Smith    return 0;
108*11320018SBarry Smith }
109*11320018SBarry Smith /*@
110*11320018SBarry Smith    SNESGetApplicationContext - Gets the user-defined context for the
111*11320018SBarry Smith    nonlinear solvers.
112*11320018SBarry Smith 
113*11320018SBarry Smith    Input Parameter:
114*11320018SBarry Smith .  snes - SNES context
115*11320018SBarry Smith 
116*11320018SBarry Smith    Output Parameter:
117*11320018SBarry Smith .  usrP - user context
118*11320018SBarry Smith 
119*11320018SBarry Smith .keywords: SNES, nonlinear, get, application, context
120*11320018SBarry Smith 
121*11320018SBarry Smith .seealso: SNESSetApplicationContext()
122*11320018SBarry Smith @*/
123*11320018SBarry Smith int SNESGetApplicationContext( SNES snes,  void **usrP )
124*11320018SBarry Smith {
125*11320018SBarry Smith    VALIDHEADER(snes,SNES_COOKIE);
126*11320018SBarry Smith    *usrP = snes->user;
127*11320018SBarry Smith    return 0;
128*11320018SBarry Smith }
129*11320018SBarry Smith 
130*11320018SBarry Smith /*@
131*11320018SBarry Smith    SNESGetSLES - Returns the SLES context for a SNES solver.
132*11320018SBarry Smith 
133*11320018SBarry Smith    Input Parameter:
134*11320018SBarry Smith .  snes - the SNES context
135*11320018SBarry Smith 
136*11320018SBarry Smith    Output Parameter:
137*11320018SBarry Smith .  sles - the SLES context
138*11320018SBarry Smith 
139*11320018SBarry Smith    Notes:
140*11320018SBarry Smith    The user can then directly manipulate the SLES context to set various
141*11320018SBarry Smith    options, etc.  Likewise, the user can then manipulate the KSP and PC
142*11320018SBarry Smith    contexts as well.
143*11320018SBarry Smith 
144*11320018SBarry Smith .keywords: SNES, nonlinear, get, SLES, context
145*11320018SBarry Smith 
146*11320018SBarry Smith .seealso: SLESGetPC(), SLESGetKSP()
147*11320018SBarry Smith @*/
148*11320018SBarry Smith int SNESGetSLES(SNES snes,SLES *sles)
149*11320018SBarry Smith {
150*11320018SBarry Smith    VALIDHEADER(snes,SNES_COOKIE);
151*11320018SBarry Smith   *sles = snes->sles;
152*11320018SBarry Smith   return 0;
153*11320018SBarry Smith }
154*11320018SBarry Smith 
155*11320018SBarry Smith /* -----------------------------------------------------------*/
156*11320018SBarry Smith 
157*11320018SBarry Smith /*@
158*11320018SBarry Smith    SNESCreate - Creates a nonlinear solver context.
159*11320018SBarry Smith 
160*11320018SBarry Smith    Input Parameter:
161*11320018SBarry Smith .  comm - MPI communicator
162*11320018SBarry Smith 
163*11320018SBarry Smith    Output Parameter:
164*11320018SBarry Smith .  outsnes - the new SNES context
165*11320018SBarry Smith 
166*11320018SBarry Smith .keywords: SNES, nonlinear, create, context
167*11320018SBarry Smith 
168*11320018SBarry Smith .seealso: SNESSetUp(), SNESSolve(), SNESDestroy()
169*11320018SBarry Smith @*/
170*11320018SBarry Smith int SNESCreate(MPI_Comm comm, SNES *outsnes)
171*11320018SBarry Smith {
172*11320018SBarry Smith   int  ierr;
173*11320018SBarry Smith   SNES snes;
174*11320018SBarry Smith   *outsnes = 0;
175*11320018SBarry Smith   PETSCHEADERCREATE(snes,_SNES,SNES_COOKIE,SNES_NLS,comm);
176*11320018SBarry Smith   PLogObjectCreate(snes);
177*11320018SBarry Smith   snes->max_its         = 50;
178*11320018SBarry Smith   snes->max_resids	= 1000;
179*11320018SBarry Smith   snes->max_funcs	= 1000;
180*11320018SBarry Smith   snes->norm		= 0.0;
181*11320018SBarry Smith   snes->rtol		= 1.e-8;
182*11320018SBarry Smith   snes->atol		= 1.e-10;
183*11320018SBarry Smith   snes->xtol		= 1.e-8;
184*11320018SBarry Smith   snes->trunctol	= 1.e-12;
185*11320018SBarry Smith   snes->nresids         = 0;
186*11320018SBarry Smith   snes->Monitor         = 0;
187*11320018SBarry Smith   ierr = SLESCreate(comm,&snes->sles); CHKERR(ierr);
188*11320018SBarry Smith   PLogObjectParent(snes,snes->sles)
189*11320018SBarry Smith   *outsnes = snes;
190*11320018SBarry Smith   return 0;
191*11320018SBarry Smith }
192*11320018SBarry Smith 
193*11320018SBarry Smith /* --------------------------------------------------------------- */
194*11320018SBarry Smith /*@C
195*11320018SBarry Smith    SNESSetFunction - Sets the residual evaluation routine and residual
196*11320018SBarry Smith    vector for use by the SNES routines.
197*11320018SBarry Smith 
198*11320018SBarry Smith    Input Parameters:
199*11320018SBarry Smith .  snes - the SNES context
200*11320018SBarry Smith .  func - residual evaluation routine
201*11320018SBarry Smith .  resid_neg - indicator whether func evaluates f or -f.
202*11320018SBarry Smith    If resid_neg is nonzero, then func evaluates -f; otherwise,
203*11320018SBarry Smith    func evaluates f.
204*11320018SBarry Smith .  ctx - optional user-defined function context
205*11320018SBarry Smith .  r - vector to store residual
206*11320018SBarry Smith 
207*11320018SBarry Smith    Calling sequence of func:
208*11320018SBarry Smith .  func (Vec x, Vec f, void *ctx);
209*11320018SBarry Smith 
210*11320018SBarry Smith .  x - input vector
211*11320018SBarry Smith .  f - residual vector or its negative
212*11320018SBarry Smith .  ctx - optional user-defined context for private data for the
213*11320018SBarry Smith          residual evaluation routine (may be null)
214*11320018SBarry Smith 
215*11320018SBarry Smith    Notes:
216*11320018SBarry Smith    The Newton-like methods typically solve linear systems of the form
217*11320018SBarry Smith $      f'(x) x = -f(x),
218*11320018SBarry Smith $  where f'(x) denotes the Jacobian matrix and f(x) is the residual.
219*11320018SBarry Smith    By setting resid_neg = 1, the user can supply -f(x) directly.
220*11320018SBarry Smith 
221*11320018SBarry Smith .keywords: SNES, nonlinear, set, residual
222*11320018SBarry Smith 
223*11320018SBarry Smith .seealso: SNESGetFunction(), SNESSetJacobian(), SNESSetSolution()
224*11320018SBarry Smith @*/
225*11320018SBarry Smith int SNESSetFunction( SNES snes, Vec r, int (*func)(Vec,Vec,void*),
226*11320018SBarry Smith                      void *ctx,int rneg)
227*11320018SBarry Smith {
228*11320018SBarry Smith   VALIDHEADER(snes,SNES_COOKIE);
229*11320018SBarry Smith   snes->ComputeResidual     = func;
230*11320018SBarry Smith   snes->rsign               = rneg;
231*11320018SBarry Smith   snes->vec_res             = r;
232*11320018SBarry Smith   snes->resP                = ctx;
233*11320018SBarry Smith   return 0;
234*11320018SBarry Smith }
235*11320018SBarry Smith 
236*11320018SBarry Smith int SNESComputeFunction(SNES snes,Vec x, Vec y)
237*11320018SBarry Smith {
238*11320018SBarry Smith   int    ierr;
239*11320018SBarry Smith   Scalar mone = -1.0;
240*11320018SBarry Smith   ierr = (*snes->ComputeResidual)(x,y,snes->resP); CHKERR(ierr);
241*11320018SBarry Smith   snes->nresids++;
242*11320018SBarry Smith   if (!snes->rsign) {
243*11320018SBarry Smith     ierr = VecScale(&mone,y); CHKERR(ierr);
244*11320018SBarry Smith   }
245*11320018SBarry Smith   return 0;
246*11320018SBarry Smith }
247*11320018SBarry Smith 
248*11320018SBarry Smith /*@
249*11320018SBarry Smith    SNESSetJacobian - Sets the function to compute Jacobian as well as the
250*11320018SBarry Smith    location to store it.
251*11320018SBarry Smith 
252*11320018SBarry Smith    Input Parameters:
253*11320018SBarry Smith .  snes - the SNES context
254*11320018SBarry Smith .  A - Jacobian matrix
255*11320018SBarry Smith .  func - Jacobian evaluation routine
256*11320018SBarry Smith .  ctx - optional user-defined context for private data for the
257*11320018SBarry Smith          Jacobian evaluation routine (may be null)
258*11320018SBarry Smith 
259*11320018SBarry Smith    Calling sequence of func:
260*11320018SBarry Smith .  func (Vec x, Mat *A, Mat *B, int *flag,void *ctx);
261*11320018SBarry Smith 
262*11320018SBarry Smith .  x - input vector
263*11320018SBarry Smith .  A - Jacobian matrix
264*11320018SBarry Smith .  B - preconditioner matrix, usually the same as A
265*11320018SBarry Smith .  flag - same as options to SLESSetOperators(). Usually 0 or
266*11320018SBarry Smith $         MAT_SAME_NONZERO_PATTERN
267*11320018SBarry Smith .  ctx - optional user-defined Jacobian context
268*11320018SBarry Smith 
269*11320018SBarry Smith    Notes:
270*11320018SBarry Smith    The function func() takes a Mat * as an argument rather than a Mat.
271*11320018SBarry Smith    This is to allow the Jacobian code to replace it with a new matrix
272*11320018SBarry Smith    when appropriate, for instance, if the nonzero structure is changing.
273*11320018SBarry Smith 
274*11320018SBarry Smith .keywords: SNES, nonlinear, set, Jacobian, matrix
275*11320018SBarry Smith 
276*11320018SBarry Smith .seealso: SNESSetFunction(), SNESSetSolution()
277*11320018SBarry Smith @*/
278*11320018SBarry Smith int SNESSetJacobian(SNES snes,Mat A,Mat B,int (*func)(Vec,Mat*,Mat*,int*,void*),
279*11320018SBarry Smith                     void *ctx)
280*11320018SBarry Smith {
281*11320018SBarry Smith   VALIDHEADER(snes,SNES_COOKIE);
282*11320018SBarry Smith   snes->ComputeJacobian = func;
283*11320018SBarry Smith   snes->jacP            = ctx;
284*11320018SBarry Smith   snes->jacobian        = A;
285*11320018SBarry Smith   snes->jacobian_pre    = B;
286*11320018SBarry Smith   return 0;
287*11320018SBarry Smith }
288*11320018SBarry Smith 
289*11320018SBarry Smith /* ----- Routines to initialize and destroy a nonlinear solver ---- */
290*11320018SBarry Smith 
291*11320018SBarry Smith /*@
292*11320018SBarry Smith    SNESSetUp - Sets up the internal data structures for the later use
293*11320018SBarry Smith    of a nonlinear solver.  Call SNESSetUp() after calling SNESCreate()
294*11320018SBarry Smith    and optional routines of the form SNESSetXXX(), but before calling
295*11320018SBarry Smith    SNESSolve().
296*11320018SBarry Smith 
297*11320018SBarry Smith    Input Parameter:
298*11320018SBarry Smith .  snes - the SNES context
299*11320018SBarry Smith 
300*11320018SBarry Smith .keywords: SNES, nonlinear, setup
301*11320018SBarry Smith 
302*11320018SBarry Smith .seealso: SNESCreate(), SNESSolve(), SNESDestroy()
303*11320018SBarry Smith @*/
304*11320018SBarry Smith int SNESSetUp(SNES snes)
305*11320018SBarry Smith {
306*11320018SBarry Smith   VALIDHEADER(snes,SNES_COOKIE);
307*11320018SBarry Smith   return (*(snes)->Setup)( snes );
308*11320018SBarry Smith }
309*11320018SBarry Smith 
310*11320018SBarry Smith /*@
311*11320018SBarry Smith    SNESDestroy - Destroys the nonlinear solver context that was created
312*11320018SBarry Smith    with SNESCreate().
313*11320018SBarry Smith 
314*11320018SBarry Smith    Input Parameter:
315*11320018SBarry Smith .  snes - the SNES context
316*11320018SBarry Smith 
317*11320018SBarry Smith .keywords: SNES, nonlinear, destroy
318*11320018SBarry Smith 
319*11320018SBarry Smith .seealso: SNESCreate(), SNESSetUp(), SNESSolve()
320*11320018SBarry Smith @*/
321*11320018SBarry Smith int SNESDestroy(SNES snes)
322*11320018SBarry Smith {
323*11320018SBarry Smith   VALIDHEADER(snes,SNES_COOKIE);
324*11320018SBarry Smith   return (*(snes)->destroy)( (PetscObject) snes );
325*11320018SBarry Smith }
326*11320018SBarry Smith 
327*11320018SBarry Smith /* ----------- Routines to set solver parameters ---------- */
328*11320018SBarry Smith 
329*11320018SBarry Smith /*@
330*11320018SBarry Smith    SNESSetMaxIterations - Sets the maximum number of global iterations to use.
331*11320018SBarry Smith 
332*11320018SBarry Smith    Input Parameters:
333*11320018SBarry Smith .  snes - the SNES context
334*11320018SBarry Smith .  maxits - maximum number of iterations to use
335*11320018SBarry Smith 
336*11320018SBarry Smith    Options Database Key:
337*11320018SBarry Smith $  -snes_max_it  maxits
338*11320018SBarry Smith 
339*11320018SBarry Smith    Note:
340*11320018SBarry Smith    The default maximum number of iterations is 50.
341*11320018SBarry Smith 
342*11320018SBarry Smith .keywords: SNES, nonlinear, set, maximum, iterations
343*11320018SBarry Smith 
344*11320018SBarry Smith .seealso: SNESSetMaxResidualEvaluations()
345*11320018SBarry Smith @*/
346*11320018SBarry Smith int SNESSetMaxIterations(SNES snes,int maxits)
347*11320018SBarry Smith {
348*11320018SBarry Smith   VALIDHEADER(snes,SNES_COOKIE);
349*11320018SBarry Smith   snes->max_its = maxits;
350*11320018SBarry Smith   return 0;
351*11320018SBarry Smith }
352*11320018SBarry Smith 
353*11320018SBarry Smith /*@
354*11320018SBarry Smith    SNESSetMaxResidualEvaluations - Sets the maximum number of residual
355*11320018SBarry Smith    evaluations to use.
356*11320018SBarry Smith 
357*11320018SBarry Smith    Input Parameters:
358*11320018SBarry Smith .  snes - the SNES context
359*11320018SBarry Smith .  maxr - maximum number of residual evaluations
360*11320018SBarry Smith 
361*11320018SBarry Smith    Options Database Key:
362*11320018SBarry Smith $  -snes_max_resid maxr
363*11320018SBarry Smith 
364*11320018SBarry Smith    Note:
365*11320018SBarry Smith    The default maximum number of residual evaluations is 1000.
366*11320018SBarry Smith 
367*11320018SBarry Smith .keywords: SNES, nonlinear, set, maximum, residual, evaluations
368*11320018SBarry Smith 
369*11320018SBarry Smith .seealso: SNESSetMaxIterations()
370*11320018SBarry Smith @*/
371*11320018SBarry Smith int SNESSetMaxResidualEvaluations(SNES snes,int maxr)
372*11320018SBarry Smith {
373*11320018SBarry Smith   VALIDHEADER(snes,SNES_COOKIE);
374*11320018SBarry Smith   snes->max_resids = maxr;
375*11320018SBarry Smith   return 0;
376*11320018SBarry Smith }
377*11320018SBarry Smith 
378*11320018SBarry Smith /*@
379*11320018SBarry Smith    SNESSetRelativeTolerance - Sets the relative convergence tolerance.
380*11320018SBarry Smith 
381*11320018SBarry Smith    Input Parameters:
382*11320018SBarry Smith .  snes - the SNES context
383*11320018SBarry Smith .  rtol - tolerance
384*11320018SBarry Smith 
385*11320018SBarry Smith    Options Database Key:
386*11320018SBarry Smith $    -snes_rtol tol
387*11320018SBarry Smith 
388*11320018SBarry Smith .keywords: SNES, nonlinear, set, relative, convergence, tolerance
389*11320018SBarry Smith 
390*11320018SBarry Smith .seealso: SNESSetAbsoluteTolerance(), SNESSetSolutionTolerance(),
391*11320018SBarry Smith            SNESSetTruncationTolerance()
392*11320018SBarry Smith @*/
393*11320018SBarry Smith int SNESSetRelativeTolerance(SNES snes,double rtol)
394*11320018SBarry Smith {
395*11320018SBarry Smith   VALIDHEADER(snes,SNES_COOKIE);
396*11320018SBarry Smith   snes->rtol = rtol;
397*11320018SBarry Smith   return 0;
398*11320018SBarry Smith }
399*11320018SBarry Smith 
400*11320018SBarry Smith /*@
401*11320018SBarry Smith    SNESSetAbsoluteTolerance - Sets the absolute convergence tolerance.
402*11320018SBarry Smith 
403*11320018SBarry Smith    Input Parameters:
404*11320018SBarry Smith .  snes - the SNES context
405*11320018SBarry Smith .  atol - tolerance
406*11320018SBarry Smith 
407*11320018SBarry Smith    Options Database Key:
408*11320018SBarry Smith $    -snes_atol tol
409*11320018SBarry Smith 
410*11320018SBarry Smith    Notes:
411*11320018SBarry Smith $  The following convergence monitoring routines use atol
412*11320018SBarry Smith 
413*11320018SBarry Smith .keywords: SNES, nonlinear, set, absolute, convergence, tolerance
414*11320018SBarry Smith 
415*11320018SBarry Smith .seealso: SNESSetRelativeTolerance(), SNESSetSolutionTolerance(),
416*11320018SBarry Smith            SNESSetTruncationTolerance()
417*11320018SBarry Smith @*/
418*11320018SBarry Smith int SNESSetAbsoluteTolerance(SNES snes,double atol)
419*11320018SBarry Smith {
420*11320018SBarry Smith   VALIDHEADER(snes,SNES_COOKIE);
421*11320018SBarry Smith   snes->atol = atol;
422*11320018SBarry Smith   return 0;
423*11320018SBarry Smith }
424*11320018SBarry Smith 
425*11320018SBarry Smith /*@
426*11320018SBarry Smith    SNESSetTruncationTolerance - Sets the tolerance that may be used by the
427*11320018SBarry Smith    step routines to control the accuracy of the step computation.
428*11320018SBarry Smith 
429*11320018SBarry Smith    Input Parameters:
430*11320018SBarry Smith .  snes - the SNES context
431*11320018SBarry Smith .  tol - tolerance
432*11320018SBarry Smith 
433*11320018SBarry Smith    Options Database Key:
434*11320018SBarry Smith $    -snes_ttol tol
435*11320018SBarry Smith 
436*11320018SBarry Smith    Notes:
437*11320018SBarry Smith    If the step computation involves an application of the inverse
438*11320018SBarry Smith    Jacobian (or Hessian), this parameter may be used to control the
439*11320018SBarry Smith    accuracy of that application.  In particular, this tolerance is used
440*11320018SBarry Smith    by SNESKSPDefaultConverged() and SNESKSPQuadraticConverged() to determine
441*11320018SBarry Smith    the minimum convergence tolerance for the iterative linear solvers.
442*11320018SBarry Smith 
443*11320018SBarry Smith .keywords: SNES, nonlinear, set, truncation, tolerance
444*11320018SBarry Smith 
445*11320018SBarry Smith .seealso: SNESSetRelativeTolerance(), SNESSetSolutionTolerance(),
446*11320018SBarry Smith           SNESSetAbsoluteTolerance()
447*11320018SBarry Smith @*/
448*11320018SBarry Smith int SNESSetTruncationTolerance(SNES snes,double tol)
449*11320018SBarry Smith {
450*11320018SBarry Smith   VALIDHEADER(snes,SNES_COOKIE);
451*11320018SBarry Smith   snes->trunctol = tol;
452*11320018SBarry Smith   return 0;
453*11320018SBarry Smith }
454*11320018SBarry Smith 
455*11320018SBarry Smith /*@
456*11320018SBarry Smith    SNESSetSolutionTolerance - Sets the convergence tolerance in terms of
457*11320018SBarry Smith    the norm of the change in the solution between steps.
458*11320018SBarry Smith 
459*11320018SBarry Smith    Input Parameters:
460*11320018SBarry Smith .  snes - the SNES context
461*11320018SBarry Smith .  tol - tolerance
462*11320018SBarry Smith 
463*11320018SBarry Smith    Options Database Key:
464*11320018SBarry Smith $    -snes_stol tol
465*11320018SBarry Smith 
466*11320018SBarry Smith .keywords: SNES, nonlinear, set, solution, tolerance
467*11320018SBarry Smith 
468*11320018SBarry Smith .seealso: SNESSetTruncationTolerance(), SNESSetRelativeTolerance(),
469*11320018SBarry Smith           SNESSetAbsoluteTolerance()
470*11320018SBarry Smith @*/
471*11320018SBarry Smith int SNESSetSolutionTolerance( SNES snes, double tol )
472*11320018SBarry Smith {
473*11320018SBarry Smith   VALIDHEADER(snes,SNES_COOKIE);
474*11320018SBarry Smith   snes->xtol = tol;
475*11320018SBarry Smith   return 0;
476*11320018SBarry Smith }
477*11320018SBarry Smith 
478*11320018SBarry Smith /* ---------- Routines to set various aspects of nonlinear solver --------- */
479*11320018SBarry Smith 
480*11320018SBarry Smith /*@
481*11320018SBarry Smith    SNESSetSolution - Sets the initial guess routine and solution vector
482*11320018SBarry Smith    for use by the SNES routines.
483*11320018SBarry Smith 
484*11320018SBarry Smith    Input Parameters:
485*11320018SBarry Smith .  snes - the SNES context
486*11320018SBarry Smith .  x - the solution vector
487*11320018SBarry Smith .  func - optional routine to compute an initial guess (may be null)
488*11320018SBarry Smith .  ctx - optional user-defined context for private data for the
489*11320018SBarry Smith          initial guess routine (may be null)
490*11320018SBarry Smith 
491*11320018SBarry Smith    Calling sequence of func:
492*11320018SBarry Smith    int guess(Vec x, void *ctx)
493*11320018SBarry Smith 
494*11320018SBarry Smith .  x - input vector
495*11320018SBarry Smith .  ctx - optional user-defined initial guess context
496*11320018SBarry Smith 
497*11320018SBarry Smith    Note:
498*11320018SBarry Smith    If no initial guess routine is indicated, an initial guess of zero
499*11320018SBarry Smith    will be used.
500*11320018SBarry Smith 
501*11320018SBarry Smith .keywords: SNES, nonlinear, set, solution, initial guess
502*11320018SBarry Smith 
503*11320018SBarry Smith .seealso: SNESGetSolution(), SNESSetJacobian(), SNESSetFunction()
504*11320018SBarry Smith @*/
505*11320018SBarry Smith int SNESSetSolution(SNES snes,Vec x,int (*func)(Vec,void*),void *ctx)
506*11320018SBarry Smith {
507*11320018SBarry Smith   VALIDHEADER(snes,SNES_COOKIE);
508*11320018SBarry Smith   snes->vec_sol             = x;
509*11320018SBarry Smith   snes->ComputeInitialGuess = func;
510*11320018SBarry Smith   snes->gusP                = ctx;
511*11320018SBarry Smith   return 0;
512*11320018SBarry Smith }
513*11320018SBarry Smith 
514*11320018SBarry Smith /* ------------ Routines to set performance monitoring options ----------- */
515*11320018SBarry Smith 
516*11320018SBarry Smith /*@C
517*11320018SBarry Smith    SNESSetMonitor - Sets the function that is to be used at every
518*11320018SBarry Smith    iteration of the nonlinear solver to display the iteration's
519*11320018SBarry Smith    progress.
520*11320018SBarry Smith 
521*11320018SBarry Smith    Input Parameters:
522*11320018SBarry Smith .  snes - the SNES context
523*11320018SBarry Smith .  func - monitoring routine
524*11320018SBarry Smith .  mctx - optional user-defined context for private data for the
525*11320018SBarry Smith           monitor routine (may be null)
526*11320018SBarry Smith 
527*11320018SBarry Smith    Calling sequence of func:
528*11320018SBarry Smith    int func((SNES snes,int its, Vec x,Vec f,double fnorm,void *mctx)
529*11320018SBarry Smith 
530*11320018SBarry Smith .  snes - the SNES context
531*11320018SBarry Smith .  its - iteration number
532*11320018SBarry Smith .  x - current iterate
533*11320018SBarry Smith .  f - current residual (+/-).  f is either the residual or its negative,
534*11320018SBarry Smith        depending on the user's preference, as set with SNESSetFunction()
535*11320018SBarry Smith .  fnorm - 2-norm residual value (may be estimated)
536*11320018SBarry Smith .  mctx - optional monitoring context
537*11320018SBarry Smith 
538*11320018SBarry Smith .keywords: SNES, nonlinear, set, monitor
539*11320018SBarry Smith 
540*11320018SBarry Smith .seealso: SNESDefaultMonitor()
541*11320018SBarry Smith @*/
542*11320018SBarry Smith int SNESSetMonitor( SNES snes, int (*func)(SNES,int,double,void*),
543*11320018SBarry Smith                     void *mctx )
544*11320018SBarry Smith {
545*11320018SBarry Smith   snes->Monitor = func;
546*11320018SBarry Smith   snes->monP    = (void*)mctx;
547*11320018SBarry Smith   return 0;
548*11320018SBarry Smith }
549*11320018SBarry Smith 
550*11320018SBarry Smith /*@C
551*11320018SBarry Smith    SNESSetConvergenceTest - Sets the function that is to be used
552*11320018SBarry Smith    to test for convergence of the nonlinear iterative solution.
553*11320018SBarry Smith 
554*11320018SBarry Smith    Input Parameters:
555*11320018SBarry Smith .  snes - the SNES context
556*11320018SBarry Smith .  func - routine to test for convergence
557*11320018SBarry Smith .  cctx - optional context for private data for the convergence routine
558*11320018SBarry Smith           (may be null)
559*11320018SBarry Smith 
560*11320018SBarry Smith    Calling sequence of func:
561*11320018SBarry Smith    int func (SNES snes,double xnorm,double pnorm,double fnorm,
562*11320018SBarry Smith              void *cctx)
563*11320018SBarry Smith 
564*11320018SBarry Smith .  snes - the SNES context
565*11320018SBarry Smith .  xnorm - 2-norm of current iterate
566*11320018SBarry Smith .  pnorm - 2-norm of current step
567*11320018SBarry Smith .  fnorm - 2-norm of residual
568*11320018SBarry Smith .  cctx - optional convergence context
569*11320018SBarry Smith 
570*11320018SBarry Smith .keywords: SNES, nonlinear, set, convergence, test
571*11320018SBarry Smith 
572*11320018SBarry Smith .seealso: SNESDefaultConverged()
573*11320018SBarry Smith @*/
574*11320018SBarry Smith int SNESSetConvergenceTest(SNES nlP,
575*11320018SBarry Smith           int (*func)(SNES,double,double,double,void*),void *cctx)
576*11320018SBarry Smith {
577*11320018SBarry Smith   (nlP)->Converged = func;
578*11320018SBarry Smith   (nlP)->cnvP      = cctx;
579*11320018SBarry Smith   return 0;
580*11320018SBarry Smith }
581*11320018SBarry Smith 
582*11320018SBarry Smith /*@
583*11320018SBarry Smith    SNESScaleStep - Scales a step so that its length is less than the
584*11320018SBarry Smith    positive parameter delta.
585*11320018SBarry Smith 
586*11320018SBarry Smith     Input Parameters:
587*11320018SBarry Smith .   snes - the SNES context
588*11320018SBarry Smith .   y - approximate solution of linear system
589*11320018SBarry Smith .   fnorm - 2-norm of current residual
590*11320018SBarry Smith .   delta - trust region size
591*11320018SBarry Smith 
592*11320018SBarry Smith     Output Parameters:
593*11320018SBarry Smith .   gpnorm - predicted residual norm at the new point, assuming local
594*11320018SBarry Smith     linearization.  The value is zero if the step lies within the trust
595*11320018SBarry Smith     region, and exceeds zero otherwise.
596*11320018SBarry Smith .   ynorm - 2-norm of the step
597*11320018SBarry Smith 
598*11320018SBarry Smith     Note:
599*11320018SBarry Smith     For non-trust region methods such as SNES_NLS, the parameter delta
600*11320018SBarry Smith     is set to be the maximum allowable step size.
601*11320018SBarry Smith 
602*11320018SBarry Smith .keywords: SNES, nonlinear, scale, step
603*11320018SBarry Smith @*/
604*11320018SBarry Smith int SNESScaleStep(SNES snes,Vec y,double *fnorm,double *delta,
605*11320018SBarry Smith                   double *gpnorm,double *ynorm)
606*11320018SBarry Smith {
607*11320018SBarry Smith   double norm;
608*11320018SBarry Smith   Scalar cnorm;
609*11320018SBarry Smith   VecNorm(y, &norm );
610*11320018SBarry Smith   if (norm > *delta) {
611*11320018SBarry Smith      norm = *delta/norm;
612*11320018SBarry Smith      *gpnorm = (1.0 - norm)*(*fnorm);
613*11320018SBarry Smith      cnorm = norm;
614*11320018SBarry Smith      VecScale( &cnorm, y );
615*11320018SBarry Smith      *ynorm = *delta;
616*11320018SBarry Smith   } else {
617*11320018SBarry Smith      *gpnorm = 0.0;
618*11320018SBarry Smith      *ynorm = norm;
619*11320018SBarry Smith   }
620*11320018SBarry Smith   return 0;
621*11320018SBarry Smith }
622*11320018SBarry Smith 
623*11320018SBarry Smith /*@
624*11320018SBarry Smith    SNESSolve - Solves a nonlinear system.  Call SNESSolve after calling
625*11320018SBarry Smith    SNESCreate(), optional routines of the form SNESSetXXX(), and SNESSetUp().
626*11320018SBarry Smith 
627*11320018SBarry Smith    Input Parameter:
628*11320018SBarry Smith .  snes - the SNES context
629*11320018SBarry Smith 
630*11320018SBarry Smith    Output Parameter:
631*11320018SBarry Smith    its - number of iterations until termination
632*11320018SBarry Smith 
633*11320018SBarry Smith .keywords: SNES, nonlinear, solve
634*11320018SBarry Smith 
635*11320018SBarry Smith .seealso: SNESCreate(), SNESSetUp(), SNESDestroy()
636*11320018SBarry Smith @*/
637*11320018SBarry Smith int SNESSolve(SNES snes,int *its)
638*11320018SBarry Smith {
639*11320018SBarry Smith   int ierr;
640*11320018SBarry Smith   PLogEventBegin(SNES_Solve,snes,0,0,0);
641*11320018SBarry Smith   ierr = (*(snes)->Solver)( snes,its ); CHKERR(ierr);
642*11320018SBarry Smith   PLogEventEnd(SNES_Solve,snes,0,0,0);
643*11320018SBarry Smith   return 0;
644*11320018SBarry Smith }
645*11320018SBarry Smith 
646*11320018SBarry Smith /* --------- Internal routines for SNES Package --------- */
647*11320018SBarry Smith 
648*11320018SBarry Smith /*
649*11320018SBarry Smith    SNESComputeInitialGuess - Manages computation of initial approximation.
650*11320018SBarry Smith  */
651*11320018SBarry Smith int SNESComputeInitialGuess( SNES nlP,Vec  x )
652*11320018SBarry Smith {
653*11320018SBarry Smith   int    ierr;
654*11320018SBarry Smith   Scalar zero = 0.0;
655*11320018SBarry Smith   if (nlP->ComputeInitialGuess) {
656*11320018SBarry Smith     ierr = (*nlP->ComputeInitialGuess)( x, nlP->gusP); CHKERR(ierr);
657*11320018SBarry Smith   }
658*11320018SBarry Smith   else VecSet(&zero, x );
659*11320018SBarry Smith   return 0;
660*11320018SBarry Smith }
661*11320018SBarry Smith 
662*11320018SBarry Smith /* ------------------------------------------------------------------ */
663*11320018SBarry Smith 
664*11320018SBarry Smith 
665*11320018SBarry Smith #include "sys/nreg.h"
666*11320018SBarry Smith NRList *__NLList;
667*11320018SBarry Smith 
668*11320018SBarry Smith /*@
669*11320018SBarry Smith    SNESSetMethod - Sets the method for the nonlinear solver.
670*11320018SBarry Smith 
671*11320018SBarry Smith    Input Parameters:
672*11320018SBarry Smith .  snes - the SNES context
673*11320018SBarry Smith .  method - choose from
674*11320018SBarry Smith 
675*11320018SBarry Smith   Possible methods:
676*11320018SBarry Smith $    SNES_NLS - Newton's method with line search
677*11320018SBarry Smith $    SNES_NTR - Newton's method with trust region
678*11320018SBarry Smith @*/
679*11320018SBarry Smith int SNESSetMethod( SNES snes, SNESMETHOD method)
680*11320018SBarry Smith {
681*11320018SBarry Smith   int (*r)(SNES);
682*11320018SBarry Smith   VALIDHEADER(snes,SNES_COOKIE);
683*11320018SBarry Smith   /* Get the function pointers for the iterative method requested */
684*11320018SBarry Smith   if (!__NLList) {SNESRegisterAll();}
685*11320018SBarry Smith   if (!__NLList) {SETERR(1,"Could not acquire list of SNES methods"); }
686*11320018SBarry Smith   r =  (int (*)(SNES))NRFindRoutine( __NLList, (int)method, (char *)0 );
687*11320018SBarry Smith   if (!r) {SETERR(1,"Unknown SNES method");}
688*11320018SBarry Smith   return (*r)(snes);
689*11320018SBarry Smith }
690*11320018SBarry Smith 
691*11320018SBarry Smith /* --------------------------------------------------------------------- */
692*11320018SBarry Smith /*@
693*11320018SBarry Smith    SNESRegister - Adds the method to the nonlinear solver package, given
694*11320018SBarry Smith    a function pointer and a nonlinear solver name of the type SNESMETHOD.
695*11320018SBarry Smith 
696*11320018SBarry Smith    Input Parameters:
697*11320018SBarry Smith .  name - for instance SNES_NLS, SNES_NTR, ...
698*11320018SBarry Smith .  sname - corresponding string for name
699*11320018SBarry Smith .  create - routine to create method context
700*11320018SBarry Smith 
701*11320018SBarry Smith .keywords: SNES, nonlinear, register
702*11320018SBarry Smith 
703*11320018SBarry Smith .seealso: SNESRegisterAll(), SNESRegisterDestroy()
704*11320018SBarry Smith @*/
705*11320018SBarry Smith int SNESRegister(int name, char *sname, int (*create)(SNES))
706*11320018SBarry Smith {
707*11320018SBarry Smith   int ierr;
708*11320018SBarry Smith   if (!__NLList) {ierr = NRCreate(&__NLList); CHKERR(ierr);}
709*11320018SBarry Smith   NRRegister( __NLList, name, sname, (int (*)(void*))create );
710*11320018SBarry Smith   return 0;
711*11320018SBarry Smith }
712*11320018SBarry Smith /* --------------------------------------------------------------------- */
713*11320018SBarry Smith /*@
714*11320018SBarry Smith    SNESRegisterDestroy - Frees the list of nonlinear solvers that were
715*11320018SBarry Smith    registered by SNESRegister().
716*11320018SBarry Smith 
717*11320018SBarry Smith .keywords: SNES, nonlinear, register, destroy
718*11320018SBarry Smith 
719*11320018SBarry Smith .seealso: SNESRegisterAll(), SNESRegisterAll()
720*11320018SBarry Smith @*/
721*11320018SBarry Smith int SNESRegisterDestroy()
722*11320018SBarry Smith {
723*11320018SBarry Smith   if (__NLList) {
724*11320018SBarry Smith     NRDestroy( __NLList );
725*11320018SBarry Smith     __NLList = 0;
726*11320018SBarry Smith   }
727*11320018SBarry Smith   return 0;
728*11320018SBarry Smith }
729*11320018SBarry Smith #include "options.h"
730*11320018SBarry Smith /*@C
731*11320018SBarry Smith    SNESGetMethodFromOptions - Sets the selected method from the options
732*11320018SBarry Smith    database.
733*11320018SBarry Smith 
734*11320018SBarry Smith    Input parameters:
735*11320018SBarry Smith .  ctx - the SNES context
736*11320018SBarry Smith 
737*11320018SBarry Smith    Output Parameter:
738*11320018SBarry Smith .  method -  solver method
739*11320018SBarry Smith 
740*11320018SBarry Smith    Returns:
741*11320018SBarry Smith    Returns 1 if the method is found; 0 otherwise.
742*11320018SBarry Smith 
743*11320018SBarry Smith    Options Database Key:
744*11320018SBarry Smith $  -snes_method  method
745*11320018SBarry Smith 
746*11320018SBarry Smith .keywords: SNES, nonlinear, options, database, get, method
747*11320018SBarry Smith 
748*11320018SBarry Smith .seealso: SNESGetMethodName()
749*11320018SBarry Smith @*/
750*11320018SBarry Smith int SNESGetMethodFromOptions(SNES ctx,SNESMETHOD *method)
751*11320018SBarry Smith {
752*11320018SBarry Smith   char sbuf[50];
753*11320018SBarry Smith   if (OptionsGetString(0,ctx->prefix,"-snes_method", sbuf, 50 )) {
754*11320018SBarry Smith     if (!__NLList) SNESRegisterAll();
755*11320018SBarry Smith     *method = (SNESMETHOD)NRFindID( __NLList, sbuf );
756*11320018SBarry Smith     return 1;
757*11320018SBarry Smith   }
758*11320018SBarry Smith   return 0;
759*11320018SBarry Smith }
760*11320018SBarry Smith 
761*11320018SBarry Smith /*@C
762*11320018SBarry Smith    SNESGetMethodName - Gets the SNES method name (as a string) from
763*11320018SBarry Smith    the method type.
764*11320018SBarry Smith 
765*11320018SBarry Smith    Input Parameter:
766*11320018SBarry Smith .  method - SNES method
767*11320018SBarry Smith 
768*11320018SBarry Smith    Output Parameter:
769*11320018SBarry Smith .  name - name of SNES method
770*11320018SBarry Smith 
771*11320018SBarry Smith .keywords: SNES, nonlinear, get, method, name
772*11320018SBarry Smith 
773*11320018SBarry Smith .seealso: SNESGetMethodFromOptions()
774*11320018SBarry Smith @*/
775*11320018SBarry Smith int SNESGetMethodName(SNESMETHOD method,char **name)
776*11320018SBarry Smith {
777*11320018SBarry Smith   if (!__NLList) SNESRegisterAll();
778*11320018SBarry Smith   *name = NRFindName( __NLList, (int) method );
779*11320018SBarry Smith   return 0;
780*11320018SBarry Smith }
781*11320018SBarry Smith 
782*11320018SBarry Smith #include <stdio.h>
783*11320018SBarry Smith /*@C
784*11320018SBarry Smith    SNESPrintMethods - Prints the SNES methods available from the options
785*11320018SBarry Smith    database.
786*11320018SBarry Smith 
787*11320018SBarry Smith    Input Parameters:
788*11320018SBarry Smith .  prefix - prefix (usually "-")
789*11320018SBarry Smith .  name - the options database name (by default "snesmethod")
790*11320018SBarry Smith 
791*11320018SBarry Smith .keywords: SNES, nonlinear, print, methods, options, database
792*11320018SBarry Smith 
793*11320018SBarry Smith .seealso: SNESPrintHelp()
794*11320018SBarry Smith @*/
795*11320018SBarry Smith int SNESPrintMethods(char* prefix,char *name)
796*11320018SBarry Smith {
797*11320018SBarry Smith   FuncList *entry;
798*11320018SBarry Smith   if (!__NLList) {SNESRegisterAll();}
799*11320018SBarry Smith   entry = __NLList->head;
800*11320018SBarry Smith   fprintf(stderr," %s%s (one of)",prefix,name);
801*11320018SBarry Smith   while (entry) {
802*11320018SBarry Smith     fprintf(stderr," %s",entry->name);
803*11320018SBarry Smith     entry = entry->next;
804*11320018SBarry Smith   }
805*11320018SBarry Smith   fprintf(stderr,"\n");
806*11320018SBarry Smith   return 0;
807*11320018SBarry Smith }
808*11320018SBarry Smith 
809*11320018SBarry Smith /*@
810*11320018SBarry Smith    SNESGetSolution - Returns the vector where the approximate solution is
811*11320018SBarry Smith    stored.
812*11320018SBarry Smith 
813*11320018SBarry Smith    Input Parameter:
814*11320018SBarry Smith .  snes - the SNES context
815*11320018SBarry Smith 
816*11320018SBarry Smith    Output Parameter:
817*11320018SBarry Smith .  x - the solution
818*11320018SBarry Smith 
819*11320018SBarry Smith .keywords: SNES, nonlinear, get, solution
820*11320018SBarry Smith 
821*11320018SBarry Smith .seealso: SNESSetSolution(), SNESGetFunction()
822*11320018SBarry Smith @*/
823*11320018SBarry Smith int SNESGetSolution(SNES snes,Vec *x)
824*11320018SBarry Smith {
825*11320018SBarry Smith   VALIDHEADER(snes,SNES_COOKIE);
826*11320018SBarry Smith   *x = snes->vec_sol;
827*11320018SBarry Smith   return 0;
828*11320018SBarry Smith }
829*11320018SBarry Smith 
830*11320018SBarry Smith /*@
831*11320018SBarry Smith    SNESGetFunction - Returns the vector where the residual is
832*11320018SBarry Smith    stored.  Actually usually returns the vector where the negative of
833*11320018SBarry Smith    the residual is stored.
834*11320018SBarry Smith 
835*11320018SBarry Smith    Input Parameter:
836*11320018SBarry Smith .  snes - the SNES context
837*11320018SBarry Smith 
838*11320018SBarry Smith    Output Parameter:
839*11320018SBarry Smith .  r - the residual (or its negative)
840*11320018SBarry Smith 
841*11320018SBarry Smith .keywords: SNES, nonlinear, get residual
842*11320018SBarry Smith 
843*11320018SBarry Smith .seealso: SNESSetFunction(), SNESGetSolution()
844*11320018SBarry Smith @*/
845*11320018SBarry Smith int SNESGetFunction(SNES snes,Vec *r)
846*11320018SBarry Smith {
847*11320018SBarry Smith   VALIDHEADER(snes,SNES_COOKIE);
848*11320018SBarry Smith   *r = snes->vec_res;
849*11320018SBarry Smith   return 0;
850*11320018SBarry Smith }
851*11320018SBarry Smith 
852*11320018SBarry Smith 
853*11320018SBarry Smith 
854*11320018SBarry Smith 
855*11320018SBarry Smith 
856*11320018SBarry Smith 
857