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; 143a34d58ebSBarry Smith PetscViewerASCIIMonitor viewer = (PetscViewerASCIIMonitor) dummy; 144d132466eSBarry Smith 1453a40ed3dSBarry Smith PetscFunctionBegin; 146a34d58ebSBarry Smith if (!dummy) { 1477adad957SLisandro Dalcin ierr = PetscViewerASCIIMonitorCreate(((PetscObject)snes)->comm,"stdout",0,&viewer);CHKERRQ(ierr); 148a34d58ebSBarry Smith } 149d9822059SBarry Smith ierr = PetscViewerASCIIMonitorPrintf(viewer,"%3D SNES Function norm %14.12e \n",its,(double)fgnorm);CHKERRQ(ierr); 150a34d58ebSBarry Smith if (!dummy) { 151a34d58ebSBarry Smith ierr = PetscViewerASCIIMonitorDestroy(viewer);CHKERRQ(ierr); 152a34d58ebSBarry Smith } 1533a40ed3dSBarry Smith PetscFunctionReturn(0); 154e7e93795SLois Curfman McInnes } 1553f1db9ecSBarry Smith 156b271bb04SBarry Smith #undef __FUNCT__ 157b271bb04SBarry Smith #define __FUNCT__ "SNESMonitorRange_Private" 1587087cfbeSBarry Smith PetscErrorCode SNESMonitorRange_Private(SNES snes,PetscInt it,PetscReal *per) 159b271bb04SBarry Smith { 160b271bb04SBarry Smith PetscErrorCode ierr; 161b271bb04SBarry Smith Vec resid; 162b271bb04SBarry Smith PetscReal rmax,pwork; 163b271bb04SBarry Smith PetscInt i,n,N; 164b271bb04SBarry Smith PetscScalar *r; 165b271bb04SBarry Smith 166b271bb04SBarry Smith PetscFunctionBegin; 167b271bb04SBarry Smith ierr = SNESGetFunction(snes,&resid,0,0);CHKERRQ(ierr); 168b271bb04SBarry Smith ierr = VecNorm(resid,NORM_INFINITY,&rmax);CHKERRQ(ierr); 169b271bb04SBarry Smith ierr = VecGetLocalSize(resid,&n);CHKERRQ(ierr); 170b271bb04SBarry Smith ierr = VecGetSize(resid,&N);CHKERRQ(ierr); 171b271bb04SBarry Smith ierr = VecGetArray(resid,&r);CHKERRQ(ierr); 172b271bb04SBarry Smith pwork = 0.0; 173b271bb04SBarry Smith for (i=0; i<n; i++) { 174b271bb04SBarry Smith pwork += (PetscAbsScalar(r[i]) > .20*rmax); 175b271bb04SBarry Smith } 17606a205a8SBarry Smith ierr = MPI_Allreduce(&pwork,per,1,MPIU_REAL,MPIU_SUM,((PetscObject)snes)->comm);CHKERRQ(ierr); 177b271bb04SBarry Smith ierr = VecRestoreArray(resid,&r);CHKERRQ(ierr); 178b271bb04SBarry Smith *per = *per/N; 179b271bb04SBarry Smith PetscFunctionReturn(0); 180b271bb04SBarry Smith } 181b271bb04SBarry Smith 182b271bb04SBarry Smith #undef __FUNCT__ 183b271bb04SBarry Smith #define __FUNCT__ "SNESMonitorRange" 184b271bb04SBarry Smith /*@C 185b271bb04SBarry Smith SNESMonitorRange - Prints the percentage of residual elements that are more then 10 percent of the maximum value. 186b271bb04SBarry Smith 187b271bb04SBarry Smith Collective on SNES 188b271bb04SBarry Smith 189b271bb04SBarry Smith Input Parameters: 190b271bb04SBarry Smith + snes - iterative context 191b271bb04SBarry Smith . it - iteration number 192b271bb04SBarry Smith . rnorm - 2-norm (preconditioned) residual value (may be estimated). 193b271bb04SBarry Smith - dummy - unused monitor context 194b271bb04SBarry Smith 195b271bb04SBarry Smith Options Database Key: 196b271bb04SBarry Smith . -snes_monitor_range - Activates SNESMonitorRange() 197b271bb04SBarry Smith 198b271bb04SBarry Smith Level: intermediate 199b271bb04SBarry Smith 200b271bb04SBarry Smith .keywords: SNES, default, monitor, residual 201b271bb04SBarry Smith 202b271bb04SBarry Smith .seealso: SNESMonitorSet(), SNESMonitorDefault(), SNESMonitorLGCreate() 203b271bb04SBarry Smith @*/ 2047087cfbeSBarry Smith PetscErrorCode SNESMonitorRange(SNES snes,PetscInt it,PetscReal rnorm,void *dummy) 205b271bb04SBarry Smith { 206b271bb04SBarry Smith PetscErrorCode ierr; 207b271bb04SBarry Smith PetscReal perc,rel; 208b271bb04SBarry Smith PetscViewerASCIIMonitor viewer = (PetscViewerASCIIMonitor) dummy; 209b271bb04SBarry Smith /* should be in a MonitorRangeContext */ 210b271bb04SBarry Smith static PetscReal prev; 211b271bb04SBarry Smith 212b271bb04SBarry Smith PetscFunctionBegin; 213b271bb04SBarry Smith if (!it) prev = rnorm; 214b271bb04SBarry Smith if (!dummy) {ierr = PetscViewerASCIIMonitorCreate(((PetscObject)snes)->comm,"stdout",0,&viewer);CHKERRQ(ierr);} 215b271bb04SBarry Smith ierr = SNESMonitorRange_Private(snes,it,&perc);CHKERRQ(ierr); 216b271bb04SBarry Smith 217b271bb04SBarry Smith rel = (prev - rnorm)/prev; 218b271bb04SBarry Smith prev = rnorm; 219d9822059SBarry Smith ierr = PetscViewerASCIIMonitorPrintf(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); 220b271bb04SBarry Smith if (!dummy) {ierr = PetscViewerASCIIMonitorDestroy(viewer);CHKERRQ(ierr);} 221b271bb04SBarry Smith PetscFunctionReturn(0); 222b271bb04SBarry Smith } 223b271bb04SBarry Smith 224eabae89aSBarry Smith typedef struct { 225a34d58ebSBarry Smith PetscViewerASCIIMonitor viewer; 226eabae89aSBarry Smith PetscReal *history; 227a6570f20SBarry Smith } SNESMonitorRatioContext; 228eabae89aSBarry Smith 2293a7fca6bSBarry Smith #undef __FUNCT__ 230a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorRatio" 2313a7fca6bSBarry Smith /*@C 232a6570f20SBarry Smith SNESMonitorRatio - Monitors progress of the SNES solvers by printing the ratio 2334b27c08aSLois Curfman McInnes of residual norm at each iteration to the previous. 2343a7fca6bSBarry Smith 2353a7fca6bSBarry Smith Collective on SNES 2363a7fca6bSBarry Smith 2373a7fca6bSBarry Smith Input Parameters: 2383a7fca6bSBarry Smith + snes - the SNES context 2393a7fca6bSBarry Smith . its - iteration number 2403a7fca6bSBarry Smith . fgnorm - 2-norm of residual (or gradient) 241eabae89aSBarry Smith - dummy - context of monitor 2423a7fca6bSBarry Smith 2433a7fca6bSBarry Smith Level: intermediate 2443a7fca6bSBarry Smith 2453a7fca6bSBarry Smith .keywords: SNES, nonlinear, monitor, norm 2463a7fca6bSBarry Smith 247a6570f20SBarry Smith .seealso: SNESMonitorSet(), SNESMonitorSolution() 2483a7fca6bSBarry Smith @*/ 2497087cfbeSBarry Smith PetscErrorCode SNESMonitorRatio(SNES snes,PetscInt its,PetscReal fgnorm,void *dummy) 2503a7fca6bSBarry Smith { 251dfbe8321SBarry Smith PetscErrorCode ierr; 25277431f27SBarry Smith PetscInt len; 25387828ca2SBarry Smith PetscReal *history; 254a6570f20SBarry Smith SNESMonitorRatioContext *ctx = (SNESMonitorRatioContext*)dummy; 2553a7fca6bSBarry Smith 2563a7fca6bSBarry Smith PetscFunctionBegin; 2573a7fca6bSBarry Smith ierr = SNESGetConvergenceHistory(snes,&history,PETSC_NULL,&len);CHKERRQ(ierr); 258958c9bccSBarry Smith if (!its || !history || its > len) { 259d9822059SBarry Smith ierr = PetscViewerASCIIMonitorPrintf(ctx->viewer,"%3D SNES Function norm %14.12e \n",its,(double)fgnorm);CHKERRQ(ierr); 2603a7fca6bSBarry Smith } else { 26187828ca2SBarry Smith PetscReal ratio = fgnorm/history[its-1]; 262d9822059SBarry Smith ierr = PetscViewerASCIIMonitorPrintf(ctx->viewer,"%3D SNES Function norm %14.12e %G \n",its,(double)fgnorm,(double)ratio);CHKERRQ(ierr); 2633a7fca6bSBarry Smith } 2643a7fca6bSBarry Smith PetscFunctionReturn(0); 2653a7fca6bSBarry Smith } 2663a7fca6bSBarry Smith 2673a7fca6bSBarry Smith /* 2683a7fca6bSBarry Smith If the we set the history monitor space then we must destroy it 2693a7fca6bSBarry Smith */ 2703a7fca6bSBarry Smith #undef __FUNCT__ 271a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorRatioDestroy" 272a6570f20SBarry Smith PetscErrorCode SNESMonitorRatioDestroy(void *ct) 2733a7fca6bSBarry Smith { 274dfbe8321SBarry Smith PetscErrorCode ierr; 275a6570f20SBarry Smith SNESMonitorRatioContext *ctx = (SNESMonitorRatioContext*)ct; 2763a7fca6bSBarry Smith 2773a7fca6bSBarry Smith PetscFunctionBegin; 27805b42c5fSBarry Smith ierr = PetscFree(ctx->history);CHKERRQ(ierr); 279a34d58ebSBarry Smith ierr = PetscViewerASCIIMonitorDestroy(ctx->viewer);CHKERRQ(ierr); 280eabae89aSBarry Smith ierr = PetscFree(ctx);CHKERRQ(ierr); 2813a7fca6bSBarry Smith PetscFunctionReturn(0); 2823a7fca6bSBarry Smith } 2833a7fca6bSBarry Smith 2843a7fca6bSBarry Smith #undef __FUNCT__ 285a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorSetRatio" 2863a7fca6bSBarry Smith /*@C 287a6570f20SBarry Smith SNESMonitorSetRatio - Sets SNES to use a monitor that prints the 2884b27c08aSLois Curfman McInnes ratio of the function norm at each iteration. 2893a7fca6bSBarry Smith 2903a7fca6bSBarry Smith Collective on SNES 2913a7fca6bSBarry Smith 2923a7fca6bSBarry Smith Input Parameters: 293eabae89aSBarry Smith + snes - the SNES context 294eabae89aSBarry Smith - viewer - ASCII viewer to print output 2953a7fca6bSBarry Smith 2963a7fca6bSBarry Smith Level: intermediate 2973a7fca6bSBarry Smith 2983a7fca6bSBarry Smith .keywords: SNES, nonlinear, monitor, norm 2993a7fca6bSBarry Smith 300a6570f20SBarry Smith .seealso: SNESMonitorSet(), SNESMonitorSolution(), SNESMonitorDefault() 3013a7fca6bSBarry Smith @*/ 3027087cfbeSBarry Smith PetscErrorCode SNESMonitorSetRatio(SNES snes,PetscViewerASCIIMonitor viewer) 3033a7fca6bSBarry Smith { 304dfbe8321SBarry Smith PetscErrorCode ierr; 305a6570f20SBarry Smith SNESMonitorRatioContext *ctx; 30687828ca2SBarry Smith PetscReal *history; 3073a7fca6bSBarry Smith 3083a7fca6bSBarry Smith PetscFunctionBegin; 309eabae89aSBarry Smith if (!viewer) { 3107adad957SLisandro Dalcin ierr = PetscViewerASCIIMonitorCreate(((PetscObject)snes)->comm,"stdout",0,&viewer);CHKERRQ(ierr); 311eabae89aSBarry Smith ierr = PetscObjectReference((PetscObject)viewer);CHKERRQ(ierr); 312eabae89aSBarry Smith } 31338f2d2fdSLisandro Dalcin ierr = PetscNewLog(snes,SNESMonitorRatioContext,&ctx); 3143a7fca6bSBarry Smith ierr = SNESGetConvergenceHistory(snes,&history,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr); 3153a7fca6bSBarry Smith if (!history) { 316eabae89aSBarry Smith ierr = PetscMalloc(100*sizeof(PetscReal),&ctx->history);CHKERRQ(ierr); 317eabae89aSBarry Smith ierr = SNESSetConvergenceHistory(snes,ctx->history,0,100,PETSC_TRUE);CHKERRQ(ierr); 3183a7fca6bSBarry Smith } 319eabae89aSBarry Smith ctx->viewer = viewer; 320a6570f20SBarry Smith ierr = SNESMonitorSet(snes,SNESMonitorRatio,ctx,SNESMonitorRatioDestroy);CHKERRQ(ierr); 3213a7fca6bSBarry Smith PetscFunctionReturn(0); 3223a7fca6bSBarry Smith } 3233a7fca6bSBarry Smith 324e7e93795SLois Curfman McInnes /* ---------------------------------------------------------------- */ 3254a2ae208SSatish Balay #undef __FUNCT__ 326a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorDefaultShort" 327be1f7002SBarry Smith /* 328a6570f20SBarry Smith Default (short) SNES Monitor, same as SNESMonitorDefault() except 329be1f7002SBarry Smith it prints fewer digits of the residual as the residual gets smaller. 330be1f7002SBarry Smith This is because the later digits are meaningless and are often 331be1f7002SBarry Smith different on different machines; by using this routine different 332be1f7002SBarry Smith machines will usually generate the same output. 333be1f7002SBarry Smith */ 3347087cfbeSBarry Smith PetscErrorCode SNESMonitorDefaultShort(SNES snes,PetscInt its,PetscReal fgnorm,void *dummy) 335e7e93795SLois Curfman McInnes { 336dfbe8321SBarry Smith PetscErrorCode ierr; 337a34d58ebSBarry Smith PetscViewerASCIIMonitor viewer = (PetscViewerASCIIMonitor) dummy; 338d132466eSBarry Smith 3393a40ed3dSBarry Smith PetscFunctionBegin; 340a34d58ebSBarry Smith if (!dummy) { 3417adad957SLisandro Dalcin ierr = PetscViewerASCIIMonitorCreate(((PetscObject)snes)->comm,"stdout",0,&viewer);CHKERRQ(ierr); 342a34d58ebSBarry Smith } 3438f240d10SBarry Smith if (fgnorm > 1.e-9) { 344a34d58ebSBarry Smith ierr = PetscViewerASCIIMonitorPrintf(viewer,"%3D SNES Function norm %G \n",its,fgnorm);CHKERRQ(ierr); 3453a40ed3dSBarry Smith } else if (fgnorm > 1.e-11){ 346a34d58ebSBarry Smith ierr = PetscViewerASCIIMonitorPrintf(viewer,"%3D SNES Function norm %5.3e \n",its,fgnorm);CHKERRQ(ierr); 3473a40ed3dSBarry Smith } else { 348a34d58ebSBarry Smith ierr = PetscViewerASCIIMonitorPrintf(viewer,"%3D SNES Function norm < 1.e-11\n",its);CHKERRQ(ierr); 349a34d58ebSBarry Smith } 350a34d58ebSBarry Smith if (!dummy) { 351a34d58ebSBarry Smith ierr = PetscViewerASCIIMonitorDestroy(viewer);CHKERRQ(ierr); 352e7e93795SLois Curfman McInnes } 3533a40ed3dSBarry Smith PetscFunctionReturn(0); 354e7e93795SLois Curfman McInnes } 355e7e93795SLois Curfman McInnes /* ---------------------------------------------------------------- */ 3564a2ae208SSatish Balay #undef __FUNCT__ 3573f149594SLisandro Dalcin #define __FUNCT__ "SNESDefaultConverged" 3584b828684SBarry Smith /*@C 3593f149594SLisandro Dalcin SNESDefaultConverged - Convergence test of the solvers for 360f525115eSLois Curfman McInnes systems of nonlinear equations (default). 361e7e93795SLois Curfman McInnes 362c7afd0dbSLois Curfman McInnes Collective on SNES 363c7afd0dbSLois Curfman McInnes 364e7e93795SLois Curfman McInnes Input Parameters: 365c7afd0dbSLois Curfman McInnes + snes - the SNES context 36606ee9f85SBarry Smith . it - the iteration (0 indicates before any Newton steps) 367e7e93795SLois Curfman McInnes . xnorm - 2-norm of current iterate 368e7e93795SLois Curfman McInnes . pnorm - 2-norm of current step 3697f3332b4SBarry Smith . fnorm - 2-norm of function at current iterate 370c7afd0dbSLois Curfman McInnes - dummy - unused context 371e7e93795SLois Curfman McInnes 372184914b5SBarry Smith Output Parameter: 373184914b5SBarry Smith . reason - one of 37470441072SBarry Smith $ SNES_CONVERGED_FNORM_ABS - (fnorm < abstol), 3753304466cSBarry Smith $ SNES_CONVERGED_PNORM_RELATIVE - (pnorm < xtol*xnorm), 376184914b5SBarry Smith $ SNES_CONVERGED_FNORM_RELATIVE - (fnorm < rtol*fnorm0), 377184914b5SBarry Smith $ SNES_DIVERGED_FUNCTION_COUNT - (nfct > maxf), 378184914b5SBarry Smith $ SNES_DIVERGED_FNORM_NAN - (fnorm == NaN), 379184914b5SBarry Smith $ SNES_CONVERGED_ITERATING - (otherwise), 380e7e93795SLois Curfman McInnes 381e7e93795SLois Curfman McInnes where 382c7afd0dbSLois Curfman McInnes + maxf - maximum number of function evaluations, 383c7afd0dbSLois Curfman McInnes set with SNESSetTolerances() 384c7afd0dbSLois Curfman McInnes . nfct - number of function evaluations, 38570441072SBarry Smith . abstol - absolute function norm tolerance, 386c7afd0dbSLois Curfman McInnes set with SNESSetTolerances() 387c7afd0dbSLois Curfman McInnes - rtol - relative function norm tolerance, set with SNESSetTolerances() 388fee21e36SBarry Smith 38936851e7fSLois Curfman McInnes Level: intermediate 39036851e7fSLois Curfman McInnes 391e7e93795SLois Curfman McInnes .keywords: SNES, nonlinear, default, converged, convergence 392e7e93795SLois Curfman McInnes 39371f87433Sdalcinl .seealso: SNESSetConvergenceTest() 394e7e93795SLois Curfman McInnes @*/ 3957087cfbeSBarry Smith PetscErrorCode SNESDefaultConverged(SNES snes,PetscInt it,PetscReal xnorm,PetscReal pnorm,PetscReal fnorm,SNESConvergedReason *reason,void *dummy) 396e7e93795SLois Curfman McInnes { 39763ba0a88SBarry Smith PetscErrorCode ierr; 39863ba0a88SBarry Smith 3993a40ed3dSBarry Smith PetscFunctionBegin; 4000700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 4013f149594SLisandro Dalcin PetscValidPointer(reason,6); 4023f149594SLisandro Dalcin 40306ee9f85SBarry Smith *reason = SNES_CONVERGED_ITERATING; 40406ee9f85SBarry Smith 40506ee9f85SBarry Smith if (!it) { 40606ee9f85SBarry Smith /* set parameter for default relative tolerance convergence test */ 40706ee9f85SBarry Smith snes->ttol = fnorm*snes->rtol; 40806ee9f85SBarry Smith } 409d252947aSBarry Smith if (fnorm != fnorm) { 410ae15b995SBarry Smith ierr = PetscInfo(snes,"Failed to converged, function norm is NaN\n");CHKERRQ(ierr); 411184914b5SBarry Smith *reason = SNES_DIVERGED_FNORM_NAN; 41270441072SBarry Smith } else if (fnorm < snes->abstol) { 413ae15b995SBarry Smith ierr = PetscInfo2(snes,"Converged due to function norm %G < %G\n",fnorm,snes->abstol);CHKERRQ(ierr); 414184914b5SBarry Smith *reason = SNES_CONVERGED_FNORM_ABS; 41543e71028SBarry Smith } else if (snes->nfuncs >= snes->max_funcs) { 416ae15b995SBarry Smith ierr = PetscInfo2(snes,"Exceeded maximum number of function evaluations: %D > %D\n",snes->nfuncs,snes->max_funcs);CHKERRQ(ierr); 417184914b5SBarry Smith *reason = SNES_DIVERGED_FUNCTION_COUNT; 41806ee9f85SBarry Smith } 41906ee9f85SBarry Smith 42006ee9f85SBarry Smith if (it && !*reason) { 42106ee9f85SBarry Smith if (fnorm <= snes->ttol) { 42206ee9f85SBarry Smith ierr = PetscInfo2(snes,"Converged due to function norm %G < %G (relative tolerance)\n",fnorm,snes->ttol);CHKERRQ(ierr); 42306ee9f85SBarry Smith *reason = SNES_CONVERGED_FNORM_RELATIVE; 42406ee9f85SBarry Smith } else if (pnorm < snes->xtol*xnorm) { 42506ee9f85SBarry Smith ierr = PetscInfo3(snes,"Converged due to small update length: %G < %G * %G\n",pnorm,snes->xtol,xnorm);CHKERRQ(ierr); 42606ee9f85SBarry Smith *reason = SNES_CONVERGED_PNORM_RELATIVE; 42706ee9f85SBarry Smith } 428e7e93795SLois Curfman McInnes } 4293a40ed3dSBarry Smith PetscFunctionReturn(0); 430e7e93795SLois Curfman McInnes } 4313f149594SLisandro Dalcin 4323f149594SLisandro Dalcin #undef __FUNCT__ 4333f149594SLisandro Dalcin #define __FUNCT__ "SNESSkipConverged" 4343f149594SLisandro Dalcin /*@C 4353f149594SLisandro Dalcin SNESSkipConverged - Convergence test for SNES that NEVER returns as 4363f149594SLisandro Dalcin converged, UNLESS the maximum number of iteration have been reached. 4373f149594SLisandro Dalcin 4383f9fe445SBarry Smith Logically Collective on SNES 4393f149594SLisandro Dalcin 4403f149594SLisandro Dalcin Input Parameters: 4413f149594SLisandro Dalcin + snes - the SNES context 4423f149594SLisandro Dalcin . it - the iteration (0 indicates before any Newton steps) 4433f149594SLisandro Dalcin . xnorm - 2-norm of current iterate 4443f149594SLisandro Dalcin . pnorm - 2-norm of current step 4453f149594SLisandro Dalcin . fnorm - 2-norm of function at current iterate 4463f149594SLisandro Dalcin - dummy - unused context 4473f149594SLisandro Dalcin 4483f149594SLisandro Dalcin Output Parameter: 44985385478SLisandro Dalcin . reason - SNES_CONVERGED_ITERATING, SNES_CONVERGED_ITS, or SNES_DIVERGED_FNORM_NAN 4503f149594SLisandro Dalcin 4513f149594SLisandro Dalcin Notes: 4523f149594SLisandro Dalcin Convergence is then declared after a fixed number of iterations have been used. 4533f149594SLisandro Dalcin 4543f149594SLisandro Dalcin Level: advanced 4553f149594SLisandro Dalcin 4563f149594SLisandro Dalcin .keywords: SNES, nonlinear, skip, converged, convergence 4573f149594SLisandro Dalcin 4583f149594SLisandro Dalcin .seealso: SNESSetConvergenceTest() 4593f149594SLisandro Dalcin @*/ 4607087cfbeSBarry Smith PetscErrorCode SNESSkipConverged(SNES snes,PetscInt it,PetscReal xnorm,PetscReal pnorm,PetscReal fnorm,SNESConvergedReason *reason,void *dummy) 4613f149594SLisandro Dalcin { 4623f149594SLisandro Dalcin PetscErrorCode ierr; 4633f149594SLisandro Dalcin 4643f149594SLisandro Dalcin PetscFunctionBegin; 4650700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 4663f149594SLisandro Dalcin PetscValidPointer(reason,6); 4673f149594SLisandro Dalcin 4683f149594SLisandro Dalcin *reason = SNES_CONVERGED_ITERATING; 4693f149594SLisandro Dalcin 4703f149594SLisandro Dalcin if (fnorm != fnorm) { 4713f149594SLisandro Dalcin ierr = PetscInfo(snes,"Failed to converged, function norm is NaN\n");CHKERRQ(ierr); 4723f149594SLisandro Dalcin *reason = SNES_DIVERGED_FNORM_NAN; 4733f149594SLisandro Dalcin } else if(it == snes->max_its) { 4743f149594SLisandro Dalcin *reason = SNES_CONVERGED_ITS; 4753f149594SLisandro Dalcin } 4763f149594SLisandro Dalcin PetscFunctionReturn(0); 4773f149594SLisandro Dalcin } 4783f149594SLisandro Dalcin 479*58c9b817SLisandro Dalcin #undef __FUNCT__ 480*58c9b817SLisandro Dalcin #define __FUNCT__ "SNESDefaultGetWork" 481*58c9b817SLisandro Dalcin /* 482*58c9b817SLisandro Dalcin SNESDefaultGetWork - Gets a number of work vectors. 483*58c9b817SLisandro Dalcin 484*58c9b817SLisandro Dalcin Input Parameters: 485*58c9b817SLisandro Dalcin . snes - the SNES context 486*58c9b817SLisandro Dalcin . nw - number of work vectors to allocate 487*58c9b817SLisandro Dalcin 488*58c9b817SLisandro Dalcin Level: developer 489*58c9b817SLisandro Dalcin 490*58c9b817SLisandro Dalcin Notes: 491*58c9b817SLisandro Dalcin Call this only if no work vectors have been allocated 492*58c9b817SLisandro Dalcin */ 493*58c9b817SLisandro Dalcin PetscErrorCode SNESDefaultGetWork(SNES snes,PetscInt nw) 494*58c9b817SLisandro Dalcin { 495*58c9b817SLisandro Dalcin PetscErrorCode ierr; 496*58c9b817SLisandro Dalcin 497*58c9b817SLisandro Dalcin PetscFunctionBegin; 498*58c9b817SLisandro Dalcin if (snes->work) {ierr = VecDestroyVecs(snes->nwork,&snes->work);CHKERRQ(ierr);} 499*58c9b817SLisandro Dalcin snes->nwork = nw; 500*58c9b817SLisandro Dalcin ierr = VecDuplicateVecs(snes->vec_sol,snes->nwork,&snes->work);CHKERRQ(ierr); 501*58c9b817SLisandro Dalcin ierr = PetscLogObjectParents(snes,nw,snes->work);CHKERRQ(ierr); 502*58c9b817SLisandro Dalcin PetscFunctionReturn(0); 503*58c9b817SLisandro Dalcin } 504