1*29bbc08cSBarry Smith /*$Id: snesut.c,v 1.59 2000/08/24 22:43:02 bsmith Exp bsmith $*/ 2e7e93795SLois Curfman McInnes 3e090d566SSatish Balay #include "src/snes/snesimpl.h" /*I "petscsnes.h" I*/ 4e7e93795SLois Curfman McInnes 55615d1e5SSatish Balay #undef __FUNC__ 6b2863d3aSBarry Smith #define __FUNC__ /*<a name=""></a>*/"SNESVecViewMonitor" 73f1db9ecSBarry Smith /*@C 836851e7fSLois Curfman McInnes SNESVecViewMonitor - Monitors progress of the SNES solvers by calling 936851e7fSLois Curfman McInnes VecView() for the approximate solution at each iteration. 103f1db9ecSBarry Smith 113f1db9ecSBarry Smith Collective on SNES 123f1db9ecSBarry Smith 133f1db9ecSBarry Smith Input Parameters: 143f1db9ecSBarry Smith + snes - the SNES context 153f1db9ecSBarry Smith . its - iteration number 163f1db9ecSBarry Smith . fgnorm - 2-norm of residual (or gradient) 173f1db9ecSBarry Smith - dummy - either a viewer or PETSC_NULL 183f1db9ecSBarry Smith 1936851e7fSLois Curfman McInnes Level: intermediate 203f1db9ecSBarry Smith 2136851e7fSLois Curfman McInnes .keywords: SNES, nonlinear, vector, monitor, view 223f1db9ecSBarry Smith 2336851e7fSLois Curfman McInnes .seealso: SNESSetMonitor(), SNESDefaultMonitor(), VecView() 243f1db9ecSBarry Smith @*/ 25329f5518SBarry Smith int SNESVecViewMonitor(SNES snes,int its,PetscReal fgnorm,void *dummy) 263f1db9ecSBarry Smith { 273f1db9ecSBarry Smith int ierr; 283f1db9ecSBarry Smith Vec x; 293f1db9ecSBarry Smith Viewer viewer = (Viewer) dummy; 303f1db9ecSBarry Smith 313f1db9ecSBarry Smith PetscFunctionBegin; 323f1db9ecSBarry Smith ierr = SNESGetSolution(snes,&x);CHKERRQ(ierr); 333f1db9ecSBarry Smith if (!viewer) { 343f1db9ecSBarry Smith MPI_Comm comm; 353f1db9ecSBarry Smith ierr = PetscObjectGetComm((PetscObject)snes,&comm);CHKERRQ(ierr); 36c655490fSBarry Smith viewer = VIEWER_DRAW_(comm); 373f1db9ecSBarry Smith } 383f1db9ecSBarry Smith ierr = VecView(x,viewer);CHKERRQ(ierr); 393f1db9ecSBarry Smith 403f1db9ecSBarry Smith PetscFunctionReturn(0); 413f1db9ecSBarry Smith } 423f1db9ecSBarry Smith 433f1db9ecSBarry Smith #undef __FUNC__ 44b2863d3aSBarry Smith #define __FUNC__ /*<a name=""></a>*/"SNESVecViewUpdateMonitor" 45d132466eSBarry Smith /*@C 467c922b88SBarry Smith SNESVecViewUpdateMonitor - Monitors progress of the SNES solvers by calling 47d132466eSBarry Smith VecView() for the UPDATE to the solution at each iteration. 48d132466eSBarry Smith 49d132466eSBarry Smith Collective on SNES 50d132466eSBarry Smith 51d132466eSBarry Smith Input Parameters: 52d132466eSBarry Smith + snes - the SNES context 53d132466eSBarry Smith . its - iteration number 54d132466eSBarry Smith . fgnorm - 2-norm of residual (or gradient) 55d132466eSBarry Smith - dummy - either a viewer or PETSC_NULL 56d132466eSBarry Smith 57d132466eSBarry Smith Level: intermediate 58d132466eSBarry Smith 59d132466eSBarry Smith .keywords: SNES, nonlinear, vector, monitor, view 60d132466eSBarry Smith 61d132466eSBarry Smith .seealso: SNESSetMonitor(), SNESDefaultMonitor(), VecView() 62d132466eSBarry Smith @*/ 63329f5518SBarry Smith int SNESVecViewUpdateMonitor(SNES snes,int its,PetscReal fgnorm,void *dummy) 64d132466eSBarry Smith { 65d132466eSBarry Smith int ierr; 66d132466eSBarry Smith Vec x; 67d132466eSBarry Smith Viewer viewer = (Viewer) dummy; 68d132466eSBarry Smith 69d132466eSBarry Smith PetscFunctionBegin; 70d132466eSBarry Smith ierr = SNESGetSolutionUpdate(snes,&x);CHKERRQ(ierr); 71d132466eSBarry Smith if (!viewer) { 72d132466eSBarry Smith MPI_Comm comm; 73d132466eSBarry Smith ierr = PetscObjectGetComm((PetscObject)snes,&comm);CHKERRQ(ierr); 74d132466eSBarry Smith viewer = VIEWER_DRAW_(comm); 75d132466eSBarry Smith } 76d132466eSBarry Smith ierr = VecView(x,viewer);CHKERRQ(ierr); 77d132466eSBarry Smith 78d132466eSBarry Smith PetscFunctionReturn(0); 79d132466eSBarry Smith } 80d132466eSBarry Smith 81d132466eSBarry Smith #undef __FUNC__ 82b2863d3aSBarry Smith #define __FUNC__ /*<a name=""></a>*/"SNESDefaultMonitor" 834b828684SBarry Smith /*@C 84f525115eSLois Curfman McInnes SNESDefaultMonitor - Monitoring progress of the SNES solvers (default). 85e7e93795SLois Curfman McInnes 86c7afd0dbSLois Curfman McInnes Collective on SNES 87c7afd0dbSLois Curfman McInnes 88e7e93795SLois Curfman McInnes Input Parameters: 89c7afd0dbSLois Curfman McInnes + snes - the SNES context 90e7e93795SLois Curfman McInnes . its - iteration number 91e7e93795SLois Curfman McInnes . fgnorm - 2-norm of residual (or gradient) 92c7afd0dbSLois Curfman McInnes - dummy - unused context 93fee21e36SBarry Smith 94e7e93795SLois Curfman McInnes Notes: 95e7e93795SLois Curfman McInnes For SNES_NONLINEAR_EQUATIONS methods the routine prints the 96e7e93795SLois Curfman McInnes residual norm at each iteration. 97e7e93795SLois Curfman McInnes 98e7e93795SLois Curfman McInnes For SNES_UNCONSTRAINED_MINIMIZATION methods the routine prints the 99e7e93795SLois Curfman McInnes function value and gradient norm at each iteration. 100e7e93795SLois Curfman McInnes 10136851e7fSLois Curfman McInnes Level: intermediate 10236851e7fSLois Curfman McInnes 103e7e93795SLois Curfman McInnes .keywords: SNES, nonlinear, default, monitor, norm 104e7e93795SLois Curfman McInnes 10536851e7fSLois Curfman McInnes .seealso: SNESSetMonitor(), SNESVecViewMonitor() 106e7e93795SLois Curfman McInnes @*/ 107329f5518SBarry Smith int SNESDefaultMonitor(SNES snes,int its,PetscReal fgnorm,void *dummy) 108e7e93795SLois Curfman McInnes { 109d132466eSBarry Smith int ierr; 1107c922b88SBarry Smith Viewer viewer = (Viewer) dummy; 111d132466eSBarry Smith 1123a40ed3dSBarry Smith PetscFunctionBegin; 1137c922b88SBarry Smith if (!viewer) viewer = VIEWER_STDOUT_(snes->comm); 1147c922b88SBarry Smith 11576be9ce4SBarry Smith if (snes->method_class == SNES_NONLINEAR_EQUATIONS) { 11674637425SBarry Smith ierr = ViewerASCIIPrintf(viewer,"iter = %d, SNES Function norm %14.12e \n",its,fgnorm);CHKERRQ(ierr); 11776be9ce4SBarry Smith } else if (snes->method_class == SNES_UNCONSTRAINED_MINIMIZATION) { 11874637425SBarry Smith ierr = ViewerASCIIPrintf(viewer,"iter = %d, SNES Function value %14.12e, Gradient norm %14.12e \n",its,snes->fc,fgnorm);CHKERRQ(ierr); 119*29bbc08cSBarry Smith } else SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Unknown method class"); 1203a40ed3dSBarry Smith PetscFunctionReturn(0); 121e7e93795SLois Curfman McInnes } 1223f1db9ecSBarry Smith 123e7e93795SLois Curfman McInnes /* ---------------------------------------------------------------- */ 1245615d1e5SSatish Balay #undef __FUNC__ 125b2863d3aSBarry Smith #define __FUNC__ /*<a name=""></a>*/"SNESDefaultSMonitor" 126be1f7002SBarry Smith /* 127be1f7002SBarry Smith Default (short) SNES Monitor, same as SNESDefaultMonitor() except 128be1f7002SBarry Smith it prints fewer digits of the residual as the residual gets smaller. 129be1f7002SBarry Smith This is because the later digits are meaningless and are often 130be1f7002SBarry Smith different on different machines; by using this routine different 131be1f7002SBarry Smith machines will usually generate the same output. 132be1f7002SBarry Smith */ 133329f5518SBarry Smith int SNESDefaultSMonitor(SNES snes,int its,PetscReal fgnorm,void *dummy) 134e7e93795SLois Curfman McInnes { 135d132466eSBarry Smith int ierr; 136d132466eSBarry Smith 1373a40ed3dSBarry Smith PetscFunctionBegin; 138e7e93795SLois Curfman McInnes if (snes->method_class == SNES_NONLINEAR_EQUATIONS) { 1398f240d10SBarry Smith if (fgnorm > 1.e-9) { 140d132466eSBarry Smith ierr = PetscPrintf(snes->comm,"iter = %d, SNES Function norm %g \n",its,fgnorm);CHKERRQ(ierr); 1413a40ed3dSBarry Smith } else if (fgnorm > 1.e-11){ 142d132466eSBarry Smith ierr = PetscPrintf(snes->comm,"iter = %d, SNES Function norm %5.3e \n",its,fgnorm);CHKERRQ(ierr); 1433a40ed3dSBarry Smith } else { 144d132466eSBarry Smith ierr = PetscPrintf(snes->comm,"iter = %d, SNES Function norm < 1.e-11\n",its);CHKERRQ(ierr); 145e7e93795SLois Curfman McInnes } 146e7e93795SLois Curfman McInnes } else if (snes->method_class == SNES_UNCONSTRAINED_MINIMIZATION) { 1478f240d10SBarry Smith if (fgnorm > 1.e-9) { 148d132466eSBarry Smith ierr = PetscPrintf(snes->comm,"iter = %d, SNES Function value %g, Gradient norm %g \n",its,snes->fc,fgnorm);CHKERRQ(ierr); 1493a40ed3dSBarry Smith } else if (fgnorm > 1.e-11) { 150d132466eSBarry Smith ierr = PetscPrintf(snes->comm,"iter = %d, SNES Function value %g, Gradient norm %5.3e \n",its,snes->fc,fgnorm);CHKERRQ(ierr); 1513a40ed3dSBarry Smith } else { 152d132466eSBarry Smith ierr = PetscPrintf(snes->comm,"iter = %d, SNES Function value %g, Gradient norm < 1.e-11\n",its,snes->fc);CHKERRQ(ierr); 153e7e93795SLois Curfman McInnes } 154*29bbc08cSBarry Smith } else SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Unknown method class"); 1553a40ed3dSBarry Smith PetscFunctionReturn(0); 156e7e93795SLois Curfman McInnes } 157e7e93795SLois Curfman McInnes /* ---------------------------------------------------------------- */ 1585615d1e5SSatish Balay #undef __FUNC__ 159b2863d3aSBarry Smith #define __FUNC__ /*<a name=""></a>*/"SNESConverged_EQ_LS" 1604b828684SBarry Smith /*@C 161f525115eSLois Curfman McInnes SNESConverged_EQ_LS - Monitors the convergence of the solvers for 162f525115eSLois Curfman McInnes systems of nonlinear equations (default). 163e7e93795SLois Curfman McInnes 164c7afd0dbSLois Curfman McInnes Collective on SNES 165c7afd0dbSLois Curfman McInnes 166e7e93795SLois Curfman McInnes Input Parameters: 167c7afd0dbSLois Curfman McInnes + snes - the SNES context 168e7e93795SLois Curfman McInnes . xnorm - 2-norm of current iterate 169e7e93795SLois Curfman McInnes . pnorm - 2-norm of current step 170e7e93795SLois Curfman McInnes . fnorm - 2-norm of function 171c7afd0dbSLois Curfman McInnes - dummy - unused context 172e7e93795SLois Curfman McInnes 173184914b5SBarry Smith Output Parameter: 174184914b5SBarry Smith . reason - one of 175184914b5SBarry Smith $ SNES_CONVERGED_FNORM_ABS - (fnorm < atol), 176184914b5SBarry Smith $ SNES_CONVERGED_PNORM_RELATIVE - (pnorm < xtol*xnorm), 177184914b5SBarry Smith $ SNES_CONVERGED_FNORM_RELATIVE - (fnorm < rtol*fnorm0), 178184914b5SBarry Smith $ SNES_DIVERGED_FUNCTION_COUNT - (nfct > maxf), 179184914b5SBarry Smith $ SNES_DIVERGED_FNORM_NAN - (fnorm == NaN), 180184914b5SBarry Smith $ SNES_CONVERGED_ITERATING - (otherwise), 181e7e93795SLois Curfman McInnes 182e7e93795SLois Curfman McInnes where 183c7afd0dbSLois Curfman McInnes + maxf - maximum number of function evaluations, 184c7afd0dbSLois Curfman McInnes set with SNESSetTolerances() 185c7afd0dbSLois Curfman McInnes . nfct - number of function evaluations, 186c7afd0dbSLois Curfman McInnes . atol - absolute function norm tolerance, 187c7afd0dbSLois Curfman McInnes set with SNESSetTolerances() 188c7afd0dbSLois Curfman McInnes - rtol - relative function norm tolerance, set with SNESSetTolerances() 189fee21e36SBarry Smith 19036851e7fSLois Curfman McInnes Level: intermediate 19136851e7fSLois Curfman McInnes 192e7e93795SLois Curfman McInnes .keywords: SNES, nonlinear, default, converged, convergence 193e7e93795SLois Curfman McInnes 194e7e93795SLois Curfman McInnes .seealso: SNESSetConvergenceTest(), SNESEisenstatWalkerConverged() 195e7e93795SLois Curfman McInnes @*/ 196329f5518SBarry Smith int SNESConverged_EQ_LS(SNES snes,PetscReal xnorm,PetscReal pnorm,PetscReal fnorm,SNESConvergedReason *reason,void *dummy) 197e7e93795SLois Curfman McInnes { 1983a40ed3dSBarry Smith PetscFunctionBegin; 199d252947aSBarry Smith if (snes->method_class != SNES_NONLINEAR_EQUATIONS) { 200*29bbc08cSBarry Smith SETERRQ(PETSC_ERR_ARG_WRONG,"For SNES_NONLINEAR_EQUATIONS only"); 201d252947aSBarry Smith } 202184914b5SBarry Smith 203d252947aSBarry Smith if (fnorm != fnorm) { 204981c4779SBarry Smith PLogInfo(snes,"SNESConverged_EQ_LS:Failed to converged, function norm is NaN\n"); 205184914b5SBarry Smith *reason = SNES_DIVERGED_FNORM_NAN; 206184914b5SBarry Smith } else if (fnorm <= snes->ttol) { 20715091d37SBarry Smith PLogInfo(snes,"SNESConverged_EQ_LS:Converged due to function norm %g < %g (relative tolerance)\n",fnorm,snes->ttol); 208184914b5SBarry Smith *reason = SNES_CONVERGED_FNORM_RELATIVE; 209184914b5SBarry Smith } else if (fnorm < snes->atol) { 21015091d37SBarry Smith PLogInfo(snes,"SNESConverged_EQ_LS:Converged due to function norm %g < %g\n",fnorm,snes->atol); 211184914b5SBarry Smith *reason = SNES_CONVERGED_FNORM_ABS; 212184914b5SBarry Smith } else if (pnorm < snes->xtol*(xnorm)) { 21315091d37SBarry Smith PLogInfo(snes,"SNESConverged_EQ_LS:Converged due to small update length: %g < %g * %g\n",pnorm,snes->xtol,xnorm); 214184914b5SBarry Smith *reason = SNES_CONVERGED_PNORM_RELATIVE; 215184914b5SBarry Smith } else if (snes->nfuncs > snes->max_funcs) { 21615091d37SBarry Smith PLogInfo(snes,"SNESConverged_EQ_LS:Exceeded maximum number of function evaluations: %d > %d\n",snes->nfuncs,snes->max_funcs); 217184914b5SBarry Smith *reason = SNES_DIVERGED_FUNCTION_COUNT ; 218184914b5SBarry Smith } else { 219184914b5SBarry Smith *reason = SNES_CONVERGED_ITERATING; 220e7e93795SLois Curfman McInnes } 2213a40ed3dSBarry Smith PetscFunctionReturn(0); 222e7e93795SLois Curfman McInnes } 223e7e93795SLois Curfman McInnes /* ------------------------------------------------------------ */ 2245615d1e5SSatish Balay #undef __FUNC__ 225b2863d3aSBarry Smith #define __FUNC__ /*<a name=""></a>*/"SNES_KSP_SetConvergenceTestEW" 226e7e93795SLois Curfman McInnes /*@ 227f525115eSLois Curfman McInnes SNES_KSP_SetConvergenceTestEW - Sets alternative convergence test 228e7e93795SLois Curfman McInnes for the linear solvers within an inexact Newton method. 229e7e93795SLois Curfman McInnes 230c7afd0dbSLois Curfman McInnes Collective on SNES 231c7afd0dbSLois Curfman McInnes 232e7e93795SLois Curfman McInnes Input Parameter: 233e7e93795SLois Curfman McInnes . snes - SNES context 234e7e93795SLois Curfman McInnes 235e7e93795SLois Curfman McInnes Notes: 236e7e93795SLois Curfman McInnes Currently, the default is to use a constant relative tolerance for 237e7e93795SLois Curfman McInnes the inner linear solvers. Alternatively, one can use the 238e7e93795SLois Curfman McInnes Eisenstat-Walker method, where the relative convergence tolerance 239e7e93795SLois Curfman McInnes is reset at each Newton iteration according progress of the nonlinear 240e7e93795SLois Curfman McInnes solver. 241e7e93795SLois Curfman McInnes 24236851e7fSLois Curfman McInnes Level: advanced 24336851e7fSLois Curfman McInnes 244e7e93795SLois Curfman McInnes Reference: 245e7e93795SLois Curfman McInnes S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an 246e30ad881SLois Curfman McInnes inexact Newton method", SISC 17 (1), pp.16-32, 1996. 247e7e93795SLois Curfman McInnes 248e7e93795SLois Curfman McInnes .keywords: SNES, KSP, Eisenstat, Walker, convergence, test, inexact, Newton 249e7e93795SLois Curfman McInnes @*/ 250e7e93795SLois Curfman McInnes int SNES_KSP_SetConvergenceTestEW(SNES snes) 251e7e93795SLois Curfman McInnes { 2523a40ed3dSBarry Smith PetscFunctionBegin; 253186905e3SBarry Smith snes->ksp_ewconv = PETSC_TRUE; 2543a40ed3dSBarry Smith PetscFunctionReturn(0); 255e7e93795SLois Curfman McInnes } 256e7e93795SLois Curfman McInnes 2575615d1e5SSatish Balay #undef __FUNC__ 258b2863d3aSBarry Smith #define __FUNC__ /*<a name=""></a>*/"SNES_KSP_SetParametersEW" 259e7e93795SLois Curfman McInnes /*@ 260e7e93795SLois Curfman McInnes SNES_KSP_SetParametersEW - Sets parameters for Eisenstat-Walker 261e7e93795SLois Curfman McInnes convergence criteria for the linear solvers within an inexact 262e7e93795SLois Curfman McInnes Newton method. 263e7e93795SLois Curfman McInnes 264c7afd0dbSLois Curfman McInnes Collective on SNES 265c7afd0dbSLois Curfman McInnes 266e7e93795SLois Curfman McInnes Input Parameters: 267c7afd0dbSLois Curfman McInnes + snes - SNES context 268e7e93795SLois Curfman McInnes . version - version 1 or 2 (default is 2) 269c7afd0dbSLois Curfman McInnes . rtol_0 - initial relative tolerance (0 <= rtol_0 < 1) 270c7afd0dbSLois Curfman McInnes . rtol_max - maximum relative tolerance (0 <= rtol_max < 1) 271c7afd0dbSLois Curfman McInnes . alpha - power for version 2 rtol computation (1 < alpha <= 2) 272e7e93795SLois Curfman McInnes . alpha2 - power for safeguard 273e7e93795SLois Curfman McInnes . gamma2 - multiplicative factor for version 2 rtol computation 274c7afd0dbSLois Curfman McInnes (0 <= gamma2 <= 1) 275c7afd0dbSLois Curfman McInnes - threshold - threshold for imposing safeguard (0 < threshold < 1) 276fee21e36SBarry Smith 277e7e93795SLois Curfman McInnes Note: 278e7e93795SLois Curfman McInnes Use PETSC_DEFAULT to retain the default for any of the parameters. 279e7e93795SLois Curfman McInnes 28036851e7fSLois Curfman McInnes Level: advanced 28136851e7fSLois Curfman McInnes 282e7e93795SLois Curfman McInnes Reference: 283e7e93795SLois Curfman McInnes S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an 284e7e93795SLois Curfman McInnes inexact Newton method", Utah State University Math. Stat. Dept. Res. 285e7e93795SLois Curfman McInnes Report 6/94/75, June, 1994, to appear in SIAM J. Sci. Comput. 286e7e93795SLois Curfman McInnes 287e7e93795SLois Curfman McInnes .keywords: SNES, KSP, Eisenstat, Walker, set, parameters 288e7e93795SLois Curfman McInnes 289e7e93795SLois Curfman McInnes .seealso: SNES_KSP_SetConvergenceTestEW() 290e7e93795SLois Curfman McInnes @*/ 291329f5518SBarry Smith int SNES_KSP_SetParametersEW(SNES snes,int version,PetscReal rtol_0, 292329f5518SBarry Smith PetscReal rtol_max,PetscReal gamma2,PetscReal alpha, 293329f5518SBarry Smith PetscReal alpha2,PetscReal threshold) 294e7e93795SLois Curfman McInnes { 295e7e93795SLois Curfman McInnes SNES_KSP_EW_ConvCtx *kctx = (SNES_KSP_EW_ConvCtx*)snes->kspconvctx; 2963a40ed3dSBarry Smith 2973a40ed3dSBarry Smith PetscFunctionBegin; 298*29bbc08cSBarry Smith if (!kctx) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context existing"); 299e7e93795SLois Curfman McInnes if (version != PETSC_DEFAULT) kctx->version = version; 300e7e93795SLois Curfman McInnes if (rtol_0 != PETSC_DEFAULT) kctx->rtol_0 = rtol_0; 301e7e93795SLois Curfman McInnes if (rtol_max != PETSC_DEFAULT) kctx->rtol_max = rtol_max; 302e7e93795SLois Curfman McInnes if (gamma2 != PETSC_DEFAULT) kctx->gamma = gamma2; 303e7e93795SLois Curfman McInnes if (alpha != PETSC_DEFAULT) kctx->alpha = alpha; 304e7e93795SLois Curfman McInnes if (alpha2 != PETSC_DEFAULT) kctx->alpha2 = alpha2; 305e7e93795SLois Curfman McInnes if (threshold != PETSC_DEFAULT) kctx->threshold = threshold; 306a8c6a408SBarry Smith if (kctx->rtol_0 < 0.0 || kctx->rtol_0 >= 1.0) { 307*29bbc08cSBarry Smith SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"0.0 <= rtol_0 < 1.0: %g",kctx->rtol_0); 308a8c6a408SBarry Smith } 309a8c6a408SBarry Smith if (kctx->rtol_max < 0.0 || kctx->rtol_max >= 1.0) { 310*29bbc08cSBarry Smith SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"0.0 <= rtol_max < 1.0\n",kctx->rtol_max); 311a8c6a408SBarry Smith } 312a8c6a408SBarry Smith if (kctx->threshold <= 0.0 || kctx->threshold >= 1.0) { 313*29bbc08cSBarry Smith SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"0.0 < threshold < 1.0\n",kctx->threshold); 314a8c6a408SBarry Smith } 315a8c6a408SBarry Smith if (kctx->gamma < 0.0 || kctx->gamma > 1.0) { 316*29bbc08cSBarry Smith SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"0.0 <= alpha <= 1.0\n",kctx->gamma); 317a8c6a408SBarry Smith } 318a8c6a408SBarry Smith if (kctx->alpha <= 1.0 || kctx->alpha > 2.0) { 319*29bbc08cSBarry Smith SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"1.0 < alpha <= 2.0\n",kctx->alpha); 320a8c6a408SBarry Smith } 321a8c6a408SBarry Smith if (kctx->version != 1 && kctx->version !=2) { 322*29bbc08cSBarry Smith SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Only versions 1 and 2 are supported: %d",kctx->version); 323a8c6a408SBarry Smith } 3243a40ed3dSBarry Smith PetscFunctionReturn(0); 325e7e93795SLois Curfman McInnes } 326e7e93795SLois Curfman McInnes 3275615d1e5SSatish Balay #undef __FUNC__ 328b2863d3aSBarry Smith #define __FUNC__ /*<a name=""></a>*/"SNES_KSP_EW_ComputeRelativeTolerance_Private" 329e7e93795SLois Curfman McInnes int SNES_KSP_EW_ComputeRelativeTolerance_Private(SNES snes,KSP ksp) 330e7e93795SLois Curfman McInnes { 331e7e93795SLois Curfman McInnes SNES_KSP_EW_ConvCtx *kctx = (SNES_KSP_EW_ConvCtx*)snes->kspconvctx; 332329f5518SBarry Smith PetscReal rtol = 0.0,stol; 333e7e93795SLois Curfman McInnes int ierr; 3343a40ed3dSBarry Smith 3353a40ed3dSBarry Smith PetscFunctionBegin; 336*29bbc08cSBarry Smith if (!kctx) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context exists"); 337c38d4ed2SBarry Smith if (!snes->iter) { /* first time in, so use the original user rtol */ 338e7e93795SLois Curfman McInnes rtol = kctx->rtol_0; 339e7e93795SLois Curfman McInnes } else { 340e7e93795SLois Curfman McInnes if (kctx->version == 1) { 341e7e93795SLois Curfman McInnes rtol = (snes->norm - kctx->lresid_last)/kctx->norm_last; 342e7e93795SLois Curfman McInnes if (rtol < 0.0) rtol = -rtol; 343e7e93795SLois Curfman McInnes stol = pow(kctx->rtol_last,kctx->alpha2); 3440452661fSBarry Smith if (stol > kctx->threshold) rtol = PetscMax(rtol,stol); 345e7e93795SLois Curfman McInnes } else if (kctx->version == 2) { 346e7e93795SLois Curfman McInnes rtol = kctx->gamma * pow(snes->norm/kctx->norm_last,kctx->alpha); 347e7e93795SLois Curfman McInnes stol = kctx->gamma * pow(kctx->rtol_last,kctx->alpha); 3480452661fSBarry Smith if (stol > kctx->threshold) rtol = PetscMax(rtol,stol); 349*29bbc08cSBarry Smith } else SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Only versions 1 or 2 are supported: %d",kctx->version); 350e7e93795SLois Curfman McInnes } 3510452661fSBarry Smith rtol = PetscMin(rtol,kctx->rtol_max); 352e7e93795SLois Curfman McInnes kctx->rtol_last = rtol; 353184914b5SBarry Smith PLogInfo(snes,"SNES_KSP_EW_ComputeRelativeTolerance_Private: iter %d, Eisenstat-Walker (version %d) KSP rtol = %g\n",snes->iter,kctx->version,rtol); 3543131a8b6SLois Curfman McInnes ierr = KSPSetTolerances(ksp,rtol,PETSC_DEFAULT,PETSC_DEFAULT,PETSC_DEFAULT);CHKERRQ(ierr); 355e7e93795SLois Curfman McInnes kctx->norm_last = snes->norm; 3563a40ed3dSBarry Smith PetscFunctionReturn(0); 357e7e93795SLois Curfman McInnes } 358e7e93795SLois Curfman McInnes 3595615d1e5SSatish Balay #undef __FUNC__ 360b2863d3aSBarry Smith #define __FUNC__ /*<a name=""></a>*/"SNES_KSP_EW_Converged_Private" 361329f5518SBarry Smith int SNES_KSP_EW_Converged_Private(KSP ksp,int n,PetscReal rnorm,KSPConvergedReason *reason,void *ctx) 362e7e93795SLois Curfman McInnes { 363e7e93795SLois Curfman McInnes SNES snes = (SNES)ctx; 364e7e93795SLois Curfman McInnes SNES_KSP_EW_ConvCtx *kctx = (SNES_KSP_EW_ConvCtx*)snes->kspconvctx; 3653acb151aSSatish Balay int ierr; 366e7e93795SLois Curfman McInnes 3673a40ed3dSBarry Smith PetscFunctionBegin; 368*29bbc08cSBarry Smith if (!kctx) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context set"); 369184914b5SBarry Smith if (n == 0) {ierr = SNES_KSP_EW_ComputeRelativeTolerance_Private(snes,ksp);CHKERRQ(ierr);} 370211a6b7eSSatish Balay ierr = KSPDefaultConverged(ksp,n,rnorm,reason,ctx);CHKERRQ(ierr); 371e7e93795SLois Curfman McInnes kctx->lresid_last = rnorm; 372211a6b7eSSatish Balay if (*reason) { 373981c4779SBarry Smith PLogInfo(snes,"SNES_KSP_EW_Converged_Private: KSP iterations=%d, rnorm=%g\n",n,rnorm); 3743a40ed3dSBarry Smith } 375211a6b7eSSatish Balay PetscFunctionReturn(0); 376e7e93795SLois Curfman McInnes } 377e7e93795SLois Curfman McInnes 378e7e93795SLois Curfman McInnes 379