1e7e93795SLois Curfman McInnes 2e090d566SSatish Balay #include "src/snes/snesimpl.h" /*I "petscsnes.h" I*/ 3e7e93795SLois Curfman McInnes 44a2ae208SSatish Balay #undef __FUNCT__ 54a2ae208SSatish Balay #define __FUNCT__ "SNESVecViewMonitor" 63f1db9ecSBarry Smith /*@C 736851e7fSLois Curfman McInnes SNESVecViewMonitor - Monitors progress of the SNES solvers by calling 836851e7fSLois Curfman McInnes VecView() for the approximate solution at each iteration. 93f1db9ecSBarry Smith 103f1db9ecSBarry Smith Collective on SNES 113f1db9ecSBarry Smith 123f1db9ecSBarry Smith Input Parameters: 133f1db9ecSBarry Smith + snes - the SNES context 143f1db9ecSBarry Smith . its - iteration number 154b27c08aSLois Curfman McInnes . fgnorm - 2-norm of residual 163f1db9ecSBarry Smith - dummy - either a viewer or PETSC_NULL 173f1db9ecSBarry Smith 1836851e7fSLois Curfman McInnes Level: intermediate 193f1db9ecSBarry Smith 2036851e7fSLois Curfman McInnes .keywords: SNES, nonlinear, vector, monitor, view 213f1db9ecSBarry Smith 2236851e7fSLois Curfman McInnes .seealso: SNESSetMonitor(), SNESDefaultMonitor(), VecView() 233f1db9ecSBarry Smith @*/ 2477431f27SBarry Smith PetscErrorCode SNESVecViewMonitor(SNES snes,PetscInt its,PetscReal fgnorm,void *dummy) 253f1db9ecSBarry Smith { 26dfbe8321SBarry Smith PetscErrorCode ierr; 273f1db9ecSBarry Smith Vec x; 28b0a32e0cSBarry Smith PetscViewer viewer = (PetscViewer) dummy; 293f1db9ecSBarry Smith 303f1db9ecSBarry Smith PetscFunctionBegin; 313f1db9ecSBarry Smith ierr = SNESGetSolution(snes,&x);CHKERRQ(ierr); 323f1db9ecSBarry Smith if (!viewer) { 333f1db9ecSBarry Smith MPI_Comm comm; 343f1db9ecSBarry Smith ierr = PetscObjectGetComm((PetscObject)snes,&comm);CHKERRQ(ierr); 35b0a32e0cSBarry Smith viewer = PETSC_VIEWER_DRAW_(comm); 363f1db9ecSBarry Smith } 373f1db9ecSBarry Smith ierr = VecView(x,viewer);CHKERRQ(ierr); 383f1db9ecSBarry Smith 393f1db9ecSBarry Smith PetscFunctionReturn(0); 403f1db9ecSBarry Smith } 413f1db9ecSBarry Smith 424a2ae208SSatish Balay #undef __FUNCT__ 435ed2d596SBarry Smith #define __FUNCT__ "SNESVecViewResidualMonitor" 445ed2d596SBarry Smith /*@C 455ed2d596SBarry Smith SNESVecViewResidualMonitor - Monitors progress of the SNES solvers by calling 465ed2d596SBarry Smith VecView() for the residual at each iteration. 475ed2d596SBarry Smith 485ed2d596SBarry Smith Collective on SNES 495ed2d596SBarry Smith 505ed2d596SBarry Smith Input Parameters: 515ed2d596SBarry Smith + snes - the SNES context 525ed2d596SBarry Smith . its - iteration number 534b27c08aSLois Curfman McInnes . fgnorm - 2-norm of residual 545ed2d596SBarry Smith - dummy - either a viewer or PETSC_NULL 555ed2d596SBarry Smith 565ed2d596SBarry Smith Level: intermediate 575ed2d596SBarry Smith 585ed2d596SBarry Smith .keywords: SNES, nonlinear, vector, monitor, view 595ed2d596SBarry Smith 605ed2d596SBarry Smith .seealso: SNESSetMonitor(), SNESDefaultMonitor(), VecView() 615ed2d596SBarry Smith @*/ 6277431f27SBarry Smith PetscErrorCode SNESVecViewResidualMonitor(SNES snes,PetscInt its,PetscReal fgnorm,void *dummy) 635ed2d596SBarry Smith { 64dfbe8321SBarry Smith PetscErrorCode ierr; 655ed2d596SBarry Smith Vec x; 665ed2d596SBarry Smith PetscViewer viewer = (PetscViewer) dummy; 675ed2d596SBarry Smith 685ed2d596SBarry Smith PetscFunctionBegin; 695ed2d596SBarry Smith ierr = SNESGetFunction(snes,&x,0,0);CHKERRQ(ierr); 705ed2d596SBarry Smith if (!viewer) { 715ed2d596SBarry Smith MPI_Comm comm; 725ed2d596SBarry Smith ierr = PetscObjectGetComm((PetscObject)snes,&comm);CHKERRQ(ierr); 735ed2d596SBarry Smith viewer = PETSC_VIEWER_DRAW_(comm); 745ed2d596SBarry Smith } 755ed2d596SBarry Smith ierr = VecView(x,viewer);CHKERRQ(ierr); 765ed2d596SBarry Smith 775ed2d596SBarry Smith PetscFunctionReturn(0); 785ed2d596SBarry Smith } 795ed2d596SBarry Smith 805ed2d596SBarry Smith #undef __FUNCT__ 814a2ae208SSatish Balay #define __FUNCT__ "SNESVecViewUpdateMonitor" 82d132466eSBarry Smith /*@C 837c922b88SBarry Smith SNESVecViewUpdateMonitor - Monitors progress of the SNES solvers by calling 84d132466eSBarry Smith VecView() for the UPDATE to the solution at each iteration. 85d132466eSBarry Smith 86d132466eSBarry Smith Collective on SNES 87d132466eSBarry Smith 88d132466eSBarry Smith Input Parameters: 89d132466eSBarry Smith + snes - the SNES context 90d132466eSBarry Smith . its - iteration number 914b27c08aSLois Curfman McInnes . fgnorm - 2-norm of residual 92d132466eSBarry Smith - dummy - either a viewer or PETSC_NULL 93d132466eSBarry Smith 94d132466eSBarry Smith Level: intermediate 95d132466eSBarry Smith 96d132466eSBarry Smith .keywords: SNES, nonlinear, vector, monitor, view 97d132466eSBarry Smith 98d132466eSBarry Smith .seealso: SNESSetMonitor(), SNESDefaultMonitor(), VecView() 99d132466eSBarry Smith @*/ 10077431f27SBarry Smith PetscErrorCode SNESVecViewUpdateMonitor(SNES snes,PetscInt its,PetscReal fgnorm,void *dummy) 101d132466eSBarry Smith { 102dfbe8321SBarry Smith PetscErrorCode ierr; 103d132466eSBarry Smith Vec x; 104b0a32e0cSBarry Smith PetscViewer viewer = (PetscViewer) dummy; 105d132466eSBarry Smith 106d132466eSBarry Smith PetscFunctionBegin; 107d132466eSBarry Smith ierr = SNESGetSolutionUpdate(snes,&x);CHKERRQ(ierr); 108d132466eSBarry Smith if (!viewer) { 109d132466eSBarry Smith MPI_Comm comm; 110d132466eSBarry Smith ierr = PetscObjectGetComm((PetscObject)snes,&comm);CHKERRQ(ierr); 111b0a32e0cSBarry Smith viewer = PETSC_VIEWER_DRAW_(comm); 112d132466eSBarry Smith } 113d132466eSBarry Smith ierr = VecView(x,viewer);CHKERRQ(ierr); 114d132466eSBarry Smith 115d132466eSBarry Smith PetscFunctionReturn(0); 116d132466eSBarry Smith } 117d132466eSBarry Smith 1184a2ae208SSatish Balay #undef __FUNCT__ 1194a2ae208SSatish Balay #define __FUNCT__ "SNESDefaultMonitor" 1204b828684SBarry Smith /*@C 1214b27c08aSLois Curfman McInnes SNESDefaultMonitor - Monitors progress of the SNES solvers (default). 122e7e93795SLois Curfman McInnes 123c7afd0dbSLois Curfman McInnes Collective on SNES 124c7afd0dbSLois Curfman McInnes 125e7e93795SLois Curfman McInnes Input Parameters: 126c7afd0dbSLois Curfman McInnes + snes - the SNES context 127e7e93795SLois Curfman McInnes . its - iteration number 1284b27c08aSLois Curfman McInnes . fgnorm - 2-norm of residual 129c7afd0dbSLois Curfman McInnes - dummy - unused context 130fee21e36SBarry Smith 131e7e93795SLois Curfman McInnes Notes: 1324b27c08aSLois Curfman McInnes This routine prints the residual norm at each iteration. 133e7e93795SLois Curfman McInnes 13436851e7fSLois Curfman McInnes Level: intermediate 13536851e7fSLois Curfman McInnes 136e7e93795SLois Curfman McInnes .keywords: SNES, nonlinear, default, monitor, norm 137e7e93795SLois Curfman McInnes 13836851e7fSLois Curfman McInnes .seealso: SNESSetMonitor(), SNESVecViewMonitor() 139e7e93795SLois Curfman McInnes @*/ 14077431f27SBarry Smith PetscErrorCode SNESDefaultMonitor(SNES snes,PetscInt its,PetscReal fgnorm,void *dummy) 141e7e93795SLois Curfman McInnes { 142dfbe8321SBarry Smith PetscErrorCode ierr; 143b0a32e0cSBarry Smith PetscViewer viewer = (PetscViewer) dummy; 144d132466eSBarry Smith 1453a40ed3dSBarry Smith PetscFunctionBegin; 146b0a32e0cSBarry Smith if (!viewer) viewer = PETSC_VIEWER_STDOUT_(snes->comm); 147a0e26f09SSatish Balay ierr = PetscViewerASCIIPrintf(viewer,"%3d SNES Function norm %14.12e \n",its,fgnorm);CHKERRQ(ierr); 1483a40ed3dSBarry Smith PetscFunctionReturn(0); 149e7e93795SLois Curfman McInnes } 1503f1db9ecSBarry Smith 1513a7fca6bSBarry Smith #undef __FUNCT__ 1523a7fca6bSBarry Smith #define __FUNCT__ "SNESRatioMonitor" 1533a7fca6bSBarry Smith /*@C 1544b27c08aSLois Curfman McInnes SNESRatioMonitor - Monitors progress of the SNES solvers by printing the ratio 1554b27c08aSLois Curfman McInnes of residual norm at each iteration to the previous. 1563a7fca6bSBarry Smith 1573a7fca6bSBarry Smith Collective on SNES 1583a7fca6bSBarry Smith 1593a7fca6bSBarry Smith Input Parameters: 1603a7fca6bSBarry Smith + snes - the SNES context 1613a7fca6bSBarry Smith . its - iteration number 1623a7fca6bSBarry Smith . fgnorm - 2-norm of residual (or gradient) 1633a7fca6bSBarry Smith - dummy - unused context 1643a7fca6bSBarry Smith 1653a7fca6bSBarry Smith Level: intermediate 1663a7fca6bSBarry Smith 1673a7fca6bSBarry Smith .keywords: SNES, nonlinear, monitor, norm 1683a7fca6bSBarry Smith 1693a7fca6bSBarry Smith .seealso: SNESSetMonitor(), SNESVecViewMonitor() 1703a7fca6bSBarry Smith @*/ 17177431f27SBarry Smith PetscErrorCode SNESRatioMonitor(SNES snes,PetscInt its,PetscReal fgnorm,void *dummy) 1723a7fca6bSBarry Smith { 173dfbe8321SBarry Smith PetscErrorCode ierr; 17477431f27SBarry Smith PetscInt len; 17587828ca2SBarry Smith PetscReal *history; 1763a7fca6bSBarry Smith PetscViewer viewer; 1773a7fca6bSBarry Smith 1783a7fca6bSBarry Smith PetscFunctionBegin; 1793a7fca6bSBarry Smith viewer = PETSC_VIEWER_STDOUT_(snes->comm); 1803a7fca6bSBarry Smith 1813a7fca6bSBarry Smith ierr = SNESGetConvergenceHistory(snes,&history,PETSC_NULL,&len);CHKERRQ(ierr); 182958c9bccSBarry Smith if (!its || !history || its > len) { 1833a7fca6bSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"%3d SNES Function norm %14.12e \n",its,fgnorm);CHKERRQ(ierr); 1843a7fca6bSBarry Smith } else { 18587828ca2SBarry Smith PetscReal ratio = fgnorm/history[its-1]; 1863a7fca6bSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"%3d SNES Function norm %14.12e %g \n",its,fgnorm,ratio);CHKERRQ(ierr); 1873a7fca6bSBarry Smith } 1883a7fca6bSBarry Smith PetscFunctionReturn(0); 1893a7fca6bSBarry Smith } 1903a7fca6bSBarry Smith 1913a7fca6bSBarry Smith /* 1923a7fca6bSBarry Smith If the we set the history monitor space then we must destroy it 1933a7fca6bSBarry Smith */ 1943a7fca6bSBarry Smith #undef __FUNCT__ 1953a7fca6bSBarry Smith #define __FUNCT__ "SNESRatioMonitorDestroy" 196dfbe8321SBarry Smith PetscErrorCode SNESRatioMonitorDestroy(void *history) 1973a7fca6bSBarry Smith { 198dfbe8321SBarry Smith PetscErrorCode ierr; 1993a7fca6bSBarry Smith 2003a7fca6bSBarry Smith PetscFunctionBegin; 2013a7fca6bSBarry Smith ierr = PetscFree(history);CHKERRQ(ierr); 2023a7fca6bSBarry Smith PetscFunctionReturn(0); 2033a7fca6bSBarry Smith } 2043a7fca6bSBarry Smith 2053a7fca6bSBarry Smith #undef __FUNCT__ 2063a7fca6bSBarry Smith #define __FUNCT__ "SNESSetRatioMonitor" 2073a7fca6bSBarry Smith /*@C 2083a7fca6bSBarry Smith SNESSetRatioMonitor - Sets SNES to use a monitor that prints the 2094b27c08aSLois Curfman McInnes ratio of the function norm at each iteration. 2103a7fca6bSBarry Smith 2113a7fca6bSBarry Smith Collective on SNES 2123a7fca6bSBarry Smith 2133a7fca6bSBarry Smith Input Parameters: 2143a7fca6bSBarry Smith . snes - the SNES context 2153a7fca6bSBarry Smith 2163a7fca6bSBarry Smith Level: intermediate 2173a7fca6bSBarry Smith 2183a7fca6bSBarry Smith .keywords: SNES, nonlinear, monitor, norm 2193a7fca6bSBarry Smith 2203a7fca6bSBarry Smith .seealso: SNESSetMonitor(), SNESVecViewMonitor(), SNESDefaultMonitor() 2213a7fca6bSBarry Smith @*/ 222dfbe8321SBarry Smith PetscErrorCode SNESSetRatioMonitor(SNES snes) 2233a7fca6bSBarry Smith { 224dfbe8321SBarry Smith PetscErrorCode ierr; 22587828ca2SBarry Smith PetscReal *history; 2263a7fca6bSBarry Smith 2273a7fca6bSBarry Smith PetscFunctionBegin; 2283a7fca6bSBarry Smith 2293a7fca6bSBarry Smith ierr = SNESGetConvergenceHistory(snes,&history,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr); 2303a7fca6bSBarry Smith if (!history) { 2313a7fca6bSBarry Smith ierr = PetscMalloc(100*sizeof(double),&history);CHKERRQ(ierr); 2323a7fca6bSBarry Smith ierr = SNESSetConvergenceHistory(snes,history,0,100,PETSC_TRUE);CHKERRQ(ierr); 2333a7fca6bSBarry Smith ierr = SNESSetMonitor(snes,SNESRatioMonitor,history,SNESRatioMonitorDestroy);CHKERRQ(ierr); 2343a7fca6bSBarry Smith } else { 2353a7fca6bSBarry Smith ierr = SNESSetMonitor(snes,SNESRatioMonitor,0,0);CHKERRQ(ierr); 2363a7fca6bSBarry Smith } 2373a7fca6bSBarry Smith PetscFunctionReturn(0); 2383a7fca6bSBarry Smith } 2393a7fca6bSBarry Smith 240e7e93795SLois Curfman McInnes /* ---------------------------------------------------------------- */ 2414a2ae208SSatish Balay #undef __FUNCT__ 2424a2ae208SSatish Balay #define __FUNCT__ "SNESDefaultSMonitor" 243be1f7002SBarry Smith /* 244be1f7002SBarry Smith Default (short) SNES Monitor, same as SNESDefaultMonitor() except 245be1f7002SBarry Smith it prints fewer digits of the residual as the residual gets smaller. 246be1f7002SBarry Smith This is because the later digits are meaningless and are often 247be1f7002SBarry Smith different on different machines; by using this routine different 248be1f7002SBarry Smith machines will usually generate the same output. 249be1f7002SBarry Smith */ 25077431f27SBarry Smith PetscErrorCode SNESDefaultSMonitor(SNES snes,PetscInt its,PetscReal fgnorm,void *dummy) 251e7e93795SLois Curfman McInnes { 252dfbe8321SBarry Smith PetscErrorCode ierr; 253d132466eSBarry Smith 2543a40ed3dSBarry Smith PetscFunctionBegin; 2558f240d10SBarry Smith if (fgnorm > 1.e-9) { 25677431f27SBarry Smith ierr = PetscPrintf(snes->comm,"%3D SNES Function norm %g \n",its,fgnorm);CHKERRQ(ierr); 2573a40ed3dSBarry Smith } else if (fgnorm > 1.e-11){ 25877431f27SBarry Smith ierr = PetscPrintf(snes->comm,"%3D SNES Function norm %5.3e \n",its,fgnorm);CHKERRQ(ierr); 2593a40ed3dSBarry Smith } else { 26077431f27SBarry Smith ierr = PetscPrintf(snes->comm,"%3D SNES Function norm < 1.e-11\n",its);CHKERRQ(ierr); 261e7e93795SLois Curfman McInnes } 2623a40ed3dSBarry Smith PetscFunctionReturn(0); 263e7e93795SLois Curfman McInnes } 264e7e93795SLois Curfman McInnes /* ---------------------------------------------------------------- */ 2654a2ae208SSatish Balay #undef __FUNCT__ 2664b27c08aSLois Curfman McInnes #define __FUNCT__ "SNESConverged_LS" 2674b828684SBarry Smith /*@C 2684b27c08aSLois Curfman McInnes SNESConverged_LS - Monitors the convergence of the solvers for 269f525115eSLois Curfman McInnes systems of nonlinear equations (default). 270e7e93795SLois Curfman McInnes 271c7afd0dbSLois Curfman McInnes Collective on SNES 272c7afd0dbSLois Curfman McInnes 273e7e93795SLois Curfman McInnes Input Parameters: 274c7afd0dbSLois Curfman McInnes + snes - the SNES context 275e7e93795SLois Curfman McInnes . xnorm - 2-norm of current iterate 276e7e93795SLois Curfman McInnes . pnorm - 2-norm of current step 277e7e93795SLois Curfman McInnes . fnorm - 2-norm of function 278c7afd0dbSLois Curfman McInnes - dummy - unused context 279e7e93795SLois Curfman McInnes 280184914b5SBarry Smith Output Parameter: 281184914b5SBarry Smith . reason - one of 282*70441072SBarry Smith $ SNES_CONVERGED_FNORM_ABS - (fnorm < abstol), 2833304466cSBarry Smith $ SNES_CONVERGED_PNORM_RELATIVE - (pnorm < xtol*xnorm), 284184914b5SBarry Smith $ SNES_CONVERGED_FNORM_RELATIVE - (fnorm < rtol*fnorm0), 285184914b5SBarry Smith $ SNES_DIVERGED_FUNCTION_COUNT - (nfct > maxf), 286184914b5SBarry Smith $ SNES_DIVERGED_FNORM_NAN - (fnorm == NaN), 287184914b5SBarry Smith $ SNES_CONVERGED_ITERATING - (otherwise), 288e7e93795SLois Curfman McInnes 289e7e93795SLois Curfman McInnes where 290c7afd0dbSLois Curfman McInnes + maxf - maximum number of function evaluations, 291c7afd0dbSLois Curfman McInnes set with SNESSetTolerances() 292c7afd0dbSLois Curfman McInnes . nfct - number of function evaluations, 293*70441072SBarry Smith . abstol - absolute function norm tolerance, 294c7afd0dbSLois Curfman McInnes set with SNESSetTolerances() 295c7afd0dbSLois Curfman McInnes - rtol - relative function norm tolerance, set with SNESSetTolerances() 296fee21e36SBarry Smith 29736851e7fSLois Curfman McInnes Level: intermediate 29836851e7fSLois Curfman McInnes 299e7e93795SLois Curfman McInnes .keywords: SNES, nonlinear, default, converged, convergence 300e7e93795SLois Curfman McInnes 301e7e93795SLois Curfman McInnes .seealso: SNESSetConvergenceTest(), SNESEisenstatWalkerConverged() 302e7e93795SLois Curfman McInnes @*/ 303dfbe8321SBarry Smith PetscErrorCode SNESConverged_LS(SNES snes,PetscReal xnorm,PetscReal pnorm,PetscReal fnorm,SNESConvergedReason *reason,void *dummy) 304e7e93795SLois Curfman McInnes { 3053a40ed3dSBarry Smith PetscFunctionBegin; 306d252947aSBarry Smith if (fnorm != fnorm) { 3074b27c08aSLois Curfman McInnes PetscLogInfo(snes,"SNESConverged_LS:Failed to converged, function norm is NaN\n"); 308184914b5SBarry Smith *reason = SNES_DIVERGED_FNORM_NAN; 309184914b5SBarry Smith } else if (fnorm <= snes->ttol) { 3104b27c08aSLois Curfman McInnes PetscLogInfo(snes,"SNESConverged_LS:Converged due to function norm %g < %g (relative tolerance)\n",fnorm,snes->ttol); 311184914b5SBarry Smith *reason = SNES_CONVERGED_FNORM_RELATIVE; 312*70441072SBarry Smith } else if (fnorm < snes->abstol) { 313*70441072SBarry Smith PetscLogInfo(snes,"SNESConverged_LS:Converged due to function norm %g < %g\n",fnorm,snes->abstol); 314184914b5SBarry Smith *reason = SNES_CONVERGED_FNORM_ABS; 3153304466cSBarry Smith } else if (pnorm < snes->xtol*xnorm) { 3164b27c08aSLois Curfman McInnes PetscLogInfo(snes,"SNESConverged_LS:Converged due to small update length: %g < %g * %g\n",pnorm,snes->xtol,xnorm); 317184914b5SBarry Smith *reason = SNES_CONVERGED_PNORM_RELATIVE; 318184914b5SBarry Smith } else if (snes->nfuncs > snes->max_funcs) { 31977431f27SBarry Smith PetscLogInfo(snes,"SNESConverged_LS:Exceeded maximum number of function evaluations: %D > %D\n",snes->nfuncs,snes->max_funcs); 320184914b5SBarry Smith *reason = SNES_DIVERGED_FUNCTION_COUNT ; 321184914b5SBarry Smith } else { 322184914b5SBarry Smith *reason = SNES_CONVERGED_ITERATING; 323e7e93795SLois Curfman McInnes } 3243a40ed3dSBarry Smith PetscFunctionReturn(0); 325e7e93795SLois Curfman McInnes } 326e7e93795SLois Curfman McInnes /* ------------------------------------------------------------ */ 3274a2ae208SSatish Balay #undef __FUNCT__ 3284a2ae208SSatish Balay #define __FUNCT__ "SNES_KSP_SetConvergenceTestEW" 329e7e93795SLois Curfman McInnes /*@ 330f525115eSLois Curfman McInnes SNES_KSP_SetConvergenceTestEW - Sets alternative convergence test 331e7e93795SLois Curfman McInnes for the linear solvers within an inexact Newton method. 332e7e93795SLois Curfman McInnes 333c7afd0dbSLois Curfman McInnes Collective on SNES 334c7afd0dbSLois Curfman McInnes 335e7e93795SLois Curfman McInnes Input Parameter: 336e7e93795SLois Curfman McInnes . snes - SNES context 337e7e93795SLois Curfman McInnes 338e7e93795SLois Curfman McInnes Notes: 339e7e93795SLois Curfman McInnes Currently, the default is to use a constant relative tolerance for 340e7e93795SLois Curfman McInnes the inner linear solvers. Alternatively, one can use the 341e7e93795SLois Curfman McInnes Eisenstat-Walker method, where the relative convergence tolerance 342e7e93795SLois Curfman McInnes is reset at each Newton iteration according progress of the nonlinear 343e7e93795SLois Curfman McInnes solver. 344e7e93795SLois Curfman McInnes 34536851e7fSLois Curfman McInnes Level: advanced 34636851e7fSLois Curfman McInnes 347e7e93795SLois Curfman McInnes Reference: 348e7e93795SLois Curfman McInnes S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an 349e30ad881SLois Curfman McInnes inexact Newton method", SISC 17 (1), pp.16-32, 1996. 350e7e93795SLois Curfman McInnes 351e7e93795SLois Curfman McInnes .keywords: SNES, KSP, Eisenstat, Walker, convergence, test, inexact, Newton 352e7e93795SLois Curfman McInnes @*/ 353dfbe8321SBarry Smith PetscErrorCode SNES_KSP_SetConvergenceTestEW(SNES snes) 354e7e93795SLois Curfman McInnes { 3553a40ed3dSBarry Smith PetscFunctionBegin; 356186905e3SBarry Smith snes->ksp_ewconv = PETSC_TRUE; 3573a40ed3dSBarry Smith PetscFunctionReturn(0); 358e7e93795SLois Curfman McInnes } 359e7e93795SLois Curfman McInnes 3604a2ae208SSatish Balay #undef __FUNCT__ 3614a2ae208SSatish Balay #define __FUNCT__ "SNES_KSP_SetParametersEW" 362e7e93795SLois Curfman McInnes /*@ 363e7e93795SLois Curfman McInnes SNES_KSP_SetParametersEW - Sets parameters for Eisenstat-Walker 364e7e93795SLois Curfman McInnes convergence criteria for the linear solvers within an inexact 365e7e93795SLois Curfman McInnes Newton method. 366e7e93795SLois Curfman McInnes 367c7afd0dbSLois Curfman McInnes Collective on SNES 368c7afd0dbSLois Curfman McInnes 369e7e93795SLois Curfman McInnes Input Parameters: 370c7afd0dbSLois Curfman McInnes + snes - SNES context 371e7e93795SLois Curfman McInnes . version - version 1 or 2 (default is 2) 372c7afd0dbSLois Curfman McInnes . rtol_0 - initial relative tolerance (0 <= rtol_0 < 1) 373c7afd0dbSLois Curfman McInnes . rtol_max - maximum relative tolerance (0 <= rtol_max < 1) 374c7afd0dbSLois Curfman McInnes . alpha - power for version 2 rtol computation (1 < alpha <= 2) 375e7e93795SLois Curfman McInnes . alpha2 - power for safeguard 376e7e93795SLois Curfman McInnes . gamma2 - multiplicative factor for version 2 rtol computation 377c7afd0dbSLois Curfman McInnes (0 <= gamma2 <= 1) 378c7afd0dbSLois Curfman McInnes - threshold - threshold for imposing safeguard (0 < threshold < 1) 379fee21e36SBarry Smith 380e7e93795SLois Curfman McInnes Note: 381e7e93795SLois Curfman McInnes Use PETSC_DEFAULT to retain the default for any of the parameters. 382e7e93795SLois Curfman McInnes 38336851e7fSLois Curfman McInnes Level: advanced 38436851e7fSLois Curfman McInnes 385e7e93795SLois Curfman McInnes Reference: 386e7e93795SLois Curfman McInnes S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an 387e7e93795SLois Curfman McInnes inexact Newton method", Utah State University Math. Stat. Dept. Res. 388e7e93795SLois Curfman McInnes Report 6/94/75, June, 1994, to appear in SIAM J. Sci. Comput. 389e7e93795SLois Curfman McInnes 390e7e93795SLois Curfman McInnes .keywords: SNES, KSP, Eisenstat, Walker, set, parameters 391e7e93795SLois Curfman McInnes 392e7e93795SLois Curfman McInnes .seealso: SNES_KSP_SetConvergenceTestEW() 393e7e93795SLois Curfman McInnes @*/ 39477431f27SBarry Smith PetscErrorCode SNES_KSP_SetParametersEW(SNES snes,PetscInt version,PetscReal rtol_0,PetscReal rtol_max,PetscReal gamma2,PetscReal alpha, 395329f5518SBarry Smith PetscReal alpha2,PetscReal threshold) 396e7e93795SLois Curfman McInnes { 397e7e93795SLois Curfman McInnes SNES_KSP_EW_ConvCtx *kctx = (SNES_KSP_EW_ConvCtx*)snes->kspconvctx; 3983a40ed3dSBarry Smith 3993a40ed3dSBarry Smith PetscFunctionBegin; 40029bbc08cSBarry Smith if (!kctx) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context existing"); 401e7e93795SLois Curfman McInnes if (version != PETSC_DEFAULT) kctx->version = version; 402e7e93795SLois Curfman McInnes if (rtol_0 != PETSC_DEFAULT) kctx->rtol_0 = rtol_0; 403e7e93795SLois Curfman McInnes if (rtol_max != PETSC_DEFAULT) kctx->rtol_max = rtol_max; 404e7e93795SLois Curfman McInnes if (gamma2 != PETSC_DEFAULT) kctx->gamma = gamma2; 405e7e93795SLois Curfman McInnes if (alpha != PETSC_DEFAULT) kctx->alpha = alpha; 406e7e93795SLois Curfman McInnes if (alpha2 != PETSC_DEFAULT) kctx->alpha2 = alpha2; 407e7e93795SLois Curfman McInnes if (threshold != PETSC_DEFAULT) kctx->threshold = threshold; 408a8c6a408SBarry Smith if (kctx->rtol_0 < 0.0 || kctx->rtol_0 >= 1.0) { 40929bbc08cSBarry Smith SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"0.0 <= rtol_0 < 1.0: %g",kctx->rtol_0); 410a8c6a408SBarry Smith } 411a8c6a408SBarry Smith if (kctx->rtol_max < 0.0 || kctx->rtol_max >= 1.0) { 412091e6287SMatthew Knepley SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"0.0 <= rtol_max (%g) < 1.0\n",kctx->rtol_max); 413a8c6a408SBarry Smith } 414a8c6a408SBarry Smith if (kctx->threshold <= 0.0 || kctx->threshold >= 1.0) { 415091e6287SMatthew Knepley SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"0.0 < threshold (%g) < 1.0\n",kctx->threshold); 416a8c6a408SBarry Smith } 417a8c6a408SBarry Smith if (kctx->gamma < 0.0 || kctx->gamma > 1.0) { 418091e6287SMatthew Knepley SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"0.0 <= gamma (%g) <= 1.0\n",kctx->gamma); 419a8c6a408SBarry Smith } 420a8c6a408SBarry Smith if (kctx->alpha <= 1.0 || kctx->alpha > 2.0) { 421091e6287SMatthew Knepley SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"1.0 < alpha (%g) <= 2.0\n",kctx->alpha); 422a8c6a408SBarry Smith } 423a8c6a408SBarry Smith if (kctx->version != 1 && kctx->version !=2) { 42477431f27SBarry Smith SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Only versions 1 and 2 are supported: %D",kctx->version); 425a8c6a408SBarry Smith } 4263a40ed3dSBarry Smith PetscFunctionReturn(0); 427e7e93795SLois Curfman McInnes } 428e7e93795SLois Curfman McInnes 4294a2ae208SSatish Balay #undef __FUNCT__ 4304a2ae208SSatish Balay #define __FUNCT__ "SNES_KSP_EW_ComputeRelativeTolerance_Private" 431dfbe8321SBarry Smith PetscErrorCode SNES_KSP_EW_ComputeRelativeTolerance_Private(SNES snes,KSP ksp) 432e7e93795SLois Curfman McInnes { 433e7e93795SLois Curfman McInnes SNES_KSP_EW_ConvCtx *kctx = (SNES_KSP_EW_ConvCtx*)snes->kspconvctx; 434329f5518SBarry Smith PetscReal rtol = 0.0,stol; 435dfbe8321SBarry Smith PetscErrorCode ierr; 4363a40ed3dSBarry Smith 4373a40ed3dSBarry Smith PetscFunctionBegin; 43829bbc08cSBarry Smith if (!kctx) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context exists"); 439c38d4ed2SBarry Smith if (!snes->iter) { /* first time in, so use the original user rtol */ 440e7e93795SLois Curfman McInnes rtol = kctx->rtol_0; 441e7e93795SLois Curfman McInnes } else { 442e7e93795SLois Curfman McInnes if (kctx->version == 1) { 443e7e93795SLois Curfman McInnes rtol = (snes->norm - kctx->lresid_last)/kctx->norm_last; 444e7e93795SLois Curfman McInnes if (rtol < 0.0) rtol = -rtol; 445e7e93795SLois Curfman McInnes stol = pow(kctx->rtol_last,kctx->alpha2); 4460452661fSBarry Smith if (stol > kctx->threshold) rtol = PetscMax(rtol,stol); 447e7e93795SLois Curfman McInnes } else if (kctx->version == 2) { 448e7e93795SLois Curfman McInnes rtol = kctx->gamma * pow(snes->norm/kctx->norm_last,kctx->alpha); 449e7e93795SLois Curfman McInnes stol = kctx->gamma * pow(kctx->rtol_last,kctx->alpha); 4500452661fSBarry Smith if (stol > kctx->threshold) rtol = PetscMax(rtol,stol); 45177431f27SBarry Smith } else SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Only versions 1 or 2 are supported: %D",kctx->version); 452e7e93795SLois Curfman McInnes } 4530452661fSBarry Smith rtol = PetscMin(rtol,kctx->rtol_max); 454e7e93795SLois Curfman McInnes kctx->rtol_last = rtol; 45577431f27SBarry Smith PetscLogInfo(snes,"SNES_KSP_EW_ComputeRelativeTolerance_Private: iter %D, Eisenstat-Walker (version %D) KSP rtol = %g\n",snes->iter,kctx->version,rtol); 4563131a8b6SLois Curfman McInnes ierr = KSPSetTolerances(ksp,rtol,PETSC_DEFAULT,PETSC_DEFAULT,PETSC_DEFAULT);CHKERRQ(ierr); 457e7e93795SLois Curfman McInnes kctx->norm_last = snes->norm; 4583a40ed3dSBarry Smith PetscFunctionReturn(0); 459e7e93795SLois Curfman McInnes } 460e7e93795SLois Curfman McInnes 4614a2ae208SSatish Balay #undef __FUNCT__ 4624a2ae208SSatish Balay #define __FUNCT__ "SNES_KSP_EW_Converged_Private" 463dfbe8321SBarry Smith PetscErrorCode SNES_KSP_EW_Converged_Private(KSP ksp,int n,PetscReal rnorm,KSPConvergedReason *reason,void *ctx) 464e7e93795SLois Curfman McInnes { 465e7e93795SLois Curfman McInnes SNES snes = (SNES)ctx; 466e7e93795SLois Curfman McInnes SNES_KSP_EW_ConvCtx *kctx = (SNES_KSP_EW_ConvCtx*)snes->kspconvctx; 467dfbe8321SBarry Smith PetscErrorCode ierr; 468e7e93795SLois Curfman McInnes 4693a40ed3dSBarry Smith PetscFunctionBegin; 47029bbc08cSBarry Smith if (!kctx) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context set"); 471958c9bccSBarry Smith if (!n) {ierr = SNES_KSP_EW_ComputeRelativeTolerance_Private(snes,ksp);CHKERRQ(ierr);} 472211a6b7eSSatish Balay ierr = KSPDefaultConverged(ksp,n,rnorm,reason,ctx);CHKERRQ(ierr); 473e7e93795SLois Curfman McInnes kctx->lresid_last = rnorm; 474211a6b7eSSatish Balay if (*reason) { 47577431f27SBarry Smith PetscLogInfo(snes,"SNES_KSP_EW_Converged_Private: KSP iterations=%D, rnorm=%g\n",n,rnorm); 4763a40ed3dSBarry Smith } 477211a6b7eSSatish Balay PetscFunctionReturn(0); 478e7e93795SLois Curfman McInnes } 479e7e93795SLois Curfman McInnes 480e7e93795SLois Curfman McInnes 481