xref: /petsc/src/snes/impls/tr/tr.c (revision 4800dd8c79b03118fb3078c62c7fb7be821ad314)
1*4800dd8cSBarry Smith #ifndef lint
2*4800dd8cSBarry Smith static char vcid[] = "$Id: newtr1.c,v 1.8 1995/02/22 00:52:41 curfman Exp $";
3*4800dd8cSBarry Smith #endif
4*4800dd8cSBarry Smith 
5*4800dd8cSBarry Smith #include <math.h>
6*4800dd8cSBarry Smith #include "nonlin/nlall.h"
7*4800dd8cSBarry Smith #include "nonlin/snes/nlepriv.h"
8*4800dd8cSBarry Smith 
9*4800dd8cSBarry Smith /*D
10*4800dd8cSBarry Smith     NLE_NTR1 - Implements Newton's Method with a trust region
11*4800dd8cSBarry Smith     approach for solving systems of nonlinear equations.
12*4800dd8cSBarry Smith 
13*4800dd8cSBarry Smith     Input parameters:
14*4800dd8cSBarry Smith .   nlP - nonlinear context obtained from NLCreate()
15*4800dd8cSBarry Smith 
16*4800dd8cSBarry Smith     Returns:
17*4800dd8cSBarry Smith     Number of global iterations until termination.  The precise type of
18*4800dd8cSBarry Smith     termination can be examined by calling NLGetTerminationType() after
19*4800dd8cSBarry Smith     NLSolve().
20*4800dd8cSBarry Smith 
21*4800dd8cSBarry Smith     Calling sequence:
22*4800dd8cSBarry Smith $   nlP = NLCreate(NLE_NTR1,0)
23*4800dd8cSBarry Smith $   NLCreateDVectors()
24*4800dd8cSBarry Smith $   NLSet***()
25*4800dd8cSBarry Smith $   NLSetUp()
26*4800dd8cSBarry Smith $   NLSolve()
27*4800dd8cSBarry Smith $   NLDestroy()
28*4800dd8cSBarry Smith 
29*4800dd8cSBarry Smith     Notes:
30*4800dd8cSBarry Smith     See NLCreate() and NLSetUp() for information on the definition and
31*4800dd8cSBarry Smith     initialization of the nonlinear solver context.
32*4800dd8cSBarry Smith 
33*4800dd8cSBarry Smith     The basic algorithm is taken from "The Minpack Project", by More',
34*4800dd8cSBarry Smith     Sorensen, Garbow, Hillstrom, pages 88-111 of "Sources and Development
35*4800dd8cSBarry Smith     of Mathematical Software", Wayne Cowell, editor.  See the examples
36*4800dd8cSBarry Smith     in nonlin/examples.
37*4800dd8cSBarry Smith D*/
38*4800dd8cSBarry Smith /*
39*4800dd8cSBarry Smith    This is intended as a model implementation, since it does not
40*4800dd8cSBarry Smith    necessarily have many of the bells and whistles of other
41*4800dd8cSBarry Smith    implementations.
42*4800dd8cSBarry Smith 
43*4800dd8cSBarry Smith    The code is DATA-STRUCTURE NEUTRAL and can be called RECURSIVELY.
44*4800dd8cSBarry Smith    The following context variable is used:
45*4800dd8cSBarry Smith      NLCtx *nlP - The nonlinear solver context, which is created by
46*4800dd8cSBarry Smith                   calling NLCreate(NLE_NTR1).
47*4800dd8cSBarry Smith 
48*4800dd8cSBarry Smith    The step_compute routine must return two values:
49*4800dd8cSBarry Smith      1) ynorm - the norm of the step
50*4800dd8cSBarry Smith      2) gpnorm - the predicted value for the residual norm at the new
51*4800dd8cSBarry Smith         point, assuming a local linearization.  The value is 0 if the
52*4800dd8cSBarry Smith         step lies within the trust region and is > 0 otherwise.
53*4800dd8cSBarry Smith */
54*4800dd8cSBarry Smith int NLENewtonTR1Solve( nlP )
55*4800dd8cSBarry Smith NLCtx *nlP;
56*4800dd8cSBarry Smith {
57*4800dd8cSBarry Smith    NLENewtonTR1Ctx *neP = (NLENewtonTR1Ctx *) nlP->MethodPrivate;
58*4800dd8cSBarry Smith    void            *X, *F, *Y, *G, *TMP;
59*4800dd8cSBarry Smith    int             maxits, i, iters, history_len, nlconv;
60*4800dd8cSBarry Smith    double          rho, fnorm, gnorm, gpnorm, xnorm, delta;
61*4800dd8cSBarry Smith    double          *history, ynorm;
62*4800dd8cSBarry Smith    FILE            *fp = nlP->fp;
63*4800dd8cSBarry Smith    NLMonCore       *mc = &nlP->mon.core;
64*4800dd8cSBarry Smith    VECntx          *vc = NLGetVectorCtx(nlP);
65*4800dd8cSBarry Smith 
66*4800dd8cSBarry Smith    CHKCOOKIEN(nlP,NL_COOKIE);
67*4800dd8cSBarry Smith    nlconv	= 0;			/* convergence monitor */
68*4800dd8cSBarry Smith    history	= nlP->conv_hist;	/* convergence history */
69*4800dd8cSBarry Smith    history_len	= nlP->conv_hist_len;	/* convergence history length */
70*4800dd8cSBarry Smith    maxits	= nlP->max_its;		/* maximum number of iterations */
71*4800dd8cSBarry Smith    X		= nlP->vec_sol;		/* solution vector */
72*4800dd8cSBarry Smith    F		= nlP->vec_rg;		/* residual vector */
73*4800dd8cSBarry Smith    Y		= nlP->work[0];		/* work vectors */
74*4800dd8cSBarry Smith    G		= nlP->work[1];
75*4800dd8cSBarry Smith 
76*4800dd8cSBarry Smith    INITIAL_GUESS( X );			/* X <- X_0 */
77*4800dd8cSBarry Smith    VNORM( vc, X, &xnorm ); 		/* xnorm = || X || */
78*4800dd8cSBarry Smith 
79*4800dd8cSBarry Smith    RESIDUAL( X, F );			/* Evaluate (+/-) F(X) */
80*4800dd8cSBarry Smith    VNORM( vc, F, &fnorm );		/* fnorm <- || F || */
81*4800dd8cSBarry Smith    nlP->norm = fnorm;
82*4800dd8cSBarry Smith    if (history && history_len > 0) history[0] = fnorm;
83*4800dd8cSBarry Smith    delta = neP->delta0*fnorm;
84*4800dd8cSBarry Smith    neP->delta = delta;
85*4800dd8cSBarry Smith    mc->nvectors += 4; mc->nscalars += 3;
86*4800dd8cSBarry Smith    MONITOR( X, F, &fnorm );		/* Monitor progress */
87*4800dd8cSBarry Smith 
88*4800dd8cSBarry Smith    for ( i=0; i<maxits; i++ ) {
89*4800dd8cSBarry Smith        nlP->iter = i+1;
90*4800dd8cSBarry Smith 
91*4800dd8cSBarry Smith        STEP_SETUP( X );			/* Step set-up phase */
92*4800dd8cSBarry Smith        while(1) {
93*4800dd8cSBarry Smith            iters = STEP_COMPUTE( X, F, Y, &fnorm, &delta,
94*4800dd8cSBarry Smith 		   &(nlP->trunctol), &gpnorm, &ynorm, (void *)0 );
95*4800dd8cSBarry Smith 		   CHKERRV(1,-(NL));	/* Step compute phase */
96*4800dd8cSBarry Smith            VAXPY( vc, 1.0, X, Y );	/* Y <- X + Y */
97*4800dd8cSBarry Smith            RESIDUAL( Y, G );		/* Evaluate (+/-) G(Y) */
98*4800dd8cSBarry Smith            VNORM( vc, G, &gnorm );	/* gnorm <- || g || */
99*4800dd8cSBarry Smith            if (fnorm == gpnorm) rho = 0.0;
100*4800dd8cSBarry Smith            else rho = (fnorm*fnorm - gnorm*gnorm)/
101*4800dd8cSBarry Smith                       (fnorm*fnorm - gpnorm*gpnorm);
102*4800dd8cSBarry Smith 
103*4800dd8cSBarry Smith            /* Update size of trust region */
104*4800dd8cSBarry Smith            if      (rho < neP->mu)  delta *= neP->delta1;
105*4800dd8cSBarry Smith            else if (rho < neP->eta) delta *= neP->delta2;
106*4800dd8cSBarry Smith            else                     delta *= neP->delta3;
107*4800dd8cSBarry Smith 
108*4800dd8cSBarry Smith            if (fp) fprintf(fp,"%d:  f=%g, g=%g, ynorm=%g\n",
109*4800dd8cSBarry Smith                    i, fnorm, gnorm, ynorm );
110*4800dd8cSBarry Smith            if (fp) fprintf(fp,"     gpred=%g, rho=%g, delta=%g, iters=%d\n",
111*4800dd8cSBarry Smith                    gpnorm, rho, delta, iters);
112*4800dd8cSBarry Smith 
113*4800dd8cSBarry Smith            neP->delta = delta;
114*4800dd8cSBarry Smith            mc->nvectors += 4; mc->nscalars += 8;
115*4800dd8cSBarry Smith            if (rho > neP->sigma) break;
116*4800dd8cSBarry Smith            neP->itflag = 0;
117*4800dd8cSBarry Smith            if (CONVERGED( &xnorm, &ynorm, &fnorm )) {
118*4800dd8cSBarry Smith               /* We're not progressing, so return with the current iterate */
119*4800dd8cSBarry Smith               if (X != nlP->vec_sol) VCOPY( vc, X, nlP->vec_sol );
120*4800dd8cSBarry Smith               return i;
121*4800dd8cSBarry Smith               }
122*4800dd8cSBarry Smith            nlP->mon.nunsuc++;
123*4800dd8cSBarry Smith            }
124*4800dd8cSBarry Smith        STEP_DESTROY();			/* Step destroy phase */
125*4800dd8cSBarry Smith        fnorm = gnorm;
126*4800dd8cSBarry Smith        nlP->norm = fnorm;
127*4800dd8cSBarry Smith        if (history && history_len > i+1) history[i+1] = fnorm;
128*4800dd8cSBarry Smith        TMP = F; F = G; G = TMP;
129*4800dd8cSBarry Smith        TMP = X; X = Y; Y = TMP;
130*4800dd8cSBarry Smith        VNORM( vc, X, &xnorm );		/* xnorm = || X || */
131*4800dd8cSBarry Smith        mc->nvectors += 2;
132*4800dd8cSBarry Smith        mc->nscalars++;
133*4800dd8cSBarry Smith        MONITOR( X, F, &fnorm );		/* Monitor progress */
134*4800dd8cSBarry Smith 
135*4800dd8cSBarry Smith        /* Test for convergence */
136*4800dd8cSBarry Smith        neP->itflag = 1;
137*4800dd8cSBarry Smith        if (CONVERGED( &xnorm, &ynorm, &fnorm )) {
138*4800dd8cSBarry Smith            /* Verify solution is in corect location */
139*4800dd8cSBarry Smith            if (X != nlP->vec_sol) VCOPY( vc, X, nlP->vec_sol );
140*4800dd8cSBarry Smith            break;
141*4800dd8cSBarry Smith            }
142*4800dd8cSBarry Smith        }
143*4800dd8cSBarry Smith    if (i == maxits) i--;
144*4800dd8cSBarry Smith    return i+1;
145*4800dd8cSBarry Smith }
146*4800dd8cSBarry Smith /* -------------------------------------------------------------*/
147*4800dd8cSBarry Smith void NLENewtonTR1Create( nlP )
148*4800dd8cSBarry Smith NLCtx *nlP;
149*4800dd8cSBarry Smith {
150*4800dd8cSBarry Smith   NLENewtonTR1Ctx *neP;
151*4800dd8cSBarry Smith 
152*4800dd8cSBarry Smith   CHKCOOKIE(nlP,NL_COOKIE);
153*4800dd8cSBarry Smith   nlP->method		= NLE_NTR1;
154*4800dd8cSBarry Smith   nlP->method_type	= NLE;
155*4800dd8cSBarry Smith   nlP->setup		= NLENewtonTR1SetUp;
156*4800dd8cSBarry Smith   nlP->solver		= NLENewtonTR1Solve;
157*4800dd8cSBarry Smith   nlP->destroy		= NLENewtonTR1Destroy;
158*4800dd8cSBarry Smith   nlP->set_param	= NLENewtonTR1SetParameter;
159*4800dd8cSBarry Smith   nlP->get_param	= NLENewtonTR1GetParameter;
160*4800dd8cSBarry Smith   nlP->usr_monitor	= NLENewtonDefaultMonitor;
161*4800dd8cSBarry Smith   nlP->converged	= NLENewtonTR1DefaultConverged;
162*4800dd8cSBarry Smith   nlP->term_type	= NLENewtonTR1DefaultConvergedType;
163*4800dd8cSBarry Smith 
164*4800dd8cSBarry Smith   neP			= NEW(NLENewtonTR1Ctx); CHKPTR(neP);
165*4800dd8cSBarry Smith   nlP->MethodPrivate	= (void *) neP;
166*4800dd8cSBarry Smith   neP->mu		= 0.25;
167*4800dd8cSBarry Smith   neP->eta		= 0.75;
168*4800dd8cSBarry Smith   neP->delta		= 0.0;
169*4800dd8cSBarry Smith   neP->delta0		= 0.2;
170*4800dd8cSBarry Smith   neP->delta1		= 0.3;
171*4800dd8cSBarry Smith   neP->delta2		= 0.75;
172*4800dd8cSBarry Smith   neP->delta3		= 2.0;
173*4800dd8cSBarry Smith   neP->sigma		= 0.0001;
174*4800dd8cSBarry Smith   neP->itflag		= 0;
175*4800dd8cSBarry Smith }
176*4800dd8cSBarry Smith /*------------------------------------------------------------*/
177*4800dd8cSBarry Smith /*ARGSUSED*/
178*4800dd8cSBarry Smith void  NLENewtonTR1SetUp( nlP )
179*4800dd8cSBarry Smith NLCtx *nlP;
180*4800dd8cSBarry Smith {
181*4800dd8cSBarry Smith   CHKCOOKIE(nlP,NL_COOKIE);
182*4800dd8cSBarry Smith   nlP->nwork = 2;
183*4800dd8cSBarry Smith   nlP->work = VGETVECS( nlP->vc, nlP->nwork );	CHKPTR(nlP->work);
184*4800dd8cSBarry Smith   NLiBasicSetUp( nlP, "NLENewtonTR1SetUp" );	CHKERR(1);
185*4800dd8cSBarry Smith }
186*4800dd8cSBarry Smith /*------------------------------------------------------------*/
187*4800dd8cSBarry Smith /*ARGSUSED*/
188*4800dd8cSBarry Smith void NLENewtonTR1Destroy( nlP )
189*4800dd8cSBarry Smith NLCtx *nlP;
190*4800dd8cSBarry Smith {
191*4800dd8cSBarry Smith   CHKCOOKIE(nlP,NL_COOKIE);
192*4800dd8cSBarry Smith   VFREEVECS( nlP->vc, nlP->work, nlP->nwork );
193*4800dd8cSBarry Smith   NLiBasicDestroy( nlP );	CHKERR(1);
194*4800dd8cSBarry Smith }
195*4800dd8cSBarry Smith /*------------------------------------------------------------*/
196*4800dd8cSBarry Smith /*ARGSUSED*/
197*4800dd8cSBarry Smith /*@
198*4800dd8cSBarry Smith    NLENewtonTR1DefaultConverged - Default test for monitoring the
199*4800dd8cSBarry Smith    convergence of the method NLENewtonTR1Solve.
200*4800dd8cSBarry Smith 
201*4800dd8cSBarry Smith    Input Parameters:
202*4800dd8cSBarry Smith .  nlP - nonlinear context obtained from NLCreate()
203*4800dd8cSBarry Smith .  xnorm - 2-norm of current iterate
204*4800dd8cSBarry Smith .  pnorm - 2-norm of current step
205*4800dd8cSBarry Smith .  fnorm - 2-norm of residual
206*4800dd8cSBarry Smith 
207*4800dd8cSBarry Smith    Returns:
208*4800dd8cSBarry Smith $  1  if  ( delta < xnorm*deltatol ),
209*4800dd8cSBarry Smith $  2  if  ( fnorm < atol ),
210*4800dd8cSBarry Smith $  3  if  ( pnorm < xtol*xnorm ),
211*4800dd8cSBarry Smith $ -2  if  ( nres > max_res ),
212*4800dd8cSBarry Smith $ -1  if  ( delta < xnorm*epsmch ),
213*4800dd8cSBarry Smith $  0  otherwise,
214*4800dd8cSBarry Smith 
215*4800dd8cSBarry Smith    where
216*4800dd8cSBarry Smith $    atol     - absolute residual norm tolerance,
217*4800dd8cSBarry Smith $               set with NLSetAbsConvergenceTol()
218*4800dd8cSBarry Smith $    delta    - trust region paramenter
219*4800dd8cSBarry Smith $    deltatol - trust region size tolerance,
220*4800dd8cSBarry Smith $               set with NLSetTrustRegionTol()
221*4800dd8cSBarry Smith $    epsmch   - machine epsilon
222*4800dd8cSBarry Smith $    max_res  - maximum number of residual evaluations,
223*4800dd8cSBarry Smith $               set with NLSetMaxResidualEvaluations()
224*4800dd8cSBarry Smith $    nres     - number of residual evaluations
225*4800dd8cSBarry Smith $    xtol     - relative residual norm tolerance,
226*4800dd8cSBarry Smith $               set with NLSetRelConvergenceTol()
227*4800dd8cSBarry Smith 
228*4800dd8cSBarry Smith    Note:
229*4800dd8cSBarry Smith    Call NLGetConvergenceType() after calling NLSolve() to obtain
230*4800dd8cSBarry Smith    information about the type of termination which occurred for the
231*4800dd8cSBarry Smith    nonlinear solver.
232*4800dd8cSBarry Smith @*/
233*4800dd8cSBarry Smith int NLENewtonTR1DefaultConverged( nlP, xnorm, pnorm, fnorm )
234*4800dd8cSBarry Smith NLCtx  *nlP;
235*4800dd8cSBarry Smith double *xnorm;
236*4800dd8cSBarry Smith double *pnorm;
237*4800dd8cSBarry Smith double *fnorm;
238*4800dd8cSBarry Smith {
239*4800dd8cSBarry Smith   NLENewtonTR1Ctx *neP = (NLENewtonTR1Ctx *)nlP->MethodPrivate;
240*4800dd8cSBarry Smith   double          epsmch = 1.0e-14;   /* This must be fixed */
241*4800dd8cSBarry Smith 
242*4800dd8cSBarry Smith   CHKCOOKIEN(nlP,NL_COOKIE);
243*4800dd8cSBarry Smith   if (nlP->method_type != NLE) {
244*4800dd8cSBarry Smith       SETERRC(1,"Compatible with NLE component only");
245*4800dd8cSBarry Smith       return 0;
246*4800dd8cSBarry Smith       }
247*4800dd8cSBarry Smith   nlP->conv_info = 0;
248*4800dd8cSBarry Smith   if (neP->delta < *xnorm * nlP->deltatol) 	nlP->conv_info = 1;
249*4800dd8cSBarry Smith   if (neP->itflag) {
250*4800dd8cSBarry Smith       if (nlP->conv_info) return nlP->conv_info;
251*4800dd8cSBarry Smith       nlP->conv_info =
252*4800dd8cSBarry Smith           NLENewtonDefaultConverged( nlP, xnorm, pnorm, fnorm );
253*4800dd8cSBarry Smith       }
254*4800dd8cSBarry Smith   if (neP->delta < *xnorm * epsmch)		nlP->conv_info = -1;
255*4800dd8cSBarry Smith   return nlP->conv_info;
256*4800dd8cSBarry Smith }
257*4800dd8cSBarry Smith /*------------------------------------------------------------*/
258*4800dd8cSBarry Smith /*
259*4800dd8cSBarry Smith    NLENewtonTR1DefaultConvergedType - Returns information regarding
260*4800dd8cSBarry Smith    the type of termination which occurred within the
261*4800dd8cSBarry Smith    NLENewtonTR1DefaultConverged() test.
262*4800dd8cSBarry Smith 
263*4800dd8cSBarry Smith    Input Parameter:
264*4800dd8cSBarry Smith .  nlP - nonlinear context obtained from NLCreate()
265*4800dd8cSBarry Smith 
266*4800dd8cSBarry Smith    Returns:
267*4800dd8cSBarry Smith    Character string - message detailing the type of termination which
268*4800dd8cSBarry Smith    occurred.
269*4800dd8cSBarry Smith */
270*4800dd8cSBarry Smith char *NLENewtonTR1DefaultConvergedType( nlP )
271*4800dd8cSBarry Smith NLCtx *nlP;
272*4800dd8cSBarry Smith {
273*4800dd8cSBarry Smith   char *mesg;
274*4800dd8cSBarry Smith 
275*4800dd8cSBarry Smith   CHKCOOKIEN(nlP,NL_COOKIE);
276*4800dd8cSBarry Smith   if ((int)nlP->converged != (int)NLENewtonTR1DefaultConverged) {
277*4800dd8cSBarry Smith      mesg = "Compatible only with NLENewtonTR1DefaultConverged.\n";
278*4800dd8cSBarry Smith      SETERRC(1,"Compatible only with NLENewtonTR1DefaultConverged.");
279*4800dd8cSBarry Smith   } else {
280*4800dd8cSBarry Smith   switch (nlP->conv_info) {
281*4800dd8cSBarry Smith    case 1:
282*4800dd8cSBarry Smith      mesg = "Trust region parameter satisfies the trust region tolerance.\n";
283*4800dd8cSBarry Smith      break;
284*4800dd8cSBarry Smith    case -1:
285*4800dd8cSBarry Smith      mesg = "Machine epsilon tolerance exceeds the trust region parameter.\n";
286*4800dd8cSBarry Smith      break;
287*4800dd8cSBarry Smith    default:
288*4800dd8cSBarry Smith      mesg = NLENewtonDefaultConvergedType( nlP );
289*4800dd8cSBarry Smith   } }
290*4800dd8cSBarry Smith   return mesg;
291*4800dd8cSBarry Smith }
292*4800dd8cSBarry Smith /*------------------------------------------------------------*/
293*4800dd8cSBarry Smith /*
294*4800dd8cSBarry Smith    NLENewtonTR1SetParameter - Sets a chosen parameter used by the
295*4800dd8cSBarry Smith    NLE_NTR1 method to the desired value.
296*4800dd8cSBarry Smith 
297*4800dd8cSBarry Smith    Note:
298*4800dd8cSBarry Smith    Possible parameters for the NLE_NTR1 method are
299*4800dd8cSBarry Smith $       param = "mu" - used to compute trust region parameter
300*4800dd8cSBarry Smith $       param = "eta" - used to compute trust region parameter
301*4800dd8cSBarry Smith $       param = "sigma" - used to determine termination
302*4800dd8cSBarry Smith $       param = "delta0" - used to initialize trust region parameter
303*4800dd8cSBarry Smith $       param = "delta1" - used to compute trust region parameter
304*4800dd8cSBarry Smith $       param = "delta2" - used to compute trust region parameter
305*4800dd8cSBarry Smith $       param = "delta3" - used to compute trust region parameter
306*4800dd8cSBarry Smith */
307*4800dd8cSBarry Smith void NLENewtonTR1SetParameter( nlP, param, value )
308*4800dd8cSBarry Smith NLCtx  *nlP;
309*4800dd8cSBarry Smith char   *param;
310*4800dd8cSBarry Smith double *value;
311*4800dd8cSBarry Smith {
312*4800dd8cSBarry Smith   NLENewtonTR1Ctx *ctx = (NLENewtonTR1Ctx *)nlP->MethodPrivate;
313*4800dd8cSBarry Smith 
314*4800dd8cSBarry Smith   CHKCOOKIE(nlP,NL_COOKIE);
315*4800dd8cSBarry Smith   if (nlP->method != NLE_NTR1) {
316*4800dd8cSBarry Smith       SETERRC(1,"Compatible only with NLE_NTR1 method");
317*4800dd8cSBarry Smith       return;
318*4800dd8cSBarry Smith       }
319*4800dd8cSBarry Smith   if (!strcmp(param,"mu"))		ctx->mu     = *value;
320*4800dd8cSBarry Smith   else if (!strcmp(param,"eta"))	ctx->eta    = *value;
321*4800dd8cSBarry Smith   else if (!strcmp(param,"sigma"))	ctx->sigma  = *value;
322*4800dd8cSBarry Smith   else if (!strcmp(param,"delta0"))	ctx->delta0 = *value;
323*4800dd8cSBarry Smith   else if (!strcmp(param,"delta1"))	ctx->delta1 = *value;
324*4800dd8cSBarry Smith   else if (!strcmp(param,"delta2"))	ctx->delta2 = *value;
325*4800dd8cSBarry Smith   else if (!strcmp(param,"delta3"))	ctx->delta3 = *value;
326*4800dd8cSBarry Smith   else SETERRC(1,"Invalid parameter name for NLE_NTR1");
327*4800dd8cSBarry Smith }
328*4800dd8cSBarry Smith /*------------------------------------------------------------*/
329*4800dd8cSBarry Smith /*
330*4800dd8cSBarry Smith    NLENewtonTR1GetParameter - Returns the value of a chosen parameter
331*4800dd8cSBarry Smith    used by the NLE_NTR1 method.
332*4800dd8cSBarry Smith 
333*4800dd8cSBarry Smith    Note:
334*4800dd8cSBarry Smith    Possible parameters for the NLE_NTR1 method are
335*4800dd8cSBarry Smith $       param = "mu" - used to compute trust region parameter
336*4800dd8cSBarry Smith $       param = "eta" - used to compute trust region parameter
337*4800dd8cSBarry Smith $       param = "sigma" - used to determine termination
338*4800dd8cSBarry Smith $       param = "delta0" - used to initialize trust region parameter
339*4800dd8cSBarry Smith $       param = "delta1" - used to compute trust region parameter
340*4800dd8cSBarry Smith $       param = "delta2" - used to compute trust region parameter
341*4800dd8cSBarry Smith $       param = "delta3" - used to compute trust region parameter
342*4800dd8cSBarry Smith */
343*4800dd8cSBarry Smith double NLENewtonTR1GetParameter( nlP, param )
344*4800dd8cSBarry Smith NLCtx *nlP;
345*4800dd8cSBarry Smith char  *param;
346*4800dd8cSBarry Smith {
347*4800dd8cSBarry Smith   NLENewtonTR1Ctx *ctx = (NLENewtonTR1Ctx *)nlP->MethodPrivate;
348*4800dd8cSBarry Smith   double          value = 0.0;
349*4800dd8cSBarry Smith 
350*4800dd8cSBarry Smith   CHKCOOKIEN(nlP,NL_COOKIE);
351*4800dd8cSBarry Smith   if (nlP->method != NLE_NTR1) {
352*4800dd8cSBarry Smith       SETERRC(1,"Compatible only with NLE_NTR1 method");
353*4800dd8cSBarry Smith       return value;
354*4800dd8cSBarry Smith       }
355*4800dd8cSBarry Smith   if (!strcmp(param,"mu"))		value = ctx->mu;
356*4800dd8cSBarry Smith   else if (!strcmp(param,"eta"))	value = ctx->eta;
357*4800dd8cSBarry Smith   else if (!strcmp(param,"sigma"))	value = ctx->sigma;
358*4800dd8cSBarry Smith   else if (!strcmp(param,"delta0"))	value = ctx->delta0;
359*4800dd8cSBarry Smith   else if (!strcmp(param,"delta1"))	value = ctx->delta1;
360*4800dd8cSBarry Smith   else if (!strcmp(param,"delta2"))	value = ctx->delta2;
361*4800dd8cSBarry Smith   else if (!strcmp(param,"delta3"))	value = ctx->delta3;
362*4800dd8cSBarry Smith   else SETERRC(1,"Invalid parameter name for NLE_NTR1");
363*4800dd8cSBarry Smith   return value;
364*4800dd8cSBarry Smith }
365