xref: /petsc/src/snes/impls/tr/tr.c (revision 523922808279a493230cca24f81c7929a1ea7d92)
14800dd8cSBarry Smith #ifndef lint
2*52392280SLois Curfman McInnes static char vcid[] = "$Id: tr.c,v 1.18 1995/07/21 21:44:58 curfman Exp curfman $";
34800dd8cSBarry Smith #endif
44800dd8cSBarry Smith 
54800dd8cSBarry Smith #include <math.h>
6fbe28522SBarry Smith #include "tr.h"
7a935fc98SLois Curfman McInnes #include "pviewer.h"
84800dd8cSBarry Smith 
9fbe28522SBarry Smith /*
10df60cc22SBarry Smith       This convergence test determines if the two norm of the
11df60cc22SBarry Smith    solution lies outside the trust region, if so it halts.
12df60cc22SBarry Smith */
13df60cc22SBarry Smith int TRConverged_Private(KSP ksp,int n, double rnorm, void *ctx)
14df60cc22SBarry Smith {
15df60cc22SBarry Smith   SNES    snes = (SNES) ctx;
16df60cc22SBarry Smith   SNES_TR *neP = (SNES_TR*)snes->data;
17df60cc22SBarry Smith   double  rtol,atol,dtol,norm;
18df60cc22SBarry Smith   Vec     x;
1925c7317fSLois Curfman McInnes   int     ierr, mkit;
20df60cc22SBarry Smith 
2125c7317fSLois Curfman McInnes   KSPGetTolerances(ksp,&rtol,&atol,&dtol,&mkit);
22df60cc22SBarry Smith 
23df60cc22SBarry Smith   if ( n == 0 ) {
24df60cc22SBarry Smith     neP->ttol   = MAX(rtol*rnorm,atol);
25df60cc22SBarry Smith     neP->rnorm0 = rnorm;
26df60cc22SBarry Smith   }
27df60cc22SBarry Smith   if ( rnorm <= neP->ttol )      return 1;
28df60cc22SBarry Smith   if ( rnorm >= dtol*neP->rnorm0 || rnorm != rnorm) return -1;
29df60cc22SBarry Smith 
30a935fc98SLois Curfman McInnes   /* Determine norm of solution */
3178b31e54SBarry Smith   ierr = KSPBuildSolution(ksp,0,&x); CHKERRQ(ierr);
3278b31e54SBarry Smith   ierr = VecNorm(x,&norm); CHKERRQ(ierr);
33df60cc22SBarry Smith   if (norm >= neP->delta) {
34a935fc98SLois Curfman McInnes     PLogInfo((PetscObject)snes,
35a935fc98SLois Curfman McInnes       "Ending linear iteration early, delta %g length %g\n",neP->delta,norm);
36df60cc22SBarry Smith     return 1;
37df60cc22SBarry Smith   }
38df60cc22SBarry Smith   return(0);
39df60cc22SBarry Smith }
40df60cc22SBarry Smith /*
41ddbbdb52SLois Curfman McInnes    SNESSolve_TR - Implements Newton's Method with a very simple trust
42ddbbdb52SLois Curfman McInnes    region approach for solving systems of nonlinear equations.
434800dd8cSBarry Smith 
444800dd8cSBarry Smith    The basic algorithm is taken from "The Minpack Project", by More',
454800dd8cSBarry Smith    Sorensen, Garbow, Hillstrom, pages 88-111 of "Sources and Development
46ddbbdb52SLois Curfman McInnes    of Mathematical Software", Wayne Cowell, editor.
47ddbbdb52SLois Curfman McInnes 
484800dd8cSBarry Smith    This is intended as a model implementation, since it does not
494800dd8cSBarry Smith    necessarily have many of the bells and whistles of other
504800dd8cSBarry Smith    implementations.
514800dd8cSBarry Smith */
52fbe28522SBarry Smith static int SNESSolve_TR(SNES snes,int *its)
534800dd8cSBarry Smith {
54fbe28522SBarry Smith   SNES_TR      *neP = (SNES_TR *) snes->data;
556b5873e3SBarry Smith   Vec          X, F, Y, G, TMP, Ytmp;
56ddbbdb52SLois Curfman McInnes   int          maxits, i, history_len, ierr, lits;
57df60cc22SBarry Smith   MatStructure flg = ALLMAT_DIFFERENT_NONZERO_PATTERN;
58fbe28522SBarry Smith   double       rho, fnorm, gnorm, gpnorm, xnorm, delta,norm;
594800dd8cSBarry Smith   double       *history, ynorm;
60eafb4bcbSBarry Smith   Scalar       one = 1.0,cnorm;
61df60cc22SBarry Smith   KSP          ksp;
62df60cc22SBarry Smith   SLES         sles;
634800dd8cSBarry Smith 
64fbe28522SBarry Smith   history	= snes->conv_hist;	/* convergence history */
65fbe28522SBarry Smith   history_len	= snes->conv_hist_len;	/* convergence history length */
66fbe28522SBarry Smith   maxits	= snes->max_its;	/* maximum number of iterations */
67fbe28522SBarry Smith   X		= snes->vec_sol;	/* solution vector */
6839e2f89bSBarry Smith   F		= snes->vec_func;	/* residual vector */
69fbe28522SBarry Smith   Y		= snes->work[0];	/* work vectors */
70fbe28522SBarry Smith   G		= snes->work[1];
716b5873e3SBarry Smith   Ytmp          = snes->work[2];
724800dd8cSBarry Smith 
7378b31e54SBarry Smith   ierr = SNESComputeInitialGuess(snes,X); CHKERRQ(ierr);  /* X <- X_0 */
74fbe28522SBarry Smith   VecNorm(X, &xnorm ); 		/* xnorm = || X || */
754800dd8cSBarry Smith 
7678b31e54SBarry Smith   ierr = SNESComputeFunction(snes,X,F); CHKERRQ(ierr); /* (+/-) F(X) */
77fbe28522SBarry Smith   VecNorm(F, &fnorm );		/* fnorm <- || F || */
78fbe28522SBarry Smith   snes->norm = fnorm;
794800dd8cSBarry Smith   if (history && history_len > 0) history[0] = fnorm;
804800dd8cSBarry Smith   delta = neP->delta0*fnorm;
814800dd8cSBarry Smith   neP->delta = delta;
82bbb6d6a8SBarry Smith   if (snes->monitor)
83bbb6d6a8SBarry Smith     {ierr = (*snes->monitor)(snes,0,fnorm,snes->monP); CHKERRQ(ierr);}
844800dd8cSBarry Smith 
85a935fc98SLois Curfman McInnes   /* Set the stopping criteria to use the More' trick. */
8678b31e54SBarry Smith   ierr = SNESGetSLES(snes,&sles); CHKERRQ(ierr);
8778b31e54SBarry Smith   ierr = SLESGetKSP(sles,&ksp); CHKERRQ(ierr);
88df60cc22SBarry Smith   ierr = KSPSetConvergenceTest(ksp,TRConverged_Private,(void *) snes);
8978b31e54SBarry Smith   CHKERRQ(ierr);
90df60cc22SBarry Smith 
914800dd8cSBarry Smith   for ( i=0; i<maxits; i++ ) {
92fbe28522SBarry Smith      snes->iter = i+1;
93df60cc22SBarry Smith      ierr = SNESComputeJacobian(snes,X,&snes->jacobian,&snes->jacobian_pre,
94bbb6d6a8SBarry Smith                                              &flg); CHKERRQ(ierr);
95a935fc98SLois Curfman McInnes      ierr = SLESSetOperators(snes->sles,snes->jacobian,snes->jacobian_pre,
96a935fc98SLois Curfman McInnes                             flg); CHKERRQ(ierr);
9778b31e54SBarry Smith      ierr = SLESSolve(snes->sles,F,Ytmp,&lits); CHKERRQ(ierr);
986b5873e3SBarry Smith      VecNorm( Ytmp, &norm );
996b5873e3SBarry Smith      while(1) {
1006b5873e3SBarry Smith        VecCopy(Ytmp,Y);
101fbe28522SBarry Smith        /* Scale Y if need be and predict new value of F norm */
1026b5873e3SBarry Smith 
103eafb4bcbSBarry Smith        if (norm >= delta) {
104fbe28522SBarry Smith          norm = delta/norm;
105fbe28522SBarry Smith          gpnorm = (1.0 - norm)*fnorm;
106eafb4bcbSBarry Smith          cnorm = norm;
107df60cc22SBarry Smith          PLogInfo((PetscObject)snes, "Scaling direction by %g \n",norm );
108eafb4bcbSBarry Smith          VecScale( &cnorm, Y );
109eafb4bcbSBarry Smith          norm = gpnorm;
110fbe28522SBarry Smith          ynorm = delta;
111fbe28522SBarry Smith        } else {
112fbe28522SBarry Smith          gpnorm = 0.0;
113fbe28522SBarry Smith          PLogInfo((PetscObject)snes,"Direction is in Trust Region \n" );
114fbe28522SBarry Smith          ynorm = norm;
115fbe28522SBarry Smith        }
116fbe28522SBarry Smith        VecAXPY(&one, X, Y );	/* Y <- X + Y */
11781b6cf68SLois Curfman McInnes        ierr = VecCopy(X,snes->vec_sol_update_always); CHKERRQ(ierr);
11878b31e54SBarry Smith        ierr = SNESComputeFunction(snes,Y,G); CHKERRQ(ierr); /* (+/-) F(X) */
119fbe28522SBarry Smith        VecNorm( G, &gnorm );	/* gnorm <- || g || */
1204800dd8cSBarry Smith        if (fnorm == gpnorm) rho = 0.0;
121fbe28522SBarry Smith        else rho = (fnorm*fnorm - gnorm*gnorm)/(fnorm*fnorm - gpnorm*gpnorm);
1224800dd8cSBarry Smith 
1234800dd8cSBarry Smith        /* Update size of trust region */
1244800dd8cSBarry Smith        if      (rho < neP->mu)  delta *= neP->delta1;
1254800dd8cSBarry Smith        else if (rho < neP->eta) delta *= neP->delta2;
1264800dd8cSBarry Smith        else                     delta *= neP->delta3;
1274800dd8cSBarry Smith 
128fbe28522SBarry Smith        PLogInfo((PetscObject)snes,"%d:  f_norm=%g, g_norm=%g, ynorm=%g\n",
1294800dd8cSBarry Smith                                              i, fnorm, gnorm, ynorm );
130fbe28522SBarry Smith        PLogInfo((PetscObject)snes,"gpred=%g, rho=%g, delta=%g,iters=%d\n",
131fbe28522SBarry Smith                                                gpnorm, rho, delta, lits);
1324800dd8cSBarry Smith 
1334800dd8cSBarry Smith        neP->delta = delta;
1344800dd8cSBarry Smith        if (rho > neP->sigma) break;
135eafb4bcbSBarry Smith        PLogInfo((PetscObject)snes,"Trying again in smaller region\n");
1366b5873e3SBarry Smith        /* check to see if progress is hopeless */
137*52392280SLois Curfman McInnes        neP->itflag = 0;
138*52392280SLois Curfman McInnes        if ((*snes->converged)(snes,xnorm,ynorm,fnorm,snes->cnvP)) {
139*52392280SLois Curfman McInnes          /* We're not progressing, so return with the current iterate */
140*52392280SLois Curfman McInnes          if (X != snes->vec_sol) {
141*52392280SLois Curfman McInnes            VecCopy(X,snes->vec_sol);
142*52392280SLois Curfman McInnes            snes->vec_sol_always = snes->vec_sol;
143*52392280SLois Curfman McInnes            snes->vec_func_always = snes->vec_func;
144*52392280SLois Curfman McInnes          }
145*52392280SLois Curfman McInnes        }
146*52392280SLois Curfman McInnes        snes->nfailures++;
1474800dd8cSBarry Smith      }
1484800dd8cSBarry Smith      fnorm = gnorm;
149fbe28522SBarry Smith      snes->norm = fnorm;
1504800dd8cSBarry Smith      if (history && history_len > i+1) history[i+1] = fnorm;
15139e2f89bSBarry Smith      TMP = F; F = G; snes->vec_func_always = F; G = TMP;
15239e2f89bSBarry Smith      TMP = X; X = Y; snes->vec_sol_always = X; Y = TMP;
153fbe28522SBarry Smith      VecNorm(X, &xnorm );		/* xnorm = || X || */
154bbb6d6a8SBarry Smith      if (snes->monitor)
155bbb6d6a8SBarry Smith        {(*snes->monitor)(snes,i+1,fnorm,snes->monP); CHKERRQ(ierr);}
1564800dd8cSBarry Smith 
1574800dd8cSBarry Smith      /* Test for convergence */
158*52392280SLois Curfman McInnes      neP->itflag = 1;
159bbb6d6a8SBarry Smith      if ((*snes->converged)( snes, xnorm, ynorm, fnorm,snes->cnvP )) {
1604800dd8cSBarry Smith        /* Verify solution is in corect location */
16139e2f89bSBarry Smith        if (X != snes->vec_sol) {
16239e2f89bSBarry Smith          VecCopy(X,snes->vec_sol);
16339e2f89bSBarry Smith          snes->vec_sol_always = snes->vec_sol;
16439e2f89bSBarry Smith          snes->vec_func_always = snes->vec_func;
16539e2f89bSBarry Smith        }
1664800dd8cSBarry Smith        break;
1674800dd8cSBarry Smith      }
1684800dd8cSBarry Smith    }
169*52392280SLois Curfman McInnes   if (i == maxits) {
170*52392280SLois Curfman McInnes     PLogInfo((PetscObject)snes,
171*52392280SLois Curfman McInnes       "Maximum number of iterations has been reached: %d\n",maxits);
172*52392280SLois Curfman McInnes     i--;
173*52392280SLois Curfman McInnes   }
174*52392280SLois Curfman McInnes   *its = i+1;
175fbe28522SBarry Smith   return 0;
1764800dd8cSBarry Smith }
1774800dd8cSBarry Smith /*------------------------------------------------------------*/
178fbe28522SBarry Smith static int SNESSetUp_TR( SNES snes )
1794800dd8cSBarry Smith {
180fbe28522SBarry Smith   int ierr;
18181b6cf68SLois Curfman McInnes   snes->nwork = 4;
18278b31e54SBarry Smith   ierr = VecGetVecs(snes->vec_sol,snes->nwork,&snes->work ); CHKERRQ(ierr);
18381b6cf68SLois Curfman McInnes   snes->vec_sol_update_always = snes->work[3];
184fbe28522SBarry Smith   return 0;
1854800dd8cSBarry Smith }
1864800dd8cSBarry Smith /*------------------------------------------------------------*/
187fbe28522SBarry Smith static int SNESDestroy_TR(PetscObject obj )
1884800dd8cSBarry Smith {
189fbe28522SBarry Smith   SNES snes = (SNES) obj;
190fbe28522SBarry Smith   VecFreeVecs(snes->work, snes->nwork );
19178b31e54SBarry Smith   PETSCFREE(snes->data);
192fbe28522SBarry Smith   return 0;
1934800dd8cSBarry Smith }
1944800dd8cSBarry Smith /*------------------------------------------------------------*/
1954800dd8cSBarry Smith 
196fbe28522SBarry Smith static int SNESSetFromOptions_TR(SNES snes)
1974800dd8cSBarry Smith {
198fbe28522SBarry Smith   SNES_TR *ctx = (SNES_TR *)snes->data;
199fbe28522SBarry Smith   double  tmp;
2004800dd8cSBarry Smith 
201df60cc22SBarry Smith   if (OptionsGetDouble(snes->prefix,"-mu",&tmp)) {ctx->mu = tmp;}
202df60cc22SBarry Smith   if (OptionsGetDouble(snes->prefix,"-eta",&tmp)) {ctx->eta = tmp;}
203df60cc22SBarry Smith   if (OptionsGetDouble(snes->prefix,"-sigma",&tmp)) {ctx->sigma = tmp;}
204df60cc22SBarry Smith   if (OptionsGetDouble(snes->prefix,"-delta0",&tmp)) {ctx->delta0 = tmp;}
205df60cc22SBarry Smith   if (OptionsGetDouble(snes->prefix,"-delta1",&tmp)) {ctx->delta1 = tmp;}
206df60cc22SBarry Smith   if (OptionsGetDouble(snes->prefix,"-delta2",&tmp)) {ctx->delta2 = tmp;}
207df60cc22SBarry Smith   if (OptionsGetDouble(snes->prefix,"-delta3",&tmp)) {ctx->delta3 = tmp;}
208fbe28522SBarry Smith   return 0;
2094800dd8cSBarry Smith }
2104800dd8cSBarry Smith 
211fbe28522SBarry Smith static int SNESPrintHelp_TR(SNES snes)
2124800dd8cSBarry Smith {
213fbe28522SBarry Smith   SNES_TR *ctx = (SNES_TR *)snes->data;
214*52392280SLois Curfman McInnes   char    *p;
215*52392280SLois Curfman McInnes   if (snes->prefix) p = snes->prefix; else p = "-";
216*52392280SLois Curfman McInnes   MPIU_fprintf(snes->comm,stdout," method tr (system of nonlinear equations):\n");
217*52392280SLois Curfman McInnes   MPIU_fprintf(snes->comm,stdout,"   %ssnes_trust_region_mu mu (default %g)\n",p,ctx->mu);
218*52392280SLois Curfman McInnes   MPIU_fprintf(snes->comm,stdout,"   %ssnes_trust_region_eta eta (default %g)\n",p,ctx->eta);
219*52392280SLois Curfman McInnes   MPIU_fprintf(snes->comm,stdout,"   %ssnes_trust_region_sigma sigma (default %g)\n",p,ctx->sigma);
220*52392280SLois Curfman McInnes   MPIU_fprintf(snes->comm,stdout,"   %ssnes_trust_region_delta0 delta0 (default %g)\n",p,ctx->delta0);
221*52392280SLois Curfman McInnes   MPIU_fprintf(snes->comm,stdout,"   %ssnes_trust_region_delta1 delta1 (default %g)\n",p,ctx->delta1);
222*52392280SLois Curfman McInnes   MPIU_fprintf(snes->comm,stdout,"   %ssnes_trust_region_delta2 delta2 (default %g)\n",p,ctx->delta2);
223*52392280SLois Curfman McInnes   MPIU_fprintf(snes->comm,stdout,"   %ssnes_trust_region_delta3 delta3 (default %g)\n",p,ctx->delta3);
224fbe28522SBarry Smith   return 0;
2254800dd8cSBarry Smith }
2264800dd8cSBarry Smith 
227a935fc98SLois Curfman McInnes static int SNESView_TR(PetscObject obj,Viewer viewer)
228a935fc98SLois Curfman McInnes {
229a935fc98SLois Curfman McInnes   SNES    snes = (SNES)obj;
230a935fc98SLois Curfman McInnes   SNES_TR *tr = (SNES_TR *)snes->data;
231a935fc98SLois Curfman McInnes   FILE    *fd = ViewerFileGetPointer_Private(viewer);
232a935fc98SLois Curfman McInnes 
233a935fc98SLois Curfman McInnes   MPIU_fprintf(snes->comm,fd,"    mu=%g, eta=%g, sigma=%g\n",
234a935fc98SLois Curfman McInnes     tr->mu,tr->eta,tr->sigma);
235a935fc98SLois Curfman McInnes   MPIU_fprintf(snes->comm,fd,
236a935fc98SLois Curfman McInnes     "    delta0=%g, delta1=%g, delta2=%g, delta3=%g\n",
237a935fc98SLois Curfman McInnes     tr->delta0,tr->delta1,tr->delta2,tr->delta3);
238a935fc98SLois Curfman McInnes   return 0;
239a935fc98SLois Curfman McInnes }
240a935fc98SLois Curfman McInnes 
241*52392280SLois Curfman McInnes /* ---------------------------------------------------------------- */
242*52392280SLois Curfman McInnes /*@
243*52392280SLois Curfman McInnes    SNESTrustRegionDefaultConverged - Default test for monitoring the
244*52392280SLois Curfman McInnes    convergence of the trust region method SNES_EQ_TR for solving systems
245*52392280SLois Curfman McInnes    of nonlinear equations.
246*52392280SLois Curfman McInnes 
247*52392280SLois Curfman McInnes    Input Parameters:
248*52392280SLois Curfman McInnes .  snes - the SNES context
249*52392280SLois Curfman McInnes .  xnorm - 2-norm of current iterate
250*52392280SLois Curfman McInnes .  pnorm - 2-norm of current step
251*52392280SLois Curfman McInnes .  fnorm - 2-norm of function
252*52392280SLois Curfman McInnes .  dummy - unused context
253*52392280SLois Curfman McInnes 
254*52392280SLois Curfman McInnes    Returns:
255*52392280SLois Curfman McInnes $  1  if  ( delta < xnorm*deltatol ),
256*52392280SLois Curfman McInnes $  2  if  ( fnorm < atol ),
257*52392280SLois Curfman McInnes $  3  if  ( pnorm < xtol*xnorm ),
258*52392280SLois Curfman McInnes $ -2  if  ( nfct > maxf ),
259*52392280SLois Curfman McInnes $ -1  if  ( delta < xnorm*epsmch ),
260*52392280SLois Curfman McInnes $  0  otherwise,
261*52392280SLois Curfman McInnes 
262*52392280SLois Curfman McInnes    where
263*52392280SLois Curfman McInnes $    delta    - trust region paramenter
264*52392280SLois Curfman McInnes $    deltatol - trust region size tolerance,
265*52392280SLois Curfman McInnes $               set with SNESSetTrustRegionTolerance()
266*52392280SLois Curfman McInnes $    maxf - maximum number of function evaluations,
267*52392280SLois Curfman McInnes $           set with SNESSetMaxFunctionEvaluations()
268*52392280SLois Curfman McInnes $    nfct - number of function evaluations,
269*52392280SLois Curfman McInnes $    atol - absolute function norm tolerance,
270*52392280SLois Curfman McInnes $           set with SNESSetAbsoluteTolerance()
271*52392280SLois Curfman McInnes $    xtol - relative function norm tolerance,
272*52392280SLois Curfman McInnes $           set with SNESSetRelativeTolerance()
273*52392280SLois Curfman McInnes 
274*52392280SLois Curfman McInnes .keywords: SNES, nonlinear, default, converged, convergence
275*52392280SLois Curfman McInnes 
276*52392280SLois Curfman McInnes .seealso: SNESSetConvergenceTest(), SNESEisenstatWalkerConverged()
277*52392280SLois Curfman McInnes @*/
278*52392280SLois Curfman McInnes int SNESTrustRegionDefaultConverged(SNES snes,double xnorm,double pnorm,
279*52392280SLois Curfman McInnes                          double fnorm,void *dummy)
280*52392280SLois Curfman McInnes {
281*52392280SLois Curfman McInnes   SNES_TR *neP = (SNES_TR *)snes->data;
282*52392280SLois Curfman McInnes   double  epsmch = 1.0e-14;   /* This must be fixed */
283*52392280SLois Curfman McInnes   int     info;
284*52392280SLois Curfman McInnes   if (snes->method_class != SNES_NONLINEAR_EQUATIONS) SETERRQ(1,
285*52392280SLois Curfman McInnes     "SNESDefaultConverged:For SNES_NONLINEAR_EQUATIONS method only");
286*52392280SLois Curfman McInnes 
287*52392280SLois Curfman McInnes   if (neP->delta < xnorm * snes->deltatol) {
288*52392280SLois Curfman McInnes     PLogInfo((PetscObject)snes,
289*52392280SLois Curfman McInnes       "SNES: Converged due to trust region param %g < %g * %g\n",neP->delta,
290*52392280SLois Curfman McInnes        xnorm, snes->deltatol);
291*52392280SLois Curfman McInnes     return 1;
292*52392280SLois Curfman McInnes   }
293*52392280SLois Curfman McInnes   if (neP->itflag) {
294*52392280SLois Curfman McInnes     info = SNESDefaultConverged(snes,xnorm,pnorm,fnorm,dummy);
295*52392280SLois Curfman McInnes     if (info) return info;
296*52392280SLois Curfman McInnes   }
297*52392280SLois Curfman McInnes   if (neP->delta < xnorm * epsmch) {
298*52392280SLois Curfman McInnes     PLogInfo((PetscObject)snes,
299*52392280SLois Curfman McInnes       "SNES: Converged due to trust region param %g < %g * %g\n",neP->delta,
300*52392280SLois Curfman McInnes        xnorm, epsmch);
301*52392280SLois Curfman McInnes     return -1;
302*52392280SLois Curfman McInnes   }
303*52392280SLois Curfman McInnes   return 0;
304*52392280SLois Curfman McInnes }
305*52392280SLois Curfman McInnes /* ------------------------------------------------------------ */
306fbe28522SBarry Smith int SNESCreate_TR(SNES snes )
3074800dd8cSBarry Smith {
308fbe28522SBarry Smith   SNES_TR *neP;
3094800dd8cSBarry Smith 
310369a4401SLois Curfman McInnes   if (snes->method_class != SNES_NONLINEAR_EQUATIONS) SETERRQ(1,
311369a4401SLois Curfman McInnes     "SNESCreate_TR: Valid for SNES_NONLINEAR_EQUATIONS problems only");
31225c7317fSLois Curfman McInnes   snes->type 		= SNES_EQ_NTR;
31306be10caSBarry Smith   snes->setup		= SNESSetUp_TR;
31406be10caSBarry Smith   snes->solve		= SNESSolve_TR;
315fbe28522SBarry Smith   snes->destroy		= SNESDestroy_TR;
316*52392280SLois Curfman McInnes   snes->converged	= SNESTrustRegionDefaultConverged;
31706be10caSBarry Smith   snes->printhelp       = SNESPrintHelp_TR;
31806be10caSBarry Smith   snes->setfromoptions  = SNESSetFromOptions_TR;
319a935fc98SLois Curfman McInnes   snes->view            = SNESView_TR;
320fbe28522SBarry Smith 
32178b31e54SBarry Smith   neP			= PETSCNEW(SNES_TR); CHKPTRQ(neP);
322fbe28522SBarry Smith   snes->data	        = (void *) neP;
323fbe28522SBarry Smith   neP->mu		= 0.25;
324fbe28522SBarry Smith   neP->eta		= 0.75;
325fbe28522SBarry Smith   neP->delta		= 0.0;
326fbe28522SBarry Smith   neP->delta0		= 0.2;
327fbe28522SBarry Smith   neP->delta1		= 0.3;
328fbe28522SBarry Smith   neP->delta2		= 0.75;
329fbe28522SBarry Smith   neP->delta3		= 2.0;
330fbe28522SBarry Smith   neP->sigma		= 0.0001;
331fbe28522SBarry Smith   neP->itflag		= 0;
332*52392280SLois Curfman McInnes   neP->rnorm0		= 0;
333*52392280SLois Curfman McInnes   neP->ttol		= 0;
3346b5873e3SBarry Smith   return 0;
3354800dd8cSBarry Smith }
336