1e7e93795SLois Curfman McInnes 2c6db04a5SJed Brown #include <private/snesimpl.h> /*I "petscsnes.h" I*/ 3e7e93795SLois Curfman McInnes 44a2ae208SSatish Balay #undef __FUNCT__ 5a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorSolution" 63f1db9ecSBarry Smith /*@C 7a6570f20SBarry Smith SNESMonitorSolution - 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 22a6570f20SBarry Smith .seealso: SNESMonitorSet(), SNESMonitorDefault(), VecView() 233f1db9ecSBarry Smith @*/ 247087cfbeSBarry Smith PetscErrorCode SNESMonitorSolution(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__ 43a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorResidual" 445ed2d596SBarry Smith /*@C 45a6570f20SBarry Smith SNESMonitorResidual - 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 60a6570f20SBarry Smith .seealso: SNESMonitorSet(), SNESMonitorDefault(), VecView() 615ed2d596SBarry Smith @*/ 627087cfbeSBarry Smith PetscErrorCode SNESMonitorResidual(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__ 81a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorSolutionUpdate" 82d132466eSBarry Smith /*@C 83a6570f20SBarry Smith SNESMonitorSolutionUpdate - 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 98a6570f20SBarry Smith .seealso: SNESMonitorSet(), SNESMonitorDefault(), VecView() 99d132466eSBarry Smith @*/ 1007087cfbeSBarry Smith PetscErrorCode SNESMonitorSolutionUpdate(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__ 119a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorDefault" 1204b828684SBarry Smith /*@C 121a6570f20SBarry Smith SNESMonitorDefault - 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 138a6570f20SBarry Smith .seealso: SNESMonitorSet(), SNESMonitorSolution() 139e7e93795SLois Curfman McInnes @*/ 1407087cfbeSBarry Smith PetscErrorCode SNESMonitorDefault(SNES snes,PetscInt its,PetscReal fgnorm,void *dummy) 141e7e93795SLois Curfman McInnes { 142dfbe8321SBarry Smith PetscErrorCode ierr; 143649052a6SBarry Smith PetscViewer viewer = dummy ? (PetscViewer) dummy : PETSC_VIEWER_STDOUT_(((PetscObject)snes)->comm); 144d132466eSBarry Smith 1453a40ed3dSBarry Smith PetscFunctionBegin; 146649052a6SBarry Smith ierr = PetscViewerASCIIAddTab(viewer,((PetscObject)snes)->tablevel);CHKERRQ(ierr); 147649052a6SBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"%3D SNES Function norm %14.12e \n",its,(double)fgnorm);CHKERRQ(ierr); 148649052a6SBarry Smith ierr = PetscViewerASCIISubtractTab(viewer,((PetscObject)snes)->tablevel);CHKERRQ(ierr); 1493a40ed3dSBarry Smith PetscFunctionReturn(0); 150e7e93795SLois Curfman McInnes } 1513f1db9ecSBarry Smith 152b271bb04SBarry Smith #undef __FUNCT__ 153b271bb04SBarry Smith #define __FUNCT__ "SNESMonitorRange_Private" 1547087cfbeSBarry Smith PetscErrorCode SNESMonitorRange_Private(SNES snes,PetscInt it,PetscReal *per) 155b271bb04SBarry Smith { 156b271bb04SBarry Smith PetscErrorCode ierr; 157b271bb04SBarry Smith Vec resid; 158b271bb04SBarry Smith PetscReal rmax,pwork; 159b271bb04SBarry Smith PetscInt i,n,N; 160b271bb04SBarry Smith PetscScalar *r; 161b271bb04SBarry Smith 162b271bb04SBarry Smith PetscFunctionBegin; 163b271bb04SBarry Smith ierr = SNESGetFunction(snes,&resid,0,0);CHKERRQ(ierr); 164b271bb04SBarry Smith ierr = VecNorm(resid,NORM_INFINITY,&rmax);CHKERRQ(ierr); 165b271bb04SBarry Smith ierr = VecGetLocalSize(resid,&n);CHKERRQ(ierr); 166b271bb04SBarry Smith ierr = VecGetSize(resid,&N);CHKERRQ(ierr); 167b271bb04SBarry Smith ierr = VecGetArray(resid,&r);CHKERRQ(ierr); 168b271bb04SBarry Smith pwork = 0.0; 169b271bb04SBarry Smith for (i=0; i<n; i++) { 170b271bb04SBarry Smith pwork += (PetscAbsScalar(r[i]) > .20*rmax); 171b271bb04SBarry Smith } 17206a205a8SBarry Smith ierr = MPI_Allreduce(&pwork,per,1,MPIU_REAL,MPIU_SUM,((PetscObject)snes)->comm);CHKERRQ(ierr); 173b271bb04SBarry Smith ierr = VecRestoreArray(resid,&r);CHKERRQ(ierr); 174b271bb04SBarry Smith *per = *per/N; 175b271bb04SBarry Smith PetscFunctionReturn(0); 176b271bb04SBarry Smith } 177b271bb04SBarry Smith 178b271bb04SBarry Smith #undef __FUNCT__ 179b271bb04SBarry Smith #define __FUNCT__ "SNESMonitorRange" 180b271bb04SBarry Smith /*@C 181b271bb04SBarry Smith SNESMonitorRange - Prints the percentage of residual elements that are more then 10 percent of the maximum value. 182b271bb04SBarry Smith 183b271bb04SBarry Smith Collective on SNES 184b271bb04SBarry Smith 185b271bb04SBarry Smith Input Parameters: 186b271bb04SBarry Smith + snes - iterative context 187b271bb04SBarry Smith . it - iteration number 188b271bb04SBarry Smith . rnorm - 2-norm (preconditioned) residual value (may be estimated). 189b271bb04SBarry Smith - dummy - unused monitor context 190b271bb04SBarry Smith 191b271bb04SBarry Smith Options Database Key: 192b271bb04SBarry Smith . -snes_monitor_range - Activates SNESMonitorRange() 193b271bb04SBarry Smith 194b271bb04SBarry Smith Level: intermediate 195b271bb04SBarry Smith 196b271bb04SBarry Smith .keywords: SNES, default, monitor, residual 197b271bb04SBarry Smith 198b271bb04SBarry Smith .seealso: SNESMonitorSet(), SNESMonitorDefault(), SNESMonitorLGCreate() 199b271bb04SBarry Smith @*/ 2007087cfbeSBarry Smith PetscErrorCode SNESMonitorRange(SNES snes,PetscInt it,PetscReal rnorm,void *dummy) 201b271bb04SBarry Smith { 202b271bb04SBarry Smith PetscErrorCode ierr; 203b271bb04SBarry Smith PetscReal perc,rel; 204649052a6SBarry Smith PetscViewer viewer = dummy ? (PetscViewer) dummy : PETSC_VIEWER_STDOUT_(((PetscObject)snes)->comm); 205b271bb04SBarry Smith /* should be in a MonitorRangeContext */ 206b271bb04SBarry Smith static PetscReal prev; 207b271bb04SBarry Smith 208b271bb04SBarry Smith PetscFunctionBegin; 209b271bb04SBarry Smith if (!it) prev = rnorm; 210b271bb04SBarry Smith ierr = SNESMonitorRange_Private(snes,it,&perc);CHKERRQ(ierr); 211b271bb04SBarry Smith 212b271bb04SBarry Smith rel = (prev - rnorm)/prev; 213b271bb04SBarry Smith prev = rnorm; 214649052a6SBarry Smith ierr = PetscViewerASCIIAddTab(viewer,((PetscObject)snes)->tablevel);CHKERRQ(ierr); 215649052a6SBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"%3D SNES preconditioned resid norm %14.12e Percent values above 20 percent of maximum %5.2f relative decrease %5.2e ratio %5.2e \n",it,(double)rnorm,(double)100.0*perc,(double)rel,(double)rel/perc);CHKERRQ(ierr); 216649052a6SBarry Smith ierr = PetscViewerASCIISubtractTab(viewer,((PetscObject)snes)->tablevel);CHKERRQ(ierr); 217b271bb04SBarry Smith PetscFunctionReturn(0); 218b271bb04SBarry Smith } 219b271bb04SBarry Smith 220eabae89aSBarry Smith typedef struct { 221649052a6SBarry Smith PetscViewer viewer; 222eabae89aSBarry Smith PetscReal *history; 223a6570f20SBarry Smith } SNESMonitorRatioContext; 224eabae89aSBarry Smith 2253a7fca6bSBarry Smith #undef __FUNCT__ 226a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorRatio" 2273a7fca6bSBarry Smith /*@C 228a6570f20SBarry Smith SNESMonitorRatio - Monitors progress of the SNES solvers by printing the ratio 2294b27c08aSLois Curfman McInnes of residual norm at each iteration to the previous. 2303a7fca6bSBarry Smith 2313a7fca6bSBarry Smith Collective on SNES 2323a7fca6bSBarry Smith 2333a7fca6bSBarry Smith Input Parameters: 2343a7fca6bSBarry Smith + snes - the SNES context 2353a7fca6bSBarry Smith . its - iteration number 2363a7fca6bSBarry Smith . fgnorm - 2-norm of residual (or gradient) 237eabae89aSBarry Smith - dummy - context of monitor 2383a7fca6bSBarry Smith 2393a7fca6bSBarry Smith Level: intermediate 2403a7fca6bSBarry Smith 2413a7fca6bSBarry Smith .keywords: SNES, nonlinear, monitor, norm 2423a7fca6bSBarry Smith 243a6570f20SBarry Smith .seealso: SNESMonitorSet(), SNESMonitorSolution() 2443a7fca6bSBarry Smith @*/ 2457087cfbeSBarry Smith PetscErrorCode SNESMonitorRatio(SNES snes,PetscInt its,PetscReal fgnorm,void *dummy) 2463a7fca6bSBarry Smith { 247dfbe8321SBarry Smith PetscErrorCode ierr; 24877431f27SBarry Smith PetscInt len; 24987828ca2SBarry Smith PetscReal *history; 250a6570f20SBarry Smith SNESMonitorRatioContext *ctx = (SNESMonitorRatioContext*)dummy; 2513a7fca6bSBarry Smith 2523a7fca6bSBarry Smith PetscFunctionBegin; 2533a7fca6bSBarry Smith ierr = SNESGetConvergenceHistory(snes,&history,PETSC_NULL,&len);CHKERRQ(ierr); 254649052a6SBarry Smith ierr = PetscViewerASCIIAddTab(ctx->viewer,((PetscObject)snes)->tablevel);CHKERRQ(ierr); 255958c9bccSBarry Smith if (!its || !history || its > len) { 256649052a6SBarry Smith ierr = PetscViewerASCIIPrintf(ctx->viewer,"%3D SNES Function norm %14.12e \n",its,(double)fgnorm);CHKERRQ(ierr); 2573a7fca6bSBarry Smith } else { 25887828ca2SBarry Smith PetscReal ratio = fgnorm/history[its-1]; 259*8f1a2a5eSBarry Smith ierr = PetscViewerASCIIPrintf(ctx->viewer,"%3D SNES Function norm %14.12e %14.12e \n",its,(double)fgnorm,(double)ratio);CHKERRQ(ierr); 2603a7fca6bSBarry Smith } 261649052a6SBarry Smith ierr = PetscViewerASCIISubtractTab(ctx->viewer,((PetscObject)snes)->tablevel);CHKERRQ(ierr); 2623a7fca6bSBarry Smith PetscFunctionReturn(0); 2633a7fca6bSBarry Smith } 2643a7fca6bSBarry Smith 2653a7fca6bSBarry Smith /* 2663a7fca6bSBarry Smith If the we set the history monitor space then we must destroy it 2673a7fca6bSBarry Smith */ 2683a7fca6bSBarry Smith #undef __FUNCT__ 269a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorRatioDestroy" 270c2efdce3SBarry Smith PetscErrorCode SNESMonitorRatioDestroy(void **ct) 2713a7fca6bSBarry Smith { 272dfbe8321SBarry Smith PetscErrorCode ierr; 273c2efdce3SBarry Smith SNESMonitorRatioContext *ctx = *(SNESMonitorRatioContext**)ct; 2743a7fca6bSBarry Smith 2753a7fca6bSBarry Smith PetscFunctionBegin; 27605b42c5fSBarry Smith ierr = PetscFree(ctx->history);CHKERRQ(ierr); 277649052a6SBarry Smith ierr = PetscViewerDestroy(&ctx->viewer);CHKERRQ(ierr); 278eabae89aSBarry Smith ierr = PetscFree(ctx);CHKERRQ(ierr); 2793a7fca6bSBarry Smith PetscFunctionReturn(0); 2803a7fca6bSBarry Smith } 2813a7fca6bSBarry Smith 2823a7fca6bSBarry Smith #undef __FUNCT__ 283a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorSetRatio" 2843a7fca6bSBarry Smith /*@C 285a6570f20SBarry Smith SNESMonitorSetRatio - Sets SNES to use a monitor that prints the 2864b27c08aSLois Curfman McInnes ratio of the function norm at each iteration. 2873a7fca6bSBarry Smith 2883a7fca6bSBarry Smith Collective on SNES 2893a7fca6bSBarry Smith 2903a7fca6bSBarry Smith Input Parameters: 291eabae89aSBarry Smith + snes - the SNES context 292eabae89aSBarry Smith - viewer - ASCII viewer to print output 2933a7fca6bSBarry Smith 2943a7fca6bSBarry Smith Level: intermediate 2953a7fca6bSBarry Smith 2963a7fca6bSBarry Smith .keywords: SNES, nonlinear, monitor, norm 2973a7fca6bSBarry Smith 298a6570f20SBarry Smith .seealso: SNESMonitorSet(), SNESMonitorSolution(), SNESMonitorDefault() 2993a7fca6bSBarry Smith @*/ 300649052a6SBarry Smith PetscErrorCode SNESMonitorSetRatio(SNES snes,PetscViewer viewer) 3013a7fca6bSBarry Smith { 302dfbe8321SBarry Smith PetscErrorCode ierr; 303a6570f20SBarry Smith SNESMonitorRatioContext *ctx; 30487828ca2SBarry Smith PetscReal *history; 3053a7fca6bSBarry Smith 3063a7fca6bSBarry Smith PetscFunctionBegin; 307eabae89aSBarry Smith if (!viewer) { 308649052a6SBarry Smith ierr = PetscViewerASCIIOpen(((PetscObject)snes)->comm,"stdout",&viewer);CHKERRQ(ierr); 309eabae89aSBarry Smith ierr = PetscObjectReference((PetscObject)viewer);CHKERRQ(ierr); 310eabae89aSBarry Smith } 31138f2d2fdSLisandro Dalcin ierr = PetscNewLog(snes,SNESMonitorRatioContext,&ctx); 3123a7fca6bSBarry Smith ierr = SNESGetConvergenceHistory(snes,&history,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr); 3133a7fca6bSBarry Smith if (!history) { 314eabae89aSBarry Smith ierr = PetscMalloc(100*sizeof(PetscReal),&ctx->history);CHKERRQ(ierr); 315eabae89aSBarry Smith ierr = SNESSetConvergenceHistory(snes,ctx->history,0,100,PETSC_TRUE);CHKERRQ(ierr); 3163a7fca6bSBarry Smith } 317eabae89aSBarry Smith ctx->viewer = viewer; 318a6570f20SBarry Smith ierr = SNESMonitorSet(snes,SNESMonitorRatio,ctx,SNESMonitorRatioDestroy);CHKERRQ(ierr); 3193a7fca6bSBarry Smith PetscFunctionReturn(0); 3203a7fca6bSBarry Smith } 3213a7fca6bSBarry Smith 322e7e93795SLois Curfman McInnes /* ---------------------------------------------------------------- */ 3234a2ae208SSatish Balay #undef __FUNCT__ 324a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorDefaultShort" 325be1f7002SBarry Smith /* 326a6570f20SBarry Smith Default (short) SNES Monitor, same as SNESMonitorDefault() except 327be1f7002SBarry Smith it prints fewer digits of the residual as the residual gets smaller. 328be1f7002SBarry Smith This is because the later digits are meaningless and are often 329be1f7002SBarry Smith different on different machines; by using this routine different 330be1f7002SBarry Smith machines will usually generate the same output. 331be1f7002SBarry Smith */ 3327087cfbeSBarry Smith PetscErrorCode SNESMonitorDefaultShort(SNES snes,PetscInt its,PetscReal fgnorm,void *dummy) 333e7e93795SLois Curfman McInnes { 334dfbe8321SBarry Smith PetscErrorCode ierr; 335649052a6SBarry Smith PetscViewer viewer = dummy ? (PetscViewer) dummy : PETSC_VIEWER_STDOUT_(((PetscObject)snes)->comm); 336d132466eSBarry Smith 3373a40ed3dSBarry Smith PetscFunctionBegin; 338649052a6SBarry Smith ierr = PetscViewerASCIIAddTab(viewer,((PetscObject)snes)->tablevel);CHKERRQ(ierr); 3398f240d10SBarry Smith if (fgnorm > 1.e-9) { 340649052a6SBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"%3D SNES Function norm %G \n",its,fgnorm);CHKERRQ(ierr); 3413a40ed3dSBarry Smith } else if (fgnorm > 1.e-11){ 342649052a6SBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"%3D SNES Function norm %5.3e \n",its,fgnorm);CHKERRQ(ierr); 3433a40ed3dSBarry Smith } else { 344649052a6SBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"%3D SNES Function norm < 1.e-11\n",its);CHKERRQ(ierr); 345a34d58ebSBarry Smith } 346649052a6SBarry Smith ierr = PetscViewerASCIISubtractTab(viewer,((PetscObject)snes)->tablevel);CHKERRQ(ierr); 3473a40ed3dSBarry Smith PetscFunctionReturn(0); 348e7e93795SLois Curfman McInnes } 349e7e93795SLois Curfman McInnes /* ---------------------------------------------------------------- */ 3504a2ae208SSatish Balay #undef __FUNCT__ 3513f149594SLisandro Dalcin #define __FUNCT__ "SNESDefaultConverged" 3524b828684SBarry Smith /*@C 3533f149594SLisandro Dalcin SNESDefaultConverged - Convergence test of the solvers for 354f525115eSLois Curfman McInnes systems of nonlinear equations (default). 355e7e93795SLois Curfman McInnes 356c7afd0dbSLois Curfman McInnes Collective on SNES 357c7afd0dbSLois Curfman McInnes 358e7e93795SLois Curfman McInnes Input Parameters: 359c7afd0dbSLois Curfman McInnes + snes - the SNES context 36006ee9f85SBarry Smith . it - the iteration (0 indicates before any Newton steps) 361e7e93795SLois Curfman McInnes . xnorm - 2-norm of current iterate 362e7e93795SLois Curfman McInnes . pnorm - 2-norm of current step 3637f3332b4SBarry Smith . fnorm - 2-norm of function at current iterate 364c7afd0dbSLois Curfman McInnes - dummy - unused context 365e7e93795SLois Curfman McInnes 366184914b5SBarry Smith Output Parameter: 367184914b5SBarry Smith . reason - one of 36870441072SBarry Smith $ SNES_CONVERGED_FNORM_ABS - (fnorm < abstol), 3693304466cSBarry Smith $ SNES_CONVERGED_PNORM_RELATIVE - (pnorm < xtol*xnorm), 370184914b5SBarry Smith $ SNES_CONVERGED_FNORM_RELATIVE - (fnorm < rtol*fnorm0), 371184914b5SBarry Smith $ SNES_DIVERGED_FUNCTION_COUNT - (nfct > maxf), 372184914b5SBarry Smith $ SNES_DIVERGED_FNORM_NAN - (fnorm == NaN), 373184914b5SBarry Smith $ SNES_CONVERGED_ITERATING - (otherwise), 374e7e93795SLois Curfman McInnes 375e7e93795SLois Curfman McInnes where 376c7afd0dbSLois Curfman McInnes + maxf - maximum number of function evaluations, 377c7afd0dbSLois Curfman McInnes set with SNESSetTolerances() 378c7afd0dbSLois Curfman McInnes . nfct - number of function evaluations, 37970441072SBarry Smith . abstol - absolute function norm tolerance, 380c7afd0dbSLois Curfman McInnes set with SNESSetTolerances() 381c7afd0dbSLois Curfman McInnes - rtol - relative function norm tolerance, set with SNESSetTolerances() 382fee21e36SBarry Smith 38336851e7fSLois Curfman McInnes Level: intermediate 38436851e7fSLois Curfman McInnes 385e7e93795SLois Curfman McInnes .keywords: SNES, nonlinear, default, converged, convergence 386e7e93795SLois Curfman McInnes 38771f87433Sdalcinl .seealso: SNESSetConvergenceTest() 388e7e93795SLois Curfman McInnes @*/ 3897087cfbeSBarry Smith PetscErrorCode SNESDefaultConverged(SNES snes,PetscInt it,PetscReal xnorm,PetscReal pnorm,PetscReal fnorm,SNESConvergedReason *reason,void *dummy) 390e7e93795SLois Curfman McInnes { 39163ba0a88SBarry Smith PetscErrorCode ierr; 39263ba0a88SBarry Smith 3933a40ed3dSBarry Smith PetscFunctionBegin; 3940700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3953f149594SLisandro Dalcin PetscValidPointer(reason,6); 3963f149594SLisandro Dalcin 39706ee9f85SBarry Smith *reason = SNES_CONVERGED_ITERATING; 39806ee9f85SBarry Smith 39906ee9f85SBarry Smith if (!it) { 40006ee9f85SBarry Smith /* set parameter for default relative tolerance convergence test */ 40106ee9f85SBarry Smith snes->ttol = fnorm*snes->rtol; 40206ee9f85SBarry Smith } 403d252947aSBarry Smith if (fnorm != fnorm) { 404ae15b995SBarry Smith ierr = PetscInfo(snes,"Failed to converged, function norm is NaN\n");CHKERRQ(ierr); 405184914b5SBarry Smith *reason = SNES_DIVERGED_FNORM_NAN; 40670441072SBarry Smith } else if (fnorm < snes->abstol) { 407*8f1a2a5eSBarry Smith ierr = PetscInfo2(snes,"Converged due to function norm %14.12e < %14.12e\n",(double)fnorm,(double)snes->abstol);CHKERRQ(ierr); 408184914b5SBarry Smith *reason = SNES_CONVERGED_FNORM_ABS; 40943e71028SBarry Smith } else if (snes->nfuncs >= snes->max_funcs) { 410ae15b995SBarry Smith ierr = PetscInfo2(snes,"Exceeded maximum number of function evaluations: %D > %D\n",snes->nfuncs,snes->max_funcs);CHKERRQ(ierr); 411184914b5SBarry Smith *reason = SNES_DIVERGED_FUNCTION_COUNT; 41206ee9f85SBarry Smith } 41306ee9f85SBarry Smith 41406ee9f85SBarry Smith if (it && !*reason) { 41506ee9f85SBarry Smith if (fnorm <= snes->ttol) { 416*8f1a2a5eSBarry Smith ierr = PetscInfo2(snes,"Converged due to function norm %14.12e < %14.12e (relative tolerance)\n",(double)fnorm,(double)snes->ttol);CHKERRQ(ierr); 41706ee9f85SBarry Smith *reason = SNES_CONVERGED_FNORM_RELATIVE; 41806ee9f85SBarry Smith } else if (pnorm < snes->xtol*xnorm) { 419*8f1a2a5eSBarry Smith ierr = PetscInfo3(snes,"Converged due to small update length: %14.12e < %14.12e * %14.12e\n",(double)pnorm,(double)snes->xtol,(double)xnorm);CHKERRQ(ierr); 42006ee9f85SBarry Smith *reason = SNES_CONVERGED_PNORM_RELATIVE; 42106ee9f85SBarry Smith } 422e7e93795SLois Curfman McInnes } 4233a40ed3dSBarry Smith PetscFunctionReturn(0); 424e7e93795SLois Curfman McInnes } 4253f149594SLisandro Dalcin 4263f149594SLisandro Dalcin #undef __FUNCT__ 4273f149594SLisandro Dalcin #define __FUNCT__ "SNESSkipConverged" 4283f149594SLisandro Dalcin /*@C 4293f149594SLisandro Dalcin SNESSkipConverged - Convergence test for SNES that NEVER returns as 4303f149594SLisandro Dalcin converged, UNLESS the maximum number of iteration have been reached. 4313f149594SLisandro Dalcin 4323f9fe445SBarry Smith Logically Collective on SNES 4333f149594SLisandro Dalcin 4343f149594SLisandro Dalcin Input Parameters: 4353f149594SLisandro Dalcin + snes - the SNES context 4363f149594SLisandro Dalcin . it - the iteration (0 indicates before any Newton steps) 4373f149594SLisandro Dalcin . xnorm - 2-norm of current iterate 4383f149594SLisandro Dalcin . pnorm - 2-norm of current step 4393f149594SLisandro Dalcin . fnorm - 2-norm of function at current iterate 4403f149594SLisandro Dalcin - dummy - unused context 4413f149594SLisandro Dalcin 4423f149594SLisandro Dalcin Output Parameter: 44385385478SLisandro Dalcin . reason - SNES_CONVERGED_ITERATING, SNES_CONVERGED_ITS, or SNES_DIVERGED_FNORM_NAN 4443f149594SLisandro Dalcin 4453f149594SLisandro Dalcin Notes: 4463f149594SLisandro Dalcin Convergence is then declared after a fixed number of iterations have been used. 4473f149594SLisandro Dalcin 4483f149594SLisandro Dalcin Level: advanced 4493f149594SLisandro Dalcin 4503f149594SLisandro Dalcin .keywords: SNES, nonlinear, skip, converged, convergence 4513f149594SLisandro Dalcin 4523f149594SLisandro Dalcin .seealso: SNESSetConvergenceTest() 4533f149594SLisandro Dalcin @*/ 4547087cfbeSBarry Smith PetscErrorCode SNESSkipConverged(SNES snes,PetscInt it,PetscReal xnorm,PetscReal pnorm,PetscReal fnorm,SNESConvergedReason *reason,void *dummy) 4553f149594SLisandro Dalcin { 4563f149594SLisandro Dalcin PetscErrorCode ierr; 4573f149594SLisandro Dalcin 4583f149594SLisandro Dalcin PetscFunctionBegin; 4590700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 4603f149594SLisandro Dalcin PetscValidPointer(reason,6); 4613f149594SLisandro Dalcin 4623f149594SLisandro Dalcin *reason = SNES_CONVERGED_ITERATING; 4633f149594SLisandro Dalcin 4643f149594SLisandro Dalcin if (fnorm != fnorm) { 4653f149594SLisandro Dalcin ierr = PetscInfo(snes,"Failed to converged, function norm is NaN\n");CHKERRQ(ierr); 4663f149594SLisandro Dalcin *reason = SNES_DIVERGED_FNORM_NAN; 4673f149594SLisandro Dalcin } else if(it == snes->max_its) { 4683f149594SLisandro Dalcin *reason = SNES_CONVERGED_ITS; 4693f149594SLisandro Dalcin } 4703f149594SLisandro Dalcin PetscFunctionReturn(0); 4713f149594SLisandro Dalcin } 4723f149594SLisandro Dalcin 47358c9b817SLisandro Dalcin #undef __FUNCT__ 47458c9b817SLisandro Dalcin #define __FUNCT__ "SNESDefaultGetWork" 47598acb6afSMatthew G Knepley /*@ 47658c9b817SLisandro Dalcin SNESDefaultGetWork - Gets a number of work vectors. 47758c9b817SLisandro Dalcin 47858c9b817SLisandro Dalcin Input Parameters: 47958c9b817SLisandro Dalcin . snes - the SNES context 48058c9b817SLisandro Dalcin . nw - number of work vectors to allocate 48158c9b817SLisandro Dalcin 48258c9b817SLisandro Dalcin Level: developer 48358c9b817SLisandro Dalcin 48458c9b817SLisandro Dalcin Notes: 48558c9b817SLisandro Dalcin Call this only if no work vectors have been allocated 48698acb6afSMatthew G Knepley @*/ 48758c9b817SLisandro Dalcin PetscErrorCode SNESDefaultGetWork(SNES snes,PetscInt nw) 48858c9b817SLisandro Dalcin { 48958c9b817SLisandro Dalcin PetscErrorCode ierr; 49058c9b817SLisandro Dalcin 49158c9b817SLisandro Dalcin PetscFunctionBegin; 49258c9b817SLisandro Dalcin if (snes->work) {ierr = VecDestroyVecs(snes->nwork,&snes->work);CHKERRQ(ierr);} 49358c9b817SLisandro Dalcin snes->nwork = nw; 49458c9b817SLisandro Dalcin ierr = VecDuplicateVecs(snes->vec_sol,snes->nwork,&snes->work);CHKERRQ(ierr); 49558c9b817SLisandro Dalcin ierr = PetscLogObjectParents(snes,nw,snes->work);CHKERRQ(ierr); 49658c9b817SLisandro Dalcin PetscFunctionReturn(0); 49758c9b817SLisandro Dalcin } 498