xref: /petsc/src/snes/interface/snesut.c (revision c7afd0db7e14276b7be0e9afcfcc158da35539de)
1a5eb4965SSatish Balay #ifdef PETSC_RCS_HEADER
2*c7afd0dbSLois Curfman McInnes static char vcid[] = "$Id: snesut.c,v 1.38 1998/04/13 17:55:33 bsmith Exp curfman $";
3e7e93795SLois Curfman McInnes #endif
4e7e93795SLois Curfman McInnes 
5e7e93795SLois Curfman McInnes #include <math.h>
670f55243SBarry Smith #include "src/snes/snesimpl.h"       /*I   "snes.h"   I*/
7e7e93795SLois Curfman McInnes 
85615d1e5SSatish Balay #undef __FUNC__
9d4bb536fSBarry Smith #define __FUNC__ "SNESDefaultMonitor"
104b828684SBarry Smith /*@C
11f525115eSLois Curfman McInnes    SNESDefaultMonitor - Monitoring progress of the SNES solvers (default).
12e7e93795SLois Curfman McInnes 
13*c7afd0dbSLois Curfman McInnes    Collective on SNES
14*c7afd0dbSLois Curfman McInnes 
15e7e93795SLois Curfman McInnes    Input Parameters:
16*c7afd0dbSLois Curfman McInnes +  snes - the SNES context
17e7e93795SLois Curfman McInnes .  its - iteration number
18e7e93795SLois Curfman McInnes .  fgnorm - 2-norm of residual (or gradient)
19*c7afd0dbSLois Curfman McInnes -  dummy - unused context
20fee21e36SBarry Smith 
21e7e93795SLois Curfman McInnes    Notes:
22e7e93795SLois Curfman McInnes    For SNES_NONLINEAR_EQUATIONS methods the routine prints the
23e7e93795SLois Curfman McInnes    residual norm at each iteration.
24e7e93795SLois Curfman McInnes 
25e7e93795SLois Curfman McInnes    For SNES_UNCONSTRAINED_MINIMIZATION methods the routine prints the
26e7e93795SLois Curfman McInnes    function value and gradient norm at each iteration.
27e7e93795SLois Curfman McInnes 
28e7e93795SLois Curfman McInnes .keywords: SNES, nonlinear, default, monitor, norm
29e7e93795SLois Curfman McInnes 
30e7e93795SLois Curfman McInnes .seealso: SNESSetMonitor()
31e7e93795SLois Curfman McInnes @*/
32e7e93795SLois Curfman McInnes int SNESDefaultMonitor(SNES snes,int its,double fgnorm,void *dummy)
33e7e93795SLois Curfman McInnes {
343a40ed3dSBarry Smith   PetscFunctionBegin;
3576be9ce4SBarry Smith   if (snes->method_class == SNES_NONLINEAR_EQUATIONS) {
3677c4ece6SBarry Smith     PetscPrintf(snes->comm, "iter = %d, SNES Function norm %g \n",its,fgnorm);
3776be9ce4SBarry Smith   } else if (snes->method_class == SNES_UNCONSTRAINED_MINIMIZATION) {
383a40ed3dSBarry Smith     PetscPrintf(snes->comm,"iter = %d, SNES Function value %g, Gradient norm %g \n",its,snes->fc,fgnorm);
3976be9ce4SBarry Smith   } else SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Unknown method class");
403a40ed3dSBarry Smith   PetscFunctionReturn(0);
41e7e93795SLois Curfman McInnes }
42e7e93795SLois Curfman McInnes /* ---------------------------------------------------------------- */
435615d1e5SSatish Balay #undef __FUNC__
44d4bb536fSBarry Smith #define __FUNC__ "SNESDefaultSMonitor"
45be1f7002SBarry Smith /*
46be1f7002SBarry Smith      Default (short) SNES Monitor, same as SNESDefaultMonitor() except
47be1f7002SBarry Smith   it prints fewer digits of the residual as the residual gets smaller.
48be1f7002SBarry Smith   This is because the later digits are meaningless and are often
49be1f7002SBarry Smith   different on different machines; by using this routine different
50be1f7002SBarry Smith   machines will usually generate the same output.
51be1f7002SBarry Smith */
52e7e93795SLois Curfman McInnes int SNESDefaultSMonitor(SNES snes,int its, double fgnorm,void *dummy)
53e7e93795SLois Curfman McInnes {
543a40ed3dSBarry Smith   PetscFunctionBegin;
55e7e93795SLois Curfman McInnes   if (snes->method_class == SNES_NONLINEAR_EQUATIONS) {
568f240d10SBarry Smith     if (fgnorm > 1.e-9) {
57c7ab52efSLois Curfman McInnes       PetscPrintf(snes->comm, "iter = %d, SNES Function norm %g \n",its,fgnorm);
583a40ed3dSBarry Smith     } else if (fgnorm > 1.e-11){
59c7ab52efSLois Curfman McInnes       PetscPrintf(snes->comm, "iter = %d, SNES Function norm %5.3e \n",its,fgnorm);
603a40ed3dSBarry Smith     } else {
61c7ab52efSLois Curfman McInnes       PetscPrintf(snes->comm, "iter = %d, SNES Function norm < 1.e-11\n",its);
62e7e93795SLois Curfman McInnes     }
63e7e93795SLois Curfman McInnes   } else if (snes->method_class == SNES_UNCONSTRAINED_MINIMIZATION) {
648f240d10SBarry Smith     if (fgnorm > 1.e-9) {
6577c4ece6SBarry Smith       PetscPrintf(snes->comm,
663a40ed3dSBarry Smith        "iter = %d, SNES Function value %g, Gradient norm %g \n",its,snes->fc,fgnorm);
673a40ed3dSBarry Smith     } else if (fgnorm > 1.e-11) {
6877c4ece6SBarry Smith       PetscPrintf(snes->comm,
693a40ed3dSBarry Smith         "iter = %d, SNES Function value %g, Gradient norm %5.3e \n",its,snes->fc,fgnorm);
703a40ed3dSBarry Smith     } else {
7177c4ece6SBarry Smith       PetscPrintf(snes->comm,
723a40ed3dSBarry Smith         "iter = %d, SNES Function value %g, Gradient norm < 1.e-11\n",its,snes->fc);
73e7e93795SLois Curfman McInnes     }
74a8c6a408SBarry Smith   } else SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Unknown method class");
753a40ed3dSBarry Smith   PetscFunctionReturn(0);
76e7e93795SLois Curfman McInnes }
77e7e93795SLois Curfman McInnes /* ---------------------------------------------------------------- */
785615d1e5SSatish Balay #undef __FUNC__
795615d1e5SSatish Balay #define __FUNC__ "SNESConverged_EQ_LS"
804b828684SBarry Smith /*@C
81f525115eSLois Curfman McInnes    SNESConverged_EQ_LS - Monitors the convergence of the solvers for
82f525115eSLois Curfman McInnes    systems of nonlinear equations (default).
83e7e93795SLois Curfman McInnes 
84*c7afd0dbSLois Curfman McInnes    Collective on SNES
85*c7afd0dbSLois Curfman McInnes 
86e7e93795SLois Curfman McInnes    Input Parameters:
87*c7afd0dbSLois Curfman McInnes +  snes - the SNES context
88e7e93795SLois Curfman McInnes .  xnorm - 2-norm of current iterate
89e7e93795SLois Curfman McInnes .  pnorm - 2-norm of current step
90e7e93795SLois Curfman McInnes .  fnorm - 2-norm of function
91*c7afd0dbSLois Curfman McInnes -  dummy - unused context
92e7e93795SLois Curfman McInnes 
93e7e93795SLois Curfman McInnes    Returns:
94*c7afd0dbSLois Curfman McInnes +  2  - if  ( fnorm < atol ),
95*c7afd0dbSLois Curfman McInnes .  3  - if  ( pnorm < xtol*xnorm ),
96*c7afd0dbSLois Curfman McInnes .  4  - if  ( fnorm < rtol*fnorm0 ),
97*c7afd0dbSLois Curfman McInnes . -2  - if  ( nfct > maxf ),
98*c7afd0dbSLois Curfman McInnes -  0  - otherwise,
99e7e93795SLois Curfman McInnes 
100e7e93795SLois Curfman McInnes    where
101*c7afd0dbSLois Curfman McInnes +    maxf - maximum number of function evaluations,
102*c7afd0dbSLois Curfman McInnes             set with SNESSetTolerances()
103*c7afd0dbSLois Curfman McInnes .    nfct - number of function evaluations,
104*c7afd0dbSLois Curfman McInnes .    atol - absolute function norm tolerance,
105*c7afd0dbSLois Curfman McInnes             set with SNESSetTolerances()
106*c7afd0dbSLois Curfman McInnes -    rtol - relative function norm tolerance, set with SNESSetTolerances()
107fee21e36SBarry Smith 
108e7e93795SLois Curfman McInnes .keywords: SNES, nonlinear, default, converged, convergence
109e7e93795SLois Curfman McInnes 
110e7e93795SLois Curfman McInnes .seealso: SNESSetConvergenceTest(), SNESEisenstatWalkerConverged()
111e7e93795SLois Curfman McInnes @*/
11240191667SLois Curfman McInnes int SNESConverged_EQ_LS(SNES snes,double xnorm,double pnorm,double fnorm,void *dummy)
113e7e93795SLois Curfman McInnes {
1143a40ed3dSBarry Smith   PetscFunctionBegin;
115d252947aSBarry Smith   if (snes->method_class != SNES_NONLINEAR_EQUATIONS) {
116a8c6a408SBarry Smith      SETERRQ(PETSC_ERR_ARG_WRONG,0,"For SNES_NONLINEAR_EQUATIONS only");
117d252947aSBarry Smith   }
118082acdaeSLois Curfman McInnes   /* Note:  Reserve return code 1, -1 for compatibility with SNESConverged_EQ_TR */
119d252947aSBarry Smith   if (fnorm != fnorm) {
120981c4779SBarry Smith     PLogInfo(snes,"SNESConverged_EQ_LS:Failed to converged, function norm is NaN\n");
1213a40ed3dSBarry Smith     PetscFunctionReturn(-3);
122d252947aSBarry Smith   }
1235d2e0e51SBarry Smith   if (fnorm <= snes->ttol) {
12494a424c1SBarry Smith     PLogInfo(snes,
125981c4779SBarry Smith     "SNESConverged_EQ_LS:Converged due to function norm %g < %g (relative tolerance)\n",fnorm,snes->ttol);
1263a40ed3dSBarry Smith     PetscFunctionReturn(4);
1275d2e0e51SBarry Smith   }
1285d2e0e51SBarry Smith 
129e7e93795SLois Curfman McInnes   if (fnorm < snes->atol) {
13094a424c1SBarry Smith     PLogInfo(snes,
131981c4779SBarry Smith       "SNESConverged_EQ_LS: Converged due to function norm %g < %g\n",fnorm,snes->atol);
1323a40ed3dSBarry Smith     PetscFunctionReturn(2);
133e7e93795SLois Curfman McInnes   }
134e7e93795SLois Curfman McInnes   if (pnorm < snes->xtol*(xnorm)) {
13594a424c1SBarry Smith     PLogInfo(snes,
136981c4779SBarry Smith       "SNESConverged_EQ_LS: Converged due to small update length: %g < %g * %g\n",
137e7e93795SLois Curfman McInnes        pnorm,snes->xtol,xnorm);
1383a40ed3dSBarry Smith     PetscFunctionReturn(3);
139e7e93795SLois Curfman McInnes   }
140e7e93795SLois Curfman McInnes   if (snes->nfuncs > snes->max_funcs) {
141981c4779SBarry Smith     PLogInfo(snes,"SNESConverged_EQ_LS: Exceeded maximum number of function evaluations: %d > %d\n",
142e7e93795SLois Curfman McInnes       snes->nfuncs, snes->max_funcs );
1433a40ed3dSBarry Smith     PetscFunctionReturn(-2);
144e7e93795SLois Curfman McInnes   }
1453a40ed3dSBarry Smith   PetscFunctionReturn(0);
146e7e93795SLois Curfman McInnes }
147e7e93795SLois Curfman McInnes /* ------------------------------------------------------------ */
1485615d1e5SSatish Balay #undef __FUNC__
1495615d1e5SSatish Balay #define __FUNC__ "SNES_KSP_SetConvergenceTestEW"
150e7e93795SLois Curfman McInnes /*@
151f525115eSLois Curfman McInnes    SNES_KSP_SetConvergenceTestEW - Sets alternative convergence test
152e7e93795SLois Curfman McInnes    for the linear solvers within an inexact Newton method.
153e7e93795SLois Curfman McInnes 
154*c7afd0dbSLois Curfman McInnes    Collective on SNES
155*c7afd0dbSLois Curfman McInnes 
156e7e93795SLois Curfman McInnes    Input Parameter:
157e7e93795SLois Curfman McInnes .  snes - SNES context
158e7e93795SLois Curfman McInnes 
159e7e93795SLois Curfman McInnes    Notes:
160e7e93795SLois Curfman McInnes    Currently, the default is to use a constant relative tolerance for
161e7e93795SLois Curfman McInnes    the inner linear solvers.  Alternatively, one can use the
162e7e93795SLois Curfman McInnes    Eisenstat-Walker method, where the relative convergence tolerance
163e7e93795SLois Curfman McInnes    is reset at each Newton iteration according progress of the nonlinear
164e7e93795SLois Curfman McInnes    solver.
165e7e93795SLois Curfman McInnes 
166e7e93795SLois Curfman McInnes    Reference:
167e7e93795SLois Curfman McInnes    S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an
168e30ad881SLois Curfman McInnes    inexact Newton method", SISC 17 (1), pp.16-32, 1996.
169e7e93795SLois Curfman McInnes 
170e7e93795SLois Curfman McInnes .keywords: SNES, KSP, Eisenstat, Walker, convergence, test, inexact, Newton
171e7e93795SLois Curfman McInnes @*/
172e7e93795SLois Curfman McInnes int SNES_KSP_SetConvergenceTestEW(SNES snes)
173e7e93795SLois Curfman McInnes {
1743a40ed3dSBarry Smith   PetscFunctionBegin;
175e7e93795SLois Curfman McInnes   snes->ksp_ewconv = 1;
1763a40ed3dSBarry Smith   PetscFunctionReturn(0);
177e7e93795SLois Curfman McInnes }
178e7e93795SLois Curfman McInnes 
1795615d1e5SSatish Balay #undef __FUNC__
1805615d1e5SSatish Balay #define __FUNC__ "SNES_KSP_SetParametersEW"
181e7e93795SLois Curfman McInnes /*@
182e7e93795SLois Curfman McInnes    SNES_KSP_SetParametersEW - Sets parameters for Eisenstat-Walker
183e7e93795SLois Curfman McInnes    convergence criteria for the linear solvers within an inexact
184e7e93795SLois Curfman McInnes    Newton method.
185e7e93795SLois Curfman McInnes 
186*c7afd0dbSLois Curfman McInnes    Collective on SNES
187*c7afd0dbSLois Curfman McInnes 
188e7e93795SLois Curfman McInnes    Input Parameters:
189*c7afd0dbSLois Curfman McInnes +    snes - SNES context
190e7e93795SLois Curfman McInnes .    version - version 1 or 2 (default is 2)
191*c7afd0dbSLois Curfman McInnes .    rtol_0 - initial relative tolerance (0 <= rtol_0 < 1)
192*c7afd0dbSLois Curfman McInnes .    rtol_max - maximum relative tolerance (0 <= rtol_max < 1)
193*c7afd0dbSLois Curfman McInnes .    alpha - power for version 2 rtol computation (1 < alpha <= 2)
194e7e93795SLois Curfman McInnes .    alpha2 - power for safeguard
195e7e93795SLois Curfman McInnes .    gamma2 - multiplicative factor for version 2 rtol computation
196*c7afd0dbSLois Curfman McInnes               (0 <= gamma2 <= 1)
197*c7afd0dbSLois Curfman McInnes -    threshold - threshold for imposing safeguard (0 < threshold < 1)
198fee21e36SBarry Smith 
199e7e93795SLois Curfman McInnes    Note:
200e7e93795SLois Curfman McInnes    Use PETSC_DEFAULT to retain the default for any of the parameters.
201e7e93795SLois Curfman McInnes 
202e7e93795SLois Curfman McInnes    Reference:
203e7e93795SLois Curfman McInnes    S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an
204e7e93795SLois Curfman McInnes    inexact Newton method", Utah State University Math. Stat. Dept. Res.
205e7e93795SLois Curfman McInnes    Report 6/94/75, June, 1994, to appear in SIAM J. Sci. Comput.
206e7e93795SLois Curfman McInnes 
207e7e93795SLois Curfman McInnes .keywords: SNES, KSP, Eisenstat, Walker, set, parameters
208e7e93795SLois Curfman McInnes 
209e7e93795SLois Curfman McInnes .seealso: SNES_KSP_SetConvergenceTestEW()
210e7e93795SLois Curfman McInnes @*/
211e7e93795SLois Curfman McInnes int SNES_KSP_SetParametersEW(SNES snes,int version,double rtol_0,
212e7e93795SLois Curfman McInnes                              double rtol_max,double gamma2,double alpha,
213e7e93795SLois Curfman McInnes                              double alpha2,double threshold)
214e7e93795SLois Curfman McInnes {
215e7e93795SLois Curfman McInnes   SNES_KSP_EW_ConvCtx *kctx = (SNES_KSP_EW_ConvCtx*)snes->kspconvctx;
2163a40ed3dSBarry Smith 
2173a40ed3dSBarry Smith   PetscFunctionBegin;
218a8c6a408SBarry Smith   if (!kctx) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,0,"No Eisenstat-Walker context existing");
219e7e93795SLois Curfman McInnes   if (version != PETSC_DEFAULT)   kctx->version = version;
220e7e93795SLois Curfman McInnes   if (rtol_0 != PETSC_DEFAULT)    kctx->rtol_0 = rtol_0;
221e7e93795SLois Curfman McInnes   if (rtol_max != PETSC_DEFAULT)  kctx->rtol_max = rtol_max;
222e7e93795SLois Curfman McInnes   if (gamma2 != PETSC_DEFAULT)    kctx->gamma = gamma2;
223e7e93795SLois Curfman McInnes   if (alpha != PETSC_DEFAULT)     kctx->alpha = alpha;
224e7e93795SLois Curfman McInnes   if (alpha2 != PETSC_DEFAULT)    kctx->alpha2 = alpha2;
225e7e93795SLois Curfman McInnes   if (threshold != PETSC_DEFAULT) kctx->threshold = threshold;
226a8c6a408SBarry Smith   if (kctx->rtol_0 < 0.0 || kctx->rtol_0 >= 1.0) {
227a8c6a408SBarry Smith     SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"0.0 <= rtol_0 < 1.0\n");
228a8c6a408SBarry Smith   }
229a8c6a408SBarry Smith   if (kctx->rtol_max < 0.0 || kctx->rtol_max >= 1.0) {
230a8c6a408SBarry Smith     SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"0.0 <= rtol_max < 1.0\n");
231a8c6a408SBarry Smith   }
232a8c6a408SBarry Smith   if (kctx->threshold <= 0.0 || kctx->threshold >= 1.0) {
233a8c6a408SBarry Smith     SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"0.0 < threshold < 1.0\n");
234a8c6a408SBarry Smith   }
235a8c6a408SBarry Smith   if (kctx->gamma < 0.0 || kctx->gamma > 1.0) {
236a8c6a408SBarry Smith     SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"0.0 <= alpha <= 1.0\n");
237a8c6a408SBarry Smith   }
238a8c6a408SBarry Smith   if (kctx->alpha <= 1.0 || kctx->alpha > 2.0) {
239a8c6a408SBarry Smith     SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"1.0 < alpha <= 2.0\n");
240a8c6a408SBarry Smith   }
241a8c6a408SBarry Smith   if (kctx->version != 1 && kctx->version !=2) {
242a8c6a408SBarry Smith     SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Only versions 1 and 2 are supported");
243a8c6a408SBarry Smith   }
2443a40ed3dSBarry Smith   PetscFunctionReturn(0);
245e7e93795SLois Curfman McInnes }
246e7e93795SLois Curfman McInnes 
2475615d1e5SSatish Balay #undef __FUNC__
2485615d1e5SSatish Balay #define __FUNC__ "SNES_KSP_EW_ComputeRelativeTolerance_Private"
249e7e93795SLois Curfman McInnes int SNES_KSP_EW_ComputeRelativeTolerance_Private(SNES snes,KSP ksp)
250e7e93795SLois Curfman McInnes {
251e7e93795SLois Curfman McInnes   SNES_KSP_EW_ConvCtx *kctx = (SNES_KSP_EW_ConvCtx*)snes->kspconvctx;
252e7e93795SLois Curfman McInnes   double rtol, stol;
253e7e93795SLois Curfman McInnes   int    ierr;
2543a40ed3dSBarry Smith 
2553a40ed3dSBarry Smith   PetscFunctionBegin;
256a8c6a408SBarry Smith   if (!kctx) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,0,"No Eisenstat-Walker context exists");
257e7e93795SLois Curfman McInnes   if (snes->iter == 1) {
258e7e93795SLois Curfman McInnes     rtol = kctx->rtol_0;
259e7e93795SLois Curfman McInnes   } else {
260e7e93795SLois Curfman McInnes     if (kctx->version == 1) {
261e7e93795SLois Curfman McInnes       rtol = (snes->norm - kctx->lresid_last)/kctx->norm_last;
262e7e93795SLois Curfman McInnes       if (rtol < 0.0) rtol = -rtol;
263e7e93795SLois Curfman McInnes       stol = pow(kctx->rtol_last,kctx->alpha2);
2640452661fSBarry Smith       if (stol > kctx->threshold) rtol = PetscMax(rtol,stol);
265e7e93795SLois Curfman McInnes     } else if (kctx->version == 2) {
266e7e93795SLois Curfman McInnes       rtol = kctx->gamma * pow(snes->norm/kctx->norm_last,kctx->alpha);
267e7e93795SLois Curfman McInnes       stol = kctx->gamma * pow(kctx->rtol_last,kctx->alpha);
2680452661fSBarry Smith       if (stol > kctx->threshold) rtol = PetscMax(rtol,stol);
269a8c6a408SBarry Smith     } else SETERRQ( PETSC_ERR_ARG_OUTOFRANGE,0,"Only versions 1 or 2 are supported");
270e7e93795SLois Curfman McInnes   }
2710452661fSBarry Smith   rtol = PetscMin(rtol,kctx->rtol_max);
272e7e93795SLois Curfman McInnes   kctx->rtol_last = rtol;
273981c4779SBarry Smith   PLogInfo(snes,"SNESConverged_EQ_LS: iter %d, Eisenstat-Walker (version %d) KSP rtol = %g\n",
274e7e93795SLois Curfman McInnes            snes->iter,kctx->version,rtol);
2753131a8b6SLois Curfman McInnes   ierr = KSPSetTolerances(ksp,rtol,PETSC_DEFAULT,PETSC_DEFAULT,PETSC_DEFAULT); CHKERRQ(ierr);
276e7e93795SLois Curfman McInnes   kctx->norm_last = snes->norm;
2773a40ed3dSBarry Smith   PetscFunctionReturn(0);
278e7e93795SLois Curfman McInnes }
279e7e93795SLois Curfman McInnes 
2805615d1e5SSatish Balay #undef __FUNC__
2815615d1e5SSatish Balay #define __FUNC__ "SNES_KSP_EW_Converged_Private"
282e7e93795SLois Curfman McInnes int SNES_KSP_EW_Converged_Private(KSP ksp,int n,double rnorm,void *ctx)
283e7e93795SLois Curfman McInnes {
284e7e93795SLois Curfman McInnes   SNES                snes = (SNES)ctx;
285e7e93795SLois Curfman McInnes   SNES_KSP_EW_ConvCtx *kctx = (SNES_KSP_EW_ConvCtx*)snes->kspconvctx;
286e7e93795SLois Curfman McInnes   int                 convinfo;
287e7e93795SLois Curfman McInnes 
2883a40ed3dSBarry Smith   PetscFunctionBegin;
289a8c6a408SBarry Smith   if (!kctx) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,0,"No Eisenstat-Walker context set");
290e7e93795SLois Curfman McInnes   if (n == 0) SNES_KSP_EW_ComputeRelativeTolerance_Private(snes,ksp);
291e7e93795SLois Curfman McInnes   convinfo = KSPDefaultConverged(ksp,n,rnorm,ctx);
292e7e93795SLois Curfman McInnes   kctx->lresid_last = rnorm;
2933a40ed3dSBarry Smith   if (convinfo) {
294981c4779SBarry Smith     PLogInfo(snes,"SNES_KSP_EW_Converged_Private: KSP iterations=%d, rnorm=%g\n",n,rnorm);
2953a40ed3dSBarry Smith   }
2963a40ed3dSBarry Smith   PetscFunctionReturn(convinfo);
297e7e93795SLois Curfman McInnes }
298e7e93795SLois Curfman McInnes 
299e7e93795SLois Curfman McInnes 
300