1*63dd3a1aSKris Buschelman #define PETSCSNES_DLL 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 164b27c08aSLois 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 @*/ 25*63dd3a1aSKris Buschelman PetscErrorCode PETSCSNES_DLLEXPORT SNESVecViewMonitor(SNES snes,PetscInt its,PetscReal fgnorm,void *dummy) 263f1db9ecSBarry Smith { 27dfbe8321SBarry Smith PetscErrorCode 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 544b27c08aSLois 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 @*/ 63*63dd3a1aSKris Buschelman PetscErrorCode PETSCSNES_DLLEXPORT SNESVecViewResidualMonitor(SNES snes,PetscInt its,PetscReal fgnorm,void *dummy) 645ed2d596SBarry Smith { 65dfbe8321SBarry Smith PetscErrorCode 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 924b27c08aSLois 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 @*/ 101*63dd3a1aSKris Buschelman PetscErrorCode PETSCSNES_DLLEXPORT SNESVecViewUpdateMonitor(SNES snes,PetscInt its,PetscReal fgnorm,void *dummy) 102d132466eSBarry Smith { 103dfbe8321SBarry Smith PetscErrorCode 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 1224b27c08aSLois 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 1294b27c08aSLois Curfman McInnes . fgnorm - 2-norm of residual 130c7afd0dbSLois Curfman McInnes - dummy - unused context 131fee21e36SBarry Smith 132e7e93795SLois Curfman McInnes Notes: 1334b27c08aSLois 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 @*/ 141*63dd3a1aSKris Buschelman PetscErrorCode PETSCSNES_DLLEXPORT SNESDefaultMonitor(SNES snes,PetscInt its,PetscReal fgnorm,void *dummy) 142e7e93795SLois Curfman McInnes { 143dfbe8321SBarry Smith PetscErrorCode ierr; 144b0a32e0cSBarry Smith PetscViewer viewer = (PetscViewer) dummy; 145d132466eSBarry Smith 1463a40ed3dSBarry Smith PetscFunctionBegin; 147b0a32e0cSBarry Smith if (!viewer) viewer = PETSC_VIEWER_STDOUT_(snes->comm); 148a7cc72afSBarry Smith 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 1554b27c08aSLois Curfman McInnes SNESRatioMonitor - Monitors progress of the SNES solvers by printing the ratio 1564b27c08aSLois 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 @*/ 172*63dd3a1aSKris Buschelman PetscErrorCode PETSCSNES_DLLEXPORT SNESRatioMonitor(SNES snes,PetscInt its,PetscReal fgnorm,void *dummy) 1733a7fca6bSBarry Smith { 174dfbe8321SBarry Smith PetscErrorCode ierr; 17577431f27SBarry Smith PetscInt len; 17687828ca2SBarry Smith PetscReal *history; 1773a7fca6bSBarry Smith PetscViewer viewer; 1783a7fca6bSBarry Smith 1793a7fca6bSBarry Smith PetscFunctionBegin; 1803a7fca6bSBarry Smith viewer = PETSC_VIEWER_STDOUT_(snes->comm); 1813a7fca6bSBarry Smith 1823a7fca6bSBarry Smith ierr = SNESGetConvergenceHistory(snes,&history,PETSC_NULL,&len);CHKERRQ(ierr); 183958c9bccSBarry Smith if (!its || !history || its > len) { 184a7cc72afSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"%3D SNES Function norm %14.12e \n",its,fgnorm);CHKERRQ(ierr); 1853a7fca6bSBarry Smith } else { 18687828ca2SBarry Smith PetscReal ratio = fgnorm/history[its-1]; 187a7cc72afSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"%3D SNES Function norm %14.12e %g \n",its,fgnorm,ratio);CHKERRQ(ierr); 1883a7fca6bSBarry Smith } 1893a7fca6bSBarry Smith PetscFunctionReturn(0); 1903a7fca6bSBarry Smith } 1913a7fca6bSBarry Smith 1923a7fca6bSBarry Smith /* 1933a7fca6bSBarry Smith If the we set the history monitor space then we must destroy it 1943a7fca6bSBarry Smith */ 1953a7fca6bSBarry Smith #undef __FUNCT__ 1963a7fca6bSBarry Smith #define __FUNCT__ "SNESRatioMonitorDestroy" 197dfbe8321SBarry Smith PetscErrorCode SNESRatioMonitorDestroy(void *history) 1983a7fca6bSBarry Smith { 199dfbe8321SBarry Smith PetscErrorCode ierr; 2003a7fca6bSBarry Smith 2013a7fca6bSBarry Smith PetscFunctionBegin; 2023a7fca6bSBarry Smith ierr = PetscFree(history);CHKERRQ(ierr); 2033a7fca6bSBarry Smith PetscFunctionReturn(0); 2043a7fca6bSBarry Smith } 2053a7fca6bSBarry Smith 2063a7fca6bSBarry Smith #undef __FUNCT__ 2073a7fca6bSBarry Smith #define __FUNCT__ "SNESSetRatioMonitor" 2083a7fca6bSBarry Smith /*@C 2093a7fca6bSBarry Smith SNESSetRatioMonitor - Sets SNES to use a monitor that prints the 2104b27c08aSLois Curfman McInnes ratio of the function norm at each iteration. 2113a7fca6bSBarry Smith 2123a7fca6bSBarry Smith Collective on SNES 2133a7fca6bSBarry Smith 2143a7fca6bSBarry Smith Input Parameters: 2153a7fca6bSBarry Smith . snes - the SNES context 2163a7fca6bSBarry Smith 2173a7fca6bSBarry Smith Level: intermediate 2183a7fca6bSBarry Smith 2193a7fca6bSBarry Smith .keywords: SNES, nonlinear, monitor, norm 2203a7fca6bSBarry Smith 2213a7fca6bSBarry Smith .seealso: SNESSetMonitor(), SNESVecViewMonitor(), SNESDefaultMonitor() 2223a7fca6bSBarry Smith @*/ 223*63dd3a1aSKris Buschelman PetscErrorCode PETSCSNES_DLLEXPORT SNESSetRatioMonitor(SNES snes) 2243a7fca6bSBarry Smith { 225dfbe8321SBarry Smith PetscErrorCode ierr; 22687828ca2SBarry Smith PetscReal *history; 2273a7fca6bSBarry Smith 2283a7fca6bSBarry Smith PetscFunctionBegin; 2293a7fca6bSBarry Smith 2303a7fca6bSBarry Smith ierr = SNESGetConvergenceHistory(snes,&history,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr); 2313a7fca6bSBarry Smith if (!history) { 2323a7fca6bSBarry Smith ierr = PetscMalloc(100*sizeof(double),&history);CHKERRQ(ierr); 2333a7fca6bSBarry Smith ierr = SNESSetConvergenceHistory(snes,history,0,100,PETSC_TRUE);CHKERRQ(ierr); 2343a7fca6bSBarry Smith ierr = SNESSetMonitor(snes,SNESRatioMonitor,history,SNESRatioMonitorDestroy);CHKERRQ(ierr); 2353a7fca6bSBarry Smith } else { 2363a7fca6bSBarry Smith ierr = SNESSetMonitor(snes,SNESRatioMonitor,0,0);CHKERRQ(ierr); 2373a7fca6bSBarry Smith } 2383a7fca6bSBarry Smith PetscFunctionReturn(0); 2393a7fca6bSBarry Smith } 2403a7fca6bSBarry Smith 241e7e93795SLois Curfman McInnes /* ---------------------------------------------------------------- */ 2424a2ae208SSatish Balay #undef __FUNCT__ 2434a2ae208SSatish Balay #define __FUNCT__ "SNESDefaultSMonitor" 244be1f7002SBarry Smith /* 245be1f7002SBarry Smith Default (short) SNES Monitor, same as SNESDefaultMonitor() except 246be1f7002SBarry Smith it prints fewer digits of the residual as the residual gets smaller. 247be1f7002SBarry Smith This is because the later digits are meaningless and are often 248be1f7002SBarry Smith different on different machines; by using this routine different 249be1f7002SBarry Smith machines will usually generate the same output. 250be1f7002SBarry Smith */ 251*63dd3a1aSKris Buschelman PetscErrorCode PETSCSNES_DLLEXPORT SNESDefaultSMonitor(SNES snes,PetscInt its,PetscReal fgnorm,void *dummy) 252e7e93795SLois Curfman McInnes { 253dfbe8321SBarry Smith PetscErrorCode ierr; 254d132466eSBarry Smith 2553a40ed3dSBarry Smith PetscFunctionBegin; 2568f240d10SBarry Smith if (fgnorm > 1.e-9) { 25777431f27SBarry Smith ierr = PetscPrintf(snes->comm,"%3D SNES Function norm %g \n",its,fgnorm);CHKERRQ(ierr); 2583a40ed3dSBarry Smith } else if (fgnorm > 1.e-11){ 25977431f27SBarry Smith ierr = PetscPrintf(snes->comm,"%3D SNES Function norm %5.3e \n",its,fgnorm);CHKERRQ(ierr); 2603a40ed3dSBarry Smith } else { 26177431f27SBarry Smith ierr = PetscPrintf(snes->comm,"%3D SNES Function norm < 1.e-11\n",its);CHKERRQ(ierr); 262e7e93795SLois Curfman McInnes } 2633a40ed3dSBarry Smith PetscFunctionReturn(0); 264e7e93795SLois Curfman McInnes } 265e7e93795SLois Curfman McInnes /* ---------------------------------------------------------------- */ 2664a2ae208SSatish Balay #undef __FUNCT__ 2674b27c08aSLois Curfman McInnes #define __FUNCT__ "SNESConverged_LS" 2684b828684SBarry Smith /*@C 2694b27c08aSLois Curfman McInnes SNESConverged_LS - Monitors the convergence of the solvers for 270f525115eSLois Curfman McInnes systems of nonlinear equations (default). 271e7e93795SLois Curfman McInnes 272c7afd0dbSLois Curfman McInnes Collective on SNES 273c7afd0dbSLois Curfman McInnes 274e7e93795SLois Curfman McInnes Input Parameters: 275c7afd0dbSLois Curfman McInnes + snes - the SNES context 276e7e93795SLois Curfman McInnes . xnorm - 2-norm of current iterate 277e7e93795SLois Curfman McInnes . pnorm - 2-norm of current step 278e7e93795SLois Curfman McInnes . fnorm - 2-norm of function 279c7afd0dbSLois Curfman McInnes - dummy - unused context 280e7e93795SLois Curfman McInnes 281184914b5SBarry Smith Output Parameter: 282184914b5SBarry Smith . reason - one of 28370441072SBarry Smith $ SNES_CONVERGED_FNORM_ABS - (fnorm < abstol), 2843304466cSBarry Smith $ SNES_CONVERGED_PNORM_RELATIVE - (pnorm < xtol*xnorm), 285184914b5SBarry Smith $ SNES_CONVERGED_FNORM_RELATIVE - (fnorm < rtol*fnorm0), 286184914b5SBarry Smith $ SNES_DIVERGED_FUNCTION_COUNT - (nfct > maxf), 287184914b5SBarry Smith $ SNES_DIVERGED_FNORM_NAN - (fnorm == NaN), 288184914b5SBarry Smith $ SNES_CONVERGED_ITERATING - (otherwise), 289e7e93795SLois Curfman McInnes 290e7e93795SLois Curfman McInnes where 291c7afd0dbSLois Curfman McInnes + maxf - maximum number of function evaluations, 292c7afd0dbSLois Curfman McInnes set with SNESSetTolerances() 293c7afd0dbSLois Curfman McInnes . nfct - number of function evaluations, 29470441072SBarry Smith . abstol - absolute function norm tolerance, 295c7afd0dbSLois Curfman McInnes set with SNESSetTolerances() 296c7afd0dbSLois Curfman McInnes - rtol - relative function norm tolerance, set with SNESSetTolerances() 297fee21e36SBarry Smith 29836851e7fSLois Curfman McInnes Level: intermediate 29936851e7fSLois Curfman McInnes 300e7e93795SLois Curfman McInnes .keywords: SNES, nonlinear, default, converged, convergence 301e7e93795SLois Curfman McInnes 302e7e93795SLois Curfman McInnes .seealso: SNESSetConvergenceTest(), SNESEisenstatWalkerConverged() 303e7e93795SLois Curfman McInnes @*/ 304*63dd3a1aSKris Buschelman PetscErrorCode PETSCSNES_DLLEXPORT SNESConverged_LS(SNES snes,PetscReal xnorm,PetscReal pnorm,PetscReal fnorm,SNESConvergedReason *reason,void *dummy) 305e7e93795SLois Curfman McInnes { 30663ba0a88SBarry Smith PetscErrorCode ierr; 30763ba0a88SBarry Smith 3083a40ed3dSBarry Smith PetscFunctionBegin; 309d252947aSBarry Smith if (fnorm != fnorm) { 31063ba0a88SBarry Smith ierr = PetscLogInfo((snes,"SNESConverged_LS:Failed to converged, function norm is NaN\n"));CHKERRQ(ierr); 311184914b5SBarry Smith *reason = SNES_DIVERGED_FNORM_NAN; 312184914b5SBarry Smith } else if (fnorm <= snes->ttol) { 31363ba0a88SBarry Smith ierr = PetscLogInfo((snes,"SNESConverged_LS:Converged due to function norm %g < %g (relative tolerance)\n",fnorm,snes->ttol));CHKERRQ(ierr); 314184914b5SBarry Smith *reason = SNES_CONVERGED_FNORM_RELATIVE; 31570441072SBarry Smith } else if (fnorm < snes->abstol) { 31663ba0a88SBarry Smith ierr = PetscLogInfo((snes,"SNESConverged_LS:Converged due to function norm %g < %g\n",fnorm,snes->abstol));CHKERRQ(ierr); 317184914b5SBarry Smith *reason = SNES_CONVERGED_FNORM_ABS; 3183304466cSBarry Smith } else if (pnorm < snes->xtol*xnorm) { 31963ba0a88SBarry Smith ierr = PetscLogInfo((snes,"SNESConverged_LS:Converged due to small update length: %g < %g * %g\n",pnorm,snes->xtol,xnorm));CHKERRQ(ierr); 320184914b5SBarry Smith *reason = SNES_CONVERGED_PNORM_RELATIVE; 32143e71028SBarry Smith } else if (snes->nfuncs >= snes->max_funcs) { 32263ba0a88SBarry Smith ierr = PetscLogInfo((snes,"SNESConverged_LS:Exceeded maximum number of function evaluations: %D > %D\n",snes->nfuncs,snes->max_funcs));CHKERRQ(ierr); 323184914b5SBarry Smith *reason = SNES_DIVERGED_FUNCTION_COUNT ; 324184914b5SBarry Smith } else { 325184914b5SBarry Smith *reason = SNES_CONVERGED_ITERATING; 326e7e93795SLois Curfman McInnes } 3273a40ed3dSBarry Smith PetscFunctionReturn(0); 328e7e93795SLois Curfman McInnes } 329e7e93795SLois Curfman McInnes /* ------------------------------------------------------------ */ 3304a2ae208SSatish Balay #undef __FUNCT__ 3314a2ae208SSatish Balay #define __FUNCT__ "SNES_KSP_SetConvergenceTestEW" 332e7e93795SLois Curfman McInnes /*@ 333f525115eSLois Curfman McInnes SNES_KSP_SetConvergenceTestEW - Sets alternative convergence test 334e7e93795SLois Curfman McInnes for the linear solvers within an inexact Newton method. 335e7e93795SLois Curfman McInnes 336c7afd0dbSLois Curfman McInnes Collective on SNES 337c7afd0dbSLois Curfman McInnes 338e7e93795SLois Curfman McInnes Input Parameter: 339e7e93795SLois Curfman McInnes . snes - SNES context 340e7e93795SLois Curfman McInnes 341e7e93795SLois Curfman McInnes Notes: 342e7e93795SLois Curfman McInnes Currently, the default is to use a constant relative tolerance for 343e7e93795SLois Curfman McInnes the inner linear solvers. Alternatively, one can use the 344e7e93795SLois Curfman McInnes Eisenstat-Walker method, where the relative convergence tolerance 345e7e93795SLois Curfman McInnes is reset at each Newton iteration according progress of the nonlinear 346e7e93795SLois Curfman McInnes solver. 347e7e93795SLois Curfman McInnes 34836851e7fSLois Curfman McInnes Level: advanced 34936851e7fSLois Curfman McInnes 350e7e93795SLois Curfman McInnes Reference: 351e7e93795SLois Curfman McInnes S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an 352e30ad881SLois Curfman McInnes inexact Newton method", SISC 17 (1), pp.16-32, 1996. 353e7e93795SLois Curfman McInnes 354e7e93795SLois Curfman McInnes .keywords: SNES, KSP, Eisenstat, Walker, convergence, test, inexact, Newton 355e7e93795SLois Curfman McInnes @*/ 356*63dd3a1aSKris Buschelman PetscErrorCode PETSCSNES_DLLEXPORT SNES_KSP_SetConvergenceTestEW(SNES snes) 357e7e93795SLois Curfman McInnes { 3583a40ed3dSBarry Smith PetscFunctionBegin; 359186905e3SBarry Smith snes->ksp_ewconv = PETSC_TRUE; 3603a40ed3dSBarry Smith PetscFunctionReturn(0); 361e7e93795SLois Curfman McInnes } 362e7e93795SLois Curfman McInnes 3634a2ae208SSatish Balay #undef __FUNCT__ 3644a2ae208SSatish Balay #define __FUNCT__ "SNES_KSP_SetParametersEW" 365e7e93795SLois Curfman McInnes /*@ 366e7e93795SLois Curfman McInnes SNES_KSP_SetParametersEW - Sets parameters for Eisenstat-Walker 367e7e93795SLois Curfman McInnes convergence criteria for the linear solvers within an inexact 368e7e93795SLois Curfman McInnes Newton method. 369e7e93795SLois Curfman McInnes 370c7afd0dbSLois Curfman McInnes Collective on SNES 371c7afd0dbSLois Curfman McInnes 372e7e93795SLois Curfman McInnes Input Parameters: 373c7afd0dbSLois Curfman McInnes + snes - SNES context 374e7e93795SLois Curfman McInnes . version - version 1 or 2 (default is 2) 375c7afd0dbSLois Curfman McInnes . rtol_0 - initial relative tolerance (0 <= rtol_0 < 1) 376c7afd0dbSLois Curfman McInnes . rtol_max - maximum relative tolerance (0 <= rtol_max < 1) 377c7afd0dbSLois Curfman McInnes . alpha - power for version 2 rtol computation (1 < alpha <= 2) 378e7e93795SLois Curfman McInnes . alpha2 - power for safeguard 379e7e93795SLois Curfman McInnes . gamma2 - multiplicative factor for version 2 rtol computation 380c7afd0dbSLois Curfman McInnes (0 <= gamma2 <= 1) 381c7afd0dbSLois Curfman McInnes - threshold - threshold for imposing safeguard (0 < threshold < 1) 382fee21e36SBarry Smith 383e7e93795SLois Curfman McInnes Note: 384e7e93795SLois Curfman McInnes Use PETSC_DEFAULT to retain the default for any of the parameters. 385e7e93795SLois Curfman McInnes 38636851e7fSLois Curfman McInnes Level: advanced 38736851e7fSLois Curfman McInnes 388e7e93795SLois Curfman McInnes Reference: 389e7e93795SLois Curfman McInnes S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an 390e7e93795SLois Curfman McInnes inexact Newton method", Utah State University Math. Stat. Dept. Res. 391e7e93795SLois Curfman McInnes Report 6/94/75, June, 1994, to appear in SIAM J. Sci. Comput. 392e7e93795SLois Curfman McInnes 393e7e93795SLois Curfman McInnes .keywords: SNES, KSP, Eisenstat, Walker, set, parameters 394e7e93795SLois Curfman McInnes 395e7e93795SLois Curfman McInnes .seealso: SNES_KSP_SetConvergenceTestEW() 396e7e93795SLois Curfman McInnes @*/ 397*63dd3a1aSKris Buschelman PetscErrorCode PETSCSNES_DLLEXPORT SNES_KSP_SetParametersEW(SNES snes,PetscInt version,PetscReal rtol_0,PetscReal rtol_max,PetscReal gamma2,PetscReal alpha, 398329f5518SBarry Smith PetscReal alpha2,PetscReal threshold) 399e7e93795SLois Curfman McInnes { 400e7e93795SLois Curfman McInnes SNES_KSP_EW_ConvCtx *kctx = (SNES_KSP_EW_ConvCtx*)snes->kspconvctx; 4013a40ed3dSBarry Smith 4023a40ed3dSBarry Smith PetscFunctionBegin; 40329bbc08cSBarry Smith if (!kctx) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context existing"); 404e7e93795SLois Curfman McInnes if (version != PETSC_DEFAULT) kctx->version = version; 405e7e93795SLois Curfman McInnes if (rtol_0 != PETSC_DEFAULT) kctx->rtol_0 = rtol_0; 406e7e93795SLois Curfman McInnes if (rtol_max != PETSC_DEFAULT) kctx->rtol_max = rtol_max; 407e7e93795SLois Curfman McInnes if (gamma2 != PETSC_DEFAULT) kctx->gamma = gamma2; 408e7e93795SLois Curfman McInnes if (alpha != PETSC_DEFAULT) kctx->alpha = alpha; 409e7e93795SLois Curfman McInnes if (alpha2 != PETSC_DEFAULT) kctx->alpha2 = alpha2; 410e7e93795SLois Curfman McInnes if (threshold != PETSC_DEFAULT) kctx->threshold = threshold; 411a8c6a408SBarry Smith if (kctx->rtol_0 < 0.0 || kctx->rtol_0 >= 1.0) { 41229bbc08cSBarry Smith SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"0.0 <= rtol_0 < 1.0: %g",kctx->rtol_0); 413a8c6a408SBarry Smith } 414a8c6a408SBarry Smith if (kctx->rtol_max < 0.0 || kctx->rtol_max >= 1.0) { 415091e6287SMatthew Knepley SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"0.0 <= rtol_max (%g) < 1.0\n",kctx->rtol_max); 416a8c6a408SBarry Smith } 417a8c6a408SBarry Smith if (kctx->threshold <= 0.0 || kctx->threshold >= 1.0) { 418091e6287SMatthew Knepley SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"0.0 < threshold (%g) < 1.0\n",kctx->threshold); 419a8c6a408SBarry Smith } 420a8c6a408SBarry Smith if (kctx->gamma < 0.0 || kctx->gamma > 1.0) { 421091e6287SMatthew Knepley SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"0.0 <= gamma (%g) <= 1.0\n",kctx->gamma); 422a8c6a408SBarry Smith } 423a8c6a408SBarry Smith if (kctx->alpha <= 1.0 || kctx->alpha > 2.0) { 424091e6287SMatthew Knepley SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"1.0 < alpha (%g) <= 2.0\n",kctx->alpha); 425a8c6a408SBarry Smith } 426a8c6a408SBarry Smith if (kctx->version != 1 && kctx->version !=2) { 42777431f27SBarry Smith SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Only versions 1 and 2 are supported: %D",kctx->version); 428a8c6a408SBarry Smith } 4293a40ed3dSBarry Smith PetscFunctionReturn(0); 430e7e93795SLois Curfman McInnes } 431e7e93795SLois Curfman McInnes 4324a2ae208SSatish Balay #undef __FUNCT__ 4334a2ae208SSatish Balay #define __FUNCT__ "SNES_KSP_EW_ComputeRelativeTolerance_Private" 434dfbe8321SBarry Smith PetscErrorCode SNES_KSP_EW_ComputeRelativeTolerance_Private(SNES snes,KSP ksp) 435e7e93795SLois Curfman McInnes { 436e7e93795SLois Curfman McInnes SNES_KSP_EW_ConvCtx *kctx = (SNES_KSP_EW_ConvCtx*)snes->kspconvctx; 437329f5518SBarry Smith PetscReal rtol = 0.0,stol; 438dfbe8321SBarry Smith PetscErrorCode ierr; 4393a40ed3dSBarry Smith 4403a40ed3dSBarry Smith PetscFunctionBegin; 44129bbc08cSBarry Smith if (!kctx) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context exists"); 442c38d4ed2SBarry Smith if (!snes->iter) { /* first time in, so use the original user rtol */ 443e7e93795SLois Curfman McInnes rtol = kctx->rtol_0; 444e7e93795SLois Curfman McInnes } else { 445e7e93795SLois Curfman McInnes if (kctx->version == 1) { 446e7e93795SLois Curfman McInnes rtol = (snes->norm - kctx->lresid_last)/kctx->norm_last; 447e7e93795SLois Curfman McInnes if (rtol < 0.0) rtol = -rtol; 448e7e93795SLois Curfman McInnes stol = pow(kctx->rtol_last,kctx->alpha2); 4490452661fSBarry Smith if (stol > kctx->threshold) rtol = PetscMax(rtol,stol); 450e7e93795SLois Curfman McInnes } else if (kctx->version == 2) { 451e7e93795SLois Curfman McInnes rtol = kctx->gamma * pow(snes->norm/kctx->norm_last,kctx->alpha); 452e7e93795SLois Curfman McInnes stol = kctx->gamma * pow(kctx->rtol_last,kctx->alpha); 4530452661fSBarry Smith if (stol > kctx->threshold) rtol = PetscMax(rtol,stol); 45477431f27SBarry Smith } else SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Only versions 1 or 2 are supported: %D",kctx->version); 455e7e93795SLois Curfman McInnes } 4560452661fSBarry Smith rtol = PetscMin(rtol,kctx->rtol_max); 457e7e93795SLois Curfman McInnes kctx->rtol_last = rtol; 45863ba0a88SBarry Smith ierr = PetscLogInfo((snes,"SNES_KSP_EW_ComputeRelativeTolerance_Private: iter %D, Eisenstat-Walker (version %D) KSP rtol = %g\n",snes->iter,kctx->version,rtol));CHKERRQ(ierr); 4593131a8b6SLois Curfman McInnes ierr = KSPSetTolerances(ksp,rtol,PETSC_DEFAULT,PETSC_DEFAULT,PETSC_DEFAULT);CHKERRQ(ierr); 460e7e93795SLois Curfman McInnes kctx->norm_last = snes->norm; 4613a40ed3dSBarry Smith PetscFunctionReturn(0); 462e7e93795SLois Curfman McInnes } 463e7e93795SLois Curfman McInnes 4644a2ae208SSatish Balay #undef __FUNCT__ 4654a2ae208SSatish Balay #define __FUNCT__ "SNES_KSP_EW_Converged_Private" 466a7cc72afSBarry Smith PetscErrorCode SNES_KSP_EW_Converged_Private(KSP ksp,PetscInt n,PetscReal rnorm,KSPConvergedReason *reason,void *ctx) 467e7e93795SLois Curfman McInnes { 468e7e93795SLois Curfman McInnes SNES snes = (SNES)ctx; 469e7e93795SLois Curfman McInnes SNES_KSP_EW_ConvCtx *kctx = (SNES_KSP_EW_ConvCtx*)snes->kspconvctx; 470dfbe8321SBarry Smith PetscErrorCode ierr; 471e7e93795SLois Curfman McInnes 4723a40ed3dSBarry Smith PetscFunctionBegin; 47329bbc08cSBarry Smith if (!kctx) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context set"); 474958c9bccSBarry Smith if (!n) {ierr = SNES_KSP_EW_ComputeRelativeTolerance_Private(snes,ksp);CHKERRQ(ierr);} 475211a6b7eSSatish Balay ierr = KSPDefaultConverged(ksp,n,rnorm,reason,ctx);CHKERRQ(ierr); 476e7e93795SLois Curfman McInnes kctx->lresid_last = rnorm; 477211a6b7eSSatish Balay if (*reason) { 47863ba0a88SBarry Smith ierr = PetscLogInfo((snes,"SNES_KSP_EW_Converged_Private: KSP iterations=%D, rnorm=%g\n",n,rnorm));CHKERRQ(ierr); 4793a40ed3dSBarry Smith } 480211a6b7eSSatish Balay PetscFunctionReturn(0); 481e7e93795SLois Curfman McInnes } 482e7e93795SLois Curfman McInnes 483e7e93795SLois Curfman McInnes 484