1e7e93795SLois Curfman McInnes 28d359177SBarry Smith #include <petsc-private/snesimpl.h> /*I "petsc-private/snesimpl.h" I*/ 32e7541e6SPeter Brune #include <petscblaslapack.h> 4e7e93795SLois Curfman McInnes 54a2ae208SSatish Balay #undef __FUNCT__ 6a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorSolution" 73f1db9ecSBarry Smith /*@C 8a6570f20SBarry Smith SNESMonitorSolution - 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 170298fd71SBarry Smith - dummy - either a viewer or NULL 183f1db9ecSBarry Smith 1936851e7fSLois Curfman McInnes Level: intermediate 203f1db9ecSBarry Smith 2136851e7fSLois Curfman McInnes .keywords: SNES, nonlinear, vector, monitor, view 223f1db9ecSBarry Smith 23a6570f20SBarry Smith .seealso: SNESMonitorSet(), SNESMonitorDefault(), VecView() 243f1db9ecSBarry Smith @*/ 257087cfbeSBarry Smith PetscErrorCode SNESMonitorSolution(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 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 540298fd71SBarry Smith - dummy - either a viewer or 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 PetscFunctionReturn(0); 775ed2d596SBarry Smith } 785ed2d596SBarry Smith 795ed2d596SBarry Smith #undef __FUNCT__ 80a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorSolutionUpdate" 81d132466eSBarry Smith /*@C 82a6570f20SBarry Smith SNESMonitorSolutionUpdate - Monitors progress of the SNES solvers by calling 83d132466eSBarry Smith VecView() for the UPDATE to the solution at each iteration. 84d132466eSBarry Smith 85d132466eSBarry Smith Collective on SNES 86d132466eSBarry Smith 87d132466eSBarry Smith Input Parameters: 88d132466eSBarry Smith + snes - the SNES context 89d132466eSBarry Smith . its - iteration number 904b27c08aSLois Curfman McInnes . fgnorm - 2-norm of residual 910298fd71SBarry Smith - dummy - either a viewer or NULL 92d132466eSBarry Smith 93d132466eSBarry Smith Level: intermediate 94d132466eSBarry Smith 95d132466eSBarry Smith .keywords: SNES, nonlinear, vector, monitor, view 96d132466eSBarry Smith 97a6570f20SBarry Smith .seealso: SNESMonitorSet(), SNESMonitorDefault(), VecView() 98d132466eSBarry Smith @*/ 997087cfbeSBarry Smith PetscErrorCode SNESMonitorSolutionUpdate(SNES snes,PetscInt its,PetscReal fgnorm,void *dummy) 100d132466eSBarry Smith { 101dfbe8321SBarry Smith PetscErrorCode ierr; 102d132466eSBarry Smith Vec x; 103b0a32e0cSBarry Smith PetscViewer viewer = (PetscViewer) dummy; 104d132466eSBarry Smith 105d132466eSBarry Smith PetscFunctionBegin; 106d132466eSBarry Smith ierr = SNESGetSolutionUpdate(snes,&x);CHKERRQ(ierr); 107d132466eSBarry Smith if (!viewer) { 108d132466eSBarry Smith MPI_Comm comm; 109d132466eSBarry Smith ierr = PetscObjectGetComm((PetscObject)snes,&comm);CHKERRQ(ierr); 110b0a32e0cSBarry Smith viewer = PETSC_VIEWER_DRAW_(comm); 111d132466eSBarry Smith } 112d132466eSBarry Smith ierr = VecView(x,viewer);CHKERRQ(ierr); 113d132466eSBarry Smith PetscFunctionReturn(0); 114d132466eSBarry Smith } 115d132466eSBarry Smith 1164a2ae208SSatish Balay #undef __FUNCT__ 117a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorDefault" 1184b828684SBarry Smith /*@C 119a6570f20SBarry Smith SNESMonitorDefault - Monitors progress of the SNES solvers (default). 120e7e93795SLois Curfman McInnes 121c7afd0dbSLois Curfman McInnes Collective on SNES 122c7afd0dbSLois Curfman McInnes 123e7e93795SLois Curfman McInnes Input Parameters: 124c7afd0dbSLois Curfman McInnes + snes - the SNES context 125e7e93795SLois Curfman McInnes . its - iteration number 1264b27c08aSLois Curfman McInnes . fgnorm - 2-norm of residual 127c7afd0dbSLois Curfman McInnes - dummy - unused context 128fee21e36SBarry Smith 129e7e93795SLois Curfman McInnes Notes: 1304b27c08aSLois Curfman McInnes This routine prints the residual norm at each iteration. 131e7e93795SLois Curfman McInnes 13236851e7fSLois Curfman McInnes Level: intermediate 13336851e7fSLois Curfman McInnes 134e7e93795SLois Curfman McInnes .keywords: SNES, nonlinear, default, monitor, norm 135e7e93795SLois Curfman McInnes 136a6570f20SBarry Smith .seealso: SNESMonitorSet(), SNESMonitorSolution() 137e7e93795SLois Curfman McInnes @*/ 1387087cfbeSBarry Smith PetscErrorCode SNESMonitorDefault(SNES snes,PetscInt its,PetscReal fgnorm,void *dummy) 139e7e93795SLois Curfman McInnes { 140dfbe8321SBarry Smith PetscErrorCode ierr; 141ce94432eSBarry Smith PetscViewer viewer = dummy ? (PetscViewer) dummy : PETSC_VIEWER_STDOUT_(PetscObjectComm((PetscObject)snes)); 142d132466eSBarry Smith 1433a40ed3dSBarry Smith PetscFunctionBegin; 144649052a6SBarry Smith ierr = PetscViewerASCIIAddTab(viewer,((PetscObject)snes)->tablevel);CHKERRQ(ierr); 145649052a6SBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"%3D SNES Function norm %14.12e \n",its,(double)fgnorm);CHKERRQ(ierr); 146649052a6SBarry Smith ierr = PetscViewerASCIISubtractTab(viewer,((PetscObject)snes)->tablevel);CHKERRQ(ierr); 1473a40ed3dSBarry Smith PetscFunctionReturn(0); 148e7e93795SLois Curfman McInnes } 1493f1db9ecSBarry Smith 150b271bb04SBarry Smith #undef __FUNCT__ 1512e7541e6SPeter Brune #define __FUNCT__ "SNESMonitorJacUpdateSpectrum" 152a80ad3e0SBarry Smith PetscErrorCode SNESMonitorJacUpdateSpectrum(SNES snes,PetscInt it,PetscReal fnorm,void *ctx) 153a80ad3e0SBarry Smith { 154196da8b6SPeter Brune #if defined(PETSC_MISSING_LAPACK_GEEV) 155ce94432eSBarry Smith SETERRQ(PetscObjectComm((PetscObject)snes),PETSC_ERR_SUP,"GEEV - Lapack routine is unavailable\nNot able to provide eigen values."); 156196da8b6SPeter Brune #elif defined(PETSC_HAVE_ESSL) 157ce94432eSBarry Smith SETERRQ(PetscObjectComm((PetscObject)snes),PETSC_ERR_SUP,"GEEV - No support for ESSL Lapack Routines"); 158196da8b6SPeter Brune #else 1592e7541e6SPeter Brune Vec X; 1602e7541e6SPeter Brune Mat J,dJ,dJdense; 1612e7541e6SPeter Brune PetscErrorCode ierr; 1622e7541e6SPeter Brune PetscErrorCode (*func)(SNES,Vec,Mat*,Mat*,MatStructure*,void*); 1632e7541e6SPeter Brune PetscInt n,i; 1642e7541e6SPeter Brune PetscBLASInt nb,lwork; 1652e7541e6SPeter Brune PetscReal *eigr,*eigi; 1662e7541e6SPeter Brune MatStructure flg = DIFFERENT_NONZERO_PATTERN; 1672e7541e6SPeter Brune PetscScalar *work; 1682e7541e6SPeter Brune PetscScalar *a; 1692e7541e6SPeter Brune 1702e7541e6SPeter Brune PetscFunctionBegin; 1712e7541e6SPeter Brune if (it == 0) PetscFunctionReturn(0); 1722e7541e6SPeter Brune /* create the difference between the current update and the current jacobian */ 1732e7541e6SPeter Brune ierr = SNESGetSolution(snes,&X);CHKERRQ(ierr); 1740298fd71SBarry Smith ierr = SNESGetJacobian(snes,&J,NULL,&func,NULL);CHKERRQ(ierr); 1752e7541e6SPeter Brune ierr = MatDuplicate(J,MAT_COPY_VALUES,&dJ);CHKERRQ(ierr); 1762e7541e6SPeter Brune ierr = SNESComputeJacobian(snes,X,&dJ,&dJ,&flg);CHKERRQ(ierr); 1772e7541e6SPeter Brune ierr = MatAXPY(dJ,-1.0,J,SAME_NONZERO_PATTERN);CHKERRQ(ierr); 178f5af7f23SKarl Rupp 1792e7541e6SPeter Brune /* compute the spectrum directly */ 1802e7541e6SPeter Brune ierr = MatConvert(dJ,MATSEQDENSE,MAT_INITIAL_MATRIX,&dJdense);CHKERRQ(ierr); 1810298fd71SBarry Smith ierr = MatGetSize(dJ,&n,NULL);CHKERRQ(ierr); 182c5df96a5SBarry Smith ierr = PetscBLASIntCast(n,&nb);CHKERRQ(ierr); 1832e7541e6SPeter Brune lwork = 3*nb; 1842e7541e6SPeter Brune ierr = PetscMalloc(n*sizeof(PetscReal),&eigr);CHKERRQ(ierr); 1852e7541e6SPeter Brune ierr = PetscMalloc(n*sizeof(PetscReal),&eigi);CHKERRQ(ierr); 1862e7541e6SPeter Brune ierr = PetscMalloc(lwork*sizeof(PetscScalar),&work);CHKERRQ(ierr); 1878c778c55SBarry Smith ierr = MatDenseGetArray(dJdense,&a);CHKERRQ(ierr); 1882e7541e6SPeter Brune #if !defined(PETSC_USE_COMPLEX) 1892e7541e6SPeter Brune { 1902e7541e6SPeter Brune PetscBLASInt lierr; 1912e7541e6SPeter Brune ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 192*8b83055fSJed Brown PetscStackCallBLAS("LAPACKgeev",LAPACKgeev_("N","N",&nb,a,&nb,eigr,eigi,NULL,&nb,NULL,&nb,work,&lwork,&lierr)); 1932e7541e6SPeter Brune if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"geev() error %d",lierr); 1942e7541e6SPeter Brune ierr = PetscFPTrapPop();CHKERRQ(ierr); 1952e7541e6SPeter Brune } 1962e7541e6SPeter Brune #else 1972e7541e6SPeter Brune SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not coded for complex"); 1982e7541e6SPeter Brune #endif 199ce94432eSBarry Smith PetscPrintf(PetscObjectComm((PetscObject)snes),"Eigenvalues of J_%d - J_%d:\n",it,it-1);CHKERRQ(ierr); 2002e7541e6SPeter Brune for (i=0;i<n;i++) { 201ce94432eSBarry Smith PetscPrintf(PetscObjectComm((PetscObject)snes),"%5d: %20.5g + %20.5gi\n",i,eigr[i],eigi[i]);CHKERRQ(ierr); 2022e7541e6SPeter Brune } 2038c778c55SBarry Smith ierr = MatDenseRestoreArray(dJdense,&a);CHKERRQ(ierr); 2042e7541e6SPeter Brune ierr = MatDestroy(&dJ);CHKERRQ(ierr); 2052e7541e6SPeter Brune ierr = MatDestroy(&dJdense);CHKERRQ(ierr); 2062e7541e6SPeter Brune ierr = PetscFree(eigr);CHKERRQ(ierr); 2072e7541e6SPeter Brune ierr = PetscFree(eigi);CHKERRQ(ierr); 2082e7541e6SPeter Brune ierr = PetscFree(work);CHKERRQ(ierr); 2092e7541e6SPeter Brune PetscFunctionReturn(0); 210196da8b6SPeter Brune #endif 2112e7541e6SPeter Brune } 2122e7541e6SPeter Brune 2132e7541e6SPeter Brune #undef __FUNCT__ 214b271bb04SBarry Smith #define __FUNCT__ "SNESMonitorRange_Private" 2157087cfbeSBarry Smith PetscErrorCode SNESMonitorRange_Private(SNES snes,PetscInt it,PetscReal *per) 216b271bb04SBarry Smith { 217b271bb04SBarry Smith PetscErrorCode ierr; 218b271bb04SBarry Smith Vec resid; 219b271bb04SBarry Smith PetscReal rmax,pwork; 220b271bb04SBarry Smith PetscInt i,n,N; 221b271bb04SBarry Smith PetscScalar *r; 222b271bb04SBarry Smith 223b271bb04SBarry Smith PetscFunctionBegin; 224b271bb04SBarry Smith ierr = SNESGetFunction(snes,&resid,0,0);CHKERRQ(ierr); 225b271bb04SBarry Smith ierr = VecNorm(resid,NORM_INFINITY,&rmax);CHKERRQ(ierr); 226b271bb04SBarry Smith ierr = VecGetLocalSize(resid,&n);CHKERRQ(ierr); 227b271bb04SBarry Smith ierr = VecGetSize(resid,&N);CHKERRQ(ierr); 228b271bb04SBarry Smith ierr = VecGetArray(resid,&r);CHKERRQ(ierr); 229b271bb04SBarry Smith pwork = 0.0; 230b271bb04SBarry Smith for (i=0; i<n; i++) { 231b271bb04SBarry Smith pwork += (PetscAbsScalar(r[i]) > .20*rmax); 232b271bb04SBarry Smith } 233ce94432eSBarry Smith ierr = MPI_Allreduce(&pwork,per,1,MPIU_REAL,MPIU_SUM,PetscObjectComm((PetscObject)snes));CHKERRQ(ierr); 234b271bb04SBarry Smith ierr = VecRestoreArray(resid,&r);CHKERRQ(ierr); 235b271bb04SBarry Smith *per = *per/N; 236b271bb04SBarry Smith PetscFunctionReturn(0); 237b271bb04SBarry Smith } 238b271bb04SBarry Smith 239b271bb04SBarry Smith #undef __FUNCT__ 240b271bb04SBarry Smith #define __FUNCT__ "SNESMonitorRange" 241b271bb04SBarry Smith /*@C 242b271bb04SBarry Smith SNESMonitorRange - Prints the percentage of residual elements that are more then 10 percent of the maximum value. 243b271bb04SBarry Smith 244b271bb04SBarry Smith Collective on SNES 245b271bb04SBarry Smith 246b271bb04SBarry Smith Input Parameters: 247b271bb04SBarry Smith + snes - iterative context 248b271bb04SBarry Smith . it - iteration number 249b271bb04SBarry Smith . rnorm - 2-norm (preconditioned) residual value (may be estimated). 250b271bb04SBarry Smith - dummy - unused monitor context 251b271bb04SBarry Smith 252b271bb04SBarry Smith Options Database Key: 253b271bb04SBarry Smith . -snes_monitor_range - Activates SNESMonitorRange() 254b271bb04SBarry Smith 255b271bb04SBarry Smith Level: intermediate 256b271bb04SBarry Smith 257b271bb04SBarry Smith .keywords: SNES, default, monitor, residual 258b271bb04SBarry Smith 259b271bb04SBarry Smith .seealso: SNESMonitorSet(), SNESMonitorDefault(), SNESMonitorLGCreate() 260b271bb04SBarry Smith @*/ 2617087cfbeSBarry Smith PetscErrorCode SNESMonitorRange(SNES snes,PetscInt it,PetscReal rnorm,void *dummy) 262b271bb04SBarry Smith { 263b271bb04SBarry Smith PetscErrorCode ierr; 264b271bb04SBarry Smith PetscReal perc,rel; 265ce94432eSBarry Smith PetscViewer viewer = dummy ? (PetscViewer) dummy : PETSC_VIEWER_STDOUT_(PetscObjectComm((PetscObject)snes)); 266b271bb04SBarry Smith /* should be in a MonitorRangeContext */ 267b271bb04SBarry Smith static PetscReal prev; 268b271bb04SBarry Smith 269b271bb04SBarry Smith PetscFunctionBegin; 270b271bb04SBarry Smith if (!it) prev = rnorm; 271b271bb04SBarry Smith ierr = SNESMonitorRange_Private(snes,it,&perc);CHKERRQ(ierr); 272b271bb04SBarry Smith 273b271bb04SBarry Smith rel = (prev - rnorm)/prev; 274b271bb04SBarry Smith prev = rnorm; 275649052a6SBarry Smith ierr = PetscViewerASCIIAddTab(viewer,((PetscObject)snes)->tablevel);CHKERRQ(ierr); 276649052a6SBarry 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); 277649052a6SBarry Smith ierr = PetscViewerASCIISubtractTab(viewer,((PetscObject)snes)->tablevel);CHKERRQ(ierr); 278b271bb04SBarry Smith PetscFunctionReturn(0); 279b271bb04SBarry Smith } 280b271bb04SBarry Smith 281eabae89aSBarry Smith typedef struct { 282649052a6SBarry Smith PetscViewer viewer; 283eabae89aSBarry Smith PetscReal *history; 284a6570f20SBarry Smith } SNESMonitorRatioContext; 285eabae89aSBarry Smith 2863a7fca6bSBarry Smith #undef __FUNCT__ 287a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorRatio" 2883a7fca6bSBarry Smith /*@C 289a6570f20SBarry Smith SNESMonitorRatio - Monitors progress of the SNES solvers by printing the ratio 2904b27c08aSLois Curfman McInnes of residual norm at each iteration to the previous. 2913a7fca6bSBarry Smith 2923a7fca6bSBarry Smith Collective on SNES 2933a7fca6bSBarry Smith 2943a7fca6bSBarry Smith Input Parameters: 2953a7fca6bSBarry Smith + snes - the SNES context 2963a7fca6bSBarry Smith . its - iteration number 2973a7fca6bSBarry Smith . fgnorm - 2-norm of residual (or gradient) 298eabae89aSBarry Smith - dummy - context of monitor 2993a7fca6bSBarry Smith 3003a7fca6bSBarry Smith Level: intermediate 3013a7fca6bSBarry Smith 3023a7fca6bSBarry Smith .keywords: SNES, nonlinear, monitor, norm 3033a7fca6bSBarry Smith 304a6570f20SBarry Smith .seealso: SNESMonitorSet(), SNESMonitorSolution() 3053a7fca6bSBarry Smith @*/ 3067087cfbeSBarry Smith PetscErrorCode SNESMonitorRatio(SNES snes,PetscInt its,PetscReal fgnorm,void *dummy) 3073a7fca6bSBarry Smith { 308dfbe8321SBarry Smith PetscErrorCode ierr; 30977431f27SBarry Smith PetscInt len; 31087828ca2SBarry Smith PetscReal *history; 311a6570f20SBarry Smith SNESMonitorRatioContext *ctx = (SNESMonitorRatioContext*)dummy; 3123a7fca6bSBarry Smith 3133a7fca6bSBarry Smith PetscFunctionBegin; 3140298fd71SBarry Smith ierr = SNESGetConvergenceHistory(snes,&history,NULL,&len);CHKERRQ(ierr); 315649052a6SBarry Smith ierr = PetscViewerASCIIAddTab(ctx->viewer,((PetscObject)snes)->tablevel);CHKERRQ(ierr); 316958c9bccSBarry Smith if (!its || !history || its > len) { 317649052a6SBarry Smith ierr = PetscViewerASCIIPrintf(ctx->viewer,"%3D SNES Function norm %14.12e \n",its,(double)fgnorm);CHKERRQ(ierr); 3183a7fca6bSBarry Smith } else { 31987828ca2SBarry Smith PetscReal ratio = fgnorm/history[its-1]; 3208f1a2a5eSBarry Smith ierr = PetscViewerASCIIPrintf(ctx->viewer,"%3D SNES Function norm %14.12e %14.12e \n",its,(double)fgnorm,(double)ratio);CHKERRQ(ierr); 3213a7fca6bSBarry Smith } 322649052a6SBarry Smith ierr = PetscViewerASCIISubtractTab(ctx->viewer,((PetscObject)snes)->tablevel);CHKERRQ(ierr); 3233a7fca6bSBarry Smith PetscFunctionReturn(0); 3243a7fca6bSBarry Smith } 3253a7fca6bSBarry Smith 3263a7fca6bSBarry Smith /* 3273a7fca6bSBarry Smith If the we set the history monitor space then we must destroy it 3283a7fca6bSBarry Smith */ 3293a7fca6bSBarry Smith #undef __FUNCT__ 330a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorRatioDestroy" 331c2efdce3SBarry Smith PetscErrorCode SNESMonitorRatioDestroy(void **ct) 3323a7fca6bSBarry Smith { 333dfbe8321SBarry Smith PetscErrorCode ierr; 334c2efdce3SBarry Smith SNESMonitorRatioContext *ctx = *(SNESMonitorRatioContext**)ct; 3353a7fca6bSBarry Smith 3363a7fca6bSBarry Smith PetscFunctionBegin; 33705b42c5fSBarry Smith ierr = PetscFree(ctx->history);CHKERRQ(ierr); 338649052a6SBarry Smith ierr = PetscViewerDestroy(&ctx->viewer);CHKERRQ(ierr); 339eabae89aSBarry Smith ierr = PetscFree(ctx);CHKERRQ(ierr); 3403a7fca6bSBarry Smith PetscFunctionReturn(0); 3413a7fca6bSBarry Smith } 3423a7fca6bSBarry Smith 3433a7fca6bSBarry Smith #undef __FUNCT__ 344a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorSetRatio" 3453a7fca6bSBarry Smith /*@C 346a6570f20SBarry Smith SNESMonitorSetRatio - Sets SNES to use a monitor that prints the 3474b27c08aSLois Curfman McInnes ratio of the function norm at each iteration. 3483a7fca6bSBarry Smith 3493a7fca6bSBarry Smith Collective on SNES 3503a7fca6bSBarry Smith 3513a7fca6bSBarry Smith Input Parameters: 352eabae89aSBarry Smith + snes - the SNES context 353eabae89aSBarry Smith - viewer - ASCII viewer to print output 3543a7fca6bSBarry Smith 3553a7fca6bSBarry Smith Level: intermediate 3563a7fca6bSBarry Smith 3573a7fca6bSBarry Smith .keywords: SNES, nonlinear, monitor, norm 3583a7fca6bSBarry Smith 359a6570f20SBarry Smith .seealso: SNESMonitorSet(), SNESMonitorSolution(), SNESMonitorDefault() 3603a7fca6bSBarry Smith @*/ 361649052a6SBarry Smith PetscErrorCode SNESMonitorSetRatio(SNES snes,PetscViewer viewer) 3623a7fca6bSBarry Smith { 363dfbe8321SBarry Smith PetscErrorCode ierr; 364a6570f20SBarry Smith SNESMonitorRatioContext *ctx; 36587828ca2SBarry Smith PetscReal *history; 3663a7fca6bSBarry Smith 3673a7fca6bSBarry Smith PetscFunctionBegin; 368eabae89aSBarry Smith if (!viewer) { 369ce94432eSBarry Smith ierr = PetscViewerASCIIOpen(PetscObjectComm((PetscObject)snes),"stdout",&viewer);CHKERRQ(ierr); 370eabae89aSBarry Smith ierr = PetscObjectReference((PetscObject)viewer);CHKERRQ(ierr); 371eabae89aSBarry Smith } 37222d28d08SBarry Smith ierr = PetscNewLog(snes,SNESMonitorRatioContext,&ctx);CHKERRQ(ierr); 3730298fd71SBarry Smith ierr = SNESGetConvergenceHistory(snes,&history,NULL,NULL);CHKERRQ(ierr); 3743a7fca6bSBarry Smith if (!history) { 375eabae89aSBarry Smith ierr = PetscMalloc(100*sizeof(PetscReal),&ctx->history);CHKERRQ(ierr); 376eabae89aSBarry Smith ierr = SNESSetConvergenceHistory(snes,ctx->history,0,100,PETSC_TRUE);CHKERRQ(ierr); 3773a7fca6bSBarry Smith } 378eabae89aSBarry Smith ctx->viewer = viewer; 379f5af7f23SKarl Rupp 380a6570f20SBarry Smith ierr = SNESMonitorSet(snes,SNESMonitorRatio,ctx,SNESMonitorRatioDestroy);CHKERRQ(ierr); 3813a7fca6bSBarry Smith PetscFunctionReturn(0); 3823a7fca6bSBarry Smith } 3833a7fca6bSBarry Smith 384e7e93795SLois Curfman McInnes /* ---------------------------------------------------------------- */ 3854a2ae208SSatish Balay #undef __FUNCT__ 386a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorDefaultShort" 387be1f7002SBarry Smith /* 388a6570f20SBarry Smith Default (short) SNES Monitor, same as SNESMonitorDefault() except 389be1f7002SBarry Smith it prints fewer digits of the residual as the residual gets smaller. 390be1f7002SBarry Smith This is because the later digits are meaningless and are often 391be1f7002SBarry Smith different on different machines; by using this routine different 392be1f7002SBarry Smith machines will usually generate the same output. 393be1f7002SBarry Smith */ 3947087cfbeSBarry Smith PetscErrorCode SNESMonitorDefaultShort(SNES snes,PetscInt its,PetscReal fgnorm,void *dummy) 395e7e93795SLois Curfman McInnes { 396dfbe8321SBarry Smith PetscErrorCode ierr; 397ce94432eSBarry Smith PetscViewer viewer = dummy ? (PetscViewer) dummy : PETSC_VIEWER_STDOUT_(PetscObjectComm((PetscObject)snes)); 398d132466eSBarry Smith 3993a40ed3dSBarry Smith PetscFunctionBegin; 400649052a6SBarry Smith ierr = PetscViewerASCIIAddTab(viewer,((PetscObject)snes)->tablevel);CHKERRQ(ierr); 4018f240d10SBarry Smith if (fgnorm > 1.e-9) { 402649052a6SBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"%3D SNES Function norm %G \n",its,fgnorm);CHKERRQ(ierr); 4033a40ed3dSBarry Smith } else if (fgnorm > 1.e-11) { 404649052a6SBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"%3D SNES Function norm %5.3e \n",its,fgnorm);CHKERRQ(ierr); 4053a40ed3dSBarry Smith } else { 406649052a6SBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"%3D SNES Function norm < 1.e-11\n",its);CHKERRQ(ierr); 407a34d58ebSBarry Smith } 408649052a6SBarry Smith ierr = PetscViewerASCIISubtractTab(viewer,((PetscObject)snes)->tablevel);CHKERRQ(ierr); 4093a40ed3dSBarry Smith PetscFunctionReturn(0); 410e7e93795SLois Curfman McInnes } 411e7e93795SLois Curfman McInnes /* ---------------------------------------------------------------- */ 4124a2ae208SSatish Balay #undef __FUNCT__ 4138d359177SBarry Smith #define __FUNCT__ "SNESConvergedDefault" 4144b828684SBarry Smith /*@C 4158d359177SBarry Smith SNESConvergedDefault - Convergence test of the solvers for 416f525115eSLois Curfman McInnes systems of nonlinear equations (default). 417e7e93795SLois Curfman McInnes 418c7afd0dbSLois Curfman McInnes Collective on SNES 419c7afd0dbSLois Curfman McInnes 420e7e93795SLois Curfman McInnes Input Parameters: 421c7afd0dbSLois Curfman McInnes + snes - the SNES context 42206ee9f85SBarry Smith . it - the iteration (0 indicates before any Newton steps) 423e7e93795SLois Curfman McInnes . xnorm - 2-norm of current iterate 424c60f73f4SPeter Brune . snorm - 2-norm of current step 4257f3332b4SBarry Smith . fnorm - 2-norm of function at current iterate 426c7afd0dbSLois Curfman McInnes - dummy - unused context 427e7e93795SLois Curfman McInnes 428184914b5SBarry Smith Output Parameter: 429184914b5SBarry Smith . reason - one of 43070441072SBarry Smith $ SNES_CONVERGED_FNORM_ABS - (fnorm < abstol), 431c60f73f4SPeter Brune $ SNES_CONVERGED_SNORM_RELATIVE - (snorm < stol*xnorm), 432184914b5SBarry Smith $ SNES_CONVERGED_FNORM_RELATIVE - (fnorm < rtol*fnorm0), 433184914b5SBarry Smith $ SNES_DIVERGED_FUNCTION_COUNT - (nfct > maxf), 434184914b5SBarry Smith $ SNES_DIVERGED_FNORM_NAN - (fnorm == NaN), 435184914b5SBarry Smith $ SNES_CONVERGED_ITERATING - (otherwise), 436e7e93795SLois Curfman McInnes 437e7e93795SLois Curfman McInnes where 438c7afd0dbSLois Curfman McInnes + maxf - maximum number of function evaluations, 439c7afd0dbSLois Curfman McInnes set with SNESSetTolerances() 440c7afd0dbSLois Curfman McInnes . nfct - number of function evaluations, 44170441072SBarry Smith . abstol - absolute function norm tolerance, 442c7afd0dbSLois Curfman McInnes set with SNESSetTolerances() 443c7afd0dbSLois Curfman McInnes - rtol - relative function norm tolerance, set with SNESSetTolerances() 444fee21e36SBarry Smith 44536851e7fSLois Curfman McInnes Level: intermediate 44636851e7fSLois Curfman McInnes 447e7e93795SLois Curfman McInnes .keywords: SNES, nonlinear, default, converged, convergence 448e7e93795SLois Curfman McInnes 44971f87433Sdalcinl .seealso: SNESSetConvergenceTest() 450e7e93795SLois Curfman McInnes @*/ 4518d359177SBarry Smith PetscErrorCode SNESConvergedDefault(SNES snes,PetscInt it,PetscReal xnorm,PetscReal snorm,PetscReal fnorm,SNESConvergedReason *reason,void *dummy) 452e7e93795SLois Curfman McInnes { 45363ba0a88SBarry Smith PetscErrorCode ierr; 45463ba0a88SBarry Smith 4553a40ed3dSBarry Smith PetscFunctionBegin; 4560700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 4573f149594SLisandro Dalcin PetscValidPointer(reason,6); 4583f149594SLisandro Dalcin 45906ee9f85SBarry Smith *reason = SNES_CONVERGED_ITERATING; 46006ee9f85SBarry Smith 46106ee9f85SBarry Smith if (!it) { 46206ee9f85SBarry Smith /* set parameter for default relative tolerance convergence test */ 46306ee9f85SBarry Smith snes->ttol = fnorm*snes->rtol; 46406ee9f85SBarry Smith } 4658146f6ebSBarry Smith if (PetscIsInfOrNanReal(fnorm)) { 466ae15b995SBarry Smith ierr = PetscInfo(snes,"Failed to converged, function norm is NaN\n");CHKERRQ(ierr); 467184914b5SBarry Smith *reason = SNES_DIVERGED_FNORM_NAN; 46870441072SBarry Smith } else if (fnorm < snes->abstol) { 4698f1a2a5eSBarry Smith ierr = PetscInfo2(snes,"Converged due to function norm %14.12e < %14.12e\n",(double)fnorm,(double)snes->abstol);CHKERRQ(ierr); 470184914b5SBarry Smith *reason = SNES_CONVERGED_FNORM_ABS; 47143e71028SBarry Smith } else if (snes->nfuncs >= snes->max_funcs) { 472ae15b995SBarry Smith ierr = PetscInfo2(snes,"Exceeded maximum number of function evaluations: %D > %D\n",snes->nfuncs,snes->max_funcs);CHKERRQ(ierr); 473184914b5SBarry Smith *reason = SNES_DIVERGED_FUNCTION_COUNT; 47406ee9f85SBarry Smith } 47506ee9f85SBarry Smith 47606ee9f85SBarry Smith if (it && !*reason) { 47706ee9f85SBarry Smith if (fnorm <= snes->ttol) { 4788f1a2a5eSBarry Smith ierr = PetscInfo2(snes,"Converged due to function norm %14.12e < %14.12e (relative tolerance)\n",(double)fnorm,(double)snes->ttol);CHKERRQ(ierr); 47906ee9f85SBarry Smith *reason = SNES_CONVERGED_FNORM_RELATIVE; 480c60f73f4SPeter Brune } else if (snorm < snes->stol*xnorm) { 481c60f73f4SPeter 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); 482c60f73f4SPeter Brune *reason = SNES_CONVERGED_SNORM_RELATIVE; 48306ee9f85SBarry Smith } 484e7e93795SLois Curfman McInnes } 4853a40ed3dSBarry Smith PetscFunctionReturn(0); 486e7e93795SLois Curfman McInnes } 4873f149594SLisandro Dalcin 4883f149594SLisandro Dalcin #undef __FUNCT__ 4893f149594SLisandro Dalcin #define __FUNCT__ "SNESSkipConverged" 4903f149594SLisandro Dalcin /*@C 4913f149594SLisandro Dalcin SNESSkipConverged - Convergence test for SNES that NEVER returns as 4923f149594SLisandro Dalcin converged, UNLESS the maximum number of iteration have been reached. 4933f149594SLisandro Dalcin 4943f9fe445SBarry Smith Logically Collective on SNES 4953f149594SLisandro Dalcin 4963f149594SLisandro Dalcin Input Parameters: 4973f149594SLisandro Dalcin + snes - the SNES context 4983f149594SLisandro Dalcin . it - the iteration (0 indicates before any Newton steps) 4993f149594SLisandro Dalcin . xnorm - 2-norm of current iterate 500c60f73f4SPeter Brune . snorm - 2-norm of current step 5013f149594SLisandro Dalcin . fnorm - 2-norm of function at current iterate 5023f149594SLisandro Dalcin - dummy - unused context 5033f149594SLisandro Dalcin 5043f149594SLisandro Dalcin Output Parameter: 50585385478SLisandro Dalcin . reason - SNES_CONVERGED_ITERATING, SNES_CONVERGED_ITS, or SNES_DIVERGED_FNORM_NAN 5063f149594SLisandro Dalcin 5073f149594SLisandro Dalcin Notes: 5083f149594SLisandro Dalcin Convergence is then declared after a fixed number of iterations have been used. 5093f149594SLisandro Dalcin 5103f149594SLisandro Dalcin Level: advanced 5113f149594SLisandro Dalcin 5123f149594SLisandro Dalcin .keywords: SNES, nonlinear, skip, converged, convergence 5133f149594SLisandro Dalcin 5143f149594SLisandro Dalcin .seealso: SNESSetConvergenceTest() 5153f149594SLisandro Dalcin @*/ 516c60f73f4SPeter Brune PetscErrorCode SNESSkipConverged(SNES snes,PetscInt it,PetscReal xnorm,PetscReal snorm,PetscReal fnorm,SNESConvergedReason *reason,void *dummy) 5173f149594SLisandro Dalcin { 5183f149594SLisandro Dalcin PetscErrorCode ierr; 5193f149594SLisandro Dalcin 5203f149594SLisandro Dalcin PetscFunctionBegin; 5210700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 5223f149594SLisandro Dalcin PetscValidPointer(reason,6); 5233f149594SLisandro Dalcin 5243f149594SLisandro Dalcin *reason = SNES_CONVERGED_ITERATING; 5253f149594SLisandro Dalcin 5263f149594SLisandro Dalcin if (fnorm != fnorm) { 5273f149594SLisandro Dalcin ierr = PetscInfo(snes,"Failed to converged, function norm is NaN\n");CHKERRQ(ierr); 5283f149594SLisandro Dalcin *reason = SNES_DIVERGED_FNORM_NAN; 5293f149594SLisandro Dalcin } else if (it == snes->max_its) { 5303f149594SLisandro Dalcin *reason = SNES_CONVERGED_ITS; 5313f149594SLisandro Dalcin } 5323f149594SLisandro Dalcin PetscFunctionReturn(0); 5333f149594SLisandro Dalcin } 5343f149594SLisandro Dalcin 53558c9b817SLisandro Dalcin #undef __FUNCT__ 536fa0ddf94SBarry Smith #define __FUNCT__ "SNESSetWorkVecs" 5378d359177SBarry Smith /*@C 538fa0ddf94SBarry Smith SNESSetWorkVecs - Gets a number of work vectors. 53958c9b817SLisandro Dalcin 54058c9b817SLisandro Dalcin Input Parameters: 54158c9b817SLisandro Dalcin . snes - the SNES context 54258c9b817SLisandro Dalcin . nw - number of work vectors to allocate 54358c9b817SLisandro Dalcin 54458c9b817SLisandro Dalcin Level: developer 54558c9b817SLisandro Dalcin 546fa0ddf94SBarry Smith Developers Note: This is PETSC_EXTERN because it may be used by user written plugin SNES implementations 547fa0ddf94SBarry Smith 54898acb6afSMatthew G Knepley @*/ 549fa0ddf94SBarry Smith PetscErrorCode SNESSetWorkVecs(SNES snes,PetscInt nw) 55058c9b817SLisandro Dalcin { 55158c9b817SLisandro Dalcin PetscErrorCode ierr; 55258c9b817SLisandro Dalcin 55358c9b817SLisandro Dalcin PetscFunctionBegin; 55458c9b817SLisandro Dalcin if (snes->work) {ierr = VecDestroyVecs(snes->nwork,&snes->work);CHKERRQ(ierr);} 55558c9b817SLisandro Dalcin snes->nwork = nw; 556f5af7f23SKarl Rupp 55758c9b817SLisandro Dalcin ierr = VecDuplicateVecs(snes->vec_sol,snes->nwork,&snes->work);CHKERRQ(ierr); 55858c9b817SLisandro Dalcin ierr = PetscLogObjectParents(snes,nw,snes->work);CHKERRQ(ierr); 55958c9b817SLisandro Dalcin PetscFunctionReturn(0); 56058c9b817SLisandro Dalcin } 561