1a5eb4965SSatish Balay #ifdef PETSC_RCS_HEADER 2*15091d37SBarry Smith static char vcid[] = "$Id: snesut.c,v 1.44 1999/02/01 03:22:39 curfman Exp bsmith $"; 3e7e93795SLois Curfman McInnes #endif 4e7e93795SLois Curfman McInnes 570f55243SBarry Smith #include "src/snes/snesimpl.h" /*I "snes.h" I*/ 6e7e93795SLois Curfman McInnes 75615d1e5SSatish Balay #undef __FUNC__ 83f1db9ecSBarry Smith #define __FUNC__ "SNESVecViewMonitor" 93f1db9ecSBarry Smith /*@C 1036851e7fSLois Curfman McInnes SNESVecViewMonitor - Monitors progress of the SNES solvers by calling 1136851e7fSLois Curfman McInnes VecView() for the approximate solution at each iteration. 123f1db9ecSBarry Smith 133f1db9ecSBarry Smith Collective on SNES 143f1db9ecSBarry Smith 153f1db9ecSBarry Smith Input Parameters: 163f1db9ecSBarry Smith + snes - the SNES context 173f1db9ecSBarry Smith . its - iteration number 183f1db9ecSBarry Smith . fgnorm - 2-norm of residual (or gradient) 193f1db9ecSBarry Smith - dummy - either a viewer or PETSC_NULL 203f1db9ecSBarry Smith 2136851e7fSLois Curfman McInnes Level: intermediate 223f1db9ecSBarry Smith 2336851e7fSLois Curfman McInnes .keywords: SNES, nonlinear, vector, monitor, view 243f1db9ecSBarry Smith 2536851e7fSLois Curfman McInnes .seealso: SNESSetMonitor(), SNESDefaultMonitor(), VecView() 263f1db9ecSBarry Smith @*/ 273f1db9ecSBarry Smith int SNESVecViewMonitor(SNES snes,int its,double fgnorm,void *dummy) 283f1db9ecSBarry Smith { 293f1db9ecSBarry Smith int ierr; 303f1db9ecSBarry Smith Vec x; 313f1db9ecSBarry Smith Viewer viewer = (Viewer) dummy; 323f1db9ecSBarry Smith 333f1db9ecSBarry Smith PetscFunctionBegin; 343f1db9ecSBarry Smith ierr = SNESGetSolution(snes,&x);CHKERRQ(ierr); 353f1db9ecSBarry Smith if (!viewer) { 363f1db9ecSBarry Smith MPI_Comm comm; 373f1db9ecSBarry Smith ierr = PetscObjectGetComm((PetscObject)snes,&comm);CHKERRQ(ierr); 38c655490fSBarry Smith viewer = VIEWER_DRAW_(comm); 393f1db9ecSBarry Smith } 403f1db9ecSBarry Smith ierr = VecView(x,viewer);CHKERRQ(ierr); 413f1db9ecSBarry Smith 423f1db9ecSBarry Smith PetscFunctionReturn(0); 433f1db9ecSBarry Smith } 443f1db9ecSBarry Smith 453f1db9ecSBarry Smith #undef __FUNC__ 46d4bb536fSBarry Smith #define __FUNC__ "SNESDefaultMonitor" 474b828684SBarry Smith /*@C 48f525115eSLois Curfman McInnes SNESDefaultMonitor - Monitoring progress of the SNES solvers (default). 49e7e93795SLois Curfman McInnes 50c7afd0dbSLois Curfman McInnes Collective on SNES 51c7afd0dbSLois Curfman McInnes 52e7e93795SLois Curfman McInnes Input Parameters: 53c7afd0dbSLois Curfman McInnes + snes - the SNES context 54e7e93795SLois Curfman McInnes . its - iteration number 55e7e93795SLois Curfman McInnes . fgnorm - 2-norm of residual (or gradient) 56c7afd0dbSLois Curfman McInnes - dummy - unused context 57fee21e36SBarry Smith 58e7e93795SLois Curfman McInnes Notes: 59e7e93795SLois Curfman McInnes For SNES_NONLINEAR_EQUATIONS methods the routine prints the 60e7e93795SLois Curfman McInnes residual norm at each iteration. 61e7e93795SLois Curfman McInnes 62e7e93795SLois Curfman McInnes For SNES_UNCONSTRAINED_MINIMIZATION methods the routine prints the 63e7e93795SLois Curfman McInnes function value and gradient norm at each iteration. 64e7e93795SLois Curfman McInnes 6536851e7fSLois Curfman McInnes Level: intermediate 6636851e7fSLois Curfman McInnes 67e7e93795SLois Curfman McInnes .keywords: SNES, nonlinear, default, monitor, norm 68e7e93795SLois Curfman McInnes 6936851e7fSLois Curfman McInnes .seealso: SNESSetMonitor(), SNESVecViewMonitor() 70e7e93795SLois Curfman McInnes @*/ 71e7e93795SLois Curfman McInnes int SNESDefaultMonitor(SNES snes,int its,double fgnorm,void *dummy) 72e7e93795SLois Curfman McInnes { 733a40ed3dSBarry Smith PetscFunctionBegin; 7476be9ce4SBarry Smith if (snes->method_class == SNES_NONLINEAR_EQUATIONS) { 7577c4ece6SBarry Smith PetscPrintf(snes->comm, "iter = %d, SNES Function norm %g \n",its,fgnorm); 7676be9ce4SBarry Smith } else if (snes->method_class == SNES_UNCONSTRAINED_MINIMIZATION) { 773a40ed3dSBarry Smith PetscPrintf(snes->comm,"iter = %d, SNES Function value %g, Gradient norm %g \n",its,snes->fc,fgnorm); 7876be9ce4SBarry Smith } else SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Unknown method class"); 793a40ed3dSBarry Smith PetscFunctionReturn(0); 80e7e93795SLois Curfman McInnes } 813f1db9ecSBarry Smith 82e7e93795SLois Curfman McInnes /* ---------------------------------------------------------------- */ 835615d1e5SSatish Balay #undef __FUNC__ 84d4bb536fSBarry Smith #define __FUNC__ "SNESDefaultSMonitor" 85be1f7002SBarry Smith /* 86be1f7002SBarry Smith Default (short) SNES Monitor, same as SNESDefaultMonitor() except 87be1f7002SBarry Smith it prints fewer digits of the residual as the residual gets smaller. 88be1f7002SBarry Smith This is because the later digits are meaningless and are often 89be1f7002SBarry Smith different on different machines; by using this routine different 90be1f7002SBarry Smith machines will usually generate the same output. 91be1f7002SBarry Smith */ 92e7e93795SLois Curfman McInnes int SNESDefaultSMonitor(SNES snes,int its, double fgnorm,void *dummy) 93e7e93795SLois Curfman McInnes { 943a40ed3dSBarry Smith PetscFunctionBegin; 95e7e93795SLois Curfman McInnes if (snes->method_class == SNES_NONLINEAR_EQUATIONS) { 968f240d10SBarry Smith if (fgnorm > 1.e-9) { 97c7ab52efSLois Curfman McInnes PetscPrintf(snes->comm, "iter = %d, SNES Function norm %g \n",its,fgnorm); 983a40ed3dSBarry Smith } else if (fgnorm > 1.e-11){ 99c7ab52efSLois Curfman McInnes PetscPrintf(snes->comm, "iter = %d, SNES Function norm %5.3e \n",its,fgnorm); 1003a40ed3dSBarry Smith } else { 101c7ab52efSLois Curfman McInnes PetscPrintf(snes->comm, "iter = %d, SNES Function norm < 1.e-11\n",its); 102e7e93795SLois Curfman McInnes } 103e7e93795SLois Curfman McInnes } else if (snes->method_class == SNES_UNCONSTRAINED_MINIMIZATION) { 1048f240d10SBarry Smith if (fgnorm > 1.e-9) { 10577c4ece6SBarry Smith PetscPrintf(snes->comm, 1063a40ed3dSBarry Smith "iter = %d, SNES Function value %g, Gradient norm %g \n",its,snes->fc,fgnorm); 1073a40ed3dSBarry Smith } else if (fgnorm > 1.e-11) { 10877c4ece6SBarry Smith PetscPrintf(snes->comm, 1093a40ed3dSBarry Smith "iter = %d, SNES Function value %g, Gradient norm %5.3e \n",its,snes->fc,fgnorm); 1103a40ed3dSBarry Smith } else { 11177c4ece6SBarry Smith PetscPrintf(snes->comm, 1123a40ed3dSBarry Smith "iter = %d, SNES Function value %g, Gradient norm < 1.e-11\n",its,snes->fc); 113e7e93795SLois Curfman McInnes } 114a8c6a408SBarry Smith } else SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Unknown method class"); 1153a40ed3dSBarry Smith PetscFunctionReturn(0); 116e7e93795SLois Curfman McInnes } 117e7e93795SLois Curfman McInnes /* ---------------------------------------------------------------- */ 1185615d1e5SSatish Balay #undef __FUNC__ 1195615d1e5SSatish Balay #define __FUNC__ "SNESConverged_EQ_LS" 1204b828684SBarry Smith /*@C 121f525115eSLois Curfman McInnes SNESConverged_EQ_LS - Monitors the convergence of the solvers for 122f525115eSLois Curfman McInnes systems of nonlinear equations (default). 123e7e93795SLois Curfman McInnes 124c7afd0dbSLois Curfman McInnes Collective on SNES 125c7afd0dbSLois Curfman McInnes 126e7e93795SLois Curfman McInnes Input Parameters: 127c7afd0dbSLois Curfman McInnes + snes - the SNES context 128e7e93795SLois Curfman McInnes . xnorm - 2-norm of current iterate 129e7e93795SLois Curfman McInnes . pnorm - 2-norm of current step 130e7e93795SLois Curfman McInnes . fnorm - 2-norm of function 131c7afd0dbSLois Curfman McInnes - dummy - unused context 132e7e93795SLois Curfman McInnes 133e7e93795SLois Curfman McInnes Returns: 134c7afd0dbSLois Curfman McInnes + 2 - if ( fnorm < atol ), 135c7afd0dbSLois Curfman McInnes . 3 - if ( pnorm < xtol*xnorm ), 136c7afd0dbSLois Curfman McInnes . 4 - if ( fnorm < rtol*fnorm0 ), 137c7afd0dbSLois Curfman McInnes . -2 - if ( nfct > maxf ), 138c7afd0dbSLois Curfman McInnes - 0 - otherwise, 139e7e93795SLois Curfman McInnes 140e7e93795SLois Curfman McInnes where 141c7afd0dbSLois Curfman McInnes + maxf - maximum number of function evaluations, 142c7afd0dbSLois Curfman McInnes set with SNESSetTolerances() 143c7afd0dbSLois Curfman McInnes . nfct - number of function evaluations, 144c7afd0dbSLois Curfman McInnes . atol - absolute function norm tolerance, 145c7afd0dbSLois Curfman McInnes set with SNESSetTolerances() 146c7afd0dbSLois Curfman McInnes - rtol - relative function norm tolerance, set with SNESSetTolerances() 147fee21e36SBarry Smith 14836851e7fSLois Curfman McInnes Level: intermediate 14936851e7fSLois Curfman McInnes 150e7e93795SLois Curfman McInnes .keywords: SNES, nonlinear, default, converged, convergence 151e7e93795SLois Curfman McInnes 152e7e93795SLois Curfman McInnes .seealso: SNESSetConvergenceTest(), SNESEisenstatWalkerConverged() 153e7e93795SLois Curfman McInnes @*/ 15440191667SLois Curfman McInnes int SNESConverged_EQ_LS(SNES snes,double xnorm,double pnorm,double fnorm,void *dummy) 155e7e93795SLois Curfman McInnes { 1563a40ed3dSBarry Smith PetscFunctionBegin; 157d252947aSBarry Smith if (snes->method_class != SNES_NONLINEAR_EQUATIONS) { 158a8c6a408SBarry Smith SETERRQ(PETSC_ERR_ARG_WRONG,0,"For SNES_NONLINEAR_EQUATIONS only"); 159d252947aSBarry Smith } 160082acdaeSLois Curfman McInnes /* Note: Reserve return code 1, -1 for compatibility with SNESConverged_EQ_TR */ 161d252947aSBarry Smith if (fnorm != fnorm) { 162981c4779SBarry Smith PLogInfo(snes,"SNESConverged_EQ_LS:Failed to converged, function norm is NaN\n"); 1633a40ed3dSBarry Smith PetscFunctionReturn(-3); 164d252947aSBarry Smith } 1655d2e0e51SBarry Smith if (fnorm <= snes->ttol) { 166*15091d37SBarry Smith PLogInfo(snes,"SNESConverged_EQ_LS:Converged due to function norm %g < %g (relative tolerance)\n",fnorm,snes->ttol); 1673a40ed3dSBarry Smith PetscFunctionReturn(4); 1685d2e0e51SBarry Smith } 1695d2e0e51SBarry Smith 170e7e93795SLois Curfman McInnes if (fnorm < snes->atol) { 171*15091d37SBarry Smith PLogInfo(snes,"SNESConverged_EQ_LS:Converged due to function norm %g < %g\n",fnorm,snes->atol); 1723a40ed3dSBarry Smith PetscFunctionReturn(2); 173e7e93795SLois Curfman McInnes } 174e7e93795SLois Curfman McInnes if (pnorm < snes->xtol*(xnorm)) { 175*15091d37SBarry Smith PLogInfo(snes,"SNESConverged_EQ_LS:Converged due to small update length: %g < %g * %g\n",pnorm,snes->xtol,xnorm); 1763a40ed3dSBarry Smith PetscFunctionReturn(3); 177e7e93795SLois Curfman McInnes } 178e7e93795SLois Curfman McInnes if (snes->nfuncs > snes->max_funcs) { 179*15091d37SBarry Smith PLogInfo(snes,"SNESConverged_EQ_LS:Exceeded maximum number of function evaluations: %d > %d\n",snes->nfuncs, snes->max_funcs); 1803a40ed3dSBarry Smith PetscFunctionReturn(-2); 181e7e93795SLois Curfman McInnes } 1823a40ed3dSBarry Smith PetscFunctionReturn(0); 183e7e93795SLois Curfman McInnes } 184e7e93795SLois Curfman McInnes /* ------------------------------------------------------------ */ 1855615d1e5SSatish Balay #undef __FUNC__ 1865615d1e5SSatish Balay #define __FUNC__ "SNES_KSP_SetConvergenceTestEW" 187e7e93795SLois Curfman McInnes /*@ 188f525115eSLois Curfman McInnes SNES_KSP_SetConvergenceTestEW - Sets alternative convergence test 189e7e93795SLois Curfman McInnes for the linear solvers within an inexact Newton method. 190e7e93795SLois Curfman McInnes 191c7afd0dbSLois Curfman McInnes Collective on SNES 192c7afd0dbSLois Curfman McInnes 193e7e93795SLois Curfman McInnes Input Parameter: 194e7e93795SLois Curfman McInnes . snes - SNES context 195e7e93795SLois Curfman McInnes 196e7e93795SLois Curfman McInnes Notes: 197e7e93795SLois Curfman McInnes Currently, the default is to use a constant relative tolerance for 198e7e93795SLois Curfman McInnes the inner linear solvers. Alternatively, one can use the 199e7e93795SLois Curfman McInnes Eisenstat-Walker method, where the relative convergence tolerance 200e7e93795SLois Curfman McInnes is reset at each Newton iteration according progress of the nonlinear 201e7e93795SLois Curfman McInnes solver. 202e7e93795SLois Curfman McInnes 20336851e7fSLois Curfman McInnes Level: advanced 20436851e7fSLois Curfman McInnes 205e7e93795SLois Curfman McInnes Reference: 206e7e93795SLois Curfman McInnes S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an 207e30ad881SLois Curfman McInnes inexact Newton method", SISC 17 (1), pp.16-32, 1996. 208e7e93795SLois Curfman McInnes 209e7e93795SLois Curfman McInnes .keywords: SNES, KSP, Eisenstat, Walker, convergence, test, inexact, Newton 210e7e93795SLois Curfman McInnes @*/ 211e7e93795SLois Curfman McInnes int SNES_KSP_SetConvergenceTestEW(SNES snes) 212e7e93795SLois Curfman McInnes { 2133a40ed3dSBarry Smith PetscFunctionBegin; 214e7e93795SLois Curfman McInnes snes->ksp_ewconv = 1; 2153a40ed3dSBarry Smith PetscFunctionReturn(0); 216e7e93795SLois Curfman McInnes } 217e7e93795SLois Curfman McInnes 2185615d1e5SSatish Balay #undef __FUNC__ 2195615d1e5SSatish Balay #define __FUNC__ "SNES_KSP_SetParametersEW" 220e7e93795SLois Curfman McInnes /*@ 221e7e93795SLois Curfman McInnes SNES_KSP_SetParametersEW - Sets parameters for Eisenstat-Walker 222e7e93795SLois Curfman McInnes convergence criteria for the linear solvers within an inexact 223e7e93795SLois Curfman McInnes Newton method. 224e7e93795SLois Curfman McInnes 225c7afd0dbSLois Curfman McInnes Collective on SNES 226c7afd0dbSLois Curfman McInnes 227e7e93795SLois Curfman McInnes Input Parameters: 228c7afd0dbSLois Curfman McInnes + snes - SNES context 229e7e93795SLois Curfman McInnes . version - version 1 or 2 (default is 2) 230c7afd0dbSLois Curfman McInnes . rtol_0 - initial relative tolerance (0 <= rtol_0 < 1) 231c7afd0dbSLois Curfman McInnes . rtol_max - maximum relative tolerance (0 <= rtol_max < 1) 232c7afd0dbSLois Curfman McInnes . alpha - power for version 2 rtol computation (1 < alpha <= 2) 233e7e93795SLois Curfman McInnes . alpha2 - power for safeguard 234e7e93795SLois Curfman McInnes . gamma2 - multiplicative factor for version 2 rtol computation 235c7afd0dbSLois Curfman McInnes (0 <= gamma2 <= 1) 236c7afd0dbSLois Curfman McInnes - threshold - threshold for imposing safeguard (0 < threshold < 1) 237fee21e36SBarry Smith 238e7e93795SLois Curfman McInnes Note: 239e7e93795SLois Curfman McInnes Use PETSC_DEFAULT to retain the default for any of the parameters. 240e7e93795SLois Curfman McInnes 24136851e7fSLois Curfman McInnes Level: advanced 24236851e7fSLois Curfman McInnes 243e7e93795SLois Curfman McInnes Reference: 244e7e93795SLois Curfman McInnes S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an 245e7e93795SLois Curfman McInnes inexact Newton method", Utah State University Math. Stat. Dept. Res. 246e7e93795SLois Curfman McInnes Report 6/94/75, June, 1994, to appear in SIAM J. Sci. Comput. 247e7e93795SLois Curfman McInnes 248e7e93795SLois Curfman McInnes .keywords: SNES, KSP, Eisenstat, Walker, set, parameters 249e7e93795SLois Curfman McInnes 250e7e93795SLois Curfman McInnes .seealso: SNES_KSP_SetConvergenceTestEW() 251e7e93795SLois Curfman McInnes @*/ 252e7e93795SLois Curfman McInnes int SNES_KSP_SetParametersEW(SNES snes,int version,double rtol_0, 253e7e93795SLois Curfman McInnes double rtol_max,double gamma2,double alpha, 254e7e93795SLois Curfman McInnes double alpha2,double threshold) 255e7e93795SLois Curfman McInnes { 256e7e93795SLois Curfman McInnes SNES_KSP_EW_ConvCtx *kctx = (SNES_KSP_EW_ConvCtx*)snes->kspconvctx; 2573a40ed3dSBarry Smith 2583a40ed3dSBarry Smith PetscFunctionBegin; 259a8c6a408SBarry Smith if (!kctx) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,0,"No Eisenstat-Walker context existing"); 260e7e93795SLois Curfman McInnes if (version != PETSC_DEFAULT) kctx->version = version; 261e7e93795SLois Curfman McInnes if (rtol_0 != PETSC_DEFAULT) kctx->rtol_0 = rtol_0; 262e7e93795SLois Curfman McInnes if (rtol_max != PETSC_DEFAULT) kctx->rtol_max = rtol_max; 263e7e93795SLois Curfman McInnes if (gamma2 != PETSC_DEFAULT) kctx->gamma = gamma2; 264e7e93795SLois Curfman McInnes if (alpha != PETSC_DEFAULT) kctx->alpha = alpha; 265e7e93795SLois Curfman McInnes if (alpha2 != PETSC_DEFAULT) kctx->alpha2 = alpha2; 266e7e93795SLois Curfman McInnes if (threshold != PETSC_DEFAULT) kctx->threshold = threshold; 267a8c6a408SBarry Smith if (kctx->rtol_0 < 0.0 || kctx->rtol_0 >= 1.0) { 268596552b5SBarry Smith SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,0,"0.0 <= rtol_0 < 1.0: %g",kctx->rtol_0); 269a8c6a408SBarry Smith } 270a8c6a408SBarry Smith if (kctx->rtol_max < 0.0 || kctx->rtol_max >= 1.0) { 271596552b5SBarry Smith SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,0,"0.0 <= rtol_max < 1.0\n",kctx->rtol_max); 272a8c6a408SBarry Smith } 273a8c6a408SBarry Smith if (kctx->threshold <= 0.0 || kctx->threshold >= 1.0) { 274596552b5SBarry Smith SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,0,"0.0 < threshold < 1.0\n",kctx->threshold); 275a8c6a408SBarry Smith } 276a8c6a408SBarry Smith if (kctx->gamma < 0.0 || kctx->gamma > 1.0) { 277596552b5SBarry Smith SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,0,"0.0 <= alpha <= 1.0\n",kctx->gamma); 278a8c6a408SBarry Smith } 279a8c6a408SBarry Smith if (kctx->alpha <= 1.0 || kctx->alpha > 2.0) { 280596552b5SBarry Smith SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,0,"1.0 < alpha <= 2.0\n",kctx->alpha); 281a8c6a408SBarry Smith } 282a8c6a408SBarry Smith if (kctx->version != 1 && kctx->version !=2) { 283596552b5SBarry Smith SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,0,"Only versions 1 and 2 are supported: %d",kctx->version); 284a8c6a408SBarry Smith } 2853a40ed3dSBarry Smith PetscFunctionReturn(0); 286e7e93795SLois Curfman McInnes } 287e7e93795SLois Curfman McInnes 2885615d1e5SSatish Balay #undef __FUNC__ 2895615d1e5SSatish Balay #define __FUNC__ "SNES_KSP_EW_ComputeRelativeTolerance_Private" 290e7e93795SLois Curfman McInnes int SNES_KSP_EW_ComputeRelativeTolerance_Private(SNES snes,KSP ksp) 291e7e93795SLois Curfman McInnes { 292e7e93795SLois Curfman McInnes SNES_KSP_EW_ConvCtx *kctx = (SNES_KSP_EW_ConvCtx*)snes->kspconvctx; 2933f1db9ecSBarry Smith double rtol = 0.0, stol; 294e7e93795SLois Curfman McInnes int ierr; 2953a40ed3dSBarry Smith 2963a40ed3dSBarry Smith PetscFunctionBegin; 297a8c6a408SBarry Smith if (!kctx) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,0,"No Eisenstat-Walker context exists"); 298e7e93795SLois Curfman McInnes if (snes->iter == 1) { 299e7e93795SLois Curfman McInnes rtol = kctx->rtol_0; 300e7e93795SLois Curfman McInnes } else { 301e7e93795SLois Curfman McInnes if (kctx->version == 1) { 302e7e93795SLois Curfman McInnes rtol = (snes->norm - kctx->lresid_last)/kctx->norm_last; 303e7e93795SLois Curfman McInnes if (rtol < 0.0) rtol = -rtol; 304e7e93795SLois Curfman McInnes stol = pow(kctx->rtol_last,kctx->alpha2); 3050452661fSBarry Smith if (stol > kctx->threshold) rtol = PetscMax(rtol,stol); 306e7e93795SLois Curfman McInnes } else if (kctx->version == 2) { 307e7e93795SLois Curfman McInnes rtol = kctx->gamma * pow(snes->norm/kctx->norm_last,kctx->alpha); 308e7e93795SLois Curfman McInnes stol = kctx->gamma * pow(kctx->rtol_last,kctx->alpha); 3090452661fSBarry Smith if (stol > kctx->threshold) rtol = PetscMax(rtol,stol); 310596552b5SBarry Smith } else SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,0,"Only versions 1 or 2 are supported: %d",kctx->version); 311e7e93795SLois Curfman McInnes } 3120452661fSBarry Smith rtol = PetscMin(rtol,kctx->rtol_max); 313e7e93795SLois Curfman McInnes kctx->rtol_last = rtol; 314596552b5SBarry Smith PLogInfo(snes,"SNESConverged_EQ_LS: iter %d, Eisenstat-Walker (version %d) KSP rtol = %g\n",snes->iter,kctx->version,rtol); 3153131a8b6SLois Curfman McInnes ierr = KSPSetTolerances(ksp,rtol,PETSC_DEFAULT,PETSC_DEFAULT,PETSC_DEFAULT); CHKERRQ(ierr); 316e7e93795SLois Curfman McInnes kctx->norm_last = snes->norm; 3173a40ed3dSBarry Smith PetscFunctionReturn(0); 318e7e93795SLois Curfman McInnes } 319e7e93795SLois Curfman McInnes 3205615d1e5SSatish Balay #undef __FUNC__ 3215615d1e5SSatish Balay #define __FUNC__ "SNES_KSP_EW_Converged_Private" 322e7e93795SLois Curfman McInnes int SNES_KSP_EW_Converged_Private(KSP ksp,int n,double rnorm,void *ctx) 323e7e93795SLois Curfman McInnes { 324e7e93795SLois Curfman McInnes SNES snes = (SNES)ctx; 325e7e93795SLois Curfman McInnes SNES_KSP_EW_ConvCtx *kctx = (SNES_KSP_EW_ConvCtx*)snes->kspconvctx; 326e7e93795SLois Curfman McInnes int convinfo; 327e7e93795SLois Curfman McInnes 3283a40ed3dSBarry Smith PetscFunctionBegin; 329a8c6a408SBarry Smith if (!kctx) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,0,"No Eisenstat-Walker context set"); 330e7e93795SLois Curfman McInnes if (n == 0) SNES_KSP_EW_ComputeRelativeTolerance_Private(snes,ksp); 331e7e93795SLois Curfman McInnes convinfo = KSPDefaultConverged(ksp,n,rnorm,ctx); 332e7e93795SLois Curfman McInnes kctx->lresid_last = rnorm; 3333a40ed3dSBarry Smith if (convinfo) { 334981c4779SBarry Smith PLogInfo(snes,"SNES_KSP_EW_Converged_Private: KSP iterations=%d, rnorm=%g\n",n,rnorm); 3353a40ed3dSBarry Smith } 3363a40ed3dSBarry Smith PetscFunctionReturn(convinfo); 337e7e93795SLois Curfman McInnes } 338e7e93795SLois Curfman McInnes 339e7e93795SLois Curfman McInnes 340