xref: /petsc/src/snes/interface/snesut.c (revision e30ad881237f693a94b293d84250cdaa32f1c7f8)
1a5eb4965SSatish Balay #ifdef PETSC_RCS_HEADER
2*e30ad881SLois Curfman McInnes static char vcid[] = "$Id: snesut.c,v 1.36 1998/01/14 02:44:45 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 
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 
19e7e93795SLois Curfman McInnes    Notes:
20e7e93795SLois Curfman McInnes    For SNES_NONLINEAR_EQUATIONS methods the routine prints the
21e7e93795SLois Curfman McInnes    residual norm at each iteration.
22e7e93795SLois Curfman McInnes 
23e7e93795SLois Curfman McInnes    For SNES_UNCONSTRAINED_MINIMIZATION methods the routine prints the
24e7e93795SLois Curfman McInnes    function value and gradient norm at each iteration.
25e7e93795SLois Curfman McInnes 
26e7e93795SLois Curfman McInnes .keywords: SNES, nonlinear, default, monitor, norm
27e7e93795SLois Curfman McInnes 
28e7e93795SLois Curfman McInnes .seealso: SNESSetMonitor()
29e7e93795SLois Curfman McInnes @*/
30e7e93795SLois Curfman McInnes int SNESDefaultMonitor(SNES snes,int its,double fgnorm,void *dummy)
31e7e93795SLois Curfman McInnes {
323a40ed3dSBarry Smith   PetscFunctionBegin;
3376be9ce4SBarry Smith   if (snes->method_class == SNES_NONLINEAR_EQUATIONS) {
3477c4ece6SBarry Smith     PetscPrintf(snes->comm, "iter = %d, SNES Function norm %g \n",its,fgnorm);
3576be9ce4SBarry Smith   } else if (snes->method_class == SNES_UNCONSTRAINED_MINIMIZATION) {
363a40ed3dSBarry Smith     PetscPrintf(snes->comm,"iter = %d, SNES Function value %g, Gradient norm %g \n",its,snes->fc,fgnorm);
3776be9ce4SBarry Smith   } else SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Unknown method class");
383a40ed3dSBarry Smith   PetscFunctionReturn(0);
39e7e93795SLois Curfman McInnes }
40e7e93795SLois Curfman McInnes /* ---------------------------------------------------------------- */
415615d1e5SSatish Balay #undef __FUNC__
42d4bb536fSBarry Smith #define __FUNC__ "SNESDefaultSMonitor"
43be1f7002SBarry Smith /*
44be1f7002SBarry Smith      Default (short) SNES Monitor, same as SNESDefaultMonitor() except
45be1f7002SBarry Smith   it prints fewer digits of the residual as the residual gets smaller.
46be1f7002SBarry Smith   This is because the later digits are meaningless and are often
47be1f7002SBarry Smith   different on different machines; by using this routine different
48be1f7002SBarry Smith   machines will usually generate the same output.
49be1f7002SBarry Smith */
50e7e93795SLois Curfman McInnes int SNESDefaultSMonitor(SNES snes,int its, double fgnorm,void *dummy)
51e7e93795SLois Curfman McInnes {
523a40ed3dSBarry Smith   PetscFunctionBegin;
53e7e93795SLois Curfman McInnes   if (snes->method_class == SNES_NONLINEAR_EQUATIONS) {
548f240d10SBarry Smith     if (fgnorm > 1.e-9) {
55c7ab52efSLois Curfman McInnes       PetscPrintf(snes->comm, "iter = %d, SNES Function norm %g \n",its,fgnorm);
563a40ed3dSBarry Smith     } else if (fgnorm > 1.e-11){
57c7ab52efSLois Curfman McInnes       PetscPrintf(snes->comm, "iter = %d, SNES Function norm %5.3e \n",its,fgnorm);
583a40ed3dSBarry Smith     } else {
59c7ab52efSLois Curfman McInnes       PetscPrintf(snes->comm, "iter = %d, SNES Function norm < 1.e-11\n",its);
60e7e93795SLois Curfman McInnes     }
61e7e93795SLois Curfman McInnes   } else if (snes->method_class == SNES_UNCONSTRAINED_MINIMIZATION) {
628f240d10SBarry Smith     if (fgnorm > 1.e-9) {
6377c4ece6SBarry Smith       PetscPrintf(snes->comm,
643a40ed3dSBarry Smith        "iter = %d, SNES Function value %g, Gradient norm %g \n",its,snes->fc,fgnorm);
653a40ed3dSBarry Smith     } else if (fgnorm > 1.e-11) {
6677c4ece6SBarry Smith       PetscPrintf(snes->comm,
673a40ed3dSBarry Smith         "iter = %d, SNES Function value %g, Gradient norm %5.3e \n",its,snes->fc,fgnorm);
683a40ed3dSBarry Smith     } else {
6977c4ece6SBarry Smith       PetscPrintf(snes->comm,
703a40ed3dSBarry Smith         "iter = %d, SNES Function value %g, Gradient norm < 1.e-11\n",its,snes->fc);
71e7e93795SLois Curfman McInnes     }
72a8c6a408SBarry Smith   } else SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Unknown method class");
733a40ed3dSBarry Smith   PetscFunctionReturn(0);
74e7e93795SLois Curfman McInnes }
75e7e93795SLois Curfman McInnes /* ---------------------------------------------------------------- */
765615d1e5SSatish Balay #undef __FUNC__
775615d1e5SSatish Balay #define __FUNC__ "SNESConverged_EQ_LS"
784b828684SBarry Smith /*@C
79f525115eSLois Curfman McInnes    SNESConverged_EQ_LS - Monitors the convergence of the solvers for
80f525115eSLois Curfman McInnes    systems of nonlinear equations (default).
81e7e93795SLois Curfman McInnes 
82e7e93795SLois Curfman McInnes    Input Parameters:
83e7e93795SLois Curfman McInnes .  snes - the SNES context
84e7e93795SLois Curfman McInnes .  xnorm - 2-norm of current iterate
85e7e93795SLois Curfman McInnes .  pnorm - 2-norm of current step
86e7e93795SLois Curfman McInnes .  fnorm - 2-norm of function
87e7e93795SLois Curfman McInnes .  dummy - unused context
88e7e93795SLois Curfman McInnes 
89e7e93795SLois Curfman McInnes    Returns:
90e7e93795SLois Curfman McInnes $  2  if  ( fnorm < atol ),
91e7e93795SLois Curfman McInnes $  3  if  ( pnorm < xtol*xnorm ),
925d2e0e51SBarry Smith $  4  if  ( fnorm < rtol*fnorm0 ),
93e7e93795SLois Curfman McInnes $ -2  if  ( nfct > maxf ),
94e7e93795SLois Curfman McInnes $  0  otherwise,
95e7e93795SLois Curfman McInnes 
96e7e93795SLois Curfman McInnes    where
97e7e93795SLois Curfman McInnes $    maxf - maximum number of function evaluations,
98acd914d5SLois Curfman McInnes $           set with SNESSetTolerances()
99e7e93795SLois Curfman McInnes $    nfct - number of function evaluations,
100e7e93795SLois Curfman McInnes $    atol - absolute function norm tolerance,
101acd914d5SLois Curfman McInnes $           set with SNESSetTolerances()
102d7a720efSLois Curfman McInnes $    rtol - relative function norm tolerance,
103acd914d5SLois Curfman McInnes $           set with SNESSetTolerances()
104e7e93795SLois Curfman McInnes 
105e7e93795SLois Curfman McInnes .keywords: SNES, nonlinear, default, converged, convergence
106e7e93795SLois Curfman McInnes 
107e7e93795SLois Curfman McInnes .seealso: SNESSetConvergenceTest(), SNESEisenstatWalkerConverged()
108e7e93795SLois Curfman McInnes @*/
10940191667SLois Curfman McInnes int SNESConverged_EQ_LS(SNES snes,double xnorm,double pnorm,double fnorm,void *dummy)
110e7e93795SLois Curfman McInnes {
1113a40ed3dSBarry Smith   PetscFunctionBegin;
112d252947aSBarry Smith   if (snes->method_class != SNES_NONLINEAR_EQUATIONS) {
113a8c6a408SBarry Smith      SETERRQ(PETSC_ERR_ARG_WRONG,0,"For SNES_NONLINEAR_EQUATIONS only");
114d252947aSBarry Smith   }
115082acdaeSLois Curfman McInnes   /* Note:  Reserve return code 1, -1 for compatibility with SNESConverged_EQ_TR */
116d252947aSBarry Smith   if (fnorm != fnorm) {
117981c4779SBarry Smith     PLogInfo(snes,"SNESConverged_EQ_LS:Failed to converged, function norm is NaN\n");
1183a40ed3dSBarry Smith     PetscFunctionReturn(-3);
119d252947aSBarry Smith   }
1205d2e0e51SBarry Smith   if (fnorm <= snes->ttol) {
12194a424c1SBarry Smith     PLogInfo(snes,
122981c4779SBarry Smith     "SNESConverged_EQ_LS:Converged due to function norm %g < %g (relative tolerance)\n",fnorm,snes->ttol);
1233a40ed3dSBarry Smith     PetscFunctionReturn(4);
1245d2e0e51SBarry Smith   }
1255d2e0e51SBarry Smith 
126e7e93795SLois Curfman McInnes   if (fnorm < snes->atol) {
12794a424c1SBarry Smith     PLogInfo(snes,
128981c4779SBarry Smith       "SNESConverged_EQ_LS: Converged due to function norm %g < %g\n",fnorm,snes->atol);
1293a40ed3dSBarry Smith     PetscFunctionReturn(2);
130e7e93795SLois Curfman McInnes   }
131e7e93795SLois Curfman McInnes   if (pnorm < snes->xtol*(xnorm)) {
13294a424c1SBarry Smith     PLogInfo(snes,
133981c4779SBarry Smith       "SNESConverged_EQ_LS: Converged due to small update length: %g < %g * %g\n",
134e7e93795SLois Curfman McInnes        pnorm,snes->xtol,xnorm);
1353a40ed3dSBarry Smith     PetscFunctionReturn(3);
136e7e93795SLois Curfman McInnes   }
137e7e93795SLois Curfman McInnes   if (snes->nfuncs > snes->max_funcs) {
138981c4779SBarry Smith     PLogInfo(snes,"SNESConverged_EQ_LS: Exceeded maximum number of function evaluations: %d > %d\n",
139e7e93795SLois Curfman McInnes       snes->nfuncs, snes->max_funcs );
1403a40ed3dSBarry Smith     PetscFunctionReturn(-2);
141e7e93795SLois Curfman McInnes   }
1423a40ed3dSBarry Smith   PetscFunctionReturn(0);
143e7e93795SLois Curfman McInnes }
144e7e93795SLois Curfman McInnes /* ------------------------------------------------------------ */
1455615d1e5SSatish Balay #undef __FUNC__
1465615d1e5SSatish Balay #define __FUNC__ "SNES_KSP_SetConvergenceTestEW"
147e7e93795SLois Curfman McInnes /*@
148f525115eSLois Curfman McInnes    SNES_KSP_SetConvergenceTestEW - Sets alternative convergence test
149e7e93795SLois Curfman McInnes    for the linear solvers within an inexact Newton method.
150e7e93795SLois Curfman McInnes 
151e7e93795SLois Curfman McInnes    Input Parameter:
152e7e93795SLois Curfman McInnes .  snes - SNES context
153e7e93795SLois Curfman McInnes 
154e7e93795SLois Curfman McInnes    Notes:
155e7e93795SLois Curfman McInnes    Currently, the default is to use a constant relative tolerance for
156e7e93795SLois Curfman McInnes    the inner linear solvers.  Alternatively, one can use the
157e7e93795SLois Curfman McInnes    Eisenstat-Walker method, where the relative convergence tolerance
158e7e93795SLois Curfman McInnes    is reset at each Newton iteration according progress of the nonlinear
159e7e93795SLois Curfman McInnes    solver.
160e7e93795SLois Curfman McInnes 
161e7e93795SLois Curfman McInnes    Reference:
162e7e93795SLois Curfman McInnes    S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an
163*e30ad881SLois Curfman McInnes    inexact Newton method", SISC 17 (1), pp.16-32, 1996.
164e7e93795SLois Curfman McInnes 
165e7e93795SLois Curfman McInnes .keywords: SNES, KSP, Eisenstat, Walker, convergence, test, inexact, Newton
166e7e93795SLois Curfman McInnes @*/
167e7e93795SLois Curfman McInnes int SNES_KSP_SetConvergenceTestEW(SNES snes)
168e7e93795SLois Curfman McInnes {
1693a40ed3dSBarry Smith   PetscFunctionBegin;
170e7e93795SLois Curfman McInnes   snes->ksp_ewconv = 1;
1713a40ed3dSBarry Smith   PetscFunctionReturn(0);
172e7e93795SLois Curfman McInnes }
173e7e93795SLois Curfman McInnes 
1745615d1e5SSatish Balay #undef __FUNC__
1755615d1e5SSatish Balay #define __FUNC__ "SNES_KSP_SetParametersEW"
176e7e93795SLois Curfman McInnes /*@
177e7e93795SLois Curfman McInnes    SNES_KSP_SetParametersEW - Sets parameters for Eisenstat-Walker
178e7e93795SLois Curfman McInnes    convergence criteria for the linear solvers within an inexact
179e7e93795SLois Curfman McInnes    Newton method.
180e7e93795SLois Curfman McInnes 
181e7e93795SLois Curfman McInnes    Input Parameters:
182e7e93795SLois Curfman McInnes .  snes - SNES context
183e7e93795SLois Curfman McInnes .  version - version 1 or 2 (default is 2)
184e7e93795SLois Curfman McInnes .  rtol_0 - initial relative tolerance
185e7e93795SLois Curfman McInnes $    (0 <= rtol_0 < 1)
186e7e93795SLois Curfman McInnes .  rtol_max - maximum relative tolerance
187e7e93795SLois Curfman McInnes $    (0 <= rtol_max < 1)
188e7e93795SLois Curfman McInnes .  alpha - power for version 2 rtol computation
189e7e93795SLois Curfman McInnes $    (1 < alpha <= 2)
190e7e93795SLois Curfman McInnes .  alpha2 - power for safeguard
191e7e93795SLois Curfman McInnes .  gamma2 - multiplicative factor for version 2 rtol computation
192e7e93795SLois Curfman McInnes $    (0 <= gamma2 <= 1)
193e7e93795SLois Curfman McInnes .  threshold - threshold for imposing safeguard
194e7e93795SLois Curfman McInnes $    (0 < threshold < 1)
195e7e93795SLois Curfman McInnes 
196e7e93795SLois Curfman McInnes    Note:
197e7e93795SLois Curfman McInnes    Use PETSC_DEFAULT to retain the default for any of the parameters.
198e7e93795SLois Curfman McInnes 
199e7e93795SLois Curfman McInnes    Reference:
200e7e93795SLois Curfman McInnes    S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an
201e7e93795SLois Curfman McInnes    inexact Newton method", Utah State University Math. Stat. Dept. Res.
202e7e93795SLois Curfman McInnes    Report 6/94/75, June, 1994, to appear in SIAM J. Sci. Comput.
203e7e93795SLois Curfman McInnes 
204e7e93795SLois Curfman McInnes .keywords: SNES, KSP, Eisenstat, Walker, set, parameters
205e7e93795SLois Curfman McInnes 
206e7e93795SLois Curfman McInnes .seealso: SNES_KSP_SetConvergenceTestEW()
207e7e93795SLois Curfman McInnes @*/
208e7e93795SLois Curfman McInnes int SNES_KSP_SetParametersEW(SNES snes,int version,double rtol_0,
209e7e93795SLois Curfman McInnes                              double rtol_max,double gamma2,double alpha,
210e7e93795SLois Curfman McInnes                              double alpha2,double threshold)
211e7e93795SLois Curfman McInnes {
212e7e93795SLois Curfman McInnes   SNES_KSP_EW_ConvCtx *kctx = (SNES_KSP_EW_ConvCtx*)snes->kspconvctx;
2133a40ed3dSBarry Smith 
2143a40ed3dSBarry Smith   PetscFunctionBegin;
215a8c6a408SBarry Smith   if (!kctx) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,0,"No Eisenstat-Walker context existing");
216e7e93795SLois Curfman McInnes   if (version != PETSC_DEFAULT)   kctx->version = version;
217e7e93795SLois Curfman McInnes   if (rtol_0 != PETSC_DEFAULT)    kctx->rtol_0 = rtol_0;
218e7e93795SLois Curfman McInnes   if (rtol_max != PETSC_DEFAULT)  kctx->rtol_max = rtol_max;
219e7e93795SLois Curfman McInnes   if (gamma2 != PETSC_DEFAULT)    kctx->gamma = gamma2;
220e7e93795SLois Curfman McInnes   if (alpha != PETSC_DEFAULT)     kctx->alpha = alpha;
221e7e93795SLois Curfman McInnes   if (alpha2 != PETSC_DEFAULT)    kctx->alpha2 = alpha2;
222e7e93795SLois Curfman McInnes   if (threshold != PETSC_DEFAULT) kctx->threshold = threshold;
223a8c6a408SBarry Smith   if (kctx->rtol_0 < 0.0 || kctx->rtol_0 >= 1.0) {
224a8c6a408SBarry Smith     SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"0.0 <= rtol_0 < 1.0\n");
225a8c6a408SBarry Smith   }
226a8c6a408SBarry Smith   if (kctx->rtol_max < 0.0 || kctx->rtol_max >= 1.0) {
227a8c6a408SBarry Smith     SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"0.0 <= rtol_max < 1.0\n");
228a8c6a408SBarry Smith   }
229a8c6a408SBarry Smith   if (kctx->threshold <= 0.0 || kctx->threshold >= 1.0) {
230a8c6a408SBarry Smith     SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"0.0 < threshold < 1.0\n");
231a8c6a408SBarry Smith   }
232a8c6a408SBarry Smith   if (kctx->gamma < 0.0 || kctx->gamma > 1.0) {
233a8c6a408SBarry Smith     SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"0.0 <= alpha <= 1.0\n");
234a8c6a408SBarry Smith   }
235a8c6a408SBarry Smith   if (kctx->alpha <= 1.0 || kctx->alpha > 2.0) {
236a8c6a408SBarry Smith     SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"1.0 < alpha <= 2.0\n");
237a8c6a408SBarry Smith   }
238a8c6a408SBarry Smith   if (kctx->version != 1 && kctx->version !=2) {
239a8c6a408SBarry Smith     SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Only versions 1 and 2 are supported");
240a8c6a408SBarry Smith   }
2413a40ed3dSBarry Smith   PetscFunctionReturn(0);
242e7e93795SLois Curfman McInnes }
243e7e93795SLois Curfman McInnes 
2445615d1e5SSatish Balay #undef __FUNC__
2455615d1e5SSatish Balay #define __FUNC__ "SNES_KSP_EW_ComputeRelativeTolerance_Private"
246e7e93795SLois Curfman McInnes int SNES_KSP_EW_ComputeRelativeTolerance_Private(SNES snes,KSP ksp)
247e7e93795SLois Curfman McInnes {
248e7e93795SLois Curfman McInnes   SNES_KSP_EW_ConvCtx *kctx = (SNES_KSP_EW_ConvCtx*)snes->kspconvctx;
249e7e93795SLois Curfman McInnes   double rtol, stol;
250e7e93795SLois Curfman McInnes   int    ierr;
2513a40ed3dSBarry Smith 
2523a40ed3dSBarry Smith   PetscFunctionBegin;
253a8c6a408SBarry Smith   if (!kctx) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,0,"No Eisenstat-Walker context exists");
254e7e93795SLois Curfman McInnes   if (snes->iter == 1) {
255e7e93795SLois Curfman McInnes     rtol = kctx->rtol_0;
256e7e93795SLois Curfman McInnes   } else {
257e7e93795SLois Curfman McInnes     if (kctx->version == 1) {
258e7e93795SLois Curfman McInnes       rtol = (snes->norm - kctx->lresid_last)/kctx->norm_last;
259e7e93795SLois Curfman McInnes       if (rtol < 0.0) rtol = -rtol;
260e7e93795SLois Curfman McInnes       stol = pow(kctx->rtol_last,kctx->alpha2);
2610452661fSBarry Smith       if (stol > kctx->threshold) rtol = PetscMax(rtol,stol);
262e7e93795SLois Curfman McInnes     } else if (kctx->version == 2) {
263e7e93795SLois Curfman McInnes       rtol = kctx->gamma * pow(snes->norm/kctx->norm_last,kctx->alpha);
264e7e93795SLois Curfman McInnes       stol = kctx->gamma * pow(kctx->rtol_last,kctx->alpha);
2650452661fSBarry Smith       if (stol > kctx->threshold) rtol = PetscMax(rtol,stol);
266a8c6a408SBarry Smith     } else SETERRQ( PETSC_ERR_ARG_OUTOFRANGE,0,"Only versions 1 or 2 are supported");
267e7e93795SLois Curfman McInnes   }
2680452661fSBarry Smith   rtol = PetscMin(rtol,kctx->rtol_max);
269e7e93795SLois Curfman McInnes   kctx->rtol_last = rtol;
270981c4779SBarry Smith   PLogInfo(snes,"SNESConverged_EQ_LS: iter %d, Eisenstat-Walker (version %d) KSP rtol = %g\n",
271e7e93795SLois Curfman McInnes            snes->iter,kctx->version,rtol);
2723131a8b6SLois Curfman McInnes   ierr = KSPSetTolerances(ksp,rtol,PETSC_DEFAULT,PETSC_DEFAULT,PETSC_DEFAULT); CHKERRQ(ierr);
273e7e93795SLois Curfman McInnes   kctx->norm_last = snes->norm;
2743a40ed3dSBarry Smith   PetscFunctionReturn(0);
275e7e93795SLois Curfman McInnes }
276e7e93795SLois Curfman McInnes 
2775615d1e5SSatish Balay #undef __FUNC__
2785615d1e5SSatish Balay #define __FUNC__ "SNES_KSP_EW_Converged_Private"
279e7e93795SLois Curfman McInnes int SNES_KSP_EW_Converged_Private(KSP ksp,int n,double rnorm,void *ctx)
280e7e93795SLois Curfman McInnes {
281e7e93795SLois Curfman McInnes   SNES                snes = (SNES)ctx;
282e7e93795SLois Curfman McInnes   SNES_KSP_EW_ConvCtx *kctx = (SNES_KSP_EW_ConvCtx*)snes->kspconvctx;
283e7e93795SLois Curfman McInnes   int                 convinfo;
284e7e93795SLois Curfman McInnes 
2853a40ed3dSBarry Smith   PetscFunctionBegin;
286a8c6a408SBarry Smith   if (!kctx) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,0,"No Eisenstat-Walker context set");
287e7e93795SLois Curfman McInnes   if (n == 0) SNES_KSP_EW_ComputeRelativeTolerance_Private(snes,ksp);
288e7e93795SLois Curfman McInnes   convinfo = KSPDefaultConverged(ksp,n,rnorm,ctx);
289e7e93795SLois Curfman McInnes   kctx->lresid_last = rnorm;
2903a40ed3dSBarry Smith   if (convinfo) {
291981c4779SBarry Smith     PLogInfo(snes,"SNES_KSP_EW_Converged_Private: KSP iterations=%d, rnorm=%g\n",n,rnorm);
2923a40ed3dSBarry Smith   }
2933a40ed3dSBarry Smith   PetscFunctionReturn(convinfo);
294e7e93795SLois Curfman McInnes }
295e7e93795SLois Curfman McInnes 
296e7e93795SLois Curfman McInnes 
297