1a5eb4965SSatish Balay #ifdef PETSC_RCS_HEADER 2*184914b5SBarry Smith static char vcid[] = "$Id: snesut.c,v 1.47 1999/05/04 20:35:43 balay 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__ 46d132466eSBarry Smith #define __FUNC__ "SNESVecViewMonitorUpdate" 47d132466eSBarry Smith /*@C 48d132466eSBarry Smith SNESVecViewMonitorUpdate - Monitors progress of the SNES solvers by calling 49d132466eSBarry Smith VecView() for the UPDATE to the solution at each iteration. 50d132466eSBarry Smith 51d132466eSBarry Smith Collective on SNES 52d132466eSBarry Smith 53d132466eSBarry Smith Input Parameters: 54d132466eSBarry Smith + snes - the SNES context 55d132466eSBarry Smith . its - iteration number 56d132466eSBarry Smith . fgnorm - 2-norm of residual (or gradient) 57d132466eSBarry Smith - dummy - either a viewer or PETSC_NULL 58d132466eSBarry Smith 59d132466eSBarry Smith Level: intermediate 60d132466eSBarry Smith 61d132466eSBarry Smith .keywords: SNES, nonlinear, vector, monitor, view 62d132466eSBarry Smith 63d132466eSBarry Smith .seealso: SNESSetMonitor(), SNESDefaultMonitor(), VecView() 64d132466eSBarry Smith @*/ 65d132466eSBarry Smith int SNESVecViewMonitorUpdate(SNES snes,int its,double fgnorm,void *dummy) 66d132466eSBarry Smith { 67d132466eSBarry Smith int ierr; 68d132466eSBarry Smith Vec x; 69d132466eSBarry Smith Viewer viewer = (Viewer) dummy; 70d132466eSBarry Smith 71d132466eSBarry Smith PetscFunctionBegin; 72d132466eSBarry Smith ierr = SNESGetSolutionUpdate(snes,&x);CHKERRQ(ierr); 73d132466eSBarry Smith if (!viewer) { 74d132466eSBarry Smith MPI_Comm comm; 75d132466eSBarry Smith ierr = PetscObjectGetComm((PetscObject)snes,&comm);CHKERRQ(ierr); 76d132466eSBarry Smith viewer = VIEWER_DRAW_(comm); 77d132466eSBarry Smith } 78d132466eSBarry Smith ierr = VecView(x,viewer);CHKERRQ(ierr); 79d132466eSBarry Smith 80d132466eSBarry Smith PetscFunctionReturn(0); 81d132466eSBarry Smith } 82d132466eSBarry Smith 83d132466eSBarry Smith #undef __FUNC__ 84d4bb536fSBarry Smith #define __FUNC__ "SNESDefaultMonitor" 854b828684SBarry Smith /*@C 86f525115eSLois Curfman McInnes SNESDefaultMonitor - Monitoring progress of the SNES solvers (default). 87e7e93795SLois Curfman McInnes 88c7afd0dbSLois Curfman McInnes Collective on SNES 89c7afd0dbSLois Curfman McInnes 90e7e93795SLois Curfman McInnes Input Parameters: 91c7afd0dbSLois Curfman McInnes + snes - the SNES context 92e7e93795SLois Curfman McInnes . its - iteration number 93e7e93795SLois Curfman McInnes . fgnorm - 2-norm of residual (or gradient) 94c7afd0dbSLois Curfman McInnes - dummy - unused context 95fee21e36SBarry Smith 96e7e93795SLois Curfman McInnes Notes: 97e7e93795SLois Curfman McInnes For SNES_NONLINEAR_EQUATIONS methods the routine prints the 98e7e93795SLois Curfman McInnes residual norm at each iteration. 99e7e93795SLois Curfman McInnes 100e7e93795SLois Curfman McInnes For SNES_UNCONSTRAINED_MINIMIZATION methods the routine prints the 101e7e93795SLois Curfman McInnes function value and gradient norm at each iteration. 102e7e93795SLois Curfman McInnes 10336851e7fSLois Curfman McInnes Level: intermediate 10436851e7fSLois Curfman McInnes 105e7e93795SLois Curfman McInnes .keywords: SNES, nonlinear, default, monitor, norm 106e7e93795SLois Curfman McInnes 10736851e7fSLois Curfman McInnes .seealso: SNESSetMonitor(), SNESVecViewMonitor() 108e7e93795SLois Curfman McInnes @*/ 109e7e93795SLois Curfman McInnes int SNESDefaultMonitor(SNES snes,int its,double fgnorm,void *dummy) 110e7e93795SLois Curfman McInnes { 111d132466eSBarry Smith int ierr; 112d132466eSBarry Smith 1133a40ed3dSBarry Smith PetscFunctionBegin; 11476be9ce4SBarry Smith if (snes->method_class == SNES_NONLINEAR_EQUATIONS) { 115d132466eSBarry Smith ierr = PetscPrintf(snes->comm, "iter = %d, SNES Function norm %g \n",its,fgnorm);CHKERRQ(ierr); 11676be9ce4SBarry Smith } else if (snes->method_class == SNES_UNCONSTRAINED_MINIMIZATION) { 117d132466eSBarry Smith ierr = PetscPrintf(snes->comm,"iter = %d, SNES Function value %g, Gradient norm %g \n",its,snes->fc,fgnorm);CHKERRQ(ierr); 11876be9ce4SBarry Smith } else SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Unknown method class"); 1193a40ed3dSBarry Smith PetscFunctionReturn(0); 120e7e93795SLois Curfman McInnes } 1213f1db9ecSBarry Smith 122e7e93795SLois Curfman McInnes /* ---------------------------------------------------------------- */ 1235615d1e5SSatish Balay #undef __FUNC__ 124d4bb536fSBarry Smith #define __FUNC__ "SNESDefaultSMonitor" 125be1f7002SBarry Smith /* 126be1f7002SBarry Smith Default (short) SNES Monitor, same as SNESDefaultMonitor() except 127be1f7002SBarry Smith it prints fewer digits of the residual as the residual gets smaller. 128be1f7002SBarry Smith This is because the later digits are meaningless and are often 129be1f7002SBarry Smith different on different machines; by using this routine different 130be1f7002SBarry Smith machines will usually generate the same output. 131be1f7002SBarry Smith */ 132e7e93795SLois Curfman McInnes int SNESDefaultSMonitor(SNES snes,int its, double fgnorm,void *dummy) 133e7e93795SLois Curfman McInnes { 134d132466eSBarry Smith int ierr; 135d132466eSBarry Smith 1363a40ed3dSBarry Smith PetscFunctionBegin; 137e7e93795SLois Curfman McInnes if (snes->method_class == SNES_NONLINEAR_EQUATIONS) { 1388f240d10SBarry Smith if (fgnorm > 1.e-9) { 139d132466eSBarry Smith ierr = PetscPrintf(snes->comm, "iter = %d, SNES Function norm %g \n",its,fgnorm);CHKERRQ(ierr); 1403a40ed3dSBarry Smith } else if (fgnorm > 1.e-11){ 141d132466eSBarry Smith ierr = PetscPrintf(snes->comm, "iter = %d, SNES Function norm %5.3e \n",its,fgnorm);CHKERRQ(ierr); 1423a40ed3dSBarry Smith } else { 143d132466eSBarry Smith ierr = PetscPrintf(snes->comm, "iter = %d, SNES Function norm < 1.e-11\n",its);CHKERRQ(ierr); 144e7e93795SLois Curfman McInnes } 145e7e93795SLois Curfman McInnes } else if (snes->method_class == SNES_UNCONSTRAINED_MINIMIZATION) { 1468f240d10SBarry Smith if (fgnorm > 1.e-9) { 147d132466eSBarry Smith ierr = PetscPrintf(snes->comm,"iter = %d, SNES Function value %g, Gradient norm %g \n",its,snes->fc,fgnorm);CHKERRQ(ierr); 1483a40ed3dSBarry Smith } else if (fgnorm > 1.e-11) { 149d132466eSBarry Smith ierr = PetscPrintf(snes->comm,"iter = %d, SNES Function value %g, Gradient norm %5.3e \n",its,snes->fc,fgnorm);CHKERRQ(ierr); 1503a40ed3dSBarry Smith } else { 151d132466eSBarry Smith ierr = PetscPrintf(snes->comm,"iter = %d, SNES Function value %g, Gradient norm < 1.e-11\n",its,snes->fc);CHKERRQ(ierr); 152e7e93795SLois Curfman McInnes } 153a8c6a408SBarry Smith } else SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Unknown method class"); 1543a40ed3dSBarry Smith PetscFunctionReturn(0); 155e7e93795SLois Curfman McInnes } 156e7e93795SLois Curfman McInnes /* ---------------------------------------------------------------- */ 1575615d1e5SSatish Balay #undef __FUNC__ 1585615d1e5SSatish Balay #define __FUNC__ "SNESConverged_EQ_LS" 1594b828684SBarry Smith /*@C 160f525115eSLois Curfman McInnes SNESConverged_EQ_LS - Monitors the convergence of the solvers for 161f525115eSLois Curfman McInnes systems of nonlinear equations (default). 162e7e93795SLois Curfman McInnes 163c7afd0dbSLois Curfman McInnes Collective on SNES 164c7afd0dbSLois Curfman McInnes 165e7e93795SLois Curfman McInnes Input Parameters: 166c7afd0dbSLois Curfman McInnes + snes - the SNES context 167e7e93795SLois Curfman McInnes . xnorm - 2-norm of current iterate 168e7e93795SLois Curfman McInnes . pnorm - 2-norm of current step 169e7e93795SLois Curfman McInnes . fnorm - 2-norm of function 170c7afd0dbSLois Curfman McInnes - dummy - unused context 171e7e93795SLois Curfman McInnes 172*184914b5SBarry Smith Output Parameter: 173*184914b5SBarry Smith . reason - one of 174*184914b5SBarry Smith $ SNES_CONVERGED_FNORM_ABS - ( fnorm < atol ), 175*184914b5SBarry Smith $ SNES_CONVERGED_PNORM_RELATIVE - ( pnorm < xtol*xnorm ), 176*184914b5SBarry Smith $ SNES_CONVERGED_FNORM_RELATIVE - ( fnorm < rtol*fnorm0 ), 177*184914b5SBarry Smith $ SNES_DIVERGED_FUNCTION_COUNT - ( nfct > maxf ), 178*184914b5SBarry Smith $ SNES_DIVERGED_FNORM_NAN - ( fnorm == NaN ), 179*184914b5SBarry Smith $ SNES_CONVERGED_ITERATING - ( otherwise ), 180e7e93795SLois Curfman McInnes 181e7e93795SLois Curfman McInnes where 182c7afd0dbSLois Curfman McInnes + maxf - maximum number of function evaluations, 183c7afd0dbSLois Curfman McInnes set with SNESSetTolerances() 184c7afd0dbSLois Curfman McInnes . nfct - number of function evaluations, 185c7afd0dbSLois Curfman McInnes . atol - absolute function norm tolerance, 186c7afd0dbSLois Curfman McInnes set with SNESSetTolerances() 187c7afd0dbSLois Curfman McInnes - rtol - relative function norm tolerance, set with SNESSetTolerances() 188fee21e36SBarry Smith 18936851e7fSLois Curfman McInnes Level: intermediate 19036851e7fSLois Curfman McInnes 191e7e93795SLois Curfman McInnes .keywords: SNES, nonlinear, default, converged, convergence 192e7e93795SLois Curfman McInnes 193e7e93795SLois Curfman McInnes .seealso: SNESSetConvergenceTest(), SNESEisenstatWalkerConverged() 194e7e93795SLois Curfman McInnes @*/ 195*184914b5SBarry Smith int SNESConverged_EQ_LS(SNES snes,double xnorm,double pnorm,double fnorm,SNESConvergedReason *reason,void *dummy) 196e7e93795SLois Curfman McInnes { 1973a40ed3dSBarry Smith PetscFunctionBegin; 198d252947aSBarry Smith if (snes->method_class != SNES_NONLINEAR_EQUATIONS) { 199a8c6a408SBarry Smith SETERRQ(PETSC_ERR_ARG_WRONG,0,"For SNES_NONLINEAR_EQUATIONS only"); 200d252947aSBarry Smith } 201*184914b5SBarry Smith 202d252947aSBarry Smith if (fnorm != fnorm) { 203981c4779SBarry Smith PLogInfo(snes,"SNESConverged_EQ_LS:Failed to converged, function norm is NaN\n"); 204*184914b5SBarry Smith *reason = SNES_DIVERGED_FNORM_NAN; 205*184914b5SBarry Smith } else if (fnorm <= snes->ttol) { 20615091d37SBarry Smith PLogInfo(snes,"SNESConverged_EQ_LS:Converged due to function norm %g < %g (relative tolerance)\n",fnorm,snes->ttol); 207*184914b5SBarry Smith *reason = SNES_CONVERGED_FNORM_RELATIVE; 208*184914b5SBarry Smith } else if (fnorm < snes->atol) { 20915091d37SBarry Smith PLogInfo(snes,"SNESConverged_EQ_LS:Converged due to function norm %g < %g\n",fnorm,snes->atol); 210*184914b5SBarry Smith *reason = SNES_CONVERGED_FNORM_ABS; 211*184914b5SBarry Smith } else if (pnorm < snes->xtol*(xnorm)) { 21215091d37SBarry Smith PLogInfo(snes,"SNESConverged_EQ_LS:Converged due to small update length: %g < %g * %g\n",pnorm,snes->xtol,xnorm); 213*184914b5SBarry Smith *reason = SNES_CONVERGED_PNORM_RELATIVE; 214*184914b5SBarry Smith } else if (snes->nfuncs > snes->max_funcs) { 21515091d37SBarry Smith PLogInfo(snes,"SNESConverged_EQ_LS:Exceeded maximum number of function evaluations: %d > %d\n",snes->nfuncs, snes->max_funcs); 216*184914b5SBarry Smith *reason = SNES_DIVERGED_FUNCTION_COUNT ; 217*184914b5SBarry Smith } else { 218*184914b5SBarry Smith *reason = SNES_CONVERGED_ITERATING; 219e7e93795SLois Curfman McInnes } 2203a40ed3dSBarry Smith PetscFunctionReturn(0); 221e7e93795SLois Curfman McInnes } 222e7e93795SLois Curfman McInnes /* ------------------------------------------------------------ */ 2235615d1e5SSatish Balay #undef __FUNC__ 2245615d1e5SSatish Balay #define __FUNC__ "SNES_KSP_SetConvergenceTestEW" 225e7e93795SLois Curfman McInnes /*@ 226f525115eSLois Curfman McInnes SNES_KSP_SetConvergenceTestEW - Sets alternative convergence test 227e7e93795SLois Curfman McInnes for the linear solvers within an inexact Newton method. 228e7e93795SLois Curfman McInnes 229c7afd0dbSLois Curfman McInnes Collective on SNES 230c7afd0dbSLois Curfman McInnes 231e7e93795SLois Curfman McInnes Input Parameter: 232e7e93795SLois Curfman McInnes . snes - SNES context 233e7e93795SLois Curfman McInnes 234e7e93795SLois Curfman McInnes Notes: 235e7e93795SLois Curfman McInnes Currently, the default is to use a constant relative tolerance for 236e7e93795SLois Curfman McInnes the inner linear solvers. Alternatively, one can use the 237e7e93795SLois Curfman McInnes Eisenstat-Walker method, where the relative convergence tolerance 238e7e93795SLois Curfman McInnes is reset at each Newton iteration according progress of the nonlinear 239e7e93795SLois Curfman McInnes solver. 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 245e30ad881SLois Curfman McInnes inexact Newton method", SISC 17 (1), pp.16-32, 1996. 246e7e93795SLois Curfman McInnes 247e7e93795SLois Curfman McInnes .keywords: SNES, KSP, Eisenstat, Walker, convergence, test, inexact, Newton 248e7e93795SLois Curfman McInnes @*/ 249e7e93795SLois Curfman McInnes int SNES_KSP_SetConvergenceTestEW(SNES snes) 250e7e93795SLois Curfman McInnes { 2513a40ed3dSBarry Smith PetscFunctionBegin; 252e7e93795SLois Curfman McInnes snes->ksp_ewconv = 1; 2533a40ed3dSBarry Smith PetscFunctionReturn(0); 254e7e93795SLois Curfman McInnes } 255e7e93795SLois Curfman McInnes 2565615d1e5SSatish Balay #undef __FUNC__ 2575615d1e5SSatish Balay #define __FUNC__ "SNES_KSP_SetParametersEW" 258e7e93795SLois Curfman McInnes /*@ 259e7e93795SLois Curfman McInnes SNES_KSP_SetParametersEW - Sets parameters for Eisenstat-Walker 260e7e93795SLois Curfman McInnes convergence criteria for the linear solvers within an inexact 261e7e93795SLois Curfman McInnes Newton method. 262e7e93795SLois Curfman McInnes 263c7afd0dbSLois Curfman McInnes Collective on SNES 264c7afd0dbSLois Curfman McInnes 265e7e93795SLois Curfman McInnes Input Parameters: 266c7afd0dbSLois Curfman McInnes + snes - SNES context 267e7e93795SLois Curfman McInnes . version - version 1 or 2 (default is 2) 268c7afd0dbSLois Curfman McInnes . rtol_0 - initial relative tolerance (0 <= rtol_0 < 1) 269c7afd0dbSLois Curfman McInnes . rtol_max - maximum relative tolerance (0 <= rtol_max < 1) 270c7afd0dbSLois Curfman McInnes . alpha - power for version 2 rtol computation (1 < alpha <= 2) 271e7e93795SLois Curfman McInnes . alpha2 - power for safeguard 272e7e93795SLois Curfman McInnes . gamma2 - multiplicative factor for version 2 rtol computation 273c7afd0dbSLois Curfman McInnes (0 <= gamma2 <= 1) 274c7afd0dbSLois Curfman McInnes - threshold - threshold for imposing safeguard (0 < threshold < 1) 275fee21e36SBarry Smith 276e7e93795SLois Curfman McInnes Note: 277e7e93795SLois Curfman McInnes Use PETSC_DEFAULT to retain the default for any of the parameters. 278e7e93795SLois Curfman McInnes 27936851e7fSLois Curfman McInnes Level: advanced 28036851e7fSLois Curfman McInnes 281e7e93795SLois Curfman McInnes Reference: 282e7e93795SLois Curfman McInnes S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an 283e7e93795SLois Curfman McInnes inexact Newton method", Utah State University Math. Stat. Dept. Res. 284e7e93795SLois Curfman McInnes Report 6/94/75, June, 1994, to appear in SIAM J. Sci. Comput. 285e7e93795SLois Curfman McInnes 286e7e93795SLois Curfman McInnes .keywords: SNES, KSP, Eisenstat, Walker, set, parameters 287e7e93795SLois Curfman McInnes 288e7e93795SLois Curfman McInnes .seealso: SNES_KSP_SetConvergenceTestEW() 289e7e93795SLois Curfman McInnes @*/ 290e7e93795SLois Curfman McInnes int SNES_KSP_SetParametersEW(SNES snes,int version,double rtol_0, 291e7e93795SLois Curfman McInnes double rtol_max,double gamma2,double alpha, 292e7e93795SLois Curfman McInnes double alpha2,double threshold) 293e7e93795SLois Curfman McInnes { 294e7e93795SLois Curfman McInnes SNES_KSP_EW_ConvCtx *kctx = (SNES_KSP_EW_ConvCtx*)snes->kspconvctx; 2953a40ed3dSBarry Smith 2963a40ed3dSBarry Smith PetscFunctionBegin; 297a8c6a408SBarry Smith if (!kctx) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,0,"No Eisenstat-Walker context existing"); 298e7e93795SLois Curfman McInnes if (version != PETSC_DEFAULT) kctx->version = version; 299e7e93795SLois Curfman McInnes if (rtol_0 != PETSC_DEFAULT) kctx->rtol_0 = rtol_0; 300e7e93795SLois Curfman McInnes if (rtol_max != PETSC_DEFAULT) kctx->rtol_max = rtol_max; 301e7e93795SLois Curfman McInnes if (gamma2 != PETSC_DEFAULT) kctx->gamma = gamma2; 302e7e93795SLois Curfman McInnes if (alpha != PETSC_DEFAULT) kctx->alpha = alpha; 303e7e93795SLois Curfman McInnes if (alpha2 != PETSC_DEFAULT) kctx->alpha2 = alpha2; 304e7e93795SLois Curfman McInnes if (threshold != PETSC_DEFAULT) kctx->threshold = threshold; 305a8c6a408SBarry Smith if (kctx->rtol_0 < 0.0 || kctx->rtol_0 >= 1.0) { 306596552b5SBarry Smith SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,0,"0.0 <= rtol_0 < 1.0: %g",kctx->rtol_0); 307a8c6a408SBarry Smith } 308a8c6a408SBarry Smith if (kctx->rtol_max < 0.0 || kctx->rtol_max >= 1.0) { 309596552b5SBarry Smith SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,0,"0.0 <= rtol_max < 1.0\n",kctx->rtol_max); 310a8c6a408SBarry Smith } 311a8c6a408SBarry Smith if (kctx->threshold <= 0.0 || kctx->threshold >= 1.0) { 312596552b5SBarry Smith SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,0,"0.0 < threshold < 1.0\n",kctx->threshold); 313a8c6a408SBarry Smith } 314a8c6a408SBarry Smith if (kctx->gamma < 0.0 || kctx->gamma > 1.0) { 315596552b5SBarry Smith SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,0,"0.0 <= alpha <= 1.0\n",kctx->gamma); 316a8c6a408SBarry Smith } 317a8c6a408SBarry Smith if (kctx->alpha <= 1.0 || kctx->alpha > 2.0) { 318596552b5SBarry Smith SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,0,"1.0 < alpha <= 2.0\n",kctx->alpha); 319a8c6a408SBarry Smith } 320a8c6a408SBarry Smith if (kctx->version != 1 && kctx->version !=2) { 321596552b5SBarry Smith SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,0,"Only versions 1 and 2 are supported: %d",kctx->version); 322a8c6a408SBarry Smith } 3233a40ed3dSBarry Smith PetscFunctionReturn(0); 324e7e93795SLois Curfman McInnes } 325e7e93795SLois Curfman McInnes 3265615d1e5SSatish Balay #undef __FUNC__ 3275615d1e5SSatish Balay #define __FUNC__ "SNES_KSP_EW_ComputeRelativeTolerance_Private" 328e7e93795SLois Curfman McInnes int SNES_KSP_EW_ComputeRelativeTolerance_Private(SNES snes,KSP ksp) 329e7e93795SLois Curfman McInnes { 330e7e93795SLois Curfman McInnes SNES_KSP_EW_ConvCtx *kctx = (SNES_KSP_EW_ConvCtx*)snes->kspconvctx; 3313f1db9ecSBarry Smith double rtol = 0.0, stol; 332e7e93795SLois Curfman McInnes int ierr; 3333a40ed3dSBarry Smith 3343a40ed3dSBarry Smith PetscFunctionBegin; 335a8c6a408SBarry Smith if (!kctx) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,0,"No Eisenstat-Walker context exists"); 336e7e93795SLois Curfman McInnes if (snes->iter == 1) { 337e7e93795SLois Curfman McInnes rtol = kctx->rtol_0; 338e7e93795SLois Curfman McInnes } else { 339e7e93795SLois Curfman McInnes if (kctx->version == 1) { 340e7e93795SLois Curfman McInnes rtol = (snes->norm - kctx->lresid_last)/kctx->norm_last; 341e7e93795SLois Curfman McInnes if (rtol < 0.0) rtol = -rtol; 342e7e93795SLois Curfman McInnes stol = pow(kctx->rtol_last,kctx->alpha2); 3430452661fSBarry Smith if (stol > kctx->threshold) rtol = PetscMax(rtol,stol); 344e7e93795SLois Curfman McInnes } else if (kctx->version == 2) { 345e7e93795SLois Curfman McInnes rtol = kctx->gamma * pow(snes->norm/kctx->norm_last,kctx->alpha); 346e7e93795SLois Curfman McInnes stol = kctx->gamma * pow(kctx->rtol_last,kctx->alpha); 3470452661fSBarry Smith if (stol > kctx->threshold) rtol = PetscMax(rtol,stol); 348596552b5SBarry Smith } else SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,0,"Only versions 1 or 2 are supported: %d",kctx->version); 349e7e93795SLois Curfman McInnes } 3500452661fSBarry Smith rtol = PetscMin(rtol,kctx->rtol_max); 351e7e93795SLois Curfman McInnes kctx->rtol_last = rtol; 352*184914b5SBarry Smith PLogInfo(snes,"SNES_KSP_EW_ComputeRelativeTolerance_Private: iter %d, Eisenstat-Walker (version %d) KSP rtol = %g\n",snes->iter,kctx->version,rtol); 3533131a8b6SLois Curfman McInnes ierr = KSPSetTolerances(ksp,rtol,PETSC_DEFAULT,PETSC_DEFAULT,PETSC_DEFAULT);CHKERRQ(ierr); 354e7e93795SLois Curfman McInnes kctx->norm_last = snes->norm; 3553a40ed3dSBarry Smith PetscFunctionReturn(0); 356e7e93795SLois Curfman McInnes } 357e7e93795SLois Curfman McInnes 3585615d1e5SSatish Balay #undef __FUNC__ 3595615d1e5SSatish Balay #define __FUNC__ "SNES_KSP_EW_Converged_Private" 360e7e93795SLois Curfman McInnes int SNES_KSP_EW_Converged_Private(KSP ksp,int n,double rnorm,void *ctx) 361e7e93795SLois Curfman McInnes { 362e7e93795SLois Curfman McInnes SNES snes = (SNES)ctx; 363e7e93795SLois Curfman McInnes SNES_KSP_EW_ConvCtx *kctx = (SNES_KSP_EW_ConvCtx*)snes->kspconvctx; 364*184914b5SBarry Smith int convinfo,ierr; 365e7e93795SLois Curfman McInnes 3663a40ed3dSBarry Smith PetscFunctionBegin; 367a8c6a408SBarry Smith if (!kctx) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,0,"No Eisenstat-Walker context set"); 368*184914b5SBarry Smith if (n == 0) {ierr = SNES_KSP_EW_ComputeRelativeTolerance_Private(snes,ksp);CHKERRQ(ierr);} 369e7e93795SLois Curfman McInnes convinfo = KSPDefaultConverged(ksp,n,rnorm,ctx); 370e7e93795SLois Curfman McInnes kctx->lresid_last = rnorm; 3713a40ed3dSBarry Smith if (convinfo) { 372981c4779SBarry Smith PLogInfo(snes,"SNES_KSP_EW_Converged_Private: KSP iterations=%d, rnorm=%g\n",n,rnorm); 3733a40ed3dSBarry Smith } 3743a40ed3dSBarry Smith PetscFunctionReturn(convinfo); 375e7e93795SLois Curfman McInnes } 376e7e93795SLois Curfman McInnes 377e7e93795SLois Curfman McInnes 378