xref: /petsc/src/snes/impls/tr/tr.c (revision 98120f8217caf93b542d82ce8a42057870007421)
14800dd8cSBarry Smith #ifndef lint
2*98120f82SLois Curfman McInnes static char vcid[] = "$Id: tr.c,v 1.20 1995/07/29 02:11:02 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 */
139c49e667SLois Curfman McInnes int SNES_TR_KSPConverged_Private(KSP ksp,int n, double rnorm, void *ctx)
14df60cc22SBarry Smith {
15df60cc22SBarry Smith   SNES    snes = (SNES) ctx;
16*98120f82SLois Curfman McInnes   SNES_KSP_EW_ConvCtx *kctx = (SNES_KSP_EW_ConvCtx*)snes->kspconvctx;
17df60cc22SBarry Smith   SNES_TR *neP = (SNES_TR*)snes->data;
18df60cc22SBarry Smith   Vec     x;
19*98120f82SLois Curfman McInnes   double  norm;
20*98120f82SLois Curfman McInnes   int     ierr, convinfo;
21df60cc22SBarry Smith 
22*98120f82SLois Curfman McInnes   if (snes->ksp_ewconv) {
23*98120f82SLois Curfman McInnes     if (!kctx) SETERRQ(1,
24*98120f82SLois Curfman McInnes       "SNES_KSP_EW_Converged_Private: Convergence context does not exist");
25*98120f82SLois Curfman McInnes     if (n == 0) SNES_KSP_EW_ComputeRelativeTolerance_Private(snes,ksp);
26*98120f82SLois Curfman McInnes     kctx->lresid_last = rnorm;
27df60cc22SBarry Smith   }
28*98120f82SLois Curfman McInnes   convinfo = KSPDefaultConverged(ksp,n,rnorm,ctx);
29*98120f82SLois Curfman McInnes   if (convinfo) return convinfo;
30df60cc22SBarry Smith 
31a935fc98SLois Curfman McInnes   /* Determine norm of solution */
3278b31e54SBarry Smith   ierr = KSPBuildSolution(ksp,0,&x); CHKERRQ(ierr);
3378b31e54SBarry Smith   ierr = VecNorm(x,&norm); CHKERRQ(ierr);
34df60cc22SBarry Smith   if (norm >= neP->delta) {
35a935fc98SLois Curfman McInnes     PLogInfo((PetscObject)snes,
36a935fc98SLois Curfman McInnes       "Ending linear iteration early, delta %g length %g\n",neP->delta,norm);
37df60cc22SBarry Smith     return 1;
38df60cc22SBarry Smith   }
39df60cc22SBarry Smith   return(0);
40df60cc22SBarry Smith }
41df60cc22SBarry Smith /*
42ddbbdb52SLois Curfman McInnes    SNESSolve_TR - Implements Newton's Method with a very simple trust
43ddbbdb52SLois Curfman McInnes    region approach for solving systems of nonlinear equations.
444800dd8cSBarry Smith 
454800dd8cSBarry Smith    The basic algorithm is taken from "The Minpack Project", by More',
464800dd8cSBarry Smith    Sorensen, Garbow, Hillstrom, pages 88-111 of "Sources and Development
47ddbbdb52SLois Curfman McInnes    of Mathematical Software", Wayne Cowell, editor.
48ddbbdb52SLois Curfman McInnes 
494800dd8cSBarry Smith    This is intended as a model implementation, since it does not
504800dd8cSBarry Smith    necessarily have many of the bells and whistles of other
514800dd8cSBarry Smith    implementations.
524800dd8cSBarry Smith */
53fbe28522SBarry Smith static int SNESSolve_TR(SNES snes,int *its)
544800dd8cSBarry Smith {
55fbe28522SBarry Smith   SNES_TR      *neP = (SNES_TR *) snes->data;
566b5873e3SBarry Smith   Vec          X, F, Y, G, TMP, Ytmp;
57ddbbdb52SLois Curfman McInnes   int          maxits, i, history_len, ierr, lits;
58df60cc22SBarry Smith   MatStructure flg = ALLMAT_DIFFERENT_NONZERO_PATTERN;
59fbe28522SBarry Smith   double       rho, fnorm, gnorm, gpnorm, xnorm, delta,norm;
604800dd8cSBarry Smith   double       *history, ynorm;
61eafb4bcbSBarry Smith   Scalar       one = 1.0,cnorm;
62df60cc22SBarry Smith   KSP          ksp;
63df60cc22SBarry Smith   SLES         sles;
644800dd8cSBarry Smith 
65fbe28522SBarry Smith   history	= snes->conv_hist;	/* convergence history */
66fbe28522SBarry Smith   history_len	= snes->conv_hist_len;	/* convergence history length */
67fbe28522SBarry Smith   maxits	= snes->max_its;	/* maximum number of iterations */
68fbe28522SBarry Smith   X		= snes->vec_sol;	/* solution vector */
6939e2f89bSBarry Smith   F		= snes->vec_func;	/* residual vector */
70fbe28522SBarry Smith   Y		= snes->work[0];	/* work vectors */
71fbe28522SBarry Smith   G		= snes->work[1];
726b5873e3SBarry Smith   Ytmp          = snes->work[2];
734800dd8cSBarry Smith 
7478b31e54SBarry Smith   ierr = SNESComputeInitialGuess(snes,X); CHKERRQ(ierr);  /* X <- X_0 */
75fbe28522SBarry Smith   VecNorm(X, &xnorm ); 		/* xnorm = || X || */
764800dd8cSBarry Smith 
7778b31e54SBarry Smith   ierr = SNESComputeFunction(snes,X,F); CHKERRQ(ierr); /* (+/-) F(X) */
78fbe28522SBarry Smith   VecNorm(F, &fnorm );		/* fnorm <- || F || */
79fbe28522SBarry Smith   snes->norm = fnorm;
804800dd8cSBarry Smith   if (history && history_len > 0) history[0] = fnorm;
814800dd8cSBarry Smith   delta = neP->delta0*fnorm;
824800dd8cSBarry Smith   neP->delta = delta;
83bbb6d6a8SBarry Smith   if (snes->monitor)
84bbb6d6a8SBarry Smith     {ierr = (*snes->monitor)(snes,0,fnorm,snes->monP); CHKERRQ(ierr);}
854800dd8cSBarry Smith 
86a935fc98SLois Curfman McInnes   /* Set the stopping criteria to use the More' trick. */
8778b31e54SBarry Smith   ierr = SNESGetSLES(snes,&sles); CHKERRQ(ierr);
8878b31e54SBarry Smith   ierr = SLESGetKSP(sles,&ksp); CHKERRQ(ierr);
899c49e667SLois Curfman McInnes   ierr = KSPSetConvergenceTest(ksp,SNES_TR_KSPConverged_Private,(void *)snes);
9078b31e54SBarry Smith   CHKERRQ(ierr);
91df60cc22SBarry Smith 
924800dd8cSBarry Smith   for ( i=0; i<maxits; i++ ) {
93fbe28522SBarry Smith      snes->iter = i+1;
94df60cc22SBarry Smith      ierr = SNESComputeJacobian(snes,X,&snes->jacobian,&snes->jacobian_pre,
95bbb6d6a8SBarry Smith                                              &flg); CHKERRQ(ierr);
96a935fc98SLois Curfman McInnes      ierr = SLESSetOperators(snes->sles,snes->jacobian,snes->jacobian_pre,
97a935fc98SLois Curfman McInnes                             flg); CHKERRQ(ierr);
9878b31e54SBarry Smith      ierr = SLESSolve(snes->sles,F,Ytmp,&lits); CHKERRQ(ierr);
996b5873e3SBarry Smith      VecNorm( Ytmp, &norm );
1006b5873e3SBarry Smith      while(1) {
1016b5873e3SBarry Smith        VecCopy(Ytmp,Y);
102fbe28522SBarry Smith        /* Scale Y if need be and predict new value of F norm */
1036b5873e3SBarry Smith 
104eafb4bcbSBarry Smith        if (norm >= delta) {
105fbe28522SBarry Smith          norm = delta/norm;
106fbe28522SBarry Smith          gpnorm = (1.0 - norm)*fnorm;
107eafb4bcbSBarry Smith          cnorm = norm;
108df60cc22SBarry Smith          PLogInfo((PetscObject)snes, "Scaling direction by %g \n",norm );
109eafb4bcbSBarry Smith          VecScale( &cnorm, Y );
110eafb4bcbSBarry Smith          norm = gpnorm;
111fbe28522SBarry Smith          ynorm = delta;
112fbe28522SBarry Smith        } else {
113fbe28522SBarry Smith          gpnorm = 0.0;
114fbe28522SBarry Smith          PLogInfo((PetscObject)snes,"Direction is in Trust Region \n" );
115fbe28522SBarry Smith          ynorm = norm;
116fbe28522SBarry Smith        }
117fbe28522SBarry Smith        VecAXPY(&one, X, Y );	/* Y <- X + Y */
11881b6cf68SLois Curfman McInnes        ierr = VecCopy(X,snes->vec_sol_update_always); CHKERRQ(ierr);
11978b31e54SBarry Smith        ierr = SNESComputeFunction(snes,Y,G); CHKERRQ(ierr); /* (+/-) F(X) */
120fbe28522SBarry Smith        VecNorm( G, &gnorm );	/* gnorm <- || g || */
1214800dd8cSBarry Smith        if (fnorm == gpnorm) rho = 0.0;
122fbe28522SBarry Smith        else rho = (fnorm*fnorm - gnorm*gnorm)/(fnorm*fnorm - gpnorm*gpnorm);
1234800dd8cSBarry Smith 
1244800dd8cSBarry Smith        /* Update size of trust region */
1254800dd8cSBarry Smith        if      (rho < neP->mu)  delta *= neP->delta1;
1264800dd8cSBarry Smith        else if (rho < neP->eta) delta *= neP->delta2;
1274800dd8cSBarry Smith        else                     delta *= neP->delta3;
1284800dd8cSBarry Smith 
129fbe28522SBarry Smith        PLogInfo((PetscObject)snes,"%d:  f_norm=%g, g_norm=%g, ynorm=%g\n",
1304800dd8cSBarry Smith                                              i, fnorm, gnorm, ynorm );
131fbe28522SBarry Smith        PLogInfo((PetscObject)snes,"gpred=%g, rho=%g, delta=%g,iters=%d\n",
132fbe28522SBarry Smith                                                gpnorm, rho, delta, lits);
1334800dd8cSBarry Smith 
1344800dd8cSBarry Smith        neP->delta = delta;
1354800dd8cSBarry Smith        if (rho > neP->sigma) break;
136eafb4bcbSBarry Smith        PLogInfo((PetscObject)snes,"Trying again in smaller region\n");
1376b5873e3SBarry Smith        /* check to see if progress is hopeless */
13852392280SLois Curfman McInnes        neP->itflag = 0;
13952392280SLois Curfman McInnes        if ((*snes->converged)(snes,xnorm,ynorm,fnorm,snes->cnvP)) {
14052392280SLois Curfman McInnes          /* We're not progressing, so return with the current iterate */
14152392280SLois Curfman McInnes          if (X != snes->vec_sol) {
14252392280SLois Curfman McInnes            VecCopy(X,snes->vec_sol);
14352392280SLois Curfman McInnes            snes->vec_sol_always = snes->vec_sol;
14452392280SLois Curfman McInnes            snes->vec_func_always = snes->vec_func;
14552392280SLois Curfman McInnes          }
14652392280SLois Curfman McInnes        }
14752392280SLois Curfman McInnes        snes->nfailures++;
1484800dd8cSBarry Smith      }
1494800dd8cSBarry Smith      fnorm = gnorm;
150fbe28522SBarry Smith      snes->norm = fnorm;
1514800dd8cSBarry Smith      if (history && history_len > i+1) history[i+1] = fnorm;
15239e2f89bSBarry Smith      TMP = F; F = G; snes->vec_func_always = F; G = TMP;
15339e2f89bSBarry Smith      TMP = X; X = Y; snes->vec_sol_always = X; Y = TMP;
154fbe28522SBarry Smith      VecNorm(X, &xnorm );		/* xnorm = || X || */
155bbb6d6a8SBarry Smith      if (snes->monitor)
156bbb6d6a8SBarry Smith        {(*snes->monitor)(snes,i+1,fnorm,snes->monP); CHKERRQ(ierr);}
1574800dd8cSBarry Smith 
1584800dd8cSBarry Smith      /* Test for convergence */
15952392280SLois Curfman McInnes      neP->itflag = 1;
160bbb6d6a8SBarry Smith      if ((*snes->converged)( snes, xnorm, ynorm, fnorm,snes->cnvP )) {
1614800dd8cSBarry Smith        /* Verify solution is in corect location */
16239e2f89bSBarry Smith        if (X != snes->vec_sol) {
16339e2f89bSBarry Smith          VecCopy(X,snes->vec_sol);
16439e2f89bSBarry Smith          snes->vec_sol_always = snes->vec_sol;
16539e2f89bSBarry Smith          snes->vec_func_always = snes->vec_func;
16639e2f89bSBarry Smith        }
1674800dd8cSBarry Smith        break;
1684800dd8cSBarry Smith      }
1694800dd8cSBarry Smith    }
17052392280SLois Curfman McInnes   if (i == maxits) {
17152392280SLois Curfman McInnes     PLogInfo((PetscObject)snes,
17252392280SLois Curfman McInnes       "Maximum number of iterations has been reached: %d\n",maxits);
17352392280SLois Curfman McInnes     i--;
17452392280SLois Curfman McInnes   }
17552392280SLois Curfman McInnes   *its = i+1;
176fbe28522SBarry Smith   return 0;
1774800dd8cSBarry Smith }
1784800dd8cSBarry Smith /*------------------------------------------------------------*/
179fbe28522SBarry Smith static int SNESSetUp_TR( SNES snes )
1804800dd8cSBarry Smith {
181fbe28522SBarry Smith   int ierr;
18281b6cf68SLois Curfman McInnes   snes->nwork = 4;
18378b31e54SBarry Smith   ierr = VecGetVecs(snes->vec_sol,snes->nwork,&snes->work ); CHKERRQ(ierr);
18481b6cf68SLois Curfman McInnes   snes->vec_sol_update_always = snes->work[3];
185fbe28522SBarry Smith   return 0;
1864800dd8cSBarry Smith }
1874800dd8cSBarry Smith /*------------------------------------------------------------*/
188fbe28522SBarry Smith static int SNESDestroy_TR(PetscObject obj )
1894800dd8cSBarry Smith {
190fbe28522SBarry Smith   SNES snes = (SNES) obj;
191fbe28522SBarry Smith   VecFreeVecs(snes->work, snes->nwork );
19278b31e54SBarry Smith   PETSCFREE(snes->data);
193fbe28522SBarry Smith   return 0;
1944800dd8cSBarry Smith }
1954800dd8cSBarry Smith /*------------------------------------------------------------*/
1964800dd8cSBarry Smith 
197fbe28522SBarry Smith static int SNESSetFromOptions_TR(SNES snes)
1984800dd8cSBarry Smith {
199fbe28522SBarry Smith   SNES_TR *ctx = (SNES_TR *)snes->data;
200fbe28522SBarry Smith   double  tmp;
2014800dd8cSBarry Smith 
202df60cc22SBarry Smith   if (OptionsGetDouble(snes->prefix,"-mu",&tmp)) {ctx->mu = tmp;}
203df60cc22SBarry Smith   if (OptionsGetDouble(snes->prefix,"-eta",&tmp)) {ctx->eta = tmp;}
204df60cc22SBarry Smith   if (OptionsGetDouble(snes->prefix,"-sigma",&tmp)) {ctx->sigma = tmp;}
205df60cc22SBarry Smith   if (OptionsGetDouble(snes->prefix,"-delta0",&tmp)) {ctx->delta0 = tmp;}
206df60cc22SBarry Smith   if (OptionsGetDouble(snes->prefix,"-delta1",&tmp)) {ctx->delta1 = tmp;}
207df60cc22SBarry Smith   if (OptionsGetDouble(snes->prefix,"-delta2",&tmp)) {ctx->delta2 = tmp;}
208df60cc22SBarry Smith   if (OptionsGetDouble(snes->prefix,"-delta3",&tmp)) {ctx->delta3 = tmp;}
209fbe28522SBarry Smith   return 0;
2104800dd8cSBarry Smith }
2114800dd8cSBarry Smith 
212fbe28522SBarry Smith static int SNESPrintHelp_TR(SNES snes)
2134800dd8cSBarry Smith {
214fbe28522SBarry Smith   SNES_TR *ctx = (SNES_TR *)snes->data;
21552392280SLois Curfman McInnes   char    *p;
21652392280SLois Curfman McInnes   if (snes->prefix) p = snes->prefix; else p = "-";
21752392280SLois Curfman McInnes   MPIU_fprintf(snes->comm,stdout," method tr (system of nonlinear equations):\n");
21852392280SLois Curfman McInnes   MPIU_fprintf(snes->comm,stdout,"   %ssnes_trust_region_mu mu (default %g)\n",p,ctx->mu);
21952392280SLois Curfman McInnes   MPIU_fprintf(snes->comm,stdout,"   %ssnes_trust_region_eta eta (default %g)\n",p,ctx->eta);
22052392280SLois Curfman McInnes   MPIU_fprintf(snes->comm,stdout,"   %ssnes_trust_region_sigma sigma (default %g)\n",p,ctx->sigma);
22152392280SLois Curfman McInnes   MPIU_fprintf(snes->comm,stdout,"   %ssnes_trust_region_delta0 delta0 (default %g)\n",p,ctx->delta0);
22252392280SLois Curfman McInnes   MPIU_fprintf(snes->comm,stdout,"   %ssnes_trust_region_delta1 delta1 (default %g)\n",p,ctx->delta1);
22352392280SLois Curfman McInnes   MPIU_fprintf(snes->comm,stdout,"   %ssnes_trust_region_delta2 delta2 (default %g)\n",p,ctx->delta2);
22452392280SLois Curfman McInnes   MPIU_fprintf(snes->comm,stdout,"   %ssnes_trust_region_delta3 delta3 (default %g)\n",p,ctx->delta3);
225fbe28522SBarry Smith   return 0;
2264800dd8cSBarry Smith }
2274800dd8cSBarry Smith 
228a935fc98SLois Curfman McInnes static int SNESView_TR(PetscObject obj,Viewer viewer)
229a935fc98SLois Curfman McInnes {
230a935fc98SLois Curfman McInnes   SNES    snes = (SNES)obj;
231a935fc98SLois Curfman McInnes   SNES_TR *tr = (SNES_TR *)snes->data;
232a935fc98SLois Curfman McInnes   FILE    *fd = ViewerFileGetPointer_Private(viewer);
233a935fc98SLois Curfman McInnes 
234a935fc98SLois Curfman McInnes   MPIU_fprintf(snes->comm,fd,"    mu=%g, eta=%g, sigma=%g\n",
235a935fc98SLois Curfman McInnes     tr->mu,tr->eta,tr->sigma);
236a935fc98SLois Curfman McInnes   MPIU_fprintf(snes->comm,fd,
237a935fc98SLois Curfman McInnes     "    delta0=%g, delta1=%g, delta2=%g, delta3=%g\n",
238a935fc98SLois Curfman McInnes     tr->delta0,tr->delta1,tr->delta2,tr->delta3);
239a935fc98SLois Curfman McInnes   return 0;
240a935fc98SLois Curfman McInnes }
241a935fc98SLois Curfman McInnes 
24252392280SLois Curfman McInnes /* ---------------------------------------------------------------- */
24352392280SLois Curfman McInnes /*@
24452392280SLois Curfman McInnes    SNESTrustRegionDefaultConverged - Default test for monitoring the
24552392280SLois Curfman McInnes    convergence of the trust region method SNES_EQ_TR for solving systems
24652392280SLois Curfman McInnes    of nonlinear equations.
24752392280SLois Curfman McInnes 
24852392280SLois Curfman McInnes    Input Parameters:
24952392280SLois Curfman McInnes .  snes - the SNES context
25052392280SLois Curfman McInnes .  xnorm - 2-norm of current iterate
25152392280SLois Curfman McInnes .  pnorm - 2-norm of current step
25252392280SLois Curfman McInnes .  fnorm - 2-norm of function
25352392280SLois Curfman McInnes .  dummy - unused context
25452392280SLois Curfman McInnes 
25552392280SLois Curfman McInnes    Returns:
25652392280SLois Curfman McInnes $  1  if  ( delta < xnorm*deltatol ),
25752392280SLois Curfman McInnes $  2  if  ( fnorm < atol ),
25852392280SLois Curfman McInnes $  3  if  ( pnorm < xtol*xnorm ),
25952392280SLois Curfman McInnes $ -2  if  ( nfct > maxf ),
26052392280SLois Curfman McInnes $ -1  if  ( delta < xnorm*epsmch ),
26152392280SLois Curfman McInnes $  0  otherwise,
26252392280SLois Curfman McInnes 
26352392280SLois Curfman McInnes    where
26452392280SLois Curfman McInnes $    delta    - trust region paramenter
26552392280SLois Curfman McInnes $    deltatol - trust region size tolerance,
26652392280SLois Curfman McInnes $               set with SNESSetTrustRegionTolerance()
26752392280SLois Curfman McInnes $    maxf - maximum number of function evaluations,
26852392280SLois Curfman McInnes $           set with SNESSetMaxFunctionEvaluations()
26952392280SLois Curfman McInnes $    nfct - number of function evaluations,
27052392280SLois Curfman McInnes $    atol - absolute function norm tolerance,
27152392280SLois Curfman McInnes $           set with SNESSetAbsoluteTolerance()
27252392280SLois Curfman McInnes $    xtol - relative function norm tolerance,
27352392280SLois Curfman McInnes $           set with SNESSetRelativeTolerance()
27452392280SLois Curfman McInnes 
27552392280SLois Curfman McInnes .keywords: SNES, nonlinear, default, converged, convergence
27652392280SLois Curfman McInnes 
27752392280SLois Curfman McInnes .seealso: SNESSetConvergenceTest(), SNESEisenstatWalkerConverged()
27852392280SLois Curfman McInnes @*/
27952392280SLois Curfman McInnes int SNESTrustRegionDefaultConverged(SNES snes,double xnorm,double pnorm,
28052392280SLois Curfman McInnes                          double fnorm,void *dummy)
28152392280SLois Curfman McInnes {
28252392280SLois Curfman McInnes   SNES_TR *neP = (SNES_TR *)snes->data;
28352392280SLois Curfman McInnes   double  epsmch = 1.0e-14;   /* This must be fixed */
28452392280SLois Curfman McInnes   int     info;
28552392280SLois Curfman McInnes   if (snes->method_class != SNES_NONLINEAR_EQUATIONS) SETERRQ(1,
28652392280SLois Curfman McInnes     "SNESDefaultConverged:For SNES_NONLINEAR_EQUATIONS method only");
28752392280SLois Curfman McInnes 
28852392280SLois Curfman McInnes   if (neP->delta < xnorm * snes->deltatol) {
28952392280SLois Curfman McInnes     PLogInfo((PetscObject)snes,
29052392280SLois Curfman McInnes       "SNES: Converged due to trust region param %g < %g * %g\n",neP->delta,
29152392280SLois Curfman McInnes        xnorm, snes->deltatol);
29252392280SLois Curfman McInnes     return 1;
29352392280SLois Curfman McInnes   }
29452392280SLois Curfman McInnes   if (neP->itflag) {
29552392280SLois Curfman McInnes     info = SNESDefaultConverged(snes,xnorm,pnorm,fnorm,dummy);
29652392280SLois Curfman McInnes     if (info) return info;
29752392280SLois Curfman McInnes   }
29852392280SLois Curfman McInnes   if (neP->delta < xnorm * epsmch) {
29952392280SLois Curfman McInnes     PLogInfo((PetscObject)snes,
30052392280SLois Curfman McInnes       "SNES: Converged due to trust region param %g < %g * %g\n",neP->delta,
30152392280SLois Curfman McInnes        xnorm, epsmch);
30252392280SLois Curfman McInnes     return -1;
30352392280SLois Curfman McInnes   }
30452392280SLois Curfman McInnes   return 0;
30552392280SLois Curfman McInnes }
30652392280SLois Curfman McInnes /* ------------------------------------------------------------ */
307fbe28522SBarry Smith int SNESCreate_TR(SNES snes )
3084800dd8cSBarry Smith {
309fbe28522SBarry Smith   SNES_TR *neP;
3104800dd8cSBarry Smith 
311369a4401SLois Curfman McInnes   if (snes->method_class != SNES_NONLINEAR_EQUATIONS) SETERRQ(1,
312369a4401SLois Curfman McInnes     "SNESCreate_TR: Valid for SNES_NONLINEAR_EQUATIONS problems only");
31325c7317fSLois Curfman McInnes   snes->type 		= SNES_EQ_NTR;
31406be10caSBarry Smith   snes->setup		= SNESSetUp_TR;
31506be10caSBarry Smith   snes->solve		= SNESSolve_TR;
316fbe28522SBarry Smith   snes->destroy		= SNESDestroy_TR;
31752392280SLois Curfman McInnes   snes->converged	= SNESTrustRegionDefaultConverged;
31806be10caSBarry Smith   snes->printhelp       = SNESPrintHelp_TR;
31906be10caSBarry Smith   snes->setfromoptions  = SNESSetFromOptions_TR;
320a935fc98SLois Curfman McInnes   snes->view            = SNESView_TR;
321fbe28522SBarry Smith 
32278b31e54SBarry Smith   neP			= PETSCNEW(SNES_TR); CHKPTRQ(neP);
323fbe28522SBarry Smith   snes->data	        = (void *) neP;
324fbe28522SBarry Smith   neP->mu		= 0.25;
325fbe28522SBarry Smith   neP->eta		= 0.75;
326fbe28522SBarry Smith   neP->delta		= 0.0;
327fbe28522SBarry Smith   neP->delta0		= 0.2;
328fbe28522SBarry Smith   neP->delta1		= 0.3;
329fbe28522SBarry Smith   neP->delta2		= 0.75;
330fbe28522SBarry Smith   neP->delta3		= 2.0;
331fbe28522SBarry Smith   neP->sigma		= 0.0001;
332fbe28522SBarry Smith   neP->itflag		= 0;
33352392280SLois Curfman McInnes   neP->rnorm0		= 0;
33452392280SLois Curfman McInnes   neP->ttol		= 0;
3356b5873e3SBarry Smith   return 0;
3364800dd8cSBarry Smith }
337