163dd3a1aSKris 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 @*/ 2563dd3a1aSKris 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 @*/ 6363dd3a1aSKris 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 @*/ 10163dd3a1aSKris 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 @*/ 14163dd3a1aSKris 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 152eabae89aSBarry Smith typedef struct { 153eabae89aSBarry Smith PetscViewer viewer; 154eabae89aSBarry Smith PetscReal *history; 155eabae89aSBarry Smith } SNESRatioMonitorContext; 156eabae89aSBarry Smith 1573a7fca6bSBarry Smith #undef __FUNCT__ 1583a7fca6bSBarry Smith #define __FUNCT__ "SNESRatioMonitor" 1593a7fca6bSBarry Smith /*@C 1604b27c08aSLois Curfman McInnes SNESRatioMonitor - Monitors progress of the SNES solvers by printing the ratio 1614b27c08aSLois Curfman McInnes of residual norm at each iteration to the previous. 1623a7fca6bSBarry Smith 1633a7fca6bSBarry Smith Collective on SNES 1643a7fca6bSBarry Smith 1653a7fca6bSBarry Smith Input Parameters: 1663a7fca6bSBarry Smith + snes - the SNES context 1673a7fca6bSBarry Smith . its - iteration number 1683a7fca6bSBarry Smith . fgnorm - 2-norm of residual (or gradient) 169eabae89aSBarry Smith - dummy - context of monitor 1703a7fca6bSBarry Smith 1713a7fca6bSBarry Smith Level: intermediate 1723a7fca6bSBarry Smith 1733a7fca6bSBarry Smith .keywords: SNES, nonlinear, monitor, norm 1743a7fca6bSBarry Smith 1753a7fca6bSBarry Smith .seealso: SNESSetMonitor(), SNESVecViewMonitor() 1763a7fca6bSBarry Smith @*/ 17763dd3a1aSKris Buschelman PetscErrorCode PETSCSNES_DLLEXPORT SNESRatioMonitor(SNES snes,PetscInt its,PetscReal fgnorm,void *dummy) 1783a7fca6bSBarry Smith { 179dfbe8321SBarry Smith PetscErrorCode ierr; 18077431f27SBarry Smith PetscInt len; 18187828ca2SBarry Smith PetscReal *history; 182eabae89aSBarry Smith SNESRatioMonitorContext *ctx = (SNESRatioMonitorContext*)dummy; 1833a7fca6bSBarry Smith 1843a7fca6bSBarry Smith PetscFunctionBegin; 1853a7fca6bSBarry Smith ierr = SNESGetConvergenceHistory(snes,&history,PETSC_NULL,&len);CHKERRQ(ierr); 186958c9bccSBarry Smith if (!its || !history || its > len) { 187eabae89aSBarry Smith ierr = PetscViewerASCIIPrintf(ctx->viewer,"%3D SNES Function norm %14.12e \n",its,fgnorm);CHKERRQ(ierr); 1883a7fca6bSBarry Smith } else { 18987828ca2SBarry Smith PetscReal ratio = fgnorm/history[its-1]; 190a83599f4SBarry Smith ierr = PetscViewerASCIIPrintf(ctx->viewer,"%3D SNES Function norm %14.12e %G \n",its,fgnorm,ratio);CHKERRQ(ierr); 1913a7fca6bSBarry Smith } 1923a7fca6bSBarry Smith PetscFunctionReturn(0); 1933a7fca6bSBarry Smith } 1943a7fca6bSBarry Smith 1953a7fca6bSBarry Smith /* 1963a7fca6bSBarry Smith If the we set the history monitor space then we must destroy it 1973a7fca6bSBarry Smith */ 1983a7fca6bSBarry Smith #undef __FUNCT__ 1993a7fca6bSBarry Smith #define __FUNCT__ "SNESRatioMonitorDestroy" 200eabae89aSBarry Smith PetscErrorCode SNESRatioMonitorDestroy(void *ct) 2013a7fca6bSBarry Smith { 202dfbe8321SBarry Smith PetscErrorCode ierr; 203eabae89aSBarry Smith SNESRatioMonitorContext *ctx = (SNESRatioMonitorContext*)ct; 2043a7fca6bSBarry Smith 2053a7fca6bSBarry Smith PetscFunctionBegin; 206eabae89aSBarry Smith if (ctx->history) {ierr = PetscFree(ctx->history);CHKERRQ(ierr);} 207eabae89aSBarry Smith ierr = PetscViewerDestroy(ctx->viewer);CHKERRQ(ierr); 208eabae89aSBarry Smith ierr = PetscFree(ctx);CHKERRQ(ierr); 2093a7fca6bSBarry Smith PetscFunctionReturn(0); 2103a7fca6bSBarry Smith } 2113a7fca6bSBarry Smith 2123a7fca6bSBarry Smith #undef __FUNCT__ 2133a7fca6bSBarry Smith #define __FUNCT__ "SNESSetRatioMonitor" 2143a7fca6bSBarry Smith /*@C 2153a7fca6bSBarry Smith SNESSetRatioMonitor - Sets SNES to use a monitor that prints the 2164b27c08aSLois Curfman McInnes ratio of the function norm at each iteration. 2173a7fca6bSBarry Smith 2183a7fca6bSBarry Smith Collective on SNES 2193a7fca6bSBarry Smith 2203a7fca6bSBarry Smith Input Parameters: 221eabae89aSBarry Smith + snes - the SNES context 222eabae89aSBarry Smith - viewer - ASCII viewer to print output 2233a7fca6bSBarry Smith 2243a7fca6bSBarry Smith Level: intermediate 2253a7fca6bSBarry Smith 2263a7fca6bSBarry Smith .keywords: SNES, nonlinear, monitor, norm 2273a7fca6bSBarry Smith 2283a7fca6bSBarry Smith .seealso: SNESSetMonitor(), SNESVecViewMonitor(), SNESDefaultMonitor() 2293a7fca6bSBarry Smith @*/ 230eabae89aSBarry Smith PetscErrorCode PETSCSNES_DLLEXPORT SNESSetRatioMonitor(SNES snes,PetscViewer viewer) 2313a7fca6bSBarry Smith { 232dfbe8321SBarry Smith PetscErrorCode ierr; 233eabae89aSBarry Smith SNESRatioMonitorContext *ctx; 23487828ca2SBarry Smith PetscReal *history; 2353a7fca6bSBarry Smith 2363a7fca6bSBarry Smith PetscFunctionBegin; 237eabae89aSBarry Smith if (!viewer) { 238eabae89aSBarry Smith viewer = PETSC_VIEWER_STDOUT_(snes->comm); 239eabae89aSBarry Smith ierr = PetscObjectReference((PetscObject)viewer);CHKERRQ(ierr); 240eabae89aSBarry Smith } 241eabae89aSBarry Smith ierr = PetscNew(SNESRatioMonitorContext,&ctx); 2423a7fca6bSBarry Smith ierr = SNESGetConvergenceHistory(snes,&history,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr); 2433a7fca6bSBarry Smith if (!history) { 244eabae89aSBarry Smith ierr = PetscMalloc(100*sizeof(PetscReal),&ctx->history);CHKERRQ(ierr); 245eabae89aSBarry Smith ierr = SNESSetConvergenceHistory(snes,ctx->history,0,100,PETSC_TRUE);CHKERRQ(ierr); 2463a7fca6bSBarry Smith } 247eabae89aSBarry Smith ctx->viewer = viewer; 248eabae89aSBarry Smith ierr = SNESSetMonitor(snes,SNESRatioMonitor,ctx,SNESRatioMonitorDestroy);CHKERRQ(ierr); 2493a7fca6bSBarry Smith PetscFunctionReturn(0); 2503a7fca6bSBarry Smith } 2513a7fca6bSBarry Smith 252e7e93795SLois Curfman McInnes /* ---------------------------------------------------------------- */ 2534a2ae208SSatish Balay #undef __FUNCT__ 2544a2ae208SSatish Balay #define __FUNCT__ "SNESDefaultSMonitor" 255be1f7002SBarry Smith /* 256be1f7002SBarry Smith Default (short) SNES Monitor, same as SNESDefaultMonitor() except 257be1f7002SBarry Smith it prints fewer digits of the residual as the residual gets smaller. 258be1f7002SBarry Smith This is because the later digits are meaningless and are often 259be1f7002SBarry Smith different on different machines; by using this routine different 260be1f7002SBarry Smith machines will usually generate the same output. 261be1f7002SBarry Smith */ 26263dd3a1aSKris Buschelman PetscErrorCode PETSCSNES_DLLEXPORT SNESDefaultSMonitor(SNES snes,PetscInt its,PetscReal fgnorm,void *dummy) 263e7e93795SLois Curfman McInnes { 264dfbe8321SBarry Smith PetscErrorCode ierr; 265eabae89aSBarry Smith PetscViewer viewer = (PetscViewer) dummy; 266d132466eSBarry Smith 2673a40ed3dSBarry Smith PetscFunctionBegin; 268eabae89aSBarry Smith if (!viewer) viewer = PETSC_VIEWER_STDOUT_(snes->comm); 2698f240d10SBarry Smith if (fgnorm > 1.e-9) { 270a83599f4SBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"%3D SNES Function norm %G \n",its,fgnorm);CHKERRQ(ierr); 2713a40ed3dSBarry Smith } else if (fgnorm > 1.e-11){ 272eabae89aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"%3D SNES Function norm %5.3e \n",its,fgnorm);CHKERRQ(ierr); 2733a40ed3dSBarry Smith } else { 274eabae89aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"%3D SNES Function norm < 1.e-11\n",its);CHKERRQ(ierr); 275e7e93795SLois Curfman McInnes } 2763a40ed3dSBarry Smith PetscFunctionReturn(0); 277e7e93795SLois Curfman McInnes } 278e7e93795SLois Curfman McInnes /* ---------------------------------------------------------------- */ 2794a2ae208SSatish Balay #undef __FUNCT__ 2804b27c08aSLois Curfman McInnes #define __FUNCT__ "SNESConverged_LS" 2814b828684SBarry Smith /*@C 2824b27c08aSLois Curfman McInnes SNESConverged_LS - Monitors the convergence of the solvers for 283f525115eSLois Curfman McInnes systems of nonlinear equations (default). 284e7e93795SLois Curfman McInnes 285c7afd0dbSLois Curfman McInnes Collective on SNES 286c7afd0dbSLois Curfman McInnes 287e7e93795SLois Curfman McInnes Input Parameters: 288c7afd0dbSLois Curfman McInnes + snes - the SNES context 289e7e93795SLois Curfman McInnes . xnorm - 2-norm of current iterate 290e7e93795SLois Curfman McInnes . pnorm - 2-norm of current step 2917f3332b4SBarry Smith . fnorm - 2-norm of function at current iterate 292c7afd0dbSLois Curfman McInnes - dummy - unused context 293e7e93795SLois Curfman McInnes 294184914b5SBarry Smith Output Parameter: 295184914b5SBarry Smith . reason - one of 29670441072SBarry Smith $ SNES_CONVERGED_FNORM_ABS - (fnorm < abstol), 2973304466cSBarry Smith $ SNES_CONVERGED_PNORM_RELATIVE - (pnorm < xtol*xnorm), 298184914b5SBarry Smith $ SNES_CONVERGED_FNORM_RELATIVE - (fnorm < rtol*fnorm0), 299184914b5SBarry Smith $ SNES_DIVERGED_FUNCTION_COUNT - (nfct > maxf), 300184914b5SBarry Smith $ SNES_DIVERGED_FNORM_NAN - (fnorm == NaN), 301184914b5SBarry Smith $ SNES_CONVERGED_ITERATING - (otherwise), 302e7e93795SLois Curfman McInnes 303e7e93795SLois Curfman McInnes where 304c7afd0dbSLois Curfman McInnes + maxf - maximum number of function evaluations, 305c7afd0dbSLois Curfman McInnes set with SNESSetTolerances() 306c7afd0dbSLois Curfman McInnes . nfct - number of function evaluations, 30770441072SBarry Smith . abstol - absolute function norm tolerance, 308c7afd0dbSLois Curfman McInnes set with SNESSetTolerances() 309c7afd0dbSLois Curfman McInnes - rtol - relative function norm tolerance, set with SNESSetTolerances() 310fee21e36SBarry Smith 31136851e7fSLois Curfman McInnes Level: intermediate 31236851e7fSLois Curfman McInnes 313e7e93795SLois Curfman McInnes .keywords: SNES, nonlinear, default, converged, convergence 314e7e93795SLois Curfman McInnes 315e7e93795SLois Curfman McInnes .seealso: SNESSetConvergenceTest(), SNESEisenstatWalkerConverged() 316e7e93795SLois Curfman McInnes @*/ 31763dd3a1aSKris Buschelman PetscErrorCode PETSCSNES_DLLEXPORT SNESConverged_LS(SNES snes,PetscReal xnorm,PetscReal pnorm,PetscReal fnorm,SNESConvergedReason *reason,void *dummy) 318e7e93795SLois Curfman McInnes { 31963ba0a88SBarry Smith PetscErrorCode ierr; 32063ba0a88SBarry Smith 3213a40ed3dSBarry Smith PetscFunctionBegin; 322d252947aSBarry Smith if (fnorm != fnorm) { 323*ae15b995SBarry Smith ierr = PetscInfo(snes,"Failed to converged, function norm is NaN\n");CHKERRQ(ierr); 324184914b5SBarry Smith *reason = SNES_DIVERGED_FNORM_NAN; 325184914b5SBarry Smith } else if (fnorm <= snes->ttol) { 326*ae15b995SBarry Smith ierr = PetscInfo2(snes,"Converged due to function norm %G < %G (relative tolerance)\n",fnorm,snes->ttol);CHKERRQ(ierr); 327184914b5SBarry Smith *reason = SNES_CONVERGED_FNORM_RELATIVE; 32870441072SBarry Smith } else if (fnorm < snes->abstol) { 329*ae15b995SBarry Smith ierr = PetscInfo2(snes,"Converged due to function norm %G < %G\n",fnorm,snes->abstol);CHKERRQ(ierr); 330184914b5SBarry Smith *reason = SNES_CONVERGED_FNORM_ABS; 3313304466cSBarry Smith } else if (pnorm < snes->xtol*xnorm) { 332*ae15b995SBarry Smith ierr = PetscInfo3(snes,"Converged due to small update length: %G < %G * %G\n",pnorm,snes->xtol,xnorm);CHKERRQ(ierr); 333184914b5SBarry Smith *reason = SNES_CONVERGED_PNORM_RELATIVE; 33443e71028SBarry Smith } else if (snes->nfuncs >= snes->max_funcs) { 335*ae15b995SBarry Smith ierr = PetscInfo2(snes,"Exceeded maximum number of function evaluations: %D > %D\n",snes->nfuncs,snes->max_funcs);CHKERRQ(ierr); 336184914b5SBarry Smith *reason = SNES_DIVERGED_FUNCTION_COUNT ; 337184914b5SBarry Smith } else { 338184914b5SBarry Smith *reason = SNES_CONVERGED_ITERATING; 339e7e93795SLois Curfman McInnes } 3403a40ed3dSBarry Smith PetscFunctionReturn(0); 341e7e93795SLois Curfman McInnes } 342e7e93795SLois Curfman McInnes /* ------------------------------------------------------------ */ 3434a2ae208SSatish Balay #undef __FUNCT__ 3444a2ae208SSatish Balay #define __FUNCT__ "SNES_KSP_SetConvergenceTestEW" 345e7e93795SLois Curfman McInnes /*@ 346f525115eSLois Curfman McInnes SNES_KSP_SetConvergenceTestEW - Sets alternative convergence test 347e7e93795SLois Curfman McInnes for the linear solvers within an inexact Newton method. 348e7e93795SLois Curfman McInnes 349c7afd0dbSLois Curfman McInnes Collective on SNES 350c7afd0dbSLois Curfman McInnes 351e7e93795SLois Curfman McInnes Input Parameter: 352e7e93795SLois Curfman McInnes . snes - SNES context 353e7e93795SLois Curfman McInnes 354e7e93795SLois Curfman McInnes Notes: 355e7e93795SLois Curfman McInnes Currently, the default is to use a constant relative tolerance for 356e7e93795SLois Curfman McInnes the inner linear solvers. Alternatively, one can use the 357e7e93795SLois Curfman McInnes Eisenstat-Walker method, where the relative convergence tolerance 358e7e93795SLois Curfman McInnes is reset at each Newton iteration according progress of the nonlinear 359e7e93795SLois Curfman McInnes solver. 360e7e93795SLois Curfman McInnes 36136851e7fSLois Curfman McInnes Level: advanced 36236851e7fSLois Curfman McInnes 363e7e93795SLois Curfman McInnes Reference: 364e7e93795SLois Curfman McInnes S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an 365e30ad881SLois Curfman McInnes inexact Newton method", SISC 17 (1), pp.16-32, 1996. 366e7e93795SLois Curfman McInnes 367e7e93795SLois Curfman McInnes .keywords: SNES, KSP, Eisenstat, Walker, convergence, test, inexact, Newton 368e7e93795SLois Curfman McInnes @*/ 36963dd3a1aSKris Buschelman PetscErrorCode PETSCSNES_DLLEXPORT SNES_KSP_SetConvergenceTestEW(SNES snes) 370e7e93795SLois Curfman McInnes { 3713a40ed3dSBarry Smith PetscFunctionBegin; 372186905e3SBarry Smith snes->ksp_ewconv = PETSC_TRUE; 3733a40ed3dSBarry Smith PetscFunctionReturn(0); 374e7e93795SLois Curfman McInnes } 375e7e93795SLois Curfman McInnes 3764a2ae208SSatish Balay #undef __FUNCT__ 3774a2ae208SSatish Balay #define __FUNCT__ "SNES_KSP_SetParametersEW" 378e7e93795SLois Curfman McInnes /*@ 379e7e93795SLois Curfman McInnes SNES_KSP_SetParametersEW - Sets parameters for Eisenstat-Walker 380e7e93795SLois Curfman McInnes convergence criteria for the linear solvers within an inexact 381e7e93795SLois Curfman McInnes Newton method. 382e7e93795SLois Curfman McInnes 383c7afd0dbSLois Curfman McInnes Collective on SNES 384c7afd0dbSLois Curfman McInnes 385e7e93795SLois Curfman McInnes Input Parameters: 386c7afd0dbSLois Curfman McInnes + snes - SNES context 387e7e93795SLois Curfman McInnes . version - version 1 or 2 (default is 2) 388c7afd0dbSLois Curfman McInnes . rtol_0 - initial relative tolerance (0 <= rtol_0 < 1) 389c7afd0dbSLois Curfman McInnes . rtol_max - maximum relative tolerance (0 <= rtol_max < 1) 390c7afd0dbSLois Curfman McInnes . alpha - power for version 2 rtol computation (1 < alpha <= 2) 391e7e93795SLois Curfman McInnes . alpha2 - power for safeguard 392e7e93795SLois Curfman McInnes . gamma2 - multiplicative factor for version 2 rtol computation 393c7afd0dbSLois Curfman McInnes (0 <= gamma2 <= 1) 394c7afd0dbSLois Curfman McInnes - threshold - threshold for imposing safeguard (0 < threshold < 1) 395fee21e36SBarry Smith 396e7e93795SLois Curfman McInnes Note: 397e7e93795SLois Curfman McInnes Use PETSC_DEFAULT to retain the default for any of the parameters. 398e7e93795SLois Curfman McInnes 39936851e7fSLois Curfman McInnes Level: advanced 40036851e7fSLois Curfman McInnes 401e7e93795SLois Curfman McInnes Reference: 402e7e93795SLois Curfman McInnes S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an 403e7e93795SLois Curfman McInnes inexact Newton method", Utah State University Math. Stat. Dept. Res. 404e7e93795SLois Curfman McInnes Report 6/94/75, June, 1994, to appear in SIAM J. Sci. Comput. 405e7e93795SLois Curfman McInnes 406e7e93795SLois Curfman McInnes .keywords: SNES, KSP, Eisenstat, Walker, set, parameters 407e7e93795SLois Curfman McInnes 408e7e93795SLois Curfman McInnes .seealso: SNES_KSP_SetConvergenceTestEW() 409e7e93795SLois Curfman McInnes @*/ 41063dd3a1aSKris Buschelman PetscErrorCode PETSCSNES_DLLEXPORT SNES_KSP_SetParametersEW(SNES snes,PetscInt version,PetscReal rtol_0,PetscReal rtol_max,PetscReal gamma2,PetscReal alpha, 411329f5518SBarry Smith PetscReal alpha2,PetscReal threshold) 412e7e93795SLois Curfman McInnes { 413e7e93795SLois Curfman McInnes SNES_KSP_EW_ConvCtx *kctx = (SNES_KSP_EW_ConvCtx*)snes->kspconvctx; 4143a40ed3dSBarry Smith 4153a40ed3dSBarry Smith PetscFunctionBegin; 41629bbc08cSBarry Smith if (!kctx) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context existing"); 417e7e93795SLois Curfman McInnes if (version != PETSC_DEFAULT) kctx->version = version; 418e7e93795SLois Curfman McInnes if (rtol_0 != PETSC_DEFAULT) kctx->rtol_0 = rtol_0; 419e7e93795SLois Curfman McInnes if (rtol_max != PETSC_DEFAULT) kctx->rtol_max = rtol_max; 420e7e93795SLois Curfman McInnes if (gamma2 != PETSC_DEFAULT) kctx->gamma = gamma2; 421e7e93795SLois Curfman McInnes if (alpha != PETSC_DEFAULT) kctx->alpha = alpha; 422e7e93795SLois Curfman McInnes if (alpha2 != PETSC_DEFAULT) kctx->alpha2 = alpha2; 423e7e93795SLois Curfman McInnes if (threshold != PETSC_DEFAULT) kctx->threshold = threshold; 424a8c6a408SBarry Smith if (kctx->rtol_0 < 0.0 || kctx->rtol_0 >= 1.0) { 425a83599f4SBarry Smith SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"0.0 <= rtol_0 < 1.0: %G",kctx->rtol_0); 426a8c6a408SBarry Smith } 427a8c6a408SBarry Smith if (kctx->rtol_max < 0.0 || kctx->rtol_max >= 1.0) { 428a83599f4SBarry Smith SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"0.0 <= rtol_max (%G) < 1.0\n",kctx->rtol_max); 429a8c6a408SBarry Smith } 430a8c6a408SBarry Smith if (kctx->threshold <= 0.0 || kctx->threshold >= 1.0) { 431a83599f4SBarry Smith SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"0.0 < threshold (%G) < 1.0\n",kctx->threshold); 432a8c6a408SBarry Smith } 433a8c6a408SBarry Smith if (kctx->gamma < 0.0 || kctx->gamma > 1.0) { 434a83599f4SBarry Smith SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"0.0 <= gamma (%G) <= 1.0\n",kctx->gamma); 435a8c6a408SBarry Smith } 436a8c6a408SBarry Smith if (kctx->alpha <= 1.0 || kctx->alpha > 2.0) { 437a83599f4SBarry Smith SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"1.0 < alpha (%G) <= 2.0\n",kctx->alpha); 438a8c6a408SBarry Smith } 439a8c6a408SBarry Smith if (kctx->version != 1 && kctx->version !=2) { 44077431f27SBarry Smith SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Only versions 1 and 2 are supported: %D",kctx->version); 441a8c6a408SBarry Smith } 4423a40ed3dSBarry Smith PetscFunctionReturn(0); 443e7e93795SLois Curfman McInnes } 444e7e93795SLois Curfman McInnes 4454a2ae208SSatish Balay #undef __FUNCT__ 4464a2ae208SSatish Balay #define __FUNCT__ "SNES_KSP_EW_ComputeRelativeTolerance_Private" 447dfbe8321SBarry Smith PetscErrorCode SNES_KSP_EW_ComputeRelativeTolerance_Private(SNES snes,KSP ksp) 448e7e93795SLois Curfman McInnes { 449e7e93795SLois Curfman McInnes SNES_KSP_EW_ConvCtx *kctx = (SNES_KSP_EW_ConvCtx*)snes->kspconvctx; 450329f5518SBarry Smith PetscReal rtol = 0.0,stol; 451dfbe8321SBarry Smith PetscErrorCode ierr; 4523a40ed3dSBarry Smith 4533a40ed3dSBarry Smith PetscFunctionBegin; 45429bbc08cSBarry Smith if (!kctx) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context exists"); 455c38d4ed2SBarry Smith if (!snes->iter) { /* first time in, so use the original user rtol */ 456e7e93795SLois Curfman McInnes rtol = kctx->rtol_0; 457e7e93795SLois Curfman McInnes } else { 458e7e93795SLois Curfman McInnes if (kctx->version == 1) { 459e7e93795SLois Curfman McInnes rtol = (snes->norm - kctx->lresid_last)/kctx->norm_last; 460e7e93795SLois Curfman McInnes if (rtol < 0.0) rtol = -rtol; 461e7e93795SLois Curfman McInnes stol = pow(kctx->rtol_last,kctx->alpha2); 4620452661fSBarry Smith if (stol > kctx->threshold) rtol = PetscMax(rtol,stol); 463e7e93795SLois Curfman McInnes } else if (kctx->version == 2) { 464e7e93795SLois Curfman McInnes rtol = kctx->gamma * pow(snes->norm/kctx->norm_last,kctx->alpha); 465e7e93795SLois Curfman McInnes stol = kctx->gamma * pow(kctx->rtol_last,kctx->alpha); 4660452661fSBarry Smith if (stol > kctx->threshold) rtol = PetscMax(rtol,stol); 46777431f27SBarry Smith } else SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Only versions 1 or 2 are supported: %D",kctx->version); 468e7e93795SLois Curfman McInnes } 4690452661fSBarry Smith rtol = PetscMin(rtol,kctx->rtol_max); 470e7e93795SLois Curfman McInnes kctx->rtol_last = rtol; 471*ae15b995SBarry Smith ierr = PetscInfo3(snes,"iter %D, Eisenstat-Walker (version %D) KSP rtol = %G\n",snes->iter,kctx->version,rtol);CHKERRQ(ierr); 4723131a8b6SLois Curfman McInnes ierr = KSPSetTolerances(ksp,rtol,PETSC_DEFAULT,PETSC_DEFAULT,PETSC_DEFAULT);CHKERRQ(ierr); 473e7e93795SLois Curfman McInnes kctx->norm_last = snes->norm; 4743a40ed3dSBarry Smith PetscFunctionReturn(0); 475e7e93795SLois Curfman McInnes } 476e7e93795SLois Curfman McInnes 4774a2ae208SSatish Balay #undef __FUNCT__ 4784a2ae208SSatish Balay #define __FUNCT__ "SNES_KSP_EW_Converged_Private" 479a7cc72afSBarry Smith PetscErrorCode SNES_KSP_EW_Converged_Private(KSP ksp,PetscInt n,PetscReal rnorm,KSPConvergedReason *reason,void *ctx) 480e7e93795SLois Curfman McInnes { 481e7e93795SLois Curfman McInnes SNES snes = (SNES)ctx; 482e7e93795SLois Curfman McInnes SNES_KSP_EW_ConvCtx *kctx = (SNES_KSP_EW_ConvCtx*)snes->kspconvctx; 483dfbe8321SBarry Smith PetscErrorCode ierr; 484e7e93795SLois Curfman McInnes 4853a40ed3dSBarry Smith PetscFunctionBegin; 48629bbc08cSBarry Smith if (!kctx) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context set"); 487958c9bccSBarry Smith if (!n) {ierr = SNES_KSP_EW_ComputeRelativeTolerance_Private(snes,ksp);CHKERRQ(ierr);} 488211a6b7eSSatish Balay ierr = KSPDefaultConverged(ksp,n,rnorm,reason,ctx);CHKERRQ(ierr); 489e7e93795SLois Curfman McInnes kctx->lresid_last = rnorm; 490211a6b7eSSatish Balay if (*reason) { 491*ae15b995SBarry Smith ierr = PetscInfo2(snes,"KSP iterations=%D, rnorm=%G\n",n,rnorm);CHKERRQ(ierr); 4923a40ed3dSBarry Smith } 493211a6b7eSSatish Balay PetscFunctionReturn(0); 494e7e93795SLois Curfman McInnes } 495e7e93795SLois Curfman McInnes 496e7e93795SLois Curfman McInnes 497