1e7e93795SLois Curfman McInnes 28d359177SBarry Smith #include <petsc-private/snesimpl.h> /*I "petsc-private/snesimpl.h" I*/ 3636fd056SMatthew G. Knepley #include <petscdm.h> 42e7541e6SPeter Brune #include <petscblaslapack.h> 5e7e93795SLois Curfman McInnes 64a2ae208SSatish Balay #undef __FUNCT__ 7a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorSolution" 83f1db9ecSBarry Smith /*@C 9a6570f20SBarry Smith SNESMonitorSolution - Monitors progress of the SNES solvers by calling 1036851e7fSLois Curfman McInnes VecView() for the approximate solution at each iteration. 113f1db9ecSBarry Smith 123f1db9ecSBarry Smith Collective on SNES 133f1db9ecSBarry Smith 143f1db9ecSBarry Smith Input Parameters: 153f1db9ecSBarry Smith + snes - the SNES context 163f1db9ecSBarry Smith . its - iteration number 174b27c08aSLois Curfman McInnes . fgnorm - 2-norm of residual 180298fd71SBarry Smith - dummy - either a viewer or NULL 193f1db9ecSBarry Smith 2036851e7fSLois Curfman McInnes Level: intermediate 213f1db9ecSBarry Smith 2236851e7fSLois Curfman McInnes .keywords: SNES, nonlinear, vector, monitor, view 233f1db9ecSBarry Smith 24a6570f20SBarry Smith .seealso: SNESMonitorSet(), SNESMonitorDefault(), VecView() 253f1db9ecSBarry Smith @*/ 267087cfbeSBarry Smith PetscErrorCode SNESMonitorSolution(SNES snes,PetscInt its,PetscReal fgnorm,void *dummy) 273f1db9ecSBarry Smith { 28dfbe8321SBarry Smith PetscErrorCode ierr; 293f1db9ecSBarry Smith Vec x; 30b0a32e0cSBarry Smith PetscViewer viewer = (PetscViewer) dummy; 313f1db9ecSBarry Smith 323f1db9ecSBarry Smith PetscFunctionBegin; 333f1db9ecSBarry Smith ierr = SNESGetSolution(snes,&x);CHKERRQ(ierr); 343f1db9ecSBarry Smith if (!viewer) { 353f1db9ecSBarry Smith MPI_Comm comm; 363f1db9ecSBarry Smith ierr = PetscObjectGetComm((PetscObject)snes,&comm);CHKERRQ(ierr); 37b0a32e0cSBarry Smith viewer = PETSC_VIEWER_DRAW_(comm); 383f1db9ecSBarry Smith } 393f1db9ecSBarry Smith ierr = VecView(x,viewer);CHKERRQ(ierr); 403f1db9ecSBarry Smith PetscFunctionReturn(0); 413f1db9ecSBarry Smith } 423f1db9ecSBarry Smith 434a2ae208SSatish Balay #undef __FUNCT__ 44a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorResidual" 455ed2d596SBarry Smith /*@C 46a6570f20SBarry Smith SNESMonitorResidual - 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 550298fd71SBarry Smith - dummy - either a viewer or NULL 565ed2d596SBarry Smith 575ed2d596SBarry Smith Level: intermediate 585ed2d596SBarry Smith 595ed2d596SBarry Smith .keywords: SNES, nonlinear, vector, monitor, view 605ed2d596SBarry Smith 61a6570f20SBarry Smith .seealso: SNESMonitorSet(), SNESMonitorDefault(), VecView() 625ed2d596SBarry Smith @*/ 637087cfbeSBarry Smith PetscErrorCode SNESMonitorResidual(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 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 920298fd71SBarry Smith - dummy - either a viewer or 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 PetscFunctionReturn(0); 115d132466eSBarry Smith } 116d132466eSBarry Smith 1174a2ae208SSatish Balay #undef __FUNCT__ 118a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorDefault" 1194b828684SBarry Smith /*@C 120a6570f20SBarry Smith SNESMonitorDefault - Monitors progress of the SNES solvers (default). 121e7e93795SLois Curfman McInnes 122c7afd0dbSLois Curfman McInnes Collective on SNES 123c7afd0dbSLois Curfman McInnes 124e7e93795SLois Curfman McInnes Input Parameters: 125c7afd0dbSLois Curfman McInnes + snes - the SNES context 126e7e93795SLois Curfman McInnes . its - iteration number 1274b27c08aSLois Curfman McInnes . fgnorm - 2-norm of residual 128c7afd0dbSLois Curfman McInnes - dummy - unused context 129fee21e36SBarry Smith 130e7e93795SLois Curfman McInnes Notes: 1314b27c08aSLois Curfman McInnes This routine prints the residual norm at each iteration. 132e7e93795SLois Curfman McInnes 13336851e7fSLois Curfman McInnes Level: intermediate 13436851e7fSLois Curfman McInnes 135e7e93795SLois Curfman McInnes .keywords: SNES, nonlinear, default, monitor, norm 136e7e93795SLois Curfman McInnes 137a6570f20SBarry Smith .seealso: SNESMonitorSet(), SNESMonitorSolution() 138e7e93795SLois Curfman McInnes @*/ 1397087cfbeSBarry Smith PetscErrorCode SNESMonitorDefault(SNES snes,PetscInt its,PetscReal fgnorm,void *dummy) 140e7e93795SLois Curfman McInnes { 141dfbe8321SBarry Smith PetscErrorCode ierr; 142ce94432eSBarry Smith PetscViewer viewer = dummy ? (PetscViewer) dummy : PETSC_VIEWER_STDOUT_(PetscObjectComm((PetscObject)snes)); 143d132466eSBarry Smith 1443a40ed3dSBarry Smith PetscFunctionBegin; 145649052a6SBarry Smith ierr = PetscViewerASCIIAddTab(viewer,((PetscObject)snes)->tablevel);CHKERRQ(ierr); 146649052a6SBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"%3D SNES Function norm %14.12e \n",its,(double)fgnorm);CHKERRQ(ierr); 147649052a6SBarry Smith ierr = PetscViewerASCIISubtractTab(viewer,((PetscObject)snes)->tablevel);CHKERRQ(ierr); 1483a40ed3dSBarry Smith PetscFunctionReturn(0); 149e7e93795SLois Curfman McInnes } 1503f1db9ecSBarry Smith 151b271bb04SBarry Smith #undef __FUNCT__ 1522e7541e6SPeter Brune #define __FUNCT__ "SNESMonitorJacUpdateSpectrum" 153a80ad3e0SBarry Smith PetscErrorCode SNESMonitorJacUpdateSpectrum(SNES snes,PetscInt it,PetscReal fnorm,void *ctx) 154a80ad3e0SBarry Smith { 155196da8b6SPeter Brune #if defined(PETSC_MISSING_LAPACK_GEEV) 156ce94432eSBarry Smith SETERRQ(PetscObjectComm((PetscObject)snes),PETSC_ERR_SUP,"GEEV - Lapack routine is unavailable\nNot able to provide eigen values."); 157196da8b6SPeter Brune #elif defined(PETSC_HAVE_ESSL) 158ce94432eSBarry Smith SETERRQ(PetscObjectComm((PetscObject)snes),PETSC_ERR_SUP,"GEEV - No support for ESSL Lapack Routines"); 159196da8b6SPeter Brune #else 1602e7541e6SPeter Brune Vec X; 1612e7541e6SPeter Brune Mat J,dJ,dJdense; 1622e7541e6SPeter Brune PetscErrorCode ierr; 1632e7541e6SPeter Brune PetscErrorCode (*func)(SNES,Vec,Mat*,Mat*,MatStructure*,void*); 1642e7541e6SPeter Brune PetscInt n,i; 1652e7541e6SPeter Brune PetscBLASInt nb,lwork; 1662e7541e6SPeter Brune PetscReal *eigr,*eigi; 1672e7541e6SPeter Brune MatStructure flg = DIFFERENT_NONZERO_PATTERN; 1682e7541e6SPeter Brune PetscScalar *work; 1692e7541e6SPeter Brune PetscScalar *a; 1702e7541e6SPeter Brune 1712e7541e6SPeter Brune PetscFunctionBegin; 1722e7541e6SPeter Brune if (it == 0) PetscFunctionReturn(0); 1732e7541e6SPeter Brune /* create the difference between the current update and the current jacobian */ 1742e7541e6SPeter Brune ierr = SNESGetSolution(snes,&X);CHKERRQ(ierr); 1750298fd71SBarry Smith ierr = SNESGetJacobian(snes,&J,NULL,&func,NULL);CHKERRQ(ierr); 1762e7541e6SPeter Brune ierr = MatDuplicate(J,MAT_COPY_VALUES,&dJ);CHKERRQ(ierr); 1772e7541e6SPeter Brune ierr = SNESComputeJacobian(snes,X,&dJ,&dJ,&flg);CHKERRQ(ierr); 1782e7541e6SPeter Brune ierr = MatAXPY(dJ,-1.0,J,SAME_NONZERO_PATTERN);CHKERRQ(ierr); 179f5af7f23SKarl Rupp 1802e7541e6SPeter Brune /* compute the spectrum directly */ 1812e7541e6SPeter Brune ierr = MatConvert(dJ,MATSEQDENSE,MAT_INITIAL_MATRIX,&dJdense);CHKERRQ(ierr); 1820298fd71SBarry Smith ierr = MatGetSize(dJ,&n,NULL);CHKERRQ(ierr); 183c5df96a5SBarry Smith ierr = PetscBLASIntCast(n,&nb);CHKERRQ(ierr); 1842e7541e6SPeter Brune lwork = 3*nb; 185785e854fSJed Brown ierr = PetscMalloc1(n,&eigr);CHKERRQ(ierr); 186785e854fSJed Brown ierr = PetscMalloc1(n,&eigi);CHKERRQ(ierr); 187785e854fSJed Brown ierr = PetscMalloc1(lwork,&work);CHKERRQ(ierr); 1888c778c55SBarry Smith ierr = MatDenseGetArray(dJdense,&a);CHKERRQ(ierr); 1892e7541e6SPeter Brune #if !defined(PETSC_USE_COMPLEX) 1902e7541e6SPeter Brune { 1912e7541e6SPeter Brune PetscBLASInt lierr; 1922e7541e6SPeter Brune ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 1938b83055fSJed Brown PetscStackCallBLAS("LAPACKgeev",LAPACKgeev_("N","N",&nb,a,&nb,eigr,eigi,NULL,&nb,NULL,&nb,work,&lwork,&lierr)); 1942e7541e6SPeter Brune if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"geev() error %d",lierr); 1952e7541e6SPeter Brune ierr = PetscFPTrapPop();CHKERRQ(ierr); 1962e7541e6SPeter Brune } 1972e7541e6SPeter Brune #else 1982e7541e6SPeter Brune SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not coded for complex"); 1992e7541e6SPeter Brune #endif 200ce94432eSBarry Smith PetscPrintf(PetscObjectComm((PetscObject)snes),"Eigenvalues of J_%d - J_%d:\n",it,it-1);CHKERRQ(ierr); 2012e7541e6SPeter Brune for (i=0;i<n;i++) { 2028fa295daSBarry Smith PetscPrintf(PetscObjectComm((PetscObject)snes),"%5d: %20.5g + %20.5gi\n",i,(double)eigr[i],(double)eigi[i]);CHKERRQ(ierr); 2032e7541e6SPeter Brune } 2048c778c55SBarry Smith ierr = MatDenseRestoreArray(dJdense,&a);CHKERRQ(ierr); 2052e7541e6SPeter Brune ierr = MatDestroy(&dJ);CHKERRQ(ierr); 2062e7541e6SPeter Brune ierr = MatDestroy(&dJdense);CHKERRQ(ierr); 2072e7541e6SPeter Brune ierr = PetscFree(eigr);CHKERRQ(ierr); 2082e7541e6SPeter Brune ierr = PetscFree(eigi);CHKERRQ(ierr); 2092e7541e6SPeter Brune ierr = PetscFree(work);CHKERRQ(ierr); 2102e7541e6SPeter Brune PetscFunctionReturn(0); 211196da8b6SPeter Brune #endif 2122e7541e6SPeter Brune } 2132e7541e6SPeter Brune 2142e7541e6SPeter Brune #undef __FUNCT__ 215b271bb04SBarry Smith #define __FUNCT__ "SNESMonitorRange_Private" 2167087cfbeSBarry Smith PetscErrorCode SNESMonitorRange_Private(SNES snes,PetscInt it,PetscReal *per) 217b271bb04SBarry Smith { 218b271bb04SBarry Smith PetscErrorCode ierr; 219b271bb04SBarry Smith Vec resid; 220b271bb04SBarry Smith PetscReal rmax,pwork; 221b271bb04SBarry Smith PetscInt i,n,N; 222b271bb04SBarry Smith PetscScalar *r; 223b271bb04SBarry Smith 224b271bb04SBarry Smith PetscFunctionBegin; 225b271bb04SBarry Smith ierr = SNESGetFunction(snes,&resid,0,0);CHKERRQ(ierr); 226b271bb04SBarry Smith ierr = VecNorm(resid,NORM_INFINITY,&rmax);CHKERRQ(ierr); 227b271bb04SBarry Smith ierr = VecGetLocalSize(resid,&n);CHKERRQ(ierr); 228b271bb04SBarry Smith ierr = VecGetSize(resid,&N);CHKERRQ(ierr); 229b271bb04SBarry Smith ierr = VecGetArray(resid,&r);CHKERRQ(ierr); 230b271bb04SBarry Smith pwork = 0.0; 231b271bb04SBarry Smith for (i=0; i<n; i++) { 232b271bb04SBarry Smith pwork += (PetscAbsScalar(r[i]) > .20*rmax); 233b271bb04SBarry Smith } 234ce94432eSBarry Smith ierr = MPI_Allreduce(&pwork,per,1,MPIU_REAL,MPIU_SUM,PetscObjectComm((PetscObject)snes));CHKERRQ(ierr); 235b271bb04SBarry Smith ierr = VecRestoreArray(resid,&r);CHKERRQ(ierr); 236b271bb04SBarry Smith *per = *per/N; 237b271bb04SBarry Smith PetscFunctionReturn(0); 238b271bb04SBarry Smith } 239b271bb04SBarry Smith 240b271bb04SBarry Smith #undef __FUNCT__ 241b271bb04SBarry Smith #define __FUNCT__ "SNESMonitorRange" 242b271bb04SBarry Smith /*@C 243b271bb04SBarry Smith SNESMonitorRange - Prints the percentage of residual elements that are more then 10 percent of the maximum value. 244b271bb04SBarry Smith 245b271bb04SBarry Smith Collective on SNES 246b271bb04SBarry Smith 247b271bb04SBarry Smith Input Parameters: 248b271bb04SBarry Smith + snes - iterative context 249b271bb04SBarry Smith . it - iteration number 250b271bb04SBarry Smith . rnorm - 2-norm (preconditioned) residual value (may be estimated). 251b271bb04SBarry Smith - dummy - unused monitor context 252b271bb04SBarry Smith 253b271bb04SBarry Smith Options Database Key: 254b271bb04SBarry Smith . -snes_monitor_range - Activates SNESMonitorRange() 255b271bb04SBarry Smith 256b271bb04SBarry Smith Level: intermediate 257b271bb04SBarry Smith 258b271bb04SBarry Smith .keywords: SNES, default, monitor, residual 259b271bb04SBarry Smith 260b271bb04SBarry Smith .seealso: SNESMonitorSet(), SNESMonitorDefault(), SNESMonitorLGCreate() 261b271bb04SBarry Smith @*/ 2627087cfbeSBarry Smith PetscErrorCode SNESMonitorRange(SNES snes,PetscInt it,PetscReal rnorm,void *dummy) 263b271bb04SBarry Smith { 264b271bb04SBarry Smith PetscErrorCode ierr; 265b271bb04SBarry Smith PetscReal perc,rel; 266ce94432eSBarry Smith PetscViewer viewer = dummy ? (PetscViewer) dummy : PETSC_VIEWER_STDOUT_(PetscObjectComm((PetscObject)snes)); 267b271bb04SBarry Smith /* should be in a MonitorRangeContext */ 268b271bb04SBarry Smith static PetscReal prev; 269b271bb04SBarry Smith 270b271bb04SBarry Smith PetscFunctionBegin; 271b271bb04SBarry Smith if (!it) prev = rnorm; 272b271bb04SBarry Smith ierr = SNESMonitorRange_Private(snes,it,&perc);CHKERRQ(ierr); 273b271bb04SBarry Smith 274b271bb04SBarry Smith rel = (prev - rnorm)/prev; 275b271bb04SBarry Smith prev = rnorm; 276649052a6SBarry Smith ierr = PetscViewerASCIIAddTab(viewer,((PetscObject)snes)->tablevel);CHKERRQ(ierr); 277*6712e2f1SBarry 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); 278649052a6SBarry Smith ierr = PetscViewerASCIISubtractTab(viewer,((PetscObject)snes)->tablevel);CHKERRQ(ierr); 279b271bb04SBarry Smith PetscFunctionReturn(0); 280b271bb04SBarry Smith } 281b271bb04SBarry Smith 282eabae89aSBarry Smith typedef struct { 283649052a6SBarry Smith PetscViewer viewer; 284eabae89aSBarry Smith PetscReal *history; 285a6570f20SBarry Smith } SNESMonitorRatioContext; 286eabae89aSBarry Smith 2873a7fca6bSBarry Smith #undef __FUNCT__ 288a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorRatio" 2893a7fca6bSBarry Smith /*@C 290a6570f20SBarry Smith SNESMonitorRatio - Monitors progress of the SNES solvers by printing the ratio 2914b27c08aSLois Curfman McInnes of residual norm at each iteration to the previous. 2923a7fca6bSBarry Smith 2933a7fca6bSBarry Smith Collective on SNES 2943a7fca6bSBarry Smith 2953a7fca6bSBarry Smith Input Parameters: 2963a7fca6bSBarry Smith + snes - the SNES context 2973a7fca6bSBarry Smith . its - iteration number 2983a7fca6bSBarry Smith . fgnorm - 2-norm of residual (or gradient) 299eabae89aSBarry Smith - dummy - context of monitor 3003a7fca6bSBarry Smith 3013a7fca6bSBarry Smith Level: intermediate 3023a7fca6bSBarry Smith 3033a7fca6bSBarry Smith .keywords: SNES, nonlinear, monitor, norm 3043a7fca6bSBarry Smith 305a6570f20SBarry Smith .seealso: SNESMonitorSet(), SNESMonitorSolution() 3063a7fca6bSBarry Smith @*/ 3077087cfbeSBarry Smith PetscErrorCode SNESMonitorRatio(SNES snes,PetscInt its,PetscReal fgnorm,void *dummy) 3083a7fca6bSBarry Smith { 309dfbe8321SBarry Smith PetscErrorCode ierr; 31077431f27SBarry Smith PetscInt len; 31187828ca2SBarry Smith PetscReal *history; 312a6570f20SBarry Smith SNESMonitorRatioContext *ctx = (SNESMonitorRatioContext*)dummy; 3133a7fca6bSBarry Smith 3143a7fca6bSBarry Smith PetscFunctionBegin; 3150298fd71SBarry Smith ierr = SNESGetConvergenceHistory(snes,&history,NULL,&len);CHKERRQ(ierr); 316649052a6SBarry Smith ierr = PetscViewerASCIIAddTab(ctx->viewer,((PetscObject)snes)->tablevel);CHKERRQ(ierr); 317958c9bccSBarry Smith if (!its || !history || its > len) { 318649052a6SBarry Smith ierr = PetscViewerASCIIPrintf(ctx->viewer,"%3D SNES Function norm %14.12e \n",its,(double)fgnorm);CHKERRQ(ierr); 3193a7fca6bSBarry Smith } else { 32087828ca2SBarry Smith PetscReal ratio = fgnorm/history[its-1]; 3218f1a2a5eSBarry Smith ierr = PetscViewerASCIIPrintf(ctx->viewer,"%3D SNES Function norm %14.12e %14.12e \n",its,(double)fgnorm,(double)ratio);CHKERRQ(ierr); 3223a7fca6bSBarry Smith } 323649052a6SBarry Smith ierr = PetscViewerASCIISubtractTab(ctx->viewer,((PetscObject)snes)->tablevel);CHKERRQ(ierr); 3243a7fca6bSBarry Smith PetscFunctionReturn(0); 3253a7fca6bSBarry Smith } 3263a7fca6bSBarry Smith 3273a7fca6bSBarry Smith /* 3283a7fca6bSBarry Smith If the we set the history monitor space then we must destroy it 3293a7fca6bSBarry Smith */ 3303a7fca6bSBarry Smith #undef __FUNCT__ 331a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorRatioDestroy" 332c2efdce3SBarry Smith PetscErrorCode SNESMonitorRatioDestroy(void **ct) 3333a7fca6bSBarry Smith { 334dfbe8321SBarry Smith PetscErrorCode ierr; 335c2efdce3SBarry Smith SNESMonitorRatioContext *ctx = *(SNESMonitorRatioContext**)ct; 3363a7fca6bSBarry Smith 3373a7fca6bSBarry Smith PetscFunctionBegin; 33805b42c5fSBarry Smith ierr = PetscFree(ctx->history);CHKERRQ(ierr); 339649052a6SBarry Smith ierr = PetscViewerDestroy(&ctx->viewer);CHKERRQ(ierr); 340eabae89aSBarry Smith ierr = PetscFree(ctx);CHKERRQ(ierr); 3413a7fca6bSBarry Smith PetscFunctionReturn(0); 3423a7fca6bSBarry Smith } 3433a7fca6bSBarry Smith 3443a7fca6bSBarry Smith #undef __FUNCT__ 345a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorSetRatio" 3463a7fca6bSBarry Smith /*@C 347a6570f20SBarry Smith SNESMonitorSetRatio - Sets SNES to use a monitor that prints the 3484b27c08aSLois Curfman McInnes ratio of the function norm at each iteration. 3493a7fca6bSBarry Smith 3503a7fca6bSBarry Smith Collective on SNES 3513a7fca6bSBarry Smith 3523a7fca6bSBarry Smith Input Parameters: 353eabae89aSBarry Smith + snes - the SNES context 354eabae89aSBarry Smith - viewer - ASCII viewer to print output 3553a7fca6bSBarry Smith 3563a7fca6bSBarry Smith Level: intermediate 3573a7fca6bSBarry Smith 3583a7fca6bSBarry Smith .keywords: SNES, nonlinear, monitor, norm 3593a7fca6bSBarry Smith 360a6570f20SBarry Smith .seealso: SNESMonitorSet(), SNESMonitorSolution(), SNESMonitorDefault() 3613a7fca6bSBarry Smith @*/ 362649052a6SBarry Smith PetscErrorCode SNESMonitorSetRatio(SNES snes,PetscViewer viewer) 3633a7fca6bSBarry Smith { 364dfbe8321SBarry Smith PetscErrorCode ierr; 365a6570f20SBarry Smith SNESMonitorRatioContext *ctx; 36687828ca2SBarry Smith PetscReal *history; 3673a7fca6bSBarry Smith 3683a7fca6bSBarry Smith PetscFunctionBegin; 369eabae89aSBarry Smith if (!viewer) { 370ce94432eSBarry Smith ierr = PetscViewerASCIIOpen(PetscObjectComm((PetscObject)snes),"stdout",&viewer);CHKERRQ(ierr); 371eabae89aSBarry Smith ierr = PetscObjectReference((PetscObject)viewer);CHKERRQ(ierr); 372eabae89aSBarry Smith } 373b00a9115SJed Brown ierr = PetscNewLog(snes,&ctx);CHKERRQ(ierr); 3740298fd71SBarry Smith ierr = SNESGetConvergenceHistory(snes,&history,NULL,NULL);CHKERRQ(ierr); 3753a7fca6bSBarry Smith if (!history) { 376785e854fSJed Brown ierr = PetscMalloc1(100,&ctx->history);CHKERRQ(ierr); 377eabae89aSBarry Smith ierr = SNESSetConvergenceHistory(snes,ctx->history,0,100,PETSC_TRUE);CHKERRQ(ierr); 3783a7fca6bSBarry Smith } 379eabae89aSBarry Smith ctx->viewer = viewer; 380f5af7f23SKarl Rupp 381a6570f20SBarry Smith ierr = SNESMonitorSet(snes,SNESMonitorRatio,ctx,SNESMonitorRatioDestroy);CHKERRQ(ierr); 3823a7fca6bSBarry Smith PetscFunctionReturn(0); 3833a7fca6bSBarry Smith } 3843a7fca6bSBarry Smith 385e7e93795SLois Curfman McInnes /* ---------------------------------------------------------------- */ 3864a2ae208SSatish Balay #undef __FUNCT__ 387a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorDefaultShort" 388be1f7002SBarry Smith /* 389a6570f20SBarry Smith Default (short) SNES Monitor, same as SNESMonitorDefault() except 390be1f7002SBarry Smith it prints fewer digits of the residual as the residual gets smaller. 391be1f7002SBarry Smith This is because the later digits are meaningless and are often 392be1f7002SBarry Smith different on different machines; by using this routine different 393be1f7002SBarry Smith machines will usually generate the same output. 394be1f7002SBarry Smith */ 3957087cfbeSBarry Smith PetscErrorCode SNESMonitorDefaultShort(SNES snes,PetscInt its,PetscReal fgnorm,void *dummy) 396e7e93795SLois Curfman McInnes { 397dfbe8321SBarry Smith PetscErrorCode ierr; 398ce94432eSBarry Smith PetscViewer viewer = dummy ? (PetscViewer) dummy : PETSC_VIEWER_STDOUT_(PetscObjectComm((PetscObject)snes)); 399d132466eSBarry Smith 4003a40ed3dSBarry Smith PetscFunctionBegin; 401649052a6SBarry Smith ierr = PetscViewerASCIIAddTab(viewer,((PetscObject)snes)->tablevel);CHKERRQ(ierr); 4028f240d10SBarry Smith if (fgnorm > 1.e-9) { 4038fa295daSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"%3D SNES Function norm %g \n",its,(double)fgnorm);CHKERRQ(ierr); 4043a40ed3dSBarry Smith } else if (fgnorm > 1.e-11) { 4058fa295daSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"%3D SNES Function norm %5.3e \n",its,(double)fgnorm);CHKERRQ(ierr); 4063a40ed3dSBarry Smith } else { 407649052a6SBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"%3D SNES Function norm < 1.e-11\n",its);CHKERRQ(ierr); 408a34d58ebSBarry Smith } 409649052a6SBarry Smith ierr = PetscViewerASCIISubtractTab(viewer,((PetscObject)snes)->tablevel);CHKERRQ(ierr); 4103a40ed3dSBarry Smith PetscFunctionReturn(0); 411e7e93795SLois Curfman McInnes } 412e7e93795SLois Curfman McInnes /* ---------------------------------------------------------------- */ 4134a2ae208SSatish Balay #undef __FUNCT__ 4148d359177SBarry Smith #define __FUNCT__ "SNESConvergedDefault" 4154b828684SBarry Smith /*@C 4168d359177SBarry Smith SNESConvergedDefault - Convergence test of the solvers for 417f525115eSLois Curfman McInnes systems of nonlinear equations (default). 418e7e93795SLois Curfman McInnes 419c7afd0dbSLois Curfman McInnes Collective on SNES 420c7afd0dbSLois Curfman McInnes 421e7e93795SLois Curfman McInnes Input Parameters: 422c7afd0dbSLois Curfman McInnes + snes - the SNES context 42306ee9f85SBarry Smith . it - the iteration (0 indicates before any Newton steps) 424e7e93795SLois Curfman McInnes . xnorm - 2-norm of current iterate 425c60f73f4SPeter Brune . snorm - 2-norm of current step 4267f3332b4SBarry Smith . fnorm - 2-norm of function at current iterate 427c7afd0dbSLois Curfman McInnes - dummy - unused context 428e7e93795SLois Curfman McInnes 429184914b5SBarry Smith Output Parameter: 430184914b5SBarry Smith . reason - one of 43170441072SBarry Smith $ SNES_CONVERGED_FNORM_ABS - (fnorm < abstol), 432c60f73f4SPeter Brune $ SNES_CONVERGED_SNORM_RELATIVE - (snorm < stol*xnorm), 433184914b5SBarry Smith $ SNES_CONVERGED_FNORM_RELATIVE - (fnorm < rtol*fnorm0), 434184914b5SBarry Smith $ SNES_DIVERGED_FUNCTION_COUNT - (nfct > maxf), 435184914b5SBarry Smith $ SNES_DIVERGED_FNORM_NAN - (fnorm == NaN), 436184914b5SBarry Smith $ SNES_CONVERGED_ITERATING - (otherwise), 437e7e93795SLois Curfman McInnes 438e7e93795SLois Curfman McInnes where 439c7afd0dbSLois Curfman McInnes + maxf - maximum number of function evaluations, 440c7afd0dbSLois Curfman McInnes set with SNESSetTolerances() 441c7afd0dbSLois Curfman McInnes . nfct - number of function evaluations, 44270441072SBarry Smith . abstol - absolute function norm tolerance, 443c7afd0dbSLois Curfman McInnes set with SNESSetTolerances() 444c7afd0dbSLois Curfman McInnes - rtol - relative function norm tolerance, set with SNESSetTolerances() 445fee21e36SBarry Smith 44636851e7fSLois Curfman McInnes Level: intermediate 44736851e7fSLois Curfman McInnes 448e7e93795SLois Curfman McInnes .keywords: SNES, nonlinear, default, converged, convergence 449e7e93795SLois Curfman McInnes 45071f87433Sdalcinl .seealso: SNESSetConvergenceTest() 451e7e93795SLois Curfman McInnes @*/ 4528d359177SBarry Smith PetscErrorCode SNESConvergedDefault(SNES snes,PetscInt it,PetscReal xnorm,PetscReal snorm,PetscReal fnorm,SNESConvergedReason *reason,void *dummy) 453e7e93795SLois Curfman McInnes { 45463ba0a88SBarry Smith PetscErrorCode ierr; 45563ba0a88SBarry Smith 4563a40ed3dSBarry Smith PetscFunctionBegin; 4570700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 4583f149594SLisandro Dalcin PetscValidPointer(reason,6); 4593f149594SLisandro Dalcin 46006ee9f85SBarry Smith *reason = SNES_CONVERGED_ITERATING; 46106ee9f85SBarry Smith 46206ee9f85SBarry Smith if (!it) { 46306ee9f85SBarry Smith /* set parameter for default relative tolerance convergence test */ 46406ee9f85SBarry Smith snes->ttol = fnorm*snes->rtol; 46506ee9f85SBarry Smith } 4668146f6ebSBarry Smith if (PetscIsInfOrNanReal(fnorm)) { 467ae15b995SBarry Smith ierr = PetscInfo(snes,"Failed to converged, function norm is NaN\n");CHKERRQ(ierr); 468184914b5SBarry Smith *reason = SNES_DIVERGED_FNORM_NAN; 46970441072SBarry Smith } else if (fnorm < snes->abstol) { 4708f1a2a5eSBarry Smith ierr = PetscInfo2(snes,"Converged due to function norm %14.12e < %14.12e\n",(double)fnorm,(double)snes->abstol);CHKERRQ(ierr); 471184914b5SBarry Smith *reason = SNES_CONVERGED_FNORM_ABS; 47243e71028SBarry Smith } else if (snes->nfuncs >= snes->max_funcs) { 473ae15b995SBarry Smith ierr = PetscInfo2(snes,"Exceeded maximum number of function evaluations: %D > %D\n",snes->nfuncs,snes->max_funcs);CHKERRQ(ierr); 474184914b5SBarry Smith *reason = SNES_DIVERGED_FUNCTION_COUNT; 47506ee9f85SBarry Smith } 47606ee9f85SBarry Smith 47706ee9f85SBarry Smith if (it && !*reason) { 47806ee9f85SBarry Smith if (fnorm <= snes->ttol) { 4798f1a2a5eSBarry Smith ierr = PetscInfo2(snes,"Converged due to function norm %14.12e < %14.12e (relative tolerance)\n",(double)fnorm,(double)snes->ttol);CHKERRQ(ierr); 48006ee9f85SBarry Smith *reason = SNES_CONVERGED_FNORM_RELATIVE; 481c60f73f4SPeter Brune } else if (snorm < snes->stol*xnorm) { 482c60f73f4SPeter Brune ierr = PetscInfo3(snes,"Converged due to small update length: %14.12e < %14.12e * %14.12e\n",(double)snorm,(double)snes->stol,(double)xnorm);CHKERRQ(ierr); 483c60f73f4SPeter Brune *reason = SNES_CONVERGED_SNORM_RELATIVE; 48406ee9f85SBarry Smith } 485e7e93795SLois Curfman McInnes } 4863a40ed3dSBarry Smith PetscFunctionReturn(0); 487e7e93795SLois Curfman McInnes } 4883f149594SLisandro Dalcin 4893f149594SLisandro Dalcin #undef __FUNCT__ 490e2a6519dSDmitry Karpeev #define __FUNCT__ "SNESConvergedSkip" 4913f149594SLisandro Dalcin /*@C 492e2a6519dSDmitry Karpeev SNESConvergedSkip - Convergence test for SNES that NEVER returns as 4933f149594SLisandro Dalcin converged, UNLESS the maximum number of iteration have been reached. 4943f149594SLisandro Dalcin 4953f9fe445SBarry Smith Logically Collective on SNES 4963f149594SLisandro Dalcin 4973f149594SLisandro Dalcin Input Parameters: 4983f149594SLisandro Dalcin + snes - the SNES context 4993f149594SLisandro Dalcin . it - the iteration (0 indicates before any Newton steps) 5003f149594SLisandro Dalcin . xnorm - 2-norm of current iterate 501c60f73f4SPeter Brune . snorm - 2-norm of current step 5023f149594SLisandro Dalcin . fnorm - 2-norm of function at current iterate 5033f149594SLisandro Dalcin - dummy - unused context 5043f149594SLisandro Dalcin 5053f149594SLisandro Dalcin Output Parameter: 50685385478SLisandro Dalcin . reason - SNES_CONVERGED_ITERATING, SNES_CONVERGED_ITS, or SNES_DIVERGED_FNORM_NAN 5073f149594SLisandro Dalcin 5083f149594SLisandro Dalcin Notes: 5093f149594SLisandro Dalcin Convergence is then declared after a fixed number of iterations have been used. 5103f149594SLisandro Dalcin 5113f149594SLisandro Dalcin Level: advanced 5123f149594SLisandro Dalcin 5133f149594SLisandro Dalcin .keywords: SNES, nonlinear, skip, converged, convergence 5143f149594SLisandro Dalcin 5153f149594SLisandro Dalcin .seealso: SNESSetConvergenceTest() 5163f149594SLisandro Dalcin @*/ 517e2a6519dSDmitry Karpeev PetscErrorCode SNESConvergedSkip(SNES snes,PetscInt it,PetscReal xnorm,PetscReal snorm,PetscReal fnorm,SNESConvergedReason *reason,void *dummy) 5183f149594SLisandro Dalcin { 5193f149594SLisandro Dalcin PetscErrorCode ierr; 5203f149594SLisandro Dalcin 5213f149594SLisandro Dalcin PetscFunctionBegin; 5220700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 5233f149594SLisandro Dalcin PetscValidPointer(reason,6); 5243f149594SLisandro Dalcin 5253f149594SLisandro Dalcin *reason = SNES_CONVERGED_ITERATING; 5263f149594SLisandro Dalcin 5273f149594SLisandro Dalcin if (fnorm != fnorm) { 5283f149594SLisandro Dalcin ierr = PetscInfo(snes,"Failed to converged, function norm is NaN\n");CHKERRQ(ierr); 5293f149594SLisandro Dalcin *reason = SNES_DIVERGED_FNORM_NAN; 5303f149594SLisandro Dalcin } else if (it == snes->max_its) { 5313f149594SLisandro Dalcin *reason = SNES_CONVERGED_ITS; 5323f149594SLisandro Dalcin } 5333f149594SLisandro Dalcin PetscFunctionReturn(0); 5343f149594SLisandro Dalcin } 5353f149594SLisandro Dalcin 53658c9b817SLisandro Dalcin #undef __FUNCT__ 537fa0ddf94SBarry Smith #define __FUNCT__ "SNESSetWorkVecs" 5388d359177SBarry Smith /*@C 539fa0ddf94SBarry Smith SNESSetWorkVecs - Gets a number of work vectors. 54058c9b817SLisandro Dalcin 54158c9b817SLisandro Dalcin Input Parameters: 54258c9b817SLisandro Dalcin . snes - the SNES context 54358c9b817SLisandro Dalcin . nw - number of work vectors to allocate 54458c9b817SLisandro Dalcin 54558c9b817SLisandro Dalcin Level: developer 54658c9b817SLisandro Dalcin 547fa0ddf94SBarry Smith Developers Note: This is PETSC_EXTERN because it may be used by user written plugin SNES implementations 548fa0ddf94SBarry Smith 54998acb6afSMatthew G Knepley @*/ 550fa0ddf94SBarry Smith PetscErrorCode SNESSetWorkVecs(SNES snes,PetscInt nw) 55158c9b817SLisandro Dalcin { 552c5ed8070SMatthew G. Knepley DM dm; 553c5ed8070SMatthew G. Knepley Vec v; 55458c9b817SLisandro Dalcin PetscErrorCode ierr; 55558c9b817SLisandro Dalcin 55658c9b817SLisandro Dalcin PetscFunctionBegin; 55758c9b817SLisandro Dalcin if (snes->work) {ierr = VecDestroyVecs(snes->nwork,&snes->work);CHKERRQ(ierr);} 55858c9b817SLisandro Dalcin snes->nwork = nw; 559f5af7f23SKarl Rupp 560c5ed8070SMatthew G. Knepley ierr = SNESGetDM(snes, &dm);CHKERRQ(ierr); 561c5ed8070SMatthew G. Knepley ierr = DMGetGlobalVector(dm, &v);CHKERRQ(ierr); 562c5ed8070SMatthew G. Knepley ierr = VecDuplicateVecs(v,snes->nwork,&snes->work);CHKERRQ(ierr); 563c5ed8070SMatthew G. Knepley ierr = DMRestoreGlobalVector(dm, &v);CHKERRQ(ierr); 56458c9b817SLisandro Dalcin ierr = PetscLogObjectParents(snes,nw,snes->work);CHKERRQ(ierr); 56558c9b817SLisandro Dalcin PetscFunctionReturn(0); 56658c9b817SLisandro Dalcin } 567