173f4d377SMatthew Knepley /*$Id: snesut.c,v 1.66 2001/08/06 21:17:07 bsmith Exp $*/ 2e7e93795SLois Curfman McInnes 3e090d566SSatish Balay #include "src/snes/snesimpl.h" /*I "petscsnes.h" I*/ 4e7e93795SLois Curfman McInnes 54a2ae208SSatish Balay #undef __FUNCT__ 64a2ae208SSatish Balay #define __FUNCT__ "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 16*4b27c08aSLois Curfman McInnes . fgnorm - 2-norm of residual 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; 29b0a32e0cSBarry Smith PetscViewer viewer = (PetscViewer) 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); 36b0a32e0cSBarry Smith viewer = PETSC_VIEWER_DRAW_(comm); 373f1db9ecSBarry Smith } 383f1db9ecSBarry Smith ierr = VecView(x,viewer);CHKERRQ(ierr); 393f1db9ecSBarry Smith 403f1db9ecSBarry Smith PetscFunctionReturn(0); 413f1db9ecSBarry Smith } 423f1db9ecSBarry Smith 434a2ae208SSatish Balay #undef __FUNCT__ 445ed2d596SBarry Smith #define __FUNCT__ "SNESVecViewResidualMonitor" 455ed2d596SBarry Smith /*@C 465ed2d596SBarry Smith SNESVecViewResidualMonitor - Monitors progress of the SNES solvers by calling 475ed2d596SBarry Smith VecView() for the residual at each iteration. 485ed2d596SBarry Smith 495ed2d596SBarry Smith Collective on SNES 505ed2d596SBarry Smith 515ed2d596SBarry Smith Input Parameters: 525ed2d596SBarry Smith + snes - the SNES context 535ed2d596SBarry Smith . its - iteration number 54*4b27c08aSLois Curfman McInnes . fgnorm - 2-norm of residual 555ed2d596SBarry Smith - dummy - either a viewer or PETSC_NULL 565ed2d596SBarry Smith 575ed2d596SBarry Smith Level: intermediate 585ed2d596SBarry Smith 595ed2d596SBarry Smith .keywords: SNES, nonlinear, vector, monitor, view 605ed2d596SBarry Smith 615ed2d596SBarry Smith .seealso: SNESSetMonitor(), SNESDefaultMonitor(), VecView() 625ed2d596SBarry Smith @*/ 635ed2d596SBarry Smith int SNESVecViewResidualMonitor(SNES snes,int its,PetscReal fgnorm,void *dummy) 645ed2d596SBarry Smith { 655ed2d596SBarry Smith int ierr; 665ed2d596SBarry Smith Vec x; 675ed2d596SBarry Smith PetscViewer viewer = (PetscViewer) dummy; 685ed2d596SBarry Smith 695ed2d596SBarry Smith PetscFunctionBegin; 705ed2d596SBarry Smith ierr = SNESGetFunction(snes,&x,0,0);CHKERRQ(ierr); 715ed2d596SBarry Smith if (!viewer) { 725ed2d596SBarry Smith MPI_Comm comm; 735ed2d596SBarry Smith ierr = PetscObjectGetComm((PetscObject)snes,&comm);CHKERRQ(ierr); 745ed2d596SBarry Smith viewer = PETSC_VIEWER_DRAW_(comm); 755ed2d596SBarry Smith } 765ed2d596SBarry Smith ierr = VecView(x,viewer);CHKERRQ(ierr); 775ed2d596SBarry Smith 785ed2d596SBarry Smith PetscFunctionReturn(0); 795ed2d596SBarry Smith } 805ed2d596SBarry Smith 815ed2d596SBarry Smith #undef __FUNCT__ 824a2ae208SSatish Balay #define __FUNCT__ "SNESVecViewUpdateMonitor" 83d132466eSBarry Smith /*@C 847c922b88SBarry Smith SNESVecViewUpdateMonitor - Monitors progress of the SNES solvers by calling 85d132466eSBarry Smith VecView() for the UPDATE to the solution at each iteration. 86d132466eSBarry Smith 87d132466eSBarry Smith Collective on SNES 88d132466eSBarry Smith 89d132466eSBarry Smith Input Parameters: 90d132466eSBarry Smith + snes - the SNES context 91d132466eSBarry Smith . its - iteration number 92*4b27c08aSLois Curfman McInnes . fgnorm - 2-norm of residual 93d132466eSBarry Smith - dummy - either a viewer or PETSC_NULL 94d132466eSBarry Smith 95d132466eSBarry Smith Level: intermediate 96d132466eSBarry Smith 97d132466eSBarry Smith .keywords: SNES, nonlinear, vector, monitor, view 98d132466eSBarry Smith 99d132466eSBarry Smith .seealso: SNESSetMonitor(), SNESDefaultMonitor(), VecView() 100d132466eSBarry Smith @*/ 101329f5518SBarry Smith int SNESVecViewUpdateMonitor(SNES snes,int its,PetscReal fgnorm,void *dummy) 102d132466eSBarry Smith { 103d132466eSBarry Smith int ierr; 104d132466eSBarry Smith Vec x; 105b0a32e0cSBarry Smith PetscViewer viewer = (PetscViewer) dummy; 106d132466eSBarry Smith 107d132466eSBarry Smith PetscFunctionBegin; 108d132466eSBarry Smith ierr = SNESGetSolutionUpdate(snes,&x);CHKERRQ(ierr); 109d132466eSBarry Smith if (!viewer) { 110d132466eSBarry Smith MPI_Comm comm; 111d132466eSBarry Smith ierr = PetscObjectGetComm((PetscObject)snes,&comm);CHKERRQ(ierr); 112b0a32e0cSBarry Smith viewer = PETSC_VIEWER_DRAW_(comm); 113d132466eSBarry Smith } 114d132466eSBarry Smith ierr = VecView(x,viewer);CHKERRQ(ierr); 115d132466eSBarry Smith 116d132466eSBarry Smith PetscFunctionReturn(0); 117d132466eSBarry Smith } 118d132466eSBarry Smith 1194a2ae208SSatish Balay #undef __FUNCT__ 1204a2ae208SSatish Balay #define __FUNCT__ "SNESDefaultMonitor" 1214b828684SBarry Smith /*@C 122*4b27c08aSLois Curfman McInnes SNESDefaultMonitor - Monitors progress of the SNES solvers (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 . its - iteration number 129*4b27c08aSLois Curfman McInnes . fgnorm - 2-norm of residual 130c7afd0dbSLois Curfman McInnes - dummy - unused context 131fee21e36SBarry Smith 132e7e93795SLois Curfman McInnes Notes: 133*4b27c08aSLois Curfman McInnes This routine prints the residual norm at each iteration. 134e7e93795SLois Curfman McInnes 13536851e7fSLois Curfman McInnes Level: intermediate 13636851e7fSLois Curfman McInnes 137e7e93795SLois Curfman McInnes .keywords: SNES, nonlinear, default, monitor, norm 138e7e93795SLois Curfman McInnes 13936851e7fSLois Curfman McInnes .seealso: SNESSetMonitor(), SNESVecViewMonitor() 140e7e93795SLois Curfman McInnes @*/ 141329f5518SBarry Smith int SNESDefaultMonitor(SNES snes,int its,PetscReal fgnorm,void *dummy) 142e7e93795SLois Curfman McInnes { 143d132466eSBarry Smith int ierr; 144b0a32e0cSBarry Smith PetscViewer viewer = (PetscViewer) dummy; 145d132466eSBarry Smith 1463a40ed3dSBarry Smith PetscFunctionBegin; 147b0a32e0cSBarry Smith if (!viewer) viewer = PETSC_VIEWER_STDOUT_(snes->comm); 148a0e26f09SSatish Balay ierr = PetscViewerASCIIPrintf(viewer,"%3d SNES Function norm %14.12e \n",its,fgnorm);CHKERRQ(ierr); 1493a40ed3dSBarry Smith PetscFunctionReturn(0); 150e7e93795SLois Curfman McInnes } 1513f1db9ecSBarry Smith 1523a7fca6bSBarry Smith #undef __FUNCT__ 1533a7fca6bSBarry Smith #define __FUNCT__ "SNESRatioMonitor" 1543a7fca6bSBarry Smith /*@C 155*4b27c08aSLois Curfman McInnes SNESRatioMonitor - Monitors progress of the SNES solvers by printing the ratio 156*4b27c08aSLois Curfman McInnes of residual norm at each iteration to the previous. 1573a7fca6bSBarry Smith 1583a7fca6bSBarry Smith Collective on SNES 1593a7fca6bSBarry Smith 1603a7fca6bSBarry Smith Input Parameters: 1613a7fca6bSBarry Smith + snes - the SNES context 1623a7fca6bSBarry Smith . its - iteration number 1633a7fca6bSBarry Smith . fgnorm - 2-norm of residual (or gradient) 1643a7fca6bSBarry Smith - dummy - unused context 1653a7fca6bSBarry Smith 1663a7fca6bSBarry Smith Level: intermediate 1673a7fca6bSBarry Smith 1683a7fca6bSBarry Smith .keywords: SNES, nonlinear, monitor, norm 1693a7fca6bSBarry Smith 1703a7fca6bSBarry Smith .seealso: SNESSetMonitor(), SNESVecViewMonitor() 1713a7fca6bSBarry Smith @*/ 1723a7fca6bSBarry Smith int SNESRatioMonitor(SNES snes,int its,PetscReal fgnorm,void *dummy) 1733a7fca6bSBarry Smith { 1743a7fca6bSBarry Smith int ierr,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); 1823a7fca6bSBarry Smith if (its == 0 || !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" 1963a7fca6bSBarry Smith int SNESRatioMonitorDestroy(void *history) 1973a7fca6bSBarry Smith { 1983a7fca6bSBarry Smith int 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 209*4b27c08aSLois 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 @*/ 2223a7fca6bSBarry Smith int SNESSetRatioMonitor(SNES snes) 2233a7fca6bSBarry Smith { 2243a7fca6bSBarry Smith int 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 */ 250329f5518SBarry Smith int SNESDefaultSMonitor(SNES snes,int its,PetscReal fgnorm,void *dummy) 251e7e93795SLois Curfman McInnes { 252d132466eSBarry Smith int ierr; 253d132466eSBarry Smith 2543a40ed3dSBarry Smith PetscFunctionBegin; 2558f240d10SBarry Smith if (fgnorm > 1.e-9) { 256a0e26f09SSatish Balay ierr = PetscPrintf(snes->comm,"%3d SNES Function norm %g \n",its,fgnorm);CHKERRQ(ierr); 2573a40ed3dSBarry Smith } else if (fgnorm > 1.e-11){ 258a0e26f09SSatish Balay ierr = PetscPrintf(snes->comm,"%3d SNES Function norm %5.3e \n",its,fgnorm);CHKERRQ(ierr); 2593a40ed3dSBarry Smith } else { 260a0e26f09SSatish Balay 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__ 266*4b27c08aSLois Curfman McInnes #define __FUNCT__ "SNESConverged_LS" 2674b828684SBarry Smith /*@C 268*4b27c08aSLois 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 282184914b5SBarry Smith $ SNES_CONVERGED_FNORM_ABS - (fnorm < atol), 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, 293c7afd0dbSLois Curfman McInnes . atol - 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 @*/ 303*4b27c08aSLois Curfman McInnes int 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) { 307*4b27c08aSLois 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) { 310*4b27c08aSLois 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; 312184914b5SBarry Smith } else if (fnorm < snes->atol) { 313*4b27c08aSLois Curfman McInnes PetscLogInfo(snes,"SNESConverged_LS:Converged due to function norm %g < %g\n",fnorm,snes->atol); 314184914b5SBarry Smith *reason = SNES_CONVERGED_FNORM_ABS; 3153304466cSBarry Smith } else if (pnorm < snes->xtol*xnorm) { 316*4b27c08aSLois 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) { 319*4b27c08aSLois Curfman McInnes 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 @*/ 353e7e93795SLois Curfman McInnes int 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 @*/ 394329f5518SBarry Smith int SNES_KSP_SetParametersEW(SNES snes,int version,PetscReal rtol_0, 395329f5518SBarry Smith PetscReal rtol_max,PetscReal gamma2,PetscReal alpha, 396329f5518SBarry Smith PetscReal alpha2,PetscReal threshold) 397e7e93795SLois Curfman McInnes { 398e7e93795SLois Curfman McInnes SNES_KSP_EW_ConvCtx *kctx = (SNES_KSP_EW_ConvCtx*)snes->kspconvctx; 3993a40ed3dSBarry Smith 4003a40ed3dSBarry Smith PetscFunctionBegin; 40129bbc08cSBarry Smith if (!kctx) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context existing"); 402e7e93795SLois Curfman McInnes if (version != PETSC_DEFAULT) kctx->version = version; 403e7e93795SLois Curfman McInnes if (rtol_0 != PETSC_DEFAULT) kctx->rtol_0 = rtol_0; 404e7e93795SLois Curfman McInnes if (rtol_max != PETSC_DEFAULT) kctx->rtol_max = rtol_max; 405e7e93795SLois Curfman McInnes if (gamma2 != PETSC_DEFAULT) kctx->gamma = gamma2; 406e7e93795SLois Curfman McInnes if (alpha != PETSC_DEFAULT) kctx->alpha = alpha; 407e7e93795SLois Curfman McInnes if (alpha2 != PETSC_DEFAULT) kctx->alpha2 = alpha2; 408e7e93795SLois Curfman McInnes if (threshold != PETSC_DEFAULT) kctx->threshold = threshold; 409a8c6a408SBarry Smith if (kctx->rtol_0 < 0.0 || kctx->rtol_0 >= 1.0) { 41029bbc08cSBarry Smith SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"0.0 <= rtol_0 < 1.0: %g",kctx->rtol_0); 411a8c6a408SBarry Smith } 412a8c6a408SBarry Smith if (kctx->rtol_max < 0.0 || kctx->rtol_max >= 1.0) { 413091e6287SMatthew Knepley SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"0.0 <= rtol_max (%g) < 1.0\n",kctx->rtol_max); 414a8c6a408SBarry Smith } 415a8c6a408SBarry Smith if (kctx->threshold <= 0.0 || kctx->threshold >= 1.0) { 416091e6287SMatthew Knepley SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"0.0 < threshold (%g) < 1.0\n",kctx->threshold); 417a8c6a408SBarry Smith } 418a8c6a408SBarry Smith if (kctx->gamma < 0.0 || kctx->gamma > 1.0) { 419091e6287SMatthew Knepley SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"0.0 <= gamma (%g) <= 1.0\n",kctx->gamma); 420a8c6a408SBarry Smith } 421a8c6a408SBarry Smith if (kctx->alpha <= 1.0 || kctx->alpha > 2.0) { 422091e6287SMatthew Knepley SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"1.0 < alpha (%g) <= 2.0\n",kctx->alpha); 423a8c6a408SBarry Smith } 424a8c6a408SBarry Smith if (kctx->version != 1 && kctx->version !=2) { 42529bbc08cSBarry Smith SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Only versions 1 and 2 are supported: %d",kctx->version); 426a8c6a408SBarry Smith } 4273a40ed3dSBarry Smith PetscFunctionReturn(0); 428e7e93795SLois Curfman McInnes } 429e7e93795SLois Curfman McInnes 4304a2ae208SSatish Balay #undef __FUNCT__ 4314a2ae208SSatish Balay #define __FUNCT__ "SNES_KSP_EW_ComputeRelativeTolerance_Private" 432e7e93795SLois Curfman McInnes int SNES_KSP_EW_ComputeRelativeTolerance_Private(SNES snes,KSP ksp) 433e7e93795SLois Curfman McInnes { 434e7e93795SLois Curfman McInnes SNES_KSP_EW_ConvCtx *kctx = (SNES_KSP_EW_ConvCtx*)snes->kspconvctx; 435329f5518SBarry Smith PetscReal rtol = 0.0,stol; 436e7e93795SLois Curfman McInnes int ierr; 4373a40ed3dSBarry Smith 4383a40ed3dSBarry Smith PetscFunctionBegin; 43929bbc08cSBarry Smith if (!kctx) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context exists"); 440c38d4ed2SBarry Smith if (!snes->iter) { /* first time in, so use the original user rtol */ 441e7e93795SLois Curfman McInnes rtol = kctx->rtol_0; 442e7e93795SLois Curfman McInnes } else { 443e7e93795SLois Curfman McInnes if (kctx->version == 1) { 444e7e93795SLois Curfman McInnes rtol = (snes->norm - kctx->lresid_last)/kctx->norm_last; 445e7e93795SLois Curfman McInnes if (rtol < 0.0) rtol = -rtol; 446e7e93795SLois Curfman McInnes stol = pow(kctx->rtol_last,kctx->alpha2); 4470452661fSBarry Smith if (stol > kctx->threshold) rtol = PetscMax(rtol,stol); 448e7e93795SLois Curfman McInnes } else if (kctx->version == 2) { 449e7e93795SLois Curfman McInnes rtol = kctx->gamma * pow(snes->norm/kctx->norm_last,kctx->alpha); 450e7e93795SLois Curfman McInnes stol = kctx->gamma * pow(kctx->rtol_last,kctx->alpha); 4510452661fSBarry Smith if (stol > kctx->threshold) rtol = PetscMax(rtol,stol); 45229bbc08cSBarry Smith } else SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Only versions 1 or 2 are supported: %d",kctx->version); 453e7e93795SLois Curfman McInnes } 4540452661fSBarry Smith rtol = PetscMin(rtol,kctx->rtol_max); 455e7e93795SLois Curfman McInnes kctx->rtol_last = rtol; 456b0a32e0cSBarry Smith PetscLogInfo(snes,"SNES_KSP_EW_ComputeRelativeTolerance_Private: iter %d, Eisenstat-Walker (version %d) KSP rtol = %g\n",snes->iter,kctx->version,rtol); 4573131a8b6SLois Curfman McInnes ierr = KSPSetTolerances(ksp,rtol,PETSC_DEFAULT,PETSC_DEFAULT,PETSC_DEFAULT);CHKERRQ(ierr); 458e7e93795SLois Curfman McInnes kctx->norm_last = snes->norm; 4593a40ed3dSBarry Smith PetscFunctionReturn(0); 460e7e93795SLois Curfman McInnes } 461e7e93795SLois Curfman McInnes 4624a2ae208SSatish Balay #undef __FUNCT__ 4634a2ae208SSatish Balay #define __FUNCT__ "SNES_KSP_EW_Converged_Private" 464329f5518SBarry Smith int SNES_KSP_EW_Converged_Private(KSP ksp,int n,PetscReal rnorm,KSPConvergedReason *reason,void *ctx) 465e7e93795SLois Curfman McInnes { 466e7e93795SLois Curfman McInnes SNES snes = (SNES)ctx; 467e7e93795SLois Curfman McInnes SNES_KSP_EW_ConvCtx *kctx = (SNES_KSP_EW_ConvCtx*)snes->kspconvctx; 4683acb151aSSatish Balay int ierr; 469e7e93795SLois Curfman McInnes 4703a40ed3dSBarry Smith PetscFunctionBegin; 47129bbc08cSBarry Smith if (!kctx) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context set"); 472184914b5SBarry Smith if (n == 0) {ierr = SNES_KSP_EW_ComputeRelativeTolerance_Private(snes,ksp);CHKERRQ(ierr);} 473211a6b7eSSatish Balay ierr = KSPDefaultConverged(ksp,n,rnorm,reason,ctx);CHKERRQ(ierr); 474e7e93795SLois Curfman McInnes kctx->lresid_last = rnorm; 475211a6b7eSSatish Balay if (*reason) { 476b0a32e0cSBarry Smith PetscLogInfo(snes,"SNES_KSP_EW_Converged_Private: KSP iterations=%d, rnorm=%g\n",n,rnorm); 4773a40ed3dSBarry Smith } 478211a6b7eSSatish Balay PetscFunctionReturn(0); 479e7e93795SLois Curfman McInnes } 480e7e93795SLois Curfman McInnes 481e7e93795SLois Curfman McInnes 482