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