1e7e93795SLois Curfman McInnes 2af0996ceSBarry 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 18*f55353a2SBarry Smith - dummy - a viewer 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 ierr = VecView(x,viewer);CHKERRQ(ierr); 353f1db9ecSBarry Smith PetscFunctionReturn(0); 363f1db9ecSBarry Smith } 373f1db9ecSBarry Smith 384a2ae208SSatish Balay #undef __FUNCT__ 39a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorResidual" 405ed2d596SBarry Smith /*@C 41a6570f20SBarry Smith SNESMonitorResidual - Monitors progress of the SNES solvers by calling 425ed2d596SBarry Smith VecView() for the residual at each iteration. 435ed2d596SBarry Smith 445ed2d596SBarry Smith Collective on SNES 455ed2d596SBarry Smith 465ed2d596SBarry Smith Input Parameters: 475ed2d596SBarry Smith + snes - the SNES context 485ed2d596SBarry Smith . its - iteration number 494b27c08aSLois Curfman McInnes . fgnorm - 2-norm of residual 50*f55353a2SBarry Smith - dummy - a viewer 515ed2d596SBarry Smith 525ed2d596SBarry Smith Level: intermediate 535ed2d596SBarry Smith 545ed2d596SBarry Smith .keywords: SNES, nonlinear, vector, monitor, view 555ed2d596SBarry Smith 56a6570f20SBarry Smith .seealso: SNESMonitorSet(), SNESMonitorDefault(), VecView() 575ed2d596SBarry Smith @*/ 587087cfbeSBarry Smith PetscErrorCode SNESMonitorResidual(SNES snes,PetscInt its,PetscReal fgnorm,void *dummy) 595ed2d596SBarry Smith { 60dfbe8321SBarry Smith PetscErrorCode ierr; 615ed2d596SBarry Smith Vec x; 625ed2d596SBarry Smith PetscViewer viewer = (PetscViewer) dummy; 635ed2d596SBarry Smith 645ed2d596SBarry Smith PetscFunctionBegin; 655ed2d596SBarry Smith ierr = SNESGetFunction(snes,&x,0,0);CHKERRQ(ierr); 665ed2d596SBarry Smith ierr = VecView(x,viewer);CHKERRQ(ierr); 675ed2d596SBarry Smith PetscFunctionReturn(0); 685ed2d596SBarry Smith } 695ed2d596SBarry Smith 705ed2d596SBarry Smith #undef __FUNCT__ 71a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorSolutionUpdate" 72d132466eSBarry Smith /*@C 73a6570f20SBarry Smith SNESMonitorSolutionUpdate - Monitors progress of the SNES solvers by calling 74d132466eSBarry Smith VecView() for the UPDATE to the solution at each iteration. 75d132466eSBarry Smith 76d132466eSBarry Smith Collective on SNES 77d132466eSBarry Smith 78d132466eSBarry Smith Input Parameters: 79d132466eSBarry Smith + snes - the SNES context 80d132466eSBarry Smith . its - iteration number 814b27c08aSLois Curfman McInnes . fgnorm - 2-norm of residual 82*f55353a2SBarry Smith - dummy - a viewer 83d132466eSBarry Smith 84d132466eSBarry Smith Level: intermediate 85d132466eSBarry Smith 86d132466eSBarry Smith .keywords: SNES, nonlinear, vector, monitor, view 87d132466eSBarry Smith 88a6570f20SBarry Smith .seealso: SNESMonitorSet(), SNESMonitorDefault(), VecView() 89d132466eSBarry Smith @*/ 907087cfbeSBarry Smith PetscErrorCode SNESMonitorSolutionUpdate(SNES snes,PetscInt its,PetscReal fgnorm,void *dummy) 91d132466eSBarry Smith { 92dfbe8321SBarry Smith PetscErrorCode ierr; 93d132466eSBarry Smith Vec x; 94b0a32e0cSBarry Smith PetscViewer viewer = (PetscViewer) dummy; 95d132466eSBarry Smith 96d132466eSBarry Smith PetscFunctionBegin; 97d132466eSBarry Smith ierr = SNESGetSolutionUpdate(snes,&x);CHKERRQ(ierr); 98d132466eSBarry Smith ierr = VecView(x,viewer);CHKERRQ(ierr); 99d132466eSBarry Smith PetscFunctionReturn(0); 100d132466eSBarry Smith } 101d132466eSBarry Smith 1024a2ae208SSatish Balay #undef __FUNCT__ 103a5c2985bSBarry Smith #define __FUNCT__ "KSPMonitorSNES" 104a5c2985bSBarry Smith /*@C 105a5c2985bSBarry Smith KSPMonitorSNES - Print the residual norm of the nonlinear function at each iteration of the linear iterative solver. 106a5c2985bSBarry Smith 107a5c2985bSBarry Smith Collective on KSP 108a5c2985bSBarry Smith 109a5c2985bSBarry Smith Input Parameters: 110a5c2985bSBarry Smith + ksp - iterative context 111a5c2985bSBarry Smith . n - iteration number 112a5c2985bSBarry Smith . rnorm - 2-norm (preconditioned) residual value (may be estimated). 113a5c2985bSBarry Smith - dummy - unused monitor context 114a5c2985bSBarry Smith 115a5c2985bSBarry Smith Level: intermediate 116a5c2985bSBarry Smith 117a5c2985bSBarry Smith .keywords: KSP, default, monitor, residual 118a5c2985bSBarry Smith 119a5c2985bSBarry Smith .seealso: KSPMonitorSet(), KSPMonitorTrueResidualNorm(), KSPMonitorLGResidualNormCreate() 120a5c2985bSBarry Smith @*/ 121a5c2985bSBarry Smith PetscErrorCode KSPMonitorSNES(KSP ksp,PetscInt n,PetscReal rnorm,void *dummy) 122a5c2985bSBarry Smith { 123a5c2985bSBarry Smith PetscErrorCode ierr; 124a5c2985bSBarry Smith PetscViewer viewer; 125a5c2985bSBarry Smith SNES snes = (SNES) dummy; 126a5c2985bSBarry Smith Vec snes_solution,work1,work2; 127a5c2985bSBarry Smith PetscReal snorm; 128a5c2985bSBarry Smith 129a5c2985bSBarry Smith PetscFunctionBegin; 130a5c2985bSBarry Smith ierr = SNESGetSolution(snes,&snes_solution);CHKERRQ(ierr); 131a5c2985bSBarry Smith ierr = VecDuplicate(snes_solution,&work1);CHKERRQ(ierr); 132a5c2985bSBarry Smith ierr = VecDuplicate(snes_solution,&work2);CHKERRQ(ierr); 133a5c2985bSBarry Smith ierr = KSPBuildSolution(ksp,work1,NULL);CHKERRQ(ierr); 134a5c2985bSBarry Smith ierr = VecAYPX(work1,-1.0,snes_solution);CHKERRQ(ierr); 135a5c2985bSBarry Smith ierr = SNESComputeFunction(snes,work1,work2);CHKERRQ(ierr); 136a5c2985bSBarry Smith ierr = VecNorm(work2,NORM_2,&snorm);CHKERRQ(ierr); 137a5c2985bSBarry Smith ierr = VecDestroy(&work1);CHKERRQ(ierr); 138a5c2985bSBarry Smith ierr = VecDestroy(&work2);CHKERRQ(ierr); 139a5c2985bSBarry Smith 140a5c2985bSBarry Smith ierr = PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)ksp),&viewer);CHKERRQ(ierr); 141a5c2985bSBarry Smith ierr = PetscViewerASCIIAddTab(viewer,((PetscObject)ksp)->tablevel);CHKERRQ(ierr); 142a5c2985bSBarry Smith if (n == 0 && ((PetscObject)ksp)->prefix) { 143a5c2985bSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Residual norms for %s solve.\n",((PetscObject)ksp)->prefix);CHKERRQ(ierr); 144a5c2985bSBarry Smith } 145a5c2985bSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"%3D SNES Residual norm %5.3e KSP Residual norm %5.3e \n",n,(double)snorm,(double)rnorm);CHKERRQ(ierr); 146a5c2985bSBarry Smith ierr = PetscViewerASCIISubtractTab(viewer,((PetscObject)ksp)->tablevel);CHKERRQ(ierr); 147a5c2985bSBarry Smith PetscFunctionReturn(0); 148a5c2985bSBarry Smith } 149a5c2985bSBarry Smith 150e5f7ee39SBarry Smith #include <petscdraw.h> 151e5f7ee39SBarry Smith 152e5f7ee39SBarry Smith #undef __FUNCT__ 153e5f7ee39SBarry Smith #define __FUNCT__ "KSPMonitorSNESLGResidualNormCreate" 154e5f7ee39SBarry Smith /*@C 155e5f7ee39SBarry Smith KSPMonitorSNESLGResidualNormCreate - Creates a line graph context for use with 156e5f7ee39SBarry Smith KSP to monitor convergence of preconditioned residual norms. 157e5f7ee39SBarry Smith 158e5f7ee39SBarry Smith Collective on KSP 159e5f7ee39SBarry Smith 160e5f7ee39SBarry Smith Input Parameters: 161e5f7ee39SBarry Smith + host - the X display to open, or null for the local machine 162e5f7ee39SBarry Smith . label - the title to put in the title bar 163e5f7ee39SBarry Smith . x, y - the screen coordinates of the upper left coordinate of 164e5f7ee39SBarry Smith the window 165e5f7ee39SBarry Smith - m, n - the screen width and height in pixels 166e5f7ee39SBarry Smith 167e5f7ee39SBarry Smith Output Parameter: 168e5f7ee39SBarry Smith . draw - the drawing context 169e5f7ee39SBarry Smith 170e5f7ee39SBarry Smith Options Database Key: 171e5f7ee39SBarry Smith . -ksp_monitor_lg_residualnorm - Sets line graph monitor 172e5f7ee39SBarry Smith 173e5f7ee39SBarry Smith Notes: 174e5f7ee39SBarry Smith Use KSPMonitorSNESLGResidualNormDestroy() to destroy this line graph; do not use PetscDrawLGDestroy(). 175e5f7ee39SBarry Smith 176e5f7ee39SBarry Smith Level: intermediate 177e5f7ee39SBarry Smith 178e5f7ee39SBarry Smith .keywords: KSP, monitor, line graph, residual, create 179e5f7ee39SBarry Smith 180e5f7ee39SBarry Smith .seealso: KSPMonitorSNESLGResidualNormDestroy(), KSPMonitorSet(), KSPMonitorSNESLGTrueResidualCreate() 181e5f7ee39SBarry Smith @*/ 182e5f7ee39SBarry Smith PetscErrorCode KSPMonitorSNESLGResidualNormCreate(const char host[],const char label[],int x,int y,int m,int n,PetscObject **objs) 183e5f7ee39SBarry Smith { 184e5f7ee39SBarry Smith PetscDraw draw; 185e5f7ee39SBarry Smith PetscErrorCode ierr; 186e5f7ee39SBarry Smith PetscDrawAxis axis; 187e5f7ee39SBarry Smith PetscDrawLG drawlg; 188e5f7ee39SBarry Smith const char *names[] = {"Linear residual","Nonlinear residual"}; 189e5f7ee39SBarry Smith 190e5f7ee39SBarry Smith PetscFunctionBegin; 191e5f7ee39SBarry Smith ierr = PetscDrawCreate(PETSC_COMM_SELF,host,label,x,y,m,n,&draw);CHKERRQ(ierr); 192e5f7ee39SBarry Smith ierr = PetscDrawSetFromOptions(draw);CHKERRQ(ierr); 193e5f7ee39SBarry Smith ierr = PetscDrawLGCreate(draw,2,&drawlg);CHKERRQ(ierr); 194957f8de3SLisandro Dalcin ierr = PetscDrawLGSetFromOptions(drawlg);CHKERRQ(ierr); 195e5f7ee39SBarry Smith ierr = PetscDrawLGGetAxis(drawlg,&axis);CHKERRQ(ierr); 196e5f7ee39SBarry Smith ierr = PetscDrawAxisSetLabels(axis,"Convergence of Residual Norm","Iteration","Residual Norm");CHKERRQ(ierr); 197e5f7ee39SBarry Smith ierr = PetscDrawLGSetLegend(drawlg,names);CHKERRQ(ierr); 198e5f7ee39SBarry Smith ierr = PetscLogObjectParent((PetscObject)drawlg,(PetscObject)draw);CHKERRQ(ierr); 199e5f7ee39SBarry Smith 200435c5a64SBarry Smith ierr = PetscMalloc1(3,objs);CHKERRQ(ierr); 201e5f7ee39SBarry Smith (*objs)[1] = (PetscObject)drawlg; 202435c5a64SBarry Smith (*objs)[2] = (PetscObject)draw; 203e5f7ee39SBarry Smith PetscFunctionReturn(0); 204e5f7ee39SBarry Smith } 205e5f7ee39SBarry Smith 206e5f7ee39SBarry Smith #undef __FUNCT__ 207e5f7ee39SBarry Smith #define __FUNCT__ "KSPMonitorSNESLGResidualNorm" 208e5f7ee39SBarry Smith PetscErrorCode KSPMonitorSNESLGResidualNorm(KSP ksp,PetscInt n,PetscReal rnorm,PetscObject *objs) 209e5f7ee39SBarry Smith { 210e5f7ee39SBarry Smith PetscDrawLG lg = (PetscDrawLG) objs[1]; 211e5f7ee39SBarry Smith PetscErrorCode ierr; 212e5f7ee39SBarry Smith PetscReal y[2]; 213e5f7ee39SBarry Smith SNES snes = (SNES) objs[0]; 214e5f7ee39SBarry Smith Vec snes_solution,work1,work2; 215e5f7ee39SBarry Smith 216e5f7ee39SBarry Smith PetscFunctionBegin; 217e5f7ee39SBarry Smith if (rnorm > 0.0) y[0] = PetscLog10Real(rnorm); 218e5f7ee39SBarry Smith else y[0] = -15.0; 219e5f7ee39SBarry Smith 220e5f7ee39SBarry Smith ierr = SNESGetSolution(snes,&snes_solution);CHKERRQ(ierr); 221e5f7ee39SBarry Smith ierr = VecDuplicate(snes_solution,&work1);CHKERRQ(ierr); 222e5f7ee39SBarry Smith ierr = VecDuplicate(snes_solution,&work2);CHKERRQ(ierr); 223e5f7ee39SBarry Smith ierr = KSPBuildSolution(ksp,work1,NULL);CHKERRQ(ierr); 224e5f7ee39SBarry Smith ierr = VecAYPX(work1,-1.0,snes_solution);CHKERRQ(ierr); 225e5f7ee39SBarry Smith ierr = SNESComputeFunction(snes,work1,work2);CHKERRQ(ierr); 226e5f7ee39SBarry Smith ierr = VecNorm(work2,NORM_2,y+1);CHKERRQ(ierr); 227e5f7ee39SBarry Smith if (y[1] > 0.0) y[1] = PetscLog10Real(y[1]); 228e5f7ee39SBarry Smith else y[1] = -15.0; 229e5f7ee39SBarry Smith ierr = VecDestroy(&work1);CHKERRQ(ierr); 230e5f7ee39SBarry Smith ierr = VecDestroy(&work2);CHKERRQ(ierr); 231e5f7ee39SBarry Smith 232e5f7ee39SBarry Smith ierr = PetscDrawLGAddPoint(lg,NULL,y);CHKERRQ(ierr); 233e5f7ee39SBarry Smith if (n < 20 || !(n % 5)) { 234e5f7ee39SBarry Smith ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr); 235e5f7ee39SBarry Smith } 236e5f7ee39SBarry Smith PetscFunctionReturn(0); 237e5f7ee39SBarry Smith } 238e5f7ee39SBarry Smith 239e5f7ee39SBarry Smith #undef __FUNCT__ 240e5f7ee39SBarry Smith #define __FUNCT__ "KSPMonitorSNESLGResidualNormDestroy" 241e5f7ee39SBarry Smith /*@ 242e5f7ee39SBarry Smith KSPMonitorSNESLGResidualNormDestroy - Destroys a line graph context that was created 243e5f7ee39SBarry Smith with KSPMonitorSNESLGResidualNormCreate(). 244e5f7ee39SBarry Smith 245e5f7ee39SBarry Smith Collective on KSP 246e5f7ee39SBarry Smith 247e5f7ee39SBarry Smith Input Parameter: 248e5f7ee39SBarry Smith . draw - the drawing context 249e5f7ee39SBarry Smith 250e5f7ee39SBarry Smith Level: intermediate 251e5f7ee39SBarry Smith 252e5f7ee39SBarry Smith .keywords: KSP, monitor, line graph, destroy 253e5f7ee39SBarry Smith 254e5f7ee39SBarry Smith .seealso: KSPMonitorSNESLGResidualNormCreate(), KSPMonitorSNESLGTrueResidualDestroy(), KSPMonitorSet() 255e5f7ee39SBarry Smith @*/ 256e5f7ee39SBarry Smith PetscErrorCode KSPMonitorSNESLGResidualNormDestroy(PetscObject **objs) 257e5f7ee39SBarry Smith { 258e5f7ee39SBarry Smith PetscErrorCode ierr; 259e5f7ee39SBarry Smith PetscDrawLG drawlg = (PetscDrawLG) (*objs)[1]; 260435c5a64SBarry Smith PetscDraw draw = (PetscDraw) (*objs)[2]; 261e5f7ee39SBarry Smith 262e5f7ee39SBarry Smith PetscFunctionBegin; 263e5f7ee39SBarry Smith ierr = PetscDrawDestroy(&draw);CHKERRQ(ierr); 264e5f7ee39SBarry Smith ierr = PetscDrawLGDestroy(&drawlg);CHKERRQ(ierr); 265e5f7ee39SBarry Smith ierr = PetscFree(*objs);CHKERRQ(ierr); 266e5f7ee39SBarry Smith PetscFunctionReturn(0); 267e5f7ee39SBarry Smith } 268e5f7ee39SBarry Smith 269a5c2985bSBarry Smith #undef __FUNCT__ 270a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorDefault" 2714b828684SBarry Smith /*@C 272a6570f20SBarry Smith SNESMonitorDefault - Monitors progress of the SNES solvers (default). 273e7e93795SLois Curfman McInnes 274c7afd0dbSLois Curfman McInnes Collective on SNES 275c7afd0dbSLois Curfman McInnes 276e7e93795SLois Curfman McInnes Input Parameters: 277c7afd0dbSLois Curfman McInnes + snes - the SNES context 278e7e93795SLois Curfman McInnes . its - iteration number 2794b27c08aSLois Curfman McInnes . fgnorm - 2-norm of residual 280c7afd0dbSLois Curfman McInnes - dummy - unused context 281fee21e36SBarry Smith 282e7e93795SLois Curfman McInnes Notes: 2834b27c08aSLois Curfman McInnes This routine prints the residual norm at each iteration. 284e7e93795SLois Curfman McInnes 28536851e7fSLois Curfman McInnes Level: intermediate 28636851e7fSLois Curfman McInnes 287e7e93795SLois Curfman McInnes .keywords: SNES, nonlinear, default, monitor, norm 288e7e93795SLois Curfman McInnes 289a6570f20SBarry Smith .seealso: SNESMonitorSet(), SNESMonitorSolution() 290e7e93795SLois Curfman McInnes @*/ 2917087cfbeSBarry Smith PetscErrorCode SNESMonitorDefault(SNES snes,PetscInt its,PetscReal fgnorm,void *dummy) 292e7e93795SLois Curfman McInnes { 293dfbe8321SBarry Smith PetscErrorCode ierr; 294ce94432eSBarry Smith PetscViewer viewer = dummy ? (PetscViewer) dummy : PETSC_VIEWER_STDOUT_(PetscObjectComm((PetscObject)snes)); 295d132466eSBarry Smith 2963a40ed3dSBarry Smith PetscFunctionBegin; 297649052a6SBarry Smith ierr = PetscViewerASCIIAddTab(viewer,((PetscObject)snes)->tablevel);CHKERRQ(ierr); 298649052a6SBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"%3D SNES Function norm %14.12e \n",its,(double)fgnorm);CHKERRQ(ierr); 299649052a6SBarry Smith ierr = PetscViewerASCIISubtractTab(viewer,((PetscObject)snes)->tablevel);CHKERRQ(ierr); 3003a40ed3dSBarry Smith PetscFunctionReturn(0); 301e7e93795SLois Curfman McInnes } 3023f1db9ecSBarry Smith 303b271bb04SBarry Smith #undef __FUNCT__ 3042e7541e6SPeter Brune #define __FUNCT__ "SNESMonitorJacUpdateSpectrum" 305a80ad3e0SBarry Smith PetscErrorCode SNESMonitorJacUpdateSpectrum(SNES snes,PetscInt it,PetscReal fnorm,void *ctx) 306a80ad3e0SBarry Smith { 307196da8b6SPeter Brune #if defined(PETSC_MISSING_LAPACK_GEEV) 308ce94432eSBarry Smith SETERRQ(PetscObjectComm((PetscObject)snes),PETSC_ERR_SUP,"GEEV - Lapack routine is unavailable\nNot able to provide eigen values."); 309196da8b6SPeter Brune #elif defined(PETSC_HAVE_ESSL) 310ce94432eSBarry Smith SETERRQ(PetscObjectComm((PetscObject)snes),PETSC_ERR_SUP,"GEEV - No support for ESSL Lapack Routines"); 311196da8b6SPeter Brune #else 3122e7541e6SPeter Brune Vec X; 3132e7541e6SPeter Brune Mat J,dJ,dJdense; 3142e7541e6SPeter Brune PetscErrorCode ierr; 315d1e9a80fSBarry Smith PetscErrorCode (*func)(SNES,Vec,Mat,Mat,void*); 3162e7541e6SPeter Brune PetscInt n,i; 3172e7541e6SPeter Brune PetscBLASInt nb,lwork; 3182e7541e6SPeter Brune PetscReal *eigr,*eigi; 3192e7541e6SPeter Brune PetscScalar *work; 3202e7541e6SPeter Brune PetscScalar *a; 3212e7541e6SPeter Brune 3222e7541e6SPeter Brune PetscFunctionBegin; 3232e7541e6SPeter Brune if (it == 0) PetscFunctionReturn(0); 3242e7541e6SPeter Brune /* create the difference between the current update and the current jacobian */ 3252e7541e6SPeter Brune ierr = SNESGetSolution(snes,&X);CHKERRQ(ierr); 326d1e9a80fSBarry Smith ierr = SNESGetJacobian(snes,NULL,&J,&func,NULL);CHKERRQ(ierr); 3272e7541e6SPeter Brune ierr = MatDuplicate(J,MAT_COPY_VALUES,&dJ);CHKERRQ(ierr); 328d1e9a80fSBarry Smith ierr = SNESComputeJacobian(snes,X,dJ,dJ);CHKERRQ(ierr); 3292e7541e6SPeter Brune ierr = MatAXPY(dJ,-1.0,J,SAME_NONZERO_PATTERN);CHKERRQ(ierr); 330f5af7f23SKarl Rupp 3312e7541e6SPeter Brune /* compute the spectrum directly */ 3322e7541e6SPeter Brune ierr = MatConvert(dJ,MATSEQDENSE,MAT_INITIAL_MATRIX,&dJdense);CHKERRQ(ierr); 3330298fd71SBarry Smith ierr = MatGetSize(dJ,&n,NULL);CHKERRQ(ierr); 334c5df96a5SBarry Smith ierr = PetscBLASIntCast(n,&nb);CHKERRQ(ierr); 3352e7541e6SPeter Brune lwork = 3*nb; 336785e854fSJed Brown ierr = PetscMalloc1(n,&eigr);CHKERRQ(ierr); 337785e854fSJed Brown ierr = PetscMalloc1(n,&eigi);CHKERRQ(ierr); 338785e854fSJed Brown ierr = PetscMalloc1(lwork,&work);CHKERRQ(ierr); 3398c778c55SBarry Smith ierr = MatDenseGetArray(dJdense,&a);CHKERRQ(ierr); 3402e7541e6SPeter Brune #if !defined(PETSC_USE_COMPLEX) 3412e7541e6SPeter Brune { 3422e7541e6SPeter Brune PetscBLASInt lierr; 3432e7541e6SPeter Brune ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 3448b83055fSJed Brown PetscStackCallBLAS("LAPACKgeev",LAPACKgeev_("N","N",&nb,a,&nb,eigr,eigi,NULL,&nb,NULL,&nb,work,&lwork,&lierr)); 3452e7541e6SPeter Brune if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"geev() error %d",lierr); 3462e7541e6SPeter Brune ierr = PetscFPTrapPop();CHKERRQ(ierr); 3472e7541e6SPeter Brune } 3482e7541e6SPeter Brune #else 3492e7541e6SPeter Brune SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not coded for complex"); 3502e7541e6SPeter Brune #endif 351ce94432eSBarry Smith PetscPrintf(PetscObjectComm((PetscObject)snes),"Eigenvalues of J_%d - J_%d:\n",it,it-1);CHKERRQ(ierr); 3522e7541e6SPeter Brune for (i=0;i<n;i++) { 3538fa295daSBarry Smith PetscPrintf(PetscObjectComm((PetscObject)snes),"%5d: %20.5g + %20.5gi\n",i,(double)eigr[i],(double)eigi[i]);CHKERRQ(ierr); 3542e7541e6SPeter Brune } 3558c778c55SBarry Smith ierr = MatDenseRestoreArray(dJdense,&a);CHKERRQ(ierr); 3562e7541e6SPeter Brune ierr = MatDestroy(&dJ);CHKERRQ(ierr); 3572e7541e6SPeter Brune ierr = MatDestroy(&dJdense);CHKERRQ(ierr); 3582e7541e6SPeter Brune ierr = PetscFree(eigr);CHKERRQ(ierr); 3592e7541e6SPeter Brune ierr = PetscFree(eigi);CHKERRQ(ierr); 3602e7541e6SPeter Brune ierr = PetscFree(work);CHKERRQ(ierr); 3612e7541e6SPeter Brune PetscFunctionReturn(0); 362196da8b6SPeter Brune #endif 3632e7541e6SPeter Brune } 3642e7541e6SPeter Brune 3652e7541e6SPeter Brune #undef __FUNCT__ 366b271bb04SBarry Smith #define __FUNCT__ "SNESMonitorRange_Private" 3677087cfbeSBarry Smith PetscErrorCode SNESMonitorRange_Private(SNES snes,PetscInt it,PetscReal *per) 368b271bb04SBarry Smith { 369b271bb04SBarry Smith PetscErrorCode ierr; 370b271bb04SBarry Smith Vec resid; 371b271bb04SBarry Smith PetscReal rmax,pwork; 372b271bb04SBarry Smith PetscInt i,n,N; 373b271bb04SBarry Smith PetscScalar *r; 374b271bb04SBarry Smith 375b271bb04SBarry Smith PetscFunctionBegin; 376b271bb04SBarry Smith ierr = SNESGetFunction(snes,&resid,0,0);CHKERRQ(ierr); 377b271bb04SBarry Smith ierr = VecNorm(resid,NORM_INFINITY,&rmax);CHKERRQ(ierr); 378b271bb04SBarry Smith ierr = VecGetLocalSize(resid,&n);CHKERRQ(ierr); 379b271bb04SBarry Smith ierr = VecGetSize(resid,&N);CHKERRQ(ierr); 380b271bb04SBarry Smith ierr = VecGetArray(resid,&r);CHKERRQ(ierr); 381b271bb04SBarry Smith pwork = 0.0; 382b271bb04SBarry Smith for (i=0; i<n; i++) { 383b271bb04SBarry Smith pwork += (PetscAbsScalar(r[i]) > .20*rmax); 384b271bb04SBarry Smith } 385ce94432eSBarry Smith ierr = MPI_Allreduce(&pwork,per,1,MPIU_REAL,MPIU_SUM,PetscObjectComm((PetscObject)snes));CHKERRQ(ierr); 386b271bb04SBarry Smith ierr = VecRestoreArray(resid,&r);CHKERRQ(ierr); 387b271bb04SBarry Smith *per = *per/N; 388b271bb04SBarry Smith PetscFunctionReturn(0); 389b271bb04SBarry Smith } 390b271bb04SBarry Smith 391b271bb04SBarry Smith #undef __FUNCT__ 392b271bb04SBarry Smith #define __FUNCT__ "SNESMonitorRange" 393b271bb04SBarry Smith /*@C 394b271bb04SBarry Smith SNESMonitorRange - Prints the percentage of residual elements that are more then 10 percent of the maximum value. 395b271bb04SBarry Smith 396b271bb04SBarry Smith Collective on SNES 397b271bb04SBarry Smith 398b271bb04SBarry Smith Input Parameters: 399b271bb04SBarry Smith + snes - iterative context 400b271bb04SBarry Smith . it - iteration number 401b271bb04SBarry Smith . rnorm - 2-norm (preconditioned) residual value (may be estimated). 402b271bb04SBarry Smith - dummy - unused monitor context 403b271bb04SBarry Smith 404b271bb04SBarry Smith Options Database Key: 405b271bb04SBarry Smith . -snes_monitor_range - Activates SNESMonitorRange() 406b271bb04SBarry Smith 407b271bb04SBarry Smith Level: intermediate 408b271bb04SBarry Smith 409b271bb04SBarry Smith .keywords: SNES, default, monitor, residual 410b271bb04SBarry Smith 411b271bb04SBarry Smith .seealso: SNESMonitorSet(), SNESMonitorDefault(), SNESMonitorLGCreate() 412b271bb04SBarry Smith @*/ 4137087cfbeSBarry Smith PetscErrorCode SNESMonitorRange(SNES snes,PetscInt it,PetscReal rnorm,void *dummy) 414b271bb04SBarry Smith { 415b271bb04SBarry Smith PetscErrorCode ierr; 416b271bb04SBarry Smith PetscReal perc,rel; 417ce94432eSBarry Smith PetscViewer viewer = dummy ? (PetscViewer) dummy : PETSC_VIEWER_STDOUT_(PetscObjectComm((PetscObject)snes)); 418b271bb04SBarry Smith /* should be in a MonitorRangeContext */ 419b271bb04SBarry Smith static PetscReal prev; 420b271bb04SBarry Smith 421b271bb04SBarry Smith PetscFunctionBegin; 422b271bb04SBarry Smith if (!it) prev = rnorm; 423b271bb04SBarry Smith ierr = SNESMonitorRange_Private(snes,it,&perc);CHKERRQ(ierr); 424b271bb04SBarry Smith 425b271bb04SBarry Smith rel = (prev - rnorm)/prev; 426b271bb04SBarry Smith prev = rnorm; 427649052a6SBarry Smith ierr = PetscViewerASCIIAddTab(viewer,((PetscObject)snes)->tablevel);CHKERRQ(ierr); 4286712e2f1SBarry 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); 429649052a6SBarry Smith ierr = PetscViewerASCIISubtractTab(viewer,((PetscObject)snes)->tablevel);CHKERRQ(ierr); 430b271bb04SBarry Smith PetscFunctionReturn(0); 431b271bb04SBarry Smith } 432b271bb04SBarry Smith 433eabae89aSBarry Smith typedef struct { 434649052a6SBarry Smith PetscViewer viewer; 435eabae89aSBarry Smith PetscReal *history; 436a6570f20SBarry Smith } SNESMonitorRatioContext; 437eabae89aSBarry Smith 4383a7fca6bSBarry Smith #undef __FUNCT__ 439a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorRatio" 4403a7fca6bSBarry Smith /*@C 441a6570f20SBarry Smith SNESMonitorRatio - Monitors progress of the SNES solvers by printing the ratio 4424b27c08aSLois Curfman McInnes of residual norm at each iteration to the previous. 4433a7fca6bSBarry Smith 4443a7fca6bSBarry Smith Collective on SNES 4453a7fca6bSBarry Smith 4463a7fca6bSBarry Smith Input Parameters: 4473a7fca6bSBarry Smith + snes - the SNES context 4483a7fca6bSBarry Smith . its - iteration number 4493a7fca6bSBarry Smith . fgnorm - 2-norm of residual (or gradient) 450eabae89aSBarry Smith - dummy - context of monitor 4513a7fca6bSBarry Smith 4523a7fca6bSBarry Smith Level: intermediate 4533a7fca6bSBarry Smith 4543a7fca6bSBarry Smith .keywords: SNES, nonlinear, monitor, norm 4553a7fca6bSBarry Smith 456a6570f20SBarry Smith .seealso: SNESMonitorSet(), SNESMonitorSolution() 4573a7fca6bSBarry Smith @*/ 4587087cfbeSBarry Smith PetscErrorCode SNESMonitorRatio(SNES snes,PetscInt its,PetscReal fgnorm,void *dummy) 4593a7fca6bSBarry Smith { 460dfbe8321SBarry Smith PetscErrorCode ierr; 46177431f27SBarry Smith PetscInt len; 46287828ca2SBarry Smith PetscReal *history; 463a6570f20SBarry Smith SNESMonitorRatioContext *ctx = (SNESMonitorRatioContext*)dummy; 4643a7fca6bSBarry Smith 4653a7fca6bSBarry Smith PetscFunctionBegin; 4660298fd71SBarry Smith ierr = SNESGetConvergenceHistory(snes,&history,NULL,&len);CHKERRQ(ierr); 467649052a6SBarry Smith ierr = PetscViewerASCIIAddTab(ctx->viewer,((PetscObject)snes)->tablevel);CHKERRQ(ierr); 468958c9bccSBarry Smith if (!its || !history || its > len) { 469649052a6SBarry Smith ierr = PetscViewerASCIIPrintf(ctx->viewer,"%3D SNES Function norm %14.12e \n",its,(double)fgnorm);CHKERRQ(ierr); 4703a7fca6bSBarry Smith } else { 47187828ca2SBarry Smith PetscReal ratio = fgnorm/history[its-1]; 4728f1a2a5eSBarry Smith ierr = PetscViewerASCIIPrintf(ctx->viewer,"%3D SNES Function norm %14.12e %14.12e \n",its,(double)fgnorm,(double)ratio);CHKERRQ(ierr); 4733a7fca6bSBarry Smith } 474649052a6SBarry Smith ierr = PetscViewerASCIISubtractTab(ctx->viewer,((PetscObject)snes)->tablevel);CHKERRQ(ierr); 4753a7fca6bSBarry Smith PetscFunctionReturn(0); 4763a7fca6bSBarry Smith } 4773a7fca6bSBarry Smith 4783a7fca6bSBarry Smith /* 4793a7fca6bSBarry Smith If the we set the history monitor space then we must destroy it 4803a7fca6bSBarry Smith */ 4813a7fca6bSBarry Smith #undef __FUNCT__ 482a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorRatioDestroy" 483c2efdce3SBarry Smith PetscErrorCode SNESMonitorRatioDestroy(void **ct) 4843a7fca6bSBarry Smith { 485dfbe8321SBarry Smith PetscErrorCode ierr; 486c2efdce3SBarry Smith SNESMonitorRatioContext *ctx = *(SNESMonitorRatioContext**)ct; 4873a7fca6bSBarry Smith 4883a7fca6bSBarry Smith PetscFunctionBegin; 48905b42c5fSBarry Smith ierr = PetscFree(ctx->history);CHKERRQ(ierr); 490649052a6SBarry Smith ierr = PetscViewerDestroy(&ctx->viewer);CHKERRQ(ierr); 491eabae89aSBarry Smith ierr = PetscFree(ctx);CHKERRQ(ierr); 4923a7fca6bSBarry Smith PetscFunctionReturn(0); 4933a7fca6bSBarry Smith } 4943a7fca6bSBarry Smith 4953a7fca6bSBarry Smith #undef __FUNCT__ 496a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorSetRatio" 4973a7fca6bSBarry Smith /*@C 498a6570f20SBarry Smith SNESMonitorSetRatio - Sets SNES to use a monitor that prints the 4994b27c08aSLois Curfman McInnes ratio of the function norm at each iteration. 5003a7fca6bSBarry Smith 5013a7fca6bSBarry Smith Collective on SNES 5023a7fca6bSBarry Smith 5033a7fca6bSBarry Smith Input Parameters: 504eabae89aSBarry Smith + snes - the SNES context 505eabae89aSBarry Smith - viewer - ASCII viewer to print output 5063a7fca6bSBarry Smith 5073a7fca6bSBarry Smith Level: intermediate 5083a7fca6bSBarry Smith 5093a7fca6bSBarry Smith .keywords: SNES, nonlinear, monitor, norm 5103a7fca6bSBarry Smith 511a6570f20SBarry Smith .seealso: SNESMonitorSet(), SNESMonitorSolution(), SNESMonitorDefault() 5123a7fca6bSBarry Smith @*/ 513649052a6SBarry Smith PetscErrorCode SNESMonitorSetRatio(SNES snes,PetscViewer viewer) 5143a7fca6bSBarry Smith { 515dfbe8321SBarry Smith PetscErrorCode ierr; 516a6570f20SBarry Smith SNESMonitorRatioContext *ctx; 51787828ca2SBarry Smith PetscReal *history; 5183a7fca6bSBarry Smith 5193a7fca6bSBarry Smith PetscFunctionBegin; 520b00a9115SJed Brown ierr = PetscNewLog(snes,&ctx);CHKERRQ(ierr); 5210298fd71SBarry Smith ierr = SNESGetConvergenceHistory(snes,&history,NULL,NULL);CHKERRQ(ierr); 5223a7fca6bSBarry Smith if (!history) { 523785e854fSJed Brown ierr = PetscMalloc1(100,&ctx->history);CHKERRQ(ierr); 524eabae89aSBarry Smith ierr = SNESSetConvergenceHistory(snes,ctx->history,0,100,PETSC_TRUE);CHKERRQ(ierr); 5253a7fca6bSBarry Smith } 526eabae89aSBarry Smith ctx->viewer = viewer; 527f5af7f23SKarl Rupp 528a6570f20SBarry Smith ierr = SNESMonitorSet(snes,SNESMonitorRatio,ctx,SNESMonitorRatioDestroy);CHKERRQ(ierr); 5293a7fca6bSBarry Smith PetscFunctionReturn(0); 5303a7fca6bSBarry Smith } 5313a7fca6bSBarry Smith 532e7e93795SLois Curfman McInnes /* ---------------------------------------------------------------- */ 5334a2ae208SSatish Balay #undef __FUNCT__ 534a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorDefaultShort" 535be1f7002SBarry Smith /* 536a6570f20SBarry Smith Default (short) SNES Monitor, same as SNESMonitorDefault() except 537be1f7002SBarry Smith it prints fewer digits of the residual as the residual gets smaller. 538be1f7002SBarry Smith This is because the later digits are meaningless and are often 539be1f7002SBarry Smith different on different machines; by using this routine different 540be1f7002SBarry Smith machines will usually generate the same output. 541be1f7002SBarry Smith */ 5427087cfbeSBarry Smith PetscErrorCode SNESMonitorDefaultShort(SNES snes,PetscInt its,PetscReal fgnorm,void *dummy) 543e7e93795SLois Curfman McInnes { 544dfbe8321SBarry Smith PetscErrorCode ierr; 545ce94432eSBarry Smith PetscViewer viewer = dummy ? (PetscViewer) dummy : PETSC_VIEWER_STDOUT_(PetscObjectComm((PetscObject)snes)); 546d132466eSBarry Smith 5473a40ed3dSBarry Smith PetscFunctionBegin; 548649052a6SBarry Smith ierr = PetscViewerASCIIAddTab(viewer,((PetscObject)snes)->tablevel);CHKERRQ(ierr); 5498f240d10SBarry Smith if (fgnorm > 1.e-9) { 5508fa295daSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"%3D SNES Function norm %g \n",its,(double)fgnorm);CHKERRQ(ierr); 5513a40ed3dSBarry Smith } else if (fgnorm > 1.e-11) { 5528fa295daSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"%3D SNES Function norm %5.3e \n",its,(double)fgnorm);CHKERRQ(ierr); 5533a40ed3dSBarry Smith } else { 554649052a6SBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"%3D SNES Function norm < 1.e-11\n",its);CHKERRQ(ierr); 555a34d58ebSBarry Smith } 556649052a6SBarry Smith ierr = PetscViewerASCIISubtractTab(viewer,((PetscObject)snes)->tablevel);CHKERRQ(ierr); 5573a40ed3dSBarry Smith PetscFunctionReturn(0); 558e7e93795SLois Curfman McInnes } 5592db13446SMatthew G. Knepley 5602db13446SMatthew G. Knepley #undef __FUNCT__ 5612db13446SMatthew G. Knepley #define __FUNCT__ "SNESMonitorDefaultField" 5622db13446SMatthew G. Knepley /*@C 5632db13446SMatthew G. Knepley SNESMonitorDefaultField - Monitors progress of the SNES solvers, separated into fields. 5642db13446SMatthew G. Knepley 5652db13446SMatthew G. Knepley Collective on SNES 5662db13446SMatthew G. Knepley 5672db13446SMatthew G. Knepley Input Parameters: 5682db13446SMatthew G. Knepley + snes - the SNES context 5692db13446SMatthew G. Knepley . its - iteration number 5702db13446SMatthew G. Knepley . fgnorm - 2-norm of residual 5712db13446SMatthew G. Knepley - ctx - the PetscViewer 5722db13446SMatthew G. Knepley 5732db13446SMatthew G. Knepley Notes: 5742db13446SMatthew G. Knepley This routine uses the DM attached to the residual vector 5752db13446SMatthew G. Knepley 5762db13446SMatthew G. Knepley Level: intermediate 5772db13446SMatthew G. Knepley 5782db13446SMatthew G. Knepley .keywords: SNES, nonlinear, field, monitor, norm 5792db13446SMatthew G. Knepley .seealso: SNESMonitorSet(), SNESMonitorSolution(), SNESMonitorDefault(), SNESMonitorDefaultShort() 5802db13446SMatthew G. Knepley @*/ 5812db13446SMatthew G. Knepley PetscErrorCode SNESMonitorDefaultField(SNES snes, PetscInt its, PetscReal fgnorm, void *ctx) 5822db13446SMatthew G. Knepley { 5832db13446SMatthew G. Knepley PetscViewer viewer = ctx ? (PetscViewer) ctx : PETSC_VIEWER_STDOUT_(PetscObjectComm((PetscObject) snes)); 5842db13446SMatthew G. Knepley Vec r; 5852db13446SMatthew G. Knepley DM dm; 5862db13446SMatthew G. Knepley PetscReal res[256]; 5872db13446SMatthew G. Knepley PetscInt tablevel; 5882db13446SMatthew G. Knepley PetscErrorCode ierr; 5892db13446SMatthew G. Knepley 5902db13446SMatthew G. Knepley PetscFunctionBegin; 5912db13446SMatthew G. Knepley ierr = SNESGetFunction(snes, &r, NULL, NULL);CHKERRQ(ierr); 5922db13446SMatthew G. Knepley ierr = VecGetDM(r, &dm);CHKERRQ(ierr); 5932db13446SMatthew G. Knepley if (!dm) {ierr = SNESMonitorDefault(snes, its, fgnorm, ctx);CHKERRQ(ierr);} 5942db13446SMatthew G. Knepley else { 5952db13446SMatthew G. Knepley PetscSection s, gs; 5962db13446SMatthew G. Knepley PetscInt Nf, f; 5972db13446SMatthew G. Knepley 5982db13446SMatthew G. Knepley ierr = DMGetDefaultSection(dm, &s);CHKERRQ(ierr); 5992db13446SMatthew G. Knepley ierr = DMGetDefaultGlobalSection(dm, &gs);CHKERRQ(ierr); 6002db13446SMatthew G. Knepley if (!s || !gs) {ierr = SNESMonitorDefault(snes, its, fgnorm, ctx);CHKERRQ(ierr);} 6012db13446SMatthew G. Knepley ierr = PetscSectionGetNumFields(s, &Nf);CHKERRQ(ierr); 6022db13446SMatthew G. Knepley if (Nf > 256) SETERRQ1(PetscObjectComm((PetscObject) snes), PETSC_ERR_SUP, "Do not support %d fields > 256", Nf); 6032db13446SMatthew G. Knepley ierr = PetscSectionVecNorm(s, gs, r, NORM_2, res);CHKERRQ(ierr); 6042db13446SMatthew G. Knepley ierr = PetscObjectGetTabLevel((PetscObject) snes, &tablevel);CHKERRQ(ierr); 6052db13446SMatthew G. Knepley ierr = PetscViewerASCIIAddTab(viewer, tablevel);CHKERRQ(ierr); 6062db13446SMatthew G. Knepley ierr = PetscViewerASCIIPrintf(viewer, "%3D SNES Function norm %14.12e [", its, (double) fgnorm);CHKERRQ(ierr); 6072db13446SMatthew G. Knepley for (f = 0; f < Nf; ++f) { 6082db13446SMatthew G. Knepley if (f) {ierr = PetscViewerASCIIPrintf(viewer, ", ");CHKERRQ(ierr);} 6092db13446SMatthew G. Knepley ierr = PetscViewerASCIIPrintf(viewer, "%14.12e", res[f]);CHKERRQ(ierr); 6102db13446SMatthew G. Knepley } 6112db13446SMatthew G. Knepley ierr = PetscViewerASCIIPrintf(viewer, "] \n");CHKERRQ(ierr); 6122db13446SMatthew G. Knepley ierr = PetscViewerASCIISubtractTab(viewer, tablevel);CHKERRQ(ierr); 6132db13446SMatthew G. Knepley } 6142db13446SMatthew G. Knepley PetscFunctionReturn(0); 6152db13446SMatthew G. Knepley } 616e7e93795SLois Curfman McInnes /* ---------------------------------------------------------------- */ 6174a2ae208SSatish Balay #undef __FUNCT__ 6188d359177SBarry Smith #define __FUNCT__ "SNESConvergedDefault" 6194b828684SBarry Smith /*@C 6208d359177SBarry Smith SNESConvergedDefault - Convergence test of the solvers for 621f525115eSLois Curfman McInnes systems of nonlinear equations (default). 622e7e93795SLois Curfman McInnes 623c7afd0dbSLois Curfman McInnes Collective on SNES 624c7afd0dbSLois Curfman McInnes 625e7e93795SLois Curfman McInnes Input Parameters: 626c7afd0dbSLois Curfman McInnes + snes - the SNES context 62706ee9f85SBarry Smith . it - the iteration (0 indicates before any Newton steps) 628e7e93795SLois Curfman McInnes . xnorm - 2-norm of current iterate 629c60f73f4SPeter Brune . snorm - 2-norm of current step 6307f3332b4SBarry Smith . fnorm - 2-norm of function at current iterate 631c7afd0dbSLois Curfman McInnes - dummy - unused context 632e7e93795SLois Curfman McInnes 633184914b5SBarry Smith Output Parameter: 634184914b5SBarry Smith . reason - one of 63570441072SBarry Smith $ SNES_CONVERGED_FNORM_ABS - (fnorm < abstol), 636c60f73f4SPeter Brune $ SNES_CONVERGED_SNORM_RELATIVE - (snorm < stol*xnorm), 637184914b5SBarry Smith $ SNES_CONVERGED_FNORM_RELATIVE - (fnorm < rtol*fnorm0), 638184914b5SBarry Smith $ SNES_DIVERGED_FUNCTION_COUNT - (nfct > maxf), 639184914b5SBarry Smith $ SNES_DIVERGED_FNORM_NAN - (fnorm == NaN), 640184914b5SBarry Smith $ SNES_CONVERGED_ITERATING - (otherwise), 641e7e93795SLois Curfman McInnes 642e7e93795SLois Curfman McInnes where 643c7afd0dbSLois Curfman McInnes + maxf - maximum number of function evaluations, 644c7afd0dbSLois Curfman McInnes set with SNESSetTolerances() 645c7afd0dbSLois Curfman McInnes . nfct - number of function evaluations, 64670441072SBarry Smith . abstol - absolute function norm tolerance, 647c7afd0dbSLois Curfman McInnes set with SNESSetTolerances() 648c7afd0dbSLois Curfman McInnes - rtol - relative function norm tolerance, set with SNESSetTolerances() 649fee21e36SBarry Smith 65036851e7fSLois Curfman McInnes Level: intermediate 65136851e7fSLois Curfman McInnes 652e7e93795SLois Curfman McInnes .keywords: SNES, nonlinear, default, converged, convergence 653e7e93795SLois Curfman McInnes 65471f87433Sdalcinl .seealso: SNESSetConvergenceTest() 655e7e93795SLois Curfman McInnes @*/ 6568d359177SBarry Smith PetscErrorCode SNESConvergedDefault(SNES snes,PetscInt it,PetscReal xnorm,PetscReal snorm,PetscReal fnorm,SNESConvergedReason *reason,void *dummy) 657e7e93795SLois Curfman McInnes { 65863ba0a88SBarry Smith PetscErrorCode ierr; 65963ba0a88SBarry Smith 6603a40ed3dSBarry Smith PetscFunctionBegin; 6610700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 6623f149594SLisandro Dalcin PetscValidPointer(reason,6); 6633f149594SLisandro Dalcin 66406ee9f85SBarry Smith *reason = SNES_CONVERGED_ITERATING; 66506ee9f85SBarry Smith 66606ee9f85SBarry Smith if (!it) { 66706ee9f85SBarry Smith /* set parameter for default relative tolerance convergence test */ 66806ee9f85SBarry Smith snes->ttol = fnorm*snes->rtol; 66906ee9f85SBarry Smith } 6708146f6ebSBarry Smith if (PetscIsInfOrNanReal(fnorm)) { 671ae15b995SBarry Smith ierr = PetscInfo(snes,"Failed to converged, function norm is NaN\n");CHKERRQ(ierr); 672184914b5SBarry Smith *reason = SNES_DIVERGED_FNORM_NAN; 67370441072SBarry Smith } else if (fnorm < snes->abstol) { 6748f1a2a5eSBarry Smith ierr = PetscInfo2(snes,"Converged due to function norm %14.12e < %14.12e\n",(double)fnorm,(double)snes->abstol);CHKERRQ(ierr); 675184914b5SBarry Smith *reason = SNES_CONVERGED_FNORM_ABS; 67643e71028SBarry Smith } else if (snes->nfuncs >= snes->max_funcs) { 677ae15b995SBarry Smith ierr = PetscInfo2(snes,"Exceeded maximum number of function evaluations: %D > %D\n",snes->nfuncs,snes->max_funcs);CHKERRQ(ierr); 678184914b5SBarry Smith *reason = SNES_DIVERGED_FUNCTION_COUNT; 67906ee9f85SBarry Smith } 68006ee9f85SBarry Smith 68106ee9f85SBarry Smith if (it && !*reason) { 68206ee9f85SBarry Smith if (fnorm <= snes->ttol) { 6838f1a2a5eSBarry Smith ierr = PetscInfo2(snes,"Converged due to function norm %14.12e < %14.12e (relative tolerance)\n",(double)fnorm,(double)snes->ttol);CHKERRQ(ierr); 68406ee9f85SBarry Smith *reason = SNES_CONVERGED_FNORM_RELATIVE; 685c60f73f4SPeter Brune } else if (snorm < snes->stol*xnorm) { 686c60f73f4SPeter 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); 687c60f73f4SPeter Brune *reason = SNES_CONVERGED_SNORM_RELATIVE; 68806ee9f85SBarry Smith } 689e7e93795SLois Curfman McInnes } 6903a40ed3dSBarry Smith PetscFunctionReturn(0); 691e7e93795SLois Curfman McInnes } 6923f149594SLisandro Dalcin 6933f149594SLisandro Dalcin #undef __FUNCT__ 694e2a6519dSDmitry Karpeev #define __FUNCT__ "SNESConvergedSkip" 6953f149594SLisandro Dalcin /*@C 696e2a6519dSDmitry Karpeev SNESConvergedSkip - Convergence test for SNES that NEVER returns as 6973f149594SLisandro Dalcin converged, UNLESS the maximum number of iteration have been reached. 6983f149594SLisandro Dalcin 6993f9fe445SBarry Smith Logically Collective on SNES 7003f149594SLisandro Dalcin 7013f149594SLisandro Dalcin Input Parameters: 7023f149594SLisandro Dalcin + snes - the SNES context 7033f149594SLisandro Dalcin . it - the iteration (0 indicates before any Newton steps) 7043f149594SLisandro Dalcin . xnorm - 2-norm of current iterate 705c60f73f4SPeter Brune . snorm - 2-norm of current step 7063f149594SLisandro Dalcin . fnorm - 2-norm of function at current iterate 7073f149594SLisandro Dalcin - dummy - unused context 7083f149594SLisandro Dalcin 7093f149594SLisandro Dalcin Output Parameter: 71085385478SLisandro Dalcin . reason - SNES_CONVERGED_ITERATING, SNES_CONVERGED_ITS, or SNES_DIVERGED_FNORM_NAN 7113f149594SLisandro Dalcin 7123f149594SLisandro Dalcin Notes: 7133f149594SLisandro Dalcin Convergence is then declared after a fixed number of iterations have been used. 7143f149594SLisandro Dalcin 7153f149594SLisandro Dalcin Level: advanced 7163f149594SLisandro Dalcin 7173f149594SLisandro Dalcin .keywords: SNES, nonlinear, skip, converged, convergence 7183f149594SLisandro Dalcin 7193f149594SLisandro Dalcin .seealso: SNESSetConvergenceTest() 7203f149594SLisandro Dalcin @*/ 721e2a6519dSDmitry Karpeev PetscErrorCode SNESConvergedSkip(SNES snes,PetscInt it,PetscReal xnorm,PetscReal snorm,PetscReal fnorm,SNESConvergedReason *reason,void *dummy) 7223f149594SLisandro Dalcin { 7233f149594SLisandro Dalcin PetscErrorCode ierr; 7243f149594SLisandro Dalcin 7253f149594SLisandro Dalcin PetscFunctionBegin; 7260700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 7273f149594SLisandro Dalcin PetscValidPointer(reason,6); 7283f149594SLisandro Dalcin 7293f149594SLisandro Dalcin *reason = SNES_CONVERGED_ITERATING; 7303f149594SLisandro Dalcin 7313f149594SLisandro Dalcin if (fnorm != fnorm) { 7323f149594SLisandro Dalcin ierr = PetscInfo(snes,"Failed to converged, function norm is NaN\n");CHKERRQ(ierr); 7333f149594SLisandro Dalcin *reason = SNES_DIVERGED_FNORM_NAN; 7343f149594SLisandro Dalcin } else if (it == snes->max_its) { 7353f149594SLisandro Dalcin *reason = SNES_CONVERGED_ITS; 7363f149594SLisandro Dalcin } 7373f149594SLisandro Dalcin PetscFunctionReturn(0); 7383f149594SLisandro Dalcin } 7393f149594SLisandro Dalcin 74058c9b817SLisandro Dalcin #undef __FUNCT__ 741fa0ddf94SBarry Smith #define __FUNCT__ "SNESSetWorkVecs" 7428d359177SBarry Smith /*@C 743fa0ddf94SBarry Smith SNESSetWorkVecs - Gets a number of work vectors. 74458c9b817SLisandro Dalcin 74558c9b817SLisandro Dalcin Input Parameters: 74658c9b817SLisandro Dalcin . snes - the SNES context 74758c9b817SLisandro Dalcin . nw - number of work vectors to allocate 74858c9b817SLisandro Dalcin 74958c9b817SLisandro Dalcin Level: developer 75058c9b817SLisandro Dalcin 751fa0ddf94SBarry Smith Developers Note: This is PETSC_EXTERN because it may be used by user written plugin SNES implementations 752fa0ddf94SBarry Smith 75398acb6afSMatthew G Knepley @*/ 754fa0ddf94SBarry Smith PetscErrorCode SNESSetWorkVecs(SNES snes,PetscInt nw) 75558c9b817SLisandro Dalcin { 756c5ed8070SMatthew G. Knepley DM dm; 757c5ed8070SMatthew G. Knepley Vec v; 75858c9b817SLisandro Dalcin PetscErrorCode ierr; 75958c9b817SLisandro Dalcin 76058c9b817SLisandro Dalcin PetscFunctionBegin; 76158c9b817SLisandro Dalcin if (snes->work) {ierr = VecDestroyVecs(snes->nwork,&snes->work);CHKERRQ(ierr);} 76258c9b817SLisandro Dalcin snes->nwork = nw; 763f5af7f23SKarl Rupp 764c5ed8070SMatthew G. Knepley ierr = SNESGetDM(snes, &dm);CHKERRQ(ierr); 765c5ed8070SMatthew G. Knepley ierr = DMGetGlobalVector(dm, &v);CHKERRQ(ierr); 766c5ed8070SMatthew G. Knepley ierr = VecDuplicateVecs(v,snes->nwork,&snes->work);CHKERRQ(ierr); 767c5ed8070SMatthew G. Knepley ierr = DMRestoreGlobalVector(dm, &v);CHKERRQ(ierr); 76858c9b817SLisandro Dalcin ierr = PetscLogObjectParents(snes,nw,snes->work);CHKERRQ(ierr); 76958c9b817SLisandro Dalcin PetscFunctionReturn(0); 77058c9b817SLisandro Dalcin } 771