xref: /petsc/src/snes/interface/snesut.c (revision fee21e364a2af8f69c0e7984443fdef19f844ae9)
1a5eb4965SSatish Balay #ifdef PETSC_RCS_HEADER
2*fee21e36SBarry Smith static char vcid[] = "$Id: snesut.c,v 1.37 1998/02/10 19:49:03 curfman Exp bsmith $";
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 
13e7e93795SLois Curfman McInnes    Input Parameters:
14e7e93795SLois Curfman McInnes .  snes - the SNES context
15e7e93795SLois Curfman McInnes .  its - iteration number
16e7e93795SLois Curfman McInnes .  fgnorm - 2-norm of residual (or gradient)
17e7e93795SLois Curfman McInnes .  dummy - unused context
18e7e93795SLois Curfman McInnes 
19*fee21e36SBarry Smith    Collective on SNES
20*fee21e36SBarry 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 
84e7e93795SLois Curfman McInnes    Input Parameters:
85e7e93795SLois Curfman McInnes .  snes - the SNES context
86e7e93795SLois Curfman McInnes .  xnorm - 2-norm of current iterate
87e7e93795SLois Curfman McInnes .  pnorm - 2-norm of current step
88e7e93795SLois Curfman McInnes .  fnorm - 2-norm of function
89e7e93795SLois Curfman McInnes .  dummy - unused context
90e7e93795SLois Curfman McInnes 
91e7e93795SLois Curfman McInnes    Returns:
92e7e93795SLois Curfman McInnes $  2  if  ( fnorm < atol ),
93e7e93795SLois Curfman McInnes $  3  if  ( pnorm < xtol*xnorm ),
945d2e0e51SBarry Smith $  4  if  ( fnorm < rtol*fnorm0 ),
95e7e93795SLois Curfman McInnes $ -2  if  ( nfct > maxf ),
96e7e93795SLois Curfman McInnes $  0  otherwise,
97e7e93795SLois Curfman McInnes 
98e7e93795SLois Curfman McInnes    where
99e7e93795SLois Curfman McInnes $    maxf - maximum number of function evaluations,
100acd914d5SLois Curfman McInnes $           set with SNESSetTolerances()
101e7e93795SLois Curfman McInnes $    nfct - number of function evaluations,
102e7e93795SLois Curfman McInnes $    atol - absolute function norm tolerance,
103acd914d5SLois Curfman McInnes $           set with SNESSetTolerances()
104d7a720efSLois Curfman McInnes $    rtol - relative function norm tolerance,
105acd914d5SLois Curfman McInnes $           set with SNESSetTolerances()
106e7e93795SLois Curfman McInnes 
107*fee21e36SBarry Smith    Collective on SNES
108*fee21e36SBarry Smith 
109e7e93795SLois Curfman McInnes .keywords: SNES, nonlinear, default, converged, convergence
110e7e93795SLois Curfman McInnes 
111e7e93795SLois Curfman McInnes .seealso: SNESSetConvergenceTest(), SNESEisenstatWalkerConverged()
112e7e93795SLois Curfman McInnes @*/
11340191667SLois Curfman McInnes int SNESConverged_EQ_LS(SNES snes,double xnorm,double pnorm,double fnorm,void *dummy)
114e7e93795SLois Curfman McInnes {
1153a40ed3dSBarry Smith   PetscFunctionBegin;
116d252947aSBarry Smith   if (snes->method_class != SNES_NONLINEAR_EQUATIONS) {
117a8c6a408SBarry Smith      SETERRQ(PETSC_ERR_ARG_WRONG,0,"For SNES_NONLINEAR_EQUATIONS only");
118d252947aSBarry Smith   }
119082acdaeSLois Curfman McInnes   /* Note:  Reserve return code 1, -1 for compatibility with SNESConverged_EQ_TR */
120d252947aSBarry Smith   if (fnorm != fnorm) {
121981c4779SBarry Smith     PLogInfo(snes,"SNESConverged_EQ_LS:Failed to converged, function norm is NaN\n");
1223a40ed3dSBarry Smith     PetscFunctionReturn(-3);
123d252947aSBarry Smith   }
1245d2e0e51SBarry Smith   if (fnorm <= snes->ttol) {
12594a424c1SBarry Smith     PLogInfo(snes,
126981c4779SBarry Smith     "SNESConverged_EQ_LS:Converged due to function norm %g < %g (relative tolerance)\n",fnorm,snes->ttol);
1273a40ed3dSBarry Smith     PetscFunctionReturn(4);
1285d2e0e51SBarry Smith   }
1295d2e0e51SBarry Smith 
130e7e93795SLois Curfman McInnes   if (fnorm < snes->atol) {
13194a424c1SBarry Smith     PLogInfo(snes,
132981c4779SBarry Smith       "SNESConverged_EQ_LS: Converged due to function norm %g < %g\n",fnorm,snes->atol);
1333a40ed3dSBarry Smith     PetscFunctionReturn(2);
134e7e93795SLois Curfman McInnes   }
135e7e93795SLois Curfman McInnes   if (pnorm < snes->xtol*(xnorm)) {
13694a424c1SBarry Smith     PLogInfo(snes,
137981c4779SBarry Smith       "SNESConverged_EQ_LS: Converged due to small update length: %g < %g * %g\n",
138e7e93795SLois Curfman McInnes        pnorm,snes->xtol,xnorm);
1393a40ed3dSBarry Smith     PetscFunctionReturn(3);
140e7e93795SLois Curfman McInnes   }
141e7e93795SLois Curfman McInnes   if (snes->nfuncs > snes->max_funcs) {
142981c4779SBarry Smith     PLogInfo(snes,"SNESConverged_EQ_LS: Exceeded maximum number of function evaluations: %d > %d\n",
143e7e93795SLois Curfman McInnes       snes->nfuncs, snes->max_funcs );
1443a40ed3dSBarry Smith     PetscFunctionReturn(-2);
145e7e93795SLois Curfman McInnes   }
1463a40ed3dSBarry Smith   PetscFunctionReturn(0);
147e7e93795SLois Curfman McInnes }
148e7e93795SLois Curfman McInnes /* ------------------------------------------------------------ */
1495615d1e5SSatish Balay #undef __FUNC__
1505615d1e5SSatish Balay #define __FUNC__ "SNES_KSP_SetConvergenceTestEW"
151e7e93795SLois Curfman McInnes /*@
152f525115eSLois Curfman McInnes    SNES_KSP_SetConvergenceTestEW - Sets alternative convergence test
153e7e93795SLois Curfman McInnes    for the linear solvers within an inexact Newton method.
154e7e93795SLois Curfman McInnes 
155e7e93795SLois Curfman McInnes    Input Parameter:
156e7e93795SLois Curfman McInnes .  snes - SNES context
157e7e93795SLois Curfman McInnes 
158*fee21e36SBarry Smith    Collective on SNES
159*fee21e36SBarry Smith 
160e7e93795SLois Curfman McInnes    Notes:
161e7e93795SLois Curfman McInnes    Currently, the default is to use a constant relative tolerance for
162e7e93795SLois Curfman McInnes    the inner linear solvers.  Alternatively, one can use the
163e7e93795SLois Curfman McInnes    Eisenstat-Walker method, where the relative convergence tolerance
164e7e93795SLois Curfman McInnes    is reset at each Newton iteration according progress of the nonlinear
165e7e93795SLois Curfman McInnes    solver.
166e7e93795SLois Curfman McInnes 
167e7e93795SLois Curfman McInnes    Reference:
168e7e93795SLois Curfman McInnes    S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an
169e30ad881SLois Curfman McInnes    inexact Newton method", SISC 17 (1), pp.16-32, 1996.
170e7e93795SLois Curfman McInnes 
171e7e93795SLois Curfman McInnes .keywords: SNES, KSP, Eisenstat, Walker, convergence, test, inexact, Newton
172e7e93795SLois Curfman McInnes @*/
173e7e93795SLois Curfman McInnes int SNES_KSP_SetConvergenceTestEW(SNES snes)
174e7e93795SLois Curfman McInnes {
1753a40ed3dSBarry Smith   PetscFunctionBegin;
176e7e93795SLois Curfman McInnes   snes->ksp_ewconv = 1;
1773a40ed3dSBarry Smith   PetscFunctionReturn(0);
178e7e93795SLois Curfman McInnes }
179e7e93795SLois Curfman McInnes 
1805615d1e5SSatish Balay #undef __FUNC__
1815615d1e5SSatish Balay #define __FUNC__ "SNES_KSP_SetParametersEW"
182e7e93795SLois Curfman McInnes /*@
183e7e93795SLois Curfman McInnes    SNES_KSP_SetParametersEW - Sets parameters for Eisenstat-Walker
184e7e93795SLois Curfman McInnes    convergence criteria for the linear solvers within an inexact
185e7e93795SLois Curfman McInnes    Newton method.
186e7e93795SLois Curfman McInnes 
187e7e93795SLois Curfman McInnes    Input Parameters:
188e7e93795SLois Curfman McInnes .    snes - SNES context
189e7e93795SLois Curfman McInnes .    version - version 1 or 2 (default is 2)
190e7e93795SLois Curfman McInnes .    rtol_0 - initial relative tolerance
191e7e93795SLois Curfman McInnes $      (0 <= rtol_0 < 1)
192e7e93795SLois Curfman McInnes .    rtol_max - maximum relative tolerance
193e7e93795SLois Curfman McInnes $      (0 <= rtol_max < 1)
194e7e93795SLois Curfman McInnes .    alpha - power for version 2 rtol computation
195e7e93795SLois Curfman McInnes $      (1 < alpha <= 2)
196e7e93795SLois Curfman McInnes .    alpha2 - power for safeguard
197e7e93795SLois Curfman McInnes .    gamma2 - multiplicative factor for version 2 rtol computation
198e7e93795SLois Curfman McInnes $      (0 <= gamma2 <= 1)
199e7e93795SLois Curfman McInnes .    threshold - threshold for imposing safeguard
200e7e93795SLois Curfman McInnes $      (0 < threshold < 1)
201e7e93795SLois Curfman McInnes 
202*fee21e36SBarry Smith    Collective on SNES
203*fee21e36SBarry Smith 
204e7e93795SLois Curfman McInnes    Note:
205e7e93795SLois Curfman McInnes    Use PETSC_DEFAULT to retain the default for any of the parameters.
206e7e93795SLois Curfman McInnes 
207e7e93795SLois Curfman McInnes    Reference:
208e7e93795SLois Curfman McInnes    S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an
209e7e93795SLois Curfman McInnes    inexact Newton method", Utah State University Math. Stat. Dept. Res.
210e7e93795SLois Curfman McInnes    Report 6/94/75, June, 1994, to appear in SIAM J. Sci. Comput.
211e7e93795SLois Curfman McInnes 
212e7e93795SLois Curfman McInnes .keywords: SNES, KSP, Eisenstat, Walker, set, parameters
213e7e93795SLois Curfman McInnes 
214e7e93795SLois Curfman McInnes .seealso: SNES_KSP_SetConvergenceTestEW()
215e7e93795SLois Curfman McInnes @*/
216e7e93795SLois Curfman McInnes int SNES_KSP_SetParametersEW(SNES snes,int version,double rtol_0,
217e7e93795SLois Curfman McInnes                              double rtol_max,double gamma2,double alpha,
218e7e93795SLois Curfman McInnes                              double alpha2,double threshold)
219e7e93795SLois Curfman McInnes {
220e7e93795SLois Curfman McInnes   SNES_KSP_EW_ConvCtx *kctx = (SNES_KSP_EW_ConvCtx*)snes->kspconvctx;
2213a40ed3dSBarry Smith 
2223a40ed3dSBarry Smith   PetscFunctionBegin;
223a8c6a408SBarry Smith   if (!kctx) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,0,"No Eisenstat-Walker context existing");
224e7e93795SLois Curfman McInnes   if (version != PETSC_DEFAULT)   kctx->version = version;
225e7e93795SLois Curfman McInnes   if (rtol_0 != PETSC_DEFAULT)    kctx->rtol_0 = rtol_0;
226e7e93795SLois Curfman McInnes   if (rtol_max != PETSC_DEFAULT)  kctx->rtol_max = rtol_max;
227e7e93795SLois Curfman McInnes   if (gamma2 != PETSC_DEFAULT)    kctx->gamma = gamma2;
228e7e93795SLois Curfman McInnes   if (alpha != PETSC_DEFAULT)     kctx->alpha = alpha;
229e7e93795SLois Curfman McInnes   if (alpha2 != PETSC_DEFAULT)    kctx->alpha2 = alpha2;
230e7e93795SLois Curfman McInnes   if (threshold != PETSC_DEFAULT) kctx->threshold = threshold;
231a8c6a408SBarry Smith   if (kctx->rtol_0 < 0.0 || kctx->rtol_0 >= 1.0) {
232a8c6a408SBarry Smith     SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"0.0 <= rtol_0 < 1.0\n");
233a8c6a408SBarry Smith   }
234a8c6a408SBarry Smith   if (kctx->rtol_max < 0.0 || kctx->rtol_max >= 1.0) {
235a8c6a408SBarry Smith     SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"0.0 <= rtol_max < 1.0\n");
236a8c6a408SBarry Smith   }
237a8c6a408SBarry Smith   if (kctx->threshold <= 0.0 || kctx->threshold >= 1.0) {
238a8c6a408SBarry Smith     SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"0.0 < threshold < 1.0\n");
239a8c6a408SBarry Smith   }
240a8c6a408SBarry Smith   if (kctx->gamma < 0.0 || kctx->gamma > 1.0) {
241a8c6a408SBarry Smith     SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"0.0 <= alpha <= 1.0\n");
242a8c6a408SBarry Smith   }
243a8c6a408SBarry Smith   if (kctx->alpha <= 1.0 || kctx->alpha > 2.0) {
244a8c6a408SBarry Smith     SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"1.0 < alpha <= 2.0\n");
245a8c6a408SBarry Smith   }
246a8c6a408SBarry Smith   if (kctx->version != 1 && kctx->version !=2) {
247a8c6a408SBarry Smith     SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Only versions 1 and 2 are supported");
248a8c6a408SBarry Smith   }
2493a40ed3dSBarry Smith   PetscFunctionReturn(0);
250e7e93795SLois Curfman McInnes }
251e7e93795SLois Curfman McInnes 
2525615d1e5SSatish Balay #undef __FUNC__
2535615d1e5SSatish Balay #define __FUNC__ "SNES_KSP_EW_ComputeRelativeTolerance_Private"
254e7e93795SLois Curfman McInnes int SNES_KSP_EW_ComputeRelativeTolerance_Private(SNES snes,KSP ksp)
255e7e93795SLois Curfman McInnes {
256e7e93795SLois Curfman McInnes   SNES_KSP_EW_ConvCtx *kctx = (SNES_KSP_EW_ConvCtx*)snes->kspconvctx;
257e7e93795SLois Curfman McInnes   double rtol, stol;
258e7e93795SLois Curfman McInnes   int    ierr;
2593a40ed3dSBarry Smith 
2603a40ed3dSBarry Smith   PetscFunctionBegin;
261a8c6a408SBarry Smith   if (!kctx) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,0,"No Eisenstat-Walker context exists");
262e7e93795SLois Curfman McInnes   if (snes->iter == 1) {
263e7e93795SLois Curfman McInnes     rtol = kctx->rtol_0;
264e7e93795SLois Curfman McInnes   } else {
265e7e93795SLois Curfman McInnes     if (kctx->version == 1) {
266e7e93795SLois Curfman McInnes       rtol = (snes->norm - kctx->lresid_last)/kctx->norm_last;
267e7e93795SLois Curfman McInnes       if (rtol < 0.0) rtol = -rtol;
268e7e93795SLois Curfman McInnes       stol = pow(kctx->rtol_last,kctx->alpha2);
2690452661fSBarry Smith       if (stol > kctx->threshold) rtol = PetscMax(rtol,stol);
270e7e93795SLois Curfman McInnes     } else if (kctx->version == 2) {
271e7e93795SLois Curfman McInnes       rtol = kctx->gamma * pow(snes->norm/kctx->norm_last,kctx->alpha);
272e7e93795SLois Curfman McInnes       stol = kctx->gamma * pow(kctx->rtol_last,kctx->alpha);
2730452661fSBarry Smith       if (stol > kctx->threshold) rtol = PetscMax(rtol,stol);
274a8c6a408SBarry Smith     } else SETERRQ( PETSC_ERR_ARG_OUTOFRANGE,0,"Only versions 1 or 2 are supported");
275e7e93795SLois Curfman McInnes   }
2760452661fSBarry Smith   rtol = PetscMin(rtol,kctx->rtol_max);
277e7e93795SLois Curfman McInnes   kctx->rtol_last = rtol;
278981c4779SBarry Smith   PLogInfo(snes,"SNESConverged_EQ_LS: iter %d, Eisenstat-Walker (version %d) KSP rtol = %g\n",
279e7e93795SLois Curfman McInnes            snes->iter,kctx->version,rtol);
2803131a8b6SLois Curfman McInnes   ierr = KSPSetTolerances(ksp,rtol,PETSC_DEFAULT,PETSC_DEFAULT,PETSC_DEFAULT); CHKERRQ(ierr);
281e7e93795SLois Curfman McInnes   kctx->norm_last = snes->norm;
2823a40ed3dSBarry Smith   PetscFunctionReturn(0);
283e7e93795SLois Curfman McInnes }
284e7e93795SLois Curfman McInnes 
2855615d1e5SSatish Balay #undef __FUNC__
2865615d1e5SSatish Balay #define __FUNC__ "SNES_KSP_EW_Converged_Private"
287e7e93795SLois Curfman McInnes int SNES_KSP_EW_Converged_Private(KSP ksp,int n,double rnorm,void *ctx)
288e7e93795SLois Curfman McInnes {
289e7e93795SLois Curfman McInnes   SNES                snes = (SNES)ctx;
290e7e93795SLois Curfman McInnes   SNES_KSP_EW_ConvCtx *kctx = (SNES_KSP_EW_ConvCtx*)snes->kspconvctx;
291e7e93795SLois Curfman McInnes   int                 convinfo;
292e7e93795SLois Curfman McInnes 
2933a40ed3dSBarry Smith   PetscFunctionBegin;
294a8c6a408SBarry Smith   if (!kctx) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,0,"No Eisenstat-Walker context set");
295e7e93795SLois Curfman McInnes   if (n == 0) SNES_KSP_EW_ComputeRelativeTolerance_Private(snes,ksp);
296e7e93795SLois Curfman McInnes   convinfo = KSPDefaultConverged(ksp,n,rnorm,ctx);
297e7e93795SLois Curfman McInnes   kctx->lresid_last = rnorm;
2983a40ed3dSBarry Smith   if (convinfo) {
299981c4779SBarry Smith     PLogInfo(snes,"SNES_KSP_EW_Converged_Private: KSP iterations=%d, rnorm=%g\n",n,rnorm);
3003a40ed3dSBarry Smith   }
3013a40ed3dSBarry Smith   PetscFunctionReturn(convinfo);
302e7e93795SLois Curfman McInnes }
303e7e93795SLois Curfman McInnes 
304e7e93795SLois Curfman McInnes 
305