1e7e93795SLois Curfman McInnes 2af0996ceSBarry Smith #include <petsc/private/snesimpl.h> /*I "petsc/private/snesimpl.h" I*/ 3636fd056SMatthew G. Knepley #include <petscdm.h> 4ea844a1aSMatthew Knepley #include <petscsection.h> 52e7541e6SPeter Brune #include <petscblaslapack.h> 6e7e93795SLois Curfman McInnes 73f1db9ecSBarry Smith /*@C 8*f6dfbefdSBarry Smith SNESMonitorSolution - Monitors progress of the `SNES` solvers by calling 9*f6dfbefdSBarry Smith `VecView()` for the approximate solution at each iteration. 103f1db9ecSBarry Smith 11*f6dfbefdSBarry Smith Collective on snes 123f1db9ecSBarry Smith 133f1db9ecSBarry Smith Input Parameters: 14*f6dfbefdSBarry Smith + snes - the `SNES` context 153f1db9ecSBarry Smith . its - iteration number 164b27c08aSLois Curfman McInnes . fgnorm - 2-norm of residual 17f55353a2SBarry Smith - dummy - a viewer 183f1db9ecSBarry Smith 19*f6dfbefdSBarry Smith Options Database Key: 20ee32d87aSMatthew G. Knepley . -snes_monitor_solution [ascii binary draw][:filename][:viewer format] - plots solution at each iteration 21ee32d87aSMatthew G. Knepley 22*f6dfbefdSBarry Smith Note: 233a61192cSBarry Smith This is not called directly by users, rather one calls `SNESMonitorSet()`, with this function as an argument, to cause the monitor 24*f6dfbefdSBarry Smith to be used during the `SNESSolve()` 253a61192cSBarry Smith 2636851e7fSLois Curfman McInnes Level: intermediate 273f1db9ecSBarry Smith 28*f6dfbefdSBarry Smith .seealso: `SNES`, `SNESMonitorSet()`, `SNESMonitorDefault()`, `VecView()` 293f1db9ecSBarry Smith @*/ 309371c9d4SSatish Balay PetscErrorCode SNESMonitorSolution(SNES snes, PetscInt its, PetscReal fgnorm, PetscViewerAndFormat *vf) { 313f1db9ecSBarry Smith Vec x; 32d43b4f6eSBarry Smith PetscViewer viewer = vf->viewer; 333f1db9ecSBarry Smith 343f1db9ecSBarry Smith PetscFunctionBegin; 354d4332d5SBarry Smith PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 4); 369566063dSJacob Faibussowitsch PetscCall(SNESGetSolution(snes, &x)); 379566063dSJacob Faibussowitsch PetscCall(PetscViewerPushFormat(viewer, vf->format)); 389566063dSJacob Faibussowitsch PetscCall(VecView(x, viewer)); 399566063dSJacob Faibussowitsch PetscCall(PetscViewerPopFormat(viewer)); 403f1db9ecSBarry Smith PetscFunctionReturn(0); 413f1db9ecSBarry Smith } 423f1db9ecSBarry Smith 435ed2d596SBarry Smith /*@C 44*f6dfbefdSBarry Smith SNESMonitorResidual - Monitors progress of the `SNES` solvers by calling 45*f6dfbefdSBarry Smith `VecView()` for the residual at each iteration. 465ed2d596SBarry Smith 47*f6dfbefdSBarry Smith Collective on snes 485ed2d596SBarry Smith 495ed2d596SBarry Smith Input Parameters: 50*f6dfbefdSBarry Smith + snes - the `SNES` context 515ed2d596SBarry Smith . its - iteration number 524b27c08aSLois Curfman McInnes . fgnorm - 2-norm of residual 53f55353a2SBarry Smith - dummy - a viewer 545ed2d596SBarry Smith 55*f6dfbefdSBarry Smith Options Database Key: 56ee32d87aSMatthew G. Knepley . -snes_monitor_residual [ascii binary draw][:filename][:viewer format] - plots residual (not its norm) at each iteration 57ee32d87aSMatthew G. Knepley 58*f6dfbefdSBarry Smith Note: 593a61192cSBarry Smith This is not called directly by users, rather one calls `SNESMonitorSet()`, with this function as an argument, to cause the monitor 603a61192cSBarry Smith to be used during the SNES solve. 613a61192cSBarry Smith 625ed2d596SBarry Smith Level: intermediate 635ed2d596SBarry Smith 64*f6dfbefdSBarry Smith .seealso: `SNESMonitorSet()`, `SNESMonitorDefault()`, `VecView()`, `SNESMonitor()` 655ed2d596SBarry Smith @*/ 669371c9d4SSatish Balay PetscErrorCode SNESMonitorResidual(SNES snes, PetscInt its, PetscReal fgnorm, PetscViewerAndFormat *vf) { 675ed2d596SBarry Smith Vec x; 685ed2d596SBarry Smith 695ed2d596SBarry Smith PetscFunctionBegin; 70*f6dfbefdSBarry Smith PetscValidHeaderSpecific(vf->viewer, PETSC_VIEWER_CLASSID, 4); 719566063dSJacob Faibussowitsch PetscCall(SNESGetFunction(snes, &x, NULL, NULL)); 72*f6dfbefdSBarry Smith PetscCall(PetscViewerPushFormat(vf->viewer, vf->format)); 73*f6dfbefdSBarry Smith PetscCall(VecView(x, vf->viewer)); 74*f6dfbefdSBarry Smith PetscCall(PetscViewerPopFormat(vf->viewer)); 755ed2d596SBarry Smith PetscFunctionReturn(0); 765ed2d596SBarry Smith } 775ed2d596SBarry Smith 78d132466eSBarry Smith /*@C 79*f6dfbefdSBarry Smith SNESMonitorSolutionUpdate - Monitors progress of the `SNES` solvers by calling 80*f6dfbefdSBarry Smith `VecView()` for the UPDATE to the solution at each iteration. 81d132466eSBarry Smith 82*f6dfbefdSBarry Smith Collective on snes 83d132466eSBarry Smith 84d132466eSBarry Smith Input Parameters: 85*f6dfbefdSBarry Smith + snes - the `SNES` context 86d132466eSBarry Smith . its - iteration number 874b27c08aSLois Curfman McInnes . fgnorm - 2-norm of residual 88f55353a2SBarry Smith - dummy - a viewer 89d132466eSBarry Smith 90*f6dfbefdSBarry Smith Options Database Key: 91ee32d87aSMatthew G. Knepley . -snes_monitor_solution_update [ascii binary draw][:filename][:viewer format] - plots update to solution at each iteration 92ee32d87aSMatthew G. Knepley 93*f6dfbefdSBarry Smith Note: 943a61192cSBarry Smith This is not called directly by users, rather one calls `SNESMonitorSet()`, with this function as an argument, to cause the monitor 953a61192cSBarry Smith to be used during the SNES solve. 963a61192cSBarry Smith 97d132466eSBarry Smith Level: intermediate 98d132466eSBarry Smith 99*f6dfbefdSBarry Smith .seealso: `SNESMonitorSet()`, `SNESMonitorDefault()`, `VecView()`, `SNESMonitor()`, `SNESMonitor()` 100d132466eSBarry Smith @*/ 1019371c9d4SSatish Balay PetscErrorCode SNESMonitorSolutionUpdate(SNES snes, PetscInt its, PetscReal fgnorm, PetscViewerAndFormat *vf) { 102d132466eSBarry Smith Vec x; 103d43b4f6eSBarry Smith PetscViewer viewer = vf->viewer; 104d132466eSBarry Smith 105d132466eSBarry Smith PetscFunctionBegin; 1064d4332d5SBarry Smith PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 4); 1079566063dSJacob Faibussowitsch PetscCall(SNESGetSolutionUpdate(snes, &x)); 1089566063dSJacob Faibussowitsch PetscCall(PetscViewerPushFormat(viewer, vf->format)); 1099566063dSJacob Faibussowitsch PetscCall(VecView(x, viewer)); 1109566063dSJacob Faibussowitsch PetscCall(PetscViewerPopFormat(viewer)); 111d132466eSBarry Smith PetscFunctionReturn(0); 112d132466eSBarry Smith } 113d132466eSBarry Smith 114798534f6SMatthew G. Knepley #include <petscdraw.h> 115a5c2985bSBarry Smith 116798534f6SMatthew G. Knepley /*@C 117*f6dfbefdSBarry Smith KSPMonitorSNESResidual - Prints the `SNES` residual norm, as well as the `KSP` residual norm, at each iteration of an iterative solver. 118798534f6SMatthew G. Knepley 119798534f6SMatthew G. Knepley Collective on ksp 120a5c2985bSBarry Smith 121a5c2985bSBarry Smith Input Parameters: 122a5c2985bSBarry Smith + ksp - iterative context 123a5c2985bSBarry Smith . n - iteration number 124a5c2985bSBarry Smith . rnorm - 2-norm (preconditioned) residual value (may be estimated). 125798534f6SMatthew G. Knepley - vf - The viewer context 126798534f6SMatthew G. Knepley 127798534f6SMatthew G. Knepley Options Database Key: 128*f6dfbefdSBarry Smith . -snes_monitor_ksp - Activates `KSPMonitorSNESResidual()` 129a5c2985bSBarry Smith 130*f6dfbefdSBarry Smith Note: 1313a61192cSBarry Smith This is not called directly by users, rather one calls `KSPMonitorSet()`, with this function as an argument, to cause the monitor 1323a61192cSBarry Smith to be used during the KSP solve. 1333a61192cSBarry Smith 134a5c2985bSBarry Smith Level: intermediate 135a5c2985bSBarry Smith 136*f6dfbefdSBarry Smith .seealso: `KSPMonitorSet()`, `KSPMonitorResidual()`, `KSPMonitorTrueResidualMaxNorm()`, `KSPMonitor()`, `SNESMonitor()` 137a5c2985bSBarry Smith @*/ 1389371c9d4SSatish Balay PetscErrorCode KSPMonitorSNESResidual(KSP ksp, PetscInt n, PetscReal rnorm, PetscViewerAndFormat *vf) { 139798534f6SMatthew G. Knepley PetscViewer viewer = vf->viewer; 140798534f6SMatthew G. Knepley PetscViewerFormat format = vf->format; 141798534f6SMatthew G. Knepley SNES snes = (SNES)vf->data; 142a5c2985bSBarry Smith Vec snes_solution, work1, work2; 143a5c2985bSBarry Smith PetscReal snorm; 144798534f6SMatthew G. Knepley PetscInt tablevel; 145798534f6SMatthew G. Knepley const char *prefix; 146a5c2985bSBarry Smith 147a5c2985bSBarry Smith PetscFunctionBegin; 148798534f6SMatthew G. Knepley PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 4); 1499566063dSJacob Faibussowitsch PetscCall(SNESGetSolution(snes, &snes_solution)); 1509566063dSJacob Faibussowitsch PetscCall(VecDuplicate(snes_solution, &work1)); 1519566063dSJacob Faibussowitsch PetscCall(VecDuplicate(snes_solution, &work2)); 1529566063dSJacob Faibussowitsch PetscCall(KSPBuildSolution(ksp, work1, NULL)); 1539566063dSJacob Faibussowitsch PetscCall(VecAYPX(work1, -1.0, snes_solution)); 1549566063dSJacob Faibussowitsch PetscCall(SNESComputeFunction(snes, work1, work2)); 1559566063dSJacob Faibussowitsch PetscCall(VecNorm(work2, NORM_2, &snorm)); 1569566063dSJacob Faibussowitsch PetscCall(VecDestroy(&work1)); 1579566063dSJacob Faibussowitsch PetscCall(VecDestroy(&work2)); 158a5c2985bSBarry Smith 1599566063dSJacob Faibussowitsch PetscCall(PetscObjectGetTabLevel((PetscObject)ksp, &tablevel)); 1609566063dSJacob Faibussowitsch PetscCall(PetscObjectGetOptionsPrefix((PetscObject)ksp, &prefix)); 1619566063dSJacob Faibussowitsch PetscCall(PetscViewerPushFormat(viewer, format)); 1629566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIAddTab(viewer, tablevel)); 1639566063dSJacob Faibussowitsch if (n == 0 && prefix) PetscCall(PetscViewerASCIIPrintf(viewer, " Residual norms for %s solve.\n", prefix)); 16463a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "%3" PetscInt_FMT " SNES Residual norm %5.3e KSP Residual norm %5.3e \n", n, (double)snorm, (double)rnorm)); 1659566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIISubtractTab(viewer, tablevel)); 1669566063dSJacob Faibussowitsch PetscCall(PetscViewerPopFormat(viewer)); 167a5c2985bSBarry Smith PetscFunctionReturn(0); 168a5c2985bSBarry Smith } 169a5c2985bSBarry Smith 170e5f7ee39SBarry Smith /*@C 171*f6dfbefdSBarry Smith KSPMonitorSNESResidualDrawLG - Plots the linear `KSP` residual norm and the `SNES` residual norm at each iteration of an iterative solver. 172e5f7ee39SBarry Smith 173798534f6SMatthew G. Knepley Collective on ksp 174e5f7ee39SBarry Smith 175e5f7ee39SBarry Smith Input Parameters: 176798534f6SMatthew G. Knepley + ksp - iterative context 177798534f6SMatthew G. Knepley . n - iteration number 178798534f6SMatthew G. Knepley . rnorm - 2-norm (preconditioned) residual value (may be estimated). 179*f6dfbefdSBarry Smith - vf - The viewer context, created with `KSPMonitorSNESResidualDrawLGCreate()` 180e5f7ee39SBarry Smith 181e5f7ee39SBarry Smith Options Database Key: 182*f6dfbefdSBarry Smith . -snes_monitor_ksp draw::draw_lg - Activates `KSPMonitorSNESResidualDrawLG()` 183e5f7ee39SBarry Smith 184*f6dfbefdSBarry Smith Note: 1853a61192cSBarry Smith This is not called directly by users, rather one calls `SNESMonitorSet()`, with this function as an argument, to cause the monitor 186*f6dfbefdSBarry Smith to be used during the `SNESSolve()` 1873a61192cSBarry Smith 188e5f7ee39SBarry Smith Level: intermediate 189e5f7ee39SBarry Smith 190*f6dfbefdSBarry Smith .seealso: `KSPMonitorSet()`, `KSPMonitorTrueResidual()`, `SNESMonitor()`, `KSPMonitor()`, `KSPMonitorSNESResidualDrawLGCreate()` 191e5f7ee39SBarry Smith @*/ 1929371c9d4SSatish Balay PetscErrorCode KSPMonitorSNESResidualDrawLG(KSP ksp, PetscInt n, PetscReal rnorm, PetscViewerAndFormat *vf) { 193798534f6SMatthew G. Knepley PetscViewer viewer = vf->viewer; 194798534f6SMatthew G. Knepley PetscViewerFormat format = vf->format; 195798534f6SMatthew G. Knepley PetscDrawLG lg = vf->lg; 196798534f6SMatthew G. Knepley SNES snes = (SNES)vf->data; 197e5f7ee39SBarry Smith Vec snes_solution, work1, work2; 198798534f6SMatthew G. Knepley PetscReal snorm; 199798534f6SMatthew G. Knepley KSPConvergedReason reason; 200798534f6SMatthew G. Knepley PetscReal x[2], y[2]; 201e5f7ee39SBarry Smith 202e5f7ee39SBarry Smith PetscFunctionBegin; 203798534f6SMatthew G. Knepley PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 4); 204064a246eSJacob Faibussowitsch PetscValidHeaderSpecific(lg, PETSC_DRAWLG_CLASSID, 4); 2059566063dSJacob Faibussowitsch PetscCall(SNESGetSolution(snes, &snes_solution)); 2069566063dSJacob Faibussowitsch PetscCall(VecDuplicate(snes_solution, &work1)); 2079566063dSJacob Faibussowitsch PetscCall(VecDuplicate(snes_solution, &work2)); 2089566063dSJacob Faibussowitsch PetscCall(KSPBuildSolution(ksp, work1, NULL)); 2099566063dSJacob Faibussowitsch PetscCall(VecAYPX(work1, -1.0, snes_solution)); 2109566063dSJacob Faibussowitsch PetscCall(SNESComputeFunction(snes, work1, work2)); 2119566063dSJacob Faibussowitsch PetscCall(VecNorm(work2, NORM_2, &snorm)); 2129566063dSJacob Faibussowitsch PetscCall(VecDestroy(&work1)); 2139566063dSJacob Faibussowitsch PetscCall(VecDestroy(&work2)); 214e5f7ee39SBarry Smith 2159566063dSJacob Faibussowitsch PetscCall(PetscViewerPushFormat(viewer, format)); 2169566063dSJacob Faibussowitsch if (!n) PetscCall(PetscDrawLGReset(lg)); 217798534f6SMatthew G. Knepley x[0] = (PetscReal)n; 218798534f6SMatthew G. Knepley if (rnorm > 0.0) y[0] = PetscLog10Real(rnorm); 219798534f6SMatthew G. Knepley else y[0] = -15.0; 220798534f6SMatthew G. Knepley x[1] = (PetscReal)n; 221798534f6SMatthew G. Knepley if (snorm > 0.0) y[1] = PetscLog10Real(snorm); 222798534f6SMatthew G. Knepley else y[1] = -15.0; 2239566063dSJacob Faibussowitsch PetscCall(PetscDrawLGAddPoint(lg, x, y)); 2249566063dSJacob Faibussowitsch PetscCall(KSPGetConvergedReason(ksp, &reason)); 225798534f6SMatthew G. Knepley if (n <= 20 || !(n % 5) || reason) { 2269566063dSJacob Faibussowitsch PetscCall(PetscDrawLGDraw(lg)); 2279566063dSJacob Faibussowitsch PetscCall(PetscDrawLGSave(lg)); 228e5f7ee39SBarry Smith } 2299566063dSJacob Faibussowitsch PetscCall(PetscViewerPopFormat(viewer)); 230e5f7ee39SBarry Smith PetscFunctionReturn(0); 231e5f7ee39SBarry Smith } 232e5f7ee39SBarry Smith 233798534f6SMatthew G. Knepley /*@C 234*f6dfbefdSBarry Smith KSPMonitorSNESResidualDrawLGCreate - Creates the `PetscViewer` used by `KSPMonitorSNESResidualDrawLG()` 235e5f7ee39SBarry Smith 236798534f6SMatthew G. Knepley Collective on ksp 237e5f7ee39SBarry Smith 238798534f6SMatthew G. Knepley Input Parameters: 239b693eab9SMatthew G. Knepley + viewer - The PetscViewer 240798534f6SMatthew G. Knepley . format - The viewer format 241798534f6SMatthew G. Knepley - ctx - An optional user context 242798534f6SMatthew G. Knepley 243798534f6SMatthew G. Knepley Output Parameter: 244798534f6SMatthew G. Knepley . vf - The viewer context 245e5f7ee39SBarry Smith 246e5f7ee39SBarry Smith Level: intermediate 247e5f7ee39SBarry Smith 248*f6dfbefdSBarry Smith .seealso: `KSP`, `SNES`, `KSPMonitorSet()`, `KSPMonitorTrueResidual()` 249e5f7ee39SBarry Smith @*/ 2509371c9d4SSatish Balay PetscErrorCode KSPMonitorSNESResidualDrawLGCreate(PetscViewer viewer, PetscViewerFormat format, void *ctx, PetscViewerAndFormat **vf) { 251798534f6SMatthew G. Knepley const char *names[] = {"linear", "nonlinear"}; 252e5f7ee39SBarry Smith 253e5f7ee39SBarry Smith PetscFunctionBegin; 2549566063dSJacob Faibussowitsch PetscCall(PetscViewerAndFormatCreate(viewer, format, vf)); 255798534f6SMatthew G. Knepley (*vf)->data = ctx; 2569566063dSJacob Faibussowitsch PetscCall(KSPMonitorLGCreate(PetscObjectComm((PetscObject)viewer), NULL, NULL, "Log Residual Norm", 2, names, PETSC_DECIDE, PETSC_DECIDE, 400, 300, &(*vf)->lg)); 257e5f7ee39SBarry Smith PetscFunctionReturn(0); 258e5f7ee39SBarry Smith } 259e5f7ee39SBarry Smith 2609371c9d4SSatish Balay PetscErrorCode SNESMonitorDefaultSetUp(SNES snes, PetscViewerAndFormat *vf) { 261fbcc4530SMatthew G. Knepley PetscFunctionBegin; 26248a46eb9SPierre Jolivet if (vf->format == PETSC_VIEWER_DRAW_LG) PetscCall(KSPMonitorLGCreate(PetscObjectComm((PetscObject)vf->viewer), NULL, NULL, "Log Residual Norm", 1, NULL, PETSC_DECIDE, PETSC_DECIDE, 400, 300, &vf->lg)); 263fbcc4530SMatthew G. Knepley PetscFunctionReturn(0); 264fbcc4530SMatthew G. Knepley } 265fbcc4530SMatthew G. Knepley 2664b828684SBarry Smith /*@C 267*f6dfbefdSBarry Smith SNESMonitorDefault - Monitors progress of the `SNES` solvers (default). 268e7e93795SLois Curfman McInnes 269*f6dfbefdSBarry Smith Collective on snes 270c7afd0dbSLois Curfman McInnes 271e7e93795SLois Curfman McInnes Input Parameters: 272*f6dfbefdSBarry Smith + snes - the `SNES` context 273e7e93795SLois Curfman McInnes . its - iteration number 2744b27c08aSLois Curfman McInnes . fgnorm - 2-norm of residual 275d43b4f6eSBarry Smith - vf - viewer and format structure 276fee21e36SBarry Smith 2773a61192cSBarry Smith Options Database: 2783a61192cSBarry Smith . -snes_monitor - use this function to monitor the convergence of the nonlinear solver 2793a61192cSBarry Smith 280e7e93795SLois Curfman McInnes Notes: 2814b27c08aSLois Curfman McInnes This routine prints the residual norm at each iteration. 282e7e93795SLois Curfman McInnes 2833a61192cSBarry Smith This is not called directly by users, rather one calls `SNESMonitorSet()`, with this function as an argument, to cause the monitor 284*f6dfbefdSBarry Smith to be used during the `SNES` solve. 2853a61192cSBarry Smith 28636851e7fSLois Curfman McInnes Level: intermediate 28736851e7fSLois Curfman McInnes 2883a61192cSBarry Smith .seealso: `SNESMonitorSet()`, `SNESMonitorSolution()`, `SNESMonitorFunction()`, `SNESMonitorSolution()`, `SNESMonitorResidual()`, 2893a61192cSBarry Smith `SNESMonitorSolutionUpdate()`, `SNESMonitorDefault()`, `SNESMonitorScaling()`, `SNESMonitorRange()`, `SNESMonitorRatio()`, 2903a61192cSBarry Smith `SNESMonitorDefaultField()` 291e7e93795SLois Curfman McInnes @*/ 2929371c9d4SSatish Balay PetscErrorCode SNESMonitorDefault(SNES snes, PetscInt its, PetscReal fgnorm, PetscViewerAndFormat *vf) { 293d43b4f6eSBarry Smith PetscViewer viewer = vf->viewer; 294798534f6SMatthew G. Knepley PetscViewerFormat format = vf->format; 295798534f6SMatthew G. Knepley PetscBool isascii, isdraw; 296d132466eSBarry Smith 2973a40ed3dSBarry Smith PetscFunctionBegin; 2984d4332d5SBarry Smith PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 4); 2999566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &isascii)); 3009566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERDRAW, &isdraw)); 3019566063dSJacob Faibussowitsch PetscCall(PetscViewerPushFormat(viewer, format)); 302798534f6SMatthew G. Knepley if (isascii) { 3039566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIAddTab(viewer, ((PetscObject)snes)->tablevel)); 30463a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "%3" PetscInt_FMT " SNES Function norm %14.12e \n", its, (double)fgnorm)); 3059566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIISubtractTab(viewer, ((PetscObject)snes)->tablevel)); 306798534f6SMatthew G. Knepley } else if (isdraw) { 307798534f6SMatthew G. Knepley if (format == PETSC_VIEWER_DRAW_LG) { 308798534f6SMatthew G. Knepley PetscDrawLG lg = (PetscDrawLG)vf->lg; 309798534f6SMatthew G. Knepley PetscReal x, y; 310798534f6SMatthew G. Knepley 311798534f6SMatthew G. Knepley PetscValidHeaderSpecific(lg, PETSC_DRAWLG_CLASSID, 4); 3129566063dSJacob Faibussowitsch if (!its) PetscCall(PetscDrawLGReset(lg)); 313798534f6SMatthew G. Knepley x = (PetscReal)its; 314798534f6SMatthew G. Knepley if (fgnorm > 0.0) y = PetscLog10Real(fgnorm); 315798534f6SMatthew G. Knepley else y = -15.0; 3169566063dSJacob Faibussowitsch PetscCall(PetscDrawLGAddPoint(lg, &x, &y)); 317798534f6SMatthew G. Knepley if (its <= 20 || !(its % 5) || snes->reason) { 3189566063dSJacob Faibussowitsch PetscCall(PetscDrawLGDraw(lg)); 3199566063dSJacob Faibussowitsch PetscCall(PetscDrawLGSave(lg)); 320798534f6SMatthew G. Knepley } 321798534f6SMatthew G. Knepley } 322798534f6SMatthew G. Knepley } 3239566063dSJacob Faibussowitsch PetscCall(PetscViewerPopFormat(viewer)); 3243a40ed3dSBarry Smith PetscFunctionReturn(0); 325e7e93795SLois Curfman McInnes } 3263f1db9ecSBarry Smith 3271f60017eSBarry Smith /*@C 3281f60017eSBarry Smith SNESMonitorScaling - Monitors the largest value in each row of the Jacobian. 3291f60017eSBarry Smith 330*f6dfbefdSBarry Smith Collective on snes 3311f60017eSBarry Smith 3321f60017eSBarry Smith Input Parameters: 333*f6dfbefdSBarry Smith + snes - the `SNES` context 3341f60017eSBarry Smith . its - iteration number 3351f60017eSBarry Smith . fgnorm - 2-norm of residual 3361f60017eSBarry Smith - vf - viewer and format structure 3371f60017eSBarry Smith 3381f60017eSBarry Smith Notes: 3391f60017eSBarry Smith This routine prints the largest value in each row of the Jacobian 3401f60017eSBarry Smith 3413a61192cSBarry Smith This is not called directly by users, rather one calls `SNESMonitorSet()`, with this function as an argument, to cause the monitor 342*f6dfbefdSBarry Smith to be used during the `SNES` solve. 3433a61192cSBarry Smith 3441f60017eSBarry Smith Level: intermediate 3451f60017eSBarry Smith 346*f6dfbefdSBarry Smith .seealso: `SNESMonitorSet()`, `SNESMonitorSolution()`, `SNESMonitorRange()`, `SNESMonitorJacUpdateSpectrum()` 3471f60017eSBarry Smith @*/ 3489371c9d4SSatish Balay PetscErrorCode SNESMonitorScaling(SNES snes, PetscInt its, PetscReal fgnorm, PetscViewerAndFormat *vf) { 3491f60017eSBarry Smith PetscViewer viewer = vf->viewer; 3501f60017eSBarry Smith KSP ksp; 3511f60017eSBarry Smith Mat J; 3521f60017eSBarry Smith Vec v; 3531f60017eSBarry Smith 3541f60017eSBarry Smith PetscFunctionBegin; 3551f60017eSBarry Smith PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 4); 3569566063dSJacob Faibussowitsch PetscCall(SNESGetKSP(snes, &ksp)); 3579566063dSJacob Faibussowitsch PetscCall(KSPGetOperators(ksp, &J, NULL)); 3589566063dSJacob Faibussowitsch PetscCall(MatCreateVecs(J, &v, NULL)); 3599566063dSJacob Faibussowitsch PetscCall(MatGetRowMaxAbs(J, v, NULL)); 3609566063dSJacob Faibussowitsch PetscCall(PetscViewerPushFormat(viewer, vf->format)); 3619566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIAddTab(viewer, ((PetscObject)snes)->tablevel)); 36263a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "SNES Jacobian maximum row entries\n")); 3639566063dSJacob Faibussowitsch PetscCall(VecView(v, viewer)); 3649566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIISubtractTab(viewer, ((PetscObject)snes)->tablevel)); 3659566063dSJacob Faibussowitsch PetscCall(PetscViewerPopFormat(viewer)); 3669566063dSJacob Faibussowitsch PetscCall(VecDestroy(&v)); 3671f60017eSBarry Smith PetscFunctionReturn(0); 3681f60017eSBarry Smith } 3691f60017eSBarry Smith 370*f6dfbefdSBarry Smith /*@C 371*f6dfbefdSBarry Smith SNESMonitorJacUpdateSpectrum - Monitors the spectrun of the change in the Jacobian from the last Jacobian evaluation 372*f6dfbefdSBarry Smith 373*f6dfbefdSBarry Smith Collective on snes 374*f6dfbefdSBarry Smith 375*f6dfbefdSBarry Smith Input Parameters: 376*f6dfbefdSBarry Smith + snes - the `SNES` context 377*f6dfbefdSBarry Smith . its - iteration number 378*f6dfbefdSBarry Smith . fgnorm - 2-norm of residual 379*f6dfbefdSBarry Smith - vf - viewer and format structure 380*f6dfbefdSBarry Smith 381*f6dfbefdSBarry Smith Option Database Key: 382*f6dfbefdSBarry Smith . -snes_monitor_jacupdate_spectrum - activates this monitor 383*f6dfbefdSBarry Smith 384*f6dfbefdSBarry Smith Notes: 385*f6dfbefdSBarry Smith This routine prints the eigenvalues of the difference in the Jacobians 386*f6dfbefdSBarry Smith 387*f6dfbefdSBarry Smith This is not called directly by users, rather one calls `SNESMonitorSet()`, with this function as an argument, to cause the monitor 388*f6dfbefdSBarry Smith to be used during the `SNES` solve. 389*f6dfbefdSBarry Smith 390*f6dfbefdSBarry Smith Level: intermediate 391*f6dfbefdSBarry Smith 392*f6dfbefdSBarry Smith .seealso: `SNESMonitorSet()`, `SNESMonitorSolution()`, `SNESMonitorRange()` 393*f6dfbefdSBarry Smith @*/ 3949371c9d4SSatish Balay PetscErrorCode SNESMonitorJacUpdateSpectrum(SNES snes, PetscInt it, PetscReal fnorm, PetscViewerAndFormat *vf) { 3952e7541e6SPeter Brune Vec X; 3962e7541e6SPeter Brune Mat J, dJ, dJdense; 397d1e9a80fSBarry Smith PetscErrorCode (*func)(SNES, Vec, Mat, Mat, void *); 3982f96bde4SJose E. Roman PetscInt n; 39923fff9afSBarry Smith PetscBLASInt nb = 0, lwork; 4002e7541e6SPeter Brune PetscReal *eigr, *eigi; 4012e7541e6SPeter Brune PetscScalar *work; 4022e7541e6SPeter Brune PetscScalar *a; 4032e7541e6SPeter Brune 4042e7541e6SPeter Brune PetscFunctionBegin; 4052e7541e6SPeter Brune if (it == 0) PetscFunctionReturn(0); 406*f6dfbefdSBarry Smith /* create the difference between the current update and the current Jacobian */ 4079566063dSJacob Faibussowitsch PetscCall(SNESGetSolution(snes, &X)); 4089566063dSJacob Faibussowitsch PetscCall(SNESGetJacobian(snes, NULL, &J, &func, NULL)); 4099566063dSJacob Faibussowitsch PetscCall(MatDuplicate(J, MAT_COPY_VALUES, &dJ)); 4109566063dSJacob Faibussowitsch PetscCall(SNESComputeJacobian(snes, X, dJ, dJ)); 4119566063dSJacob Faibussowitsch PetscCall(MatAXPY(dJ, -1.0, J, SAME_NONZERO_PATTERN)); 412f5af7f23SKarl Rupp 4132e7541e6SPeter Brune /* compute the spectrum directly */ 4149566063dSJacob Faibussowitsch PetscCall(MatConvert(dJ, MATSEQDENSE, MAT_INITIAL_MATRIX, &dJdense)); 4159566063dSJacob Faibussowitsch PetscCall(MatGetSize(dJ, &n, NULL)); 4169566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(n, &nb)); 4172e7541e6SPeter Brune lwork = 3 * nb; 4189566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(n, &eigr)); 4199566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(n, &eigi)); 4209566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(lwork, &work)); 4219566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(dJdense, &a)); 4222e7541e6SPeter Brune #if !defined(PETSC_USE_COMPLEX) 4232e7541e6SPeter Brune { 4242e7541e6SPeter Brune PetscBLASInt lierr; 4252f96bde4SJose E. Roman PetscInt i; 4269566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF)); 427792fecdfSBarry Smith PetscCallBLAS("LAPACKgeev", LAPACKgeev_("N", "N", &nb, a, &nb, eigr, eigi, NULL, &nb, NULL, &nb, work, &lwork, &lierr)); 42863a3b9bcSJacob Faibussowitsch PetscCheck(!lierr, PETSC_COMM_SELF, PETSC_ERR_LIB, "geev() error %" PetscBLASInt_FMT, lierr); 4299566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPop()); 43063a3b9bcSJacob Faibussowitsch PetscCall(PetscPrintf(PetscObjectComm((PetscObject)snes), "Eigenvalues of J_%" PetscInt_FMT " - J_%" PetscInt_FMT ":\n", it, it - 1)); 43148a46eb9SPierre Jolivet for (i = 0; i < n; i++) PetscCall(PetscPrintf(PetscObjectComm((PetscObject)snes), "%5" PetscInt_FMT ": %20.5g + %20.5gi\n", i, (double)eigr[i], (double)eigi[i])); 4322f96bde4SJose E. Roman } 4339566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArray(dJdense, &a)); 4349566063dSJacob Faibussowitsch PetscCall(MatDestroy(&dJ)); 4359566063dSJacob Faibussowitsch PetscCall(MatDestroy(&dJdense)); 4369566063dSJacob Faibussowitsch PetscCall(PetscFree(eigr)); 4379566063dSJacob Faibussowitsch PetscCall(PetscFree(eigi)); 4389566063dSJacob Faibussowitsch PetscCall(PetscFree(work)); 4392e7541e6SPeter Brune PetscFunctionReturn(0); 4402f96bde4SJose E. Roman #else 4412f96bde4SJose E. Roman SETERRQ(PETSC_COMM_SELF, PETSC_ERR_SUP, "Not coded for complex"); 4422f96bde4SJose E. Roman #endif 4432e7541e6SPeter Brune } 4442e7541e6SPeter Brune 4456ba87a44SLisandro Dalcin PETSC_INTERN PetscErrorCode SNESMonitorRange_Private(SNES, PetscInt, PetscReal *); 4466ba87a44SLisandro Dalcin 4479371c9d4SSatish Balay PetscErrorCode SNESMonitorRange_Private(SNES snes, PetscInt it, PetscReal *per) { 448b271bb04SBarry Smith Vec resid; 449b271bb04SBarry Smith PetscReal rmax, pwork; 450b271bb04SBarry Smith PetscInt i, n, N; 451b271bb04SBarry Smith PetscScalar *r; 452b271bb04SBarry Smith 453b271bb04SBarry Smith PetscFunctionBegin; 4549566063dSJacob Faibussowitsch PetscCall(SNESGetFunction(snes, &resid, NULL, NULL)); 4559566063dSJacob Faibussowitsch PetscCall(VecNorm(resid, NORM_INFINITY, &rmax)); 4569566063dSJacob Faibussowitsch PetscCall(VecGetLocalSize(resid, &n)); 4579566063dSJacob Faibussowitsch PetscCall(VecGetSize(resid, &N)); 4589566063dSJacob Faibussowitsch PetscCall(VecGetArray(resid, &r)); 459b271bb04SBarry Smith pwork = 0.0; 460ad540459SPierre Jolivet for (i = 0; i < n; i++) pwork += (PetscAbsScalar(r[i]) > .20 * rmax); 4611c2dc1cbSBarry Smith PetscCall(MPIU_Allreduce(&pwork, per, 1, MPIU_REAL, MPIU_SUM, PetscObjectComm((PetscObject)snes))); 4629566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(resid, &r)); 463b271bb04SBarry Smith *per = *per / N; 464b271bb04SBarry Smith PetscFunctionReturn(0); 465b271bb04SBarry Smith } 466b271bb04SBarry Smith 467b271bb04SBarry Smith /*@C 468*f6dfbefdSBarry Smith SNESMonitorRange - Prints the percentage of residual elements that are more then 10 percent of the maximum entry in the residual 469b271bb04SBarry Smith 470*f6dfbefdSBarry Smith Collective on snes 471b271bb04SBarry Smith 472b271bb04SBarry Smith Input Parameters: 473b271bb04SBarry Smith + snes - iterative context 474b271bb04SBarry Smith . it - iteration number 475b271bb04SBarry Smith . rnorm - 2-norm (preconditioned) residual value (may be estimated). 476b271bb04SBarry Smith - dummy - unused monitor context 477b271bb04SBarry Smith 478b271bb04SBarry Smith Options Database Key: 479*f6dfbefdSBarry Smith . -snes_monitor_range - Activates `SNESMonitorRange()` 480b271bb04SBarry Smith 481*f6dfbefdSBarry Smith Note: 4823a61192cSBarry Smith This is not called directly by users, rather one calls `SNESMonitorSet()`, with this function as an argument, to cause the monitor 483*f6dfbefdSBarry Smith to be used during the `SNES` solve. 4843a61192cSBarry Smith 485b271bb04SBarry Smith Level: intermediate 486b271bb04SBarry Smith 487*f6dfbefdSBarry Smith .seealso: `SNESMonitorSet()`, `SNESMonitorDefault()`, `SNESMonitorLGCreate()`, `SNESMonitorScaling()` 488b271bb04SBarry Smith @*/ 4899371c9d4SSatish Balay PetscErrorCode SNESMonitorRange(SNES snes, PetscInt it, PetscReal rnorm, PetscViewerAndFormat *vf) { 490b271bb04SBarry Smith PetscReal perc, rel; 491d43b4f6eSBarry Smith PetscViewer viewer = vf->viewer; 492b271bb04SBarry Smith /* should be in a MonitorRangeContext */ 493b271bb04SBarry Smith static PetscReal prev; 494b271bb04SBarry Smith 495b271bb04SBarry Smith PetscFunctionBegin; 4964d4332d5SBarry Smith PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 4); 497b271bb04SBarry Smith if (!it) prev = rnorm; 4989566063dSJacob Faibussowitsch PetscCall(SNESMonitorRange_Private(snes, it, &perc)); 499b271bb04SBarry Smith 500b271bb04SBarry Smith rel = (prev - rnorm) / prev; 501b271bb04SBarry Smith prev = rnorm; 5029566063dSJacob Faibussowitsch PetscCall(PetscViewerPushFormat(viewer, vf->format)); 5039566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIAddTab(viewer, ((PetscObject)snes)->tablevel)); 50463a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "%3" PetscInt_FMT " SNES preconditioned resid norm %14.12e Percent values above 20 percent of maximum %5.2g relative decrease %5.2e ratio %5.2e \n", it, (double)rnorm, (double)(100.0 * perc), (double)rel, (double)(rel / perc))); 5059566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIISubtractTab(viewer, ((PetscObject)snes)->tablevel)); 5069566063dSJacob Faibussowitsch PetscCall(PetscViewerPopFormat(viewer)); 507b271bb04SBarry Smith PetscFunctionReturn(0); 508b271bb04SBarry Smith } 509b271bb04SBarry Smith 5103a7fca6bSBarry Smith /*@C 511*f6dfbefdSBarry Smith SNESMonitorRatio - Monitors progress of the `SNES` solvers by printing the ratio 5124b27c08aSLois Curfman McInnes of residual norm at each iteration to the previous. 5133a7fca6bSBarry Smith 514*f6dfbefdSBarry Smith Collective on snes 5153a7fca6bSBarry Smith 5163a7fca6bSBarry Smith Input Parameters: 517*f6dfbefdSBarry Smith + snes - the `SNES` context 5183a7fca6bSBarry Smith . its - iteration number 5193a7fca6bSBarry Smith . fgnorm - 2-norm of residual (or gradient) 520eabae89aSBarry Smith - dummy - context of monitor 5213a7fca6bSBarry Smith 522*f6dfbefdSBarry Smith Option Database Key: 523*f6dfbefdSBarry Smith . -snes_monitor_ratio - activate this monitor 524*f6dfbefdSBarry Smith 5253a7fca6bSBarry Smith Level: intermediate 5263a7fca6bSBarry Smith 52795452b02SPatrick Sanan Notes: 5283a61192cSBarry Smith This is not called directly by users, rather one calls `SNESMonitorSet()`, with this function as an argument, to cause the monitor 529*f6dfbefdSBarry Smith to be used during the `SNES` solve. 5303a61192cSBarry Smith 531*f6dfbefdSBarry Smith Be sure to call `SNESMonitorRationSetUp()` before using this monitor. 5323a61192cSBarry Smith 533*f6dfbefdSBarry Smith .seealso: `SNESMonitorRationSetUp()`, `SNESMonitorSet()`, `SNESMonitorSolution()`, `SNESMonitorDefault()` 5343a7fca6bSBarry Smith @*/ 5359371c9d4SSatish Balay PetscErrorCode SNESMonitorRatio(SNES snes, PetscInt its, PetscReal fgnorm, PetscViewerAndFormat *vf) { 53677431f27SBarry Smith PetscInt len; 53787828ca2SBarry Smith PetscReal *history; 538d43b4f6eSBarry Smith PetscViewer viewer = vf->viewer; 5393a7fca6bSBarry Smith 5403a7fca6bSBarry Smith PetscFunctionBegin; 5419566063dSJacob Faibussowitsch PetscCall(SNESGetConvergenceHistory(snes, &history, NULL, &len)); 5429566063dSJacob Faibussowitsch PetscCall(PetscViewerPushFormat(viewer, vf->format)); 5439566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIAddTab(viewer, ((PetscObject)snes)->tablevel)); 544958c9bccSBarry Smith if (!its || !history || its > len) { 54563a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "%3" PetscInt_FMT " SNES Function norm %14.12e \n", its, (double)fgnorm)); 5463a7fca6bSBarry Smith } else { 54787828ca2SBarry Smith PetscReal ratio = fgnorm / history[its - 1]; 54863a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "%3" PetscInt_FMT " SNES Function norm %14.12e %14.12e \n", its, (double)fgnorm, (double)ratio)); 5493a7fca6bSBarry Smith } 5509566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIISubtractTab(viewer, ((PetscObject)snes)->tablevel)); 5519566063dSJacob Faibussowitsch PetscCall(PetscViewerPopFormat(viewer)); 5523a7fca6bSBarry Smith PetscFunctionReturn(0); 5533a7fca6bSBarry Smith } 5543a7fca6bSBarry Smith 5553a7fca6bSBarry Smith /*@C 556*f6dfbefdSBarry Smith SNESMonitorRatioSetUp - Insures the `SNES` object is saving its history since this monitor needs access to it 5573a7fca6bSBarry Smith 558*f6dfbefdSBarry Smith Collective on snes 5593a7fca6bSBarry Smith 5603a7fca6bSBarry Smith Input Parameters: 561*f6dfbefdSBarry Smith + snes - the `SNES` context 562*f6dfbefdSBarry Smith - viewer - the `PetscViewer` object (ignored) 5633a7fca6bSBarry Smith 5643a7fca6bSBarry Smith Level: intermediate 5653a7fca6bSBarry Smith 566db781477SPatrick Sanan .seealso: `SNESMonitorSet()`, `SNESMonitorSolution()`, `SNESMonitorDefault()`, `SNESMonitorRatio()` 5673a7fca6bSBarry Smith @*/ 5689371c9d4SSatish Balay PetscErrorCode SNESMonitorRatioSetUp(SNES snes, PetscViewerAndFormat *vf) { 56987828ca2SBarry Smith PetscReal *history; 5703a7fca6bSBarry Smith 5713a7fca6bSBarry Smith PetscFunctionBegin; 5729566063dSJacob Faibussowitsch PetscCall(SNESGetConvergenceHistory(snes, &history, NULL, NULL)); 57348a46eb9SPierre Jolivet if (!history) PetscCall(SNESSetConvergenceHistory(snes, NULL, NULL, 100, PETSC_TRUE)); 5743a7fca6bSBarry Smith PetscFunctionReturn(0); 5753a7fca6bSBarry Smith } 5763a7fca6bSBarry Smith 577be1f7002SBarry Smith /* 578a6570f20SBarry Smith Default (short) SNES Monitor, same as SNESMonitorDefault() except 579be1f7002SBarry Smith it prints fewer digits of the residual as the residual gets smaller. 580be1f7002SBarry Smith This is because the later digits are meaningless and are often 581be1f7002SBarry Smith different on different machines; by using this routine different 582be1f7002SBarry Smith machines will usually generate the same output. 583dec21524SBarry Smith 584dec21524SBarry Smith Deprecated: Intentionally has no manual page 585be1f7002SBarry Smith */ 5869371c9d4SSatish Balay PetscErrorCode SNESMonitorDefaultShort(SNES snes, PetscInt its, PetscReal fgnorm, PetscViewerAndFormat *vf) { 587d43b4f6eSBarry Smith PetscViewer viewer = vf->viewer; 588d132466eSBarry Smith 5893a40ed3dSBarry Smith PetscFunctionBegin; 5904d4332d5SBarry Smith PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 4); 5919566063dSJacob Faibussowitsch PetscCall(PetscViewerPushFormat(viewer, vf->format)); 5929566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIAddTab(viewer, ((PetscObject)snes)->tablevel)); 5938f240d10SBarry Smith if (fgnorm > 1.e-9) { 59463a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "%3" PetscInt_FMT " SNES Function norm %g \n", its, (double)fgnorm)); 5953a40ed3dSBarry Smith } else if (fgnorm > 1.e-11) { 59663a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "%3" PetscInt_FMT " SNES Function norm %5.3e \n", its, (double)fgnorm)); 5973a40ed3dSBarry Smith } else { 59863a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "%3" PetscInt_FMT " SNES Function norm < 1.e-11\n", its)); 599a34d58ebSBarry Smith } 6009566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIISubtractTab(viewer, ((PetscObject)snes)->tablevel)); 6019566063dSJacob Faibussowitsch PetscCall(PetscViewerPopFormat(viewer)); 6023a40ed3dSBarry Smith PetscFunctionReturn(0); 603e7e93795SLois Curfman McInnes } 6042db13446SMatthew G. Knepley 6052db13446SMatthew G. Knepley /*@C 606*f6dfbefdSBarry Smith SNESMonitorDefaultField - Monitors progress of the `SNES` solvers, separated into fields. 6072db13446SMatthew G. Knepley 608*f6dfbefdSBarry Smith Collective on snes 6092db13446SMatthew G. Knepley 6102db13446SMatthew G. Knepley Input Parameters: 611*f6dfbefdSBarry Smith + snes - the `SNES` context 6122db13446SMatthew G. Knepley . its - iteration number 6132db13446SMatthew G. Knepley . fgnorm - 2-norm of residual 6142db13446SMatthew G. Knepley - ctx - the PetscViewer 6152db13446SMatthew G. Knepley 616*f6dfbefdSBarry Smith Option Database Key: 617*f6dfbefdSBarry Smith . -snes_monitor_field - activate this monitor 618*f6dfbefdSBarry Smith 6192db13446SMatthew G. Knepley Notes: 620*f6dfbefdSBarry Smith This routine uses the `DM` attached to the residual vector to define the fields. 6213a61192cSBarry Smith 6223a61192cSBarry Smith This is not called directly by users, rather one calls `SNESMonitorSet()`, with this function as an argument, to cause the monitor 623*f6dfbefdSBarry Smith to be used during the `SNES` solve. 6242db13446SMatthew G. Knepley 6252db13446SMatthew G. Knepley Level: intermediate 6262db13446SMatthew G. Knepley 627db781477SPatrick Sanan .seealso: `SNESMonitorSet()`, `SNESMonitorSolution()`, `SNESMonitorDefault()` 6282db13446SMatthew G. Knepley @*/ 6299371c9d4SSatish Balay PetscErrorCode SNESMonitorDefaultField(SNES snes, PetscInt its, PetscReal fgnorm, PetscViewerAndFormat *vf) { 630d43b4f6eSBarry Smith PetscViewer viewer = vf->viewer; 6312db13446SMatthew G. Knepley Vec r; 6322db13446SMatthew G. Knepley DM dm; 6332db13446SMatthew G. Knepley PetscReal res[256]; 6342db13446SMatthew G. Knepley PetscInt tablevel; 6352db13446SMatthew G. Knepley 6362db13446SMatthew G. Knepley PetscFunctionBegin; 6374d4332d5SBarry Smith PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 4); 6389566063dSJacob Faibussowitsch PetscCall(SNESGetFunction(snes, &r, NULL, NULL)); 6399566063dSJacob Faibussowitsch PetscCall(VecGetDM(r, &dm)); 6409566063dSJacob Faibussowitsch if (!dm) PetscCall(SNESMonitorDefault(snes, its, fgnorm, vf)); 6412db13446SMatthew G. Knepley else { 6422db13446SMatthew G. Knepley PetscSection s, gs; 6432db13446SMatthew G. Knepley PetscInt Nf, f; 6442db13446SMatthew G. Knepley 6459566063dSJacob Faibussowitsch PetscCall(DMGetLocalSection(dm, &s)); 6469566063dSJacob Faibussowitsch PetscCall(DMGetGlobalSection(dm, &gs)); 6479566063dSJacob Faibussowitsch if (!s || !gs) PetscCall(SNESMonitorDefault(snes, its, fgnorm, vf)); 6489566063dSJacob Faibussowitsch PetscCall(PetscSectionGetNumFields(s, &Nf)); 64963a3b9bcSJacob Faibussowitsch PetscCheck(Nf <= 256, PetscObjectComm((PetscObject)snes), PETSC_ERR_SUP, "Do not support %" PetscInt_FMT " fields > 256", Nf); 6509566063dSJacob Faibussowitsch PetscCall(PetscSectionVecNorm(s, gs, r, NORM_2, res)); 6519566063dSJacob Faibussowitsch PetscCall(PetscObjectGetTabLevel((PetscObject)snes, &tablevel)); 6529566063dSJacob Faibussowitsch PetscCall(PetscViewerPushFormat(viewer, vf->format)); 6539566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIAddTab(viewer, tablevel)); 65463a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "%3" PetscInt_FMT " SNES Function norm %14.12e [", its, (double)fgnorm)); 6552db13446SMatthew G. Knepley for (f = 0; f < Nf; ++f) { 6569566063dSJacob Faibussowitsch if (f) PetscCall(PetscViewerASCIIPrintf(viewer, ", ")); 65763a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "%14.12e", (double)res[f])); 6582db13446SMatthew G. Knepley } 6599566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "] \n")); 6609566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIISubtractTab(viewer, tablevel)); 6619566063dSJacob Faibussowitsch PetscCall(PetscViewerPopFormat(viewer)); 6622db13446SMatthew G. Knepley } 6632db13446SMatthew G. Knepley PetscFunctionReturn(0); 6642db13446SMatthew G. Knepley } 665*f6dfbefdSBarry Smith 6664b828684SBarry Smith /*@C 667c34cbdceSBarry Smith SNESConvergedDefault - Default onvergence test of the solvers for 668c34cbdceSBarry Smith systems of nonlinear equations. 669e7e93795SLois Curfman McInnes 670*f6dfbefdSBarry Smith Collective on snes 671c7afd0dbSLois Curfman McInnes 672e7e93795SLois Curfman McInnes Input Parameters: 673*f6dfbefdSBarry Smith + snes - the `SNES` context 67406ee9f85SBarry Smith . it - the iteration (0 indicates before any Newton steps) 675e7e93795SLois Curfman McInnes . xnorm - 2-norm of current iterate 676c60f73f4SPeter Brune . snorm - 2-norm of current step 6777f3332b4SBarry Smith . fnorm - 2-norm of function at current iterate 678c7afd0dbSLois Curfman McInnes - dummy - unused context 679e7e93795SLois Curfman McInnes 680184914b5SBarry Smith Output Parameter: 681184914b5SBarry Smith . reason - one of 682*f6dfbefdSBarry Smith .vb 683*f6dfbefdSBarry Smith SNES_CONVERGED_FNORM_ABS - (fnorm < abstol), 684*f6dfbefdSBarry Smith SNES_CONVERGED_SNORM_RELATIVE - (snorm < stol*xnorm), 685*f6dfbefdSBarry Smith SNES_CONVERGED_FNORM_RELATIVE - (fnorm < rtol*fnorm0), 686*f6dfbefdSBarry Smith SNES_DIVERGED_FUNCTION_COUNT - (nfct > maxf), 687*f6dfbefdSBarry Smith SNES_DIVERGED_FNORM_NAN - (fnorm == NaN), 688*f6dfbefdSBarry Smith SNES_CONVERGED_ITERATING - (otherwise), 689*f6dfbefdSBarry Smith SNES_DIVERGED_DTOL - (fnorm > divtol*snes->fnorm0) 690*f6dfbefdSBarry Smith .ve 691e7e93795SLois Curfman McInnes 692e7e93795SLois Curfman McInnes where 693*f6dfbefdSBarry Smith + maxf - maximum number of function evaluations, set with `SNESSetTolerances()` 694c7afd0dbSLois Curfman McInnes . nfct - number of function evaluations, 695*f6dfbefdSBarry Smith . abstol - absolute function norm tolerance, set with `SNESSetTolerances()` 696*f6dfbefdSBarry Smith . rtol - relative function norm tolerance, set with `SNESSetTolerances()` 697*f6dfbefdSBarry Smith . divtol - divergence tolerance, set with `SNESSetDivergenceTolerance()` 698c34cbdceSBarry Smith - fnorm0 - 2-norm of the function at the initial solution (initial guess; zeroth iteration) 699c34cbdceSBarry Smith 700c34cbdceSBarry Smith Options Database Keys: 701*f6dfbefdSBarry Smith + -snes_convergence_test default - see `SNESSetFromOptions()` 702f362779dSJed Brown . -snes_stol - convergence tolerance in terms of the norm of the change in the solution between steps 703c34cbdceSBarry Smith . -snes_atol <abstol> - absolute tolerance of residual norm 704c34cbdceSBarry Smith . -snes_rtol <rtol> - relative decrease in tolerance norm from the initial 2-norm of the solution 705c34cbdceSBarry Smith . -snes_divergence_tolerance <divtol> - if the residual goes above divtol*rnorm0, exit with divergence 706c34cbdceSBarry Smith . -snes_max_funcs <max_funcs> - maximum number of function evaluations 707c34cbdceSBarry Smith . -snes_max_fail <max_fail> - maximum number of line search failures allowed before stopping, default is none 708*f6dfbefdSBarry Smith - -snes_max_linear_solve_fail - number of linear solver failures before `SNESSolve()` stops 709fee21e36SBarry Smith 71036851e7fSLois Curfman McInnes Level: intermediate 71136851e7fSLois Curfman McInnes 712*f6dfbefdSBarry Smith .seealso: `SNES`, `SNESSolve()`, `SNESSetConvergenceTest()`, `SNESConvergedSkip()`, `SNESSetTolerances()`, `SNESSetDivergenceTolerance()` 713e7e93795SLois Curfman McInnes @*/ 7149371c9d4SSatish Balay PetscErrorCode SNESConvergedDefault(SNES snes, PetscInt it, PetscReal xnorm, PetscReal snorm, PetscReal fnorm, SNESConvergedReason *reason, void *dummy) { 7153a40ed3dSBarry Smith PetscFunctionBegin; 7160700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 7173f149594SLisandro Dalcin PetscValidPointer(reason, 6); 7183f149594SLisandro Dalcin 71906ee9f85SBarry Smith *reason = SNES_CONVERGED_ITERATING; 72006ee9f85SBarry Smith if (!it) { 72106ee9f85SBarry Smith /* set parameter for default relative tolerance convergence test */ 72206ee9f85SBarry Smith snes->ttol = fnorm * snes->rtol; 723e37c518bSBarry Smith snes->rnorm0 = fnorm; 72406ee9f85SBarry Smith } 7258146f6ebSBarry Smith if (PetscIsInfOrNanReal(fnorm)) { 7269566063dSJacob Faibussowitsch PetscCall(PetscInfo(snes, "Failed to converged, function norm is NaN\n")); 727184914b5SBarry Smith *reason = SNES_DIVERGED_FNORM_NAN; 728be5caee7SBarry Smith } else if (fnorm < snes->abstol && (it || !snes->forceiteration)) { 7299566063dSJacob Faibussowitsch PetscCall(PetscInfo(snes, "Converged due to function norm %14.12e < %14.12e\n", (double)fnorm, (double)snes->abstol)); 730184914b5SBarry Smith *reason = SNES_CONVERGED_FNORM_ABS; 731e71169deSBarry Smith } else if (snes->nfuncs >= snes->max_funcs && snes->max_funcs >= 0) { 73263a3b9bcSJacob Faibussowitsch PetscCall(PetscInfo(snes, "Exceeded maximum number of function evaluations: %" PetscInt_FMT " > %" PetscInt_FMT "\n", snes->nfuncs, snes->max_funcs)); 733184914b5SBarry Smith *reason = SNES_DIVERGED_FUNCTION_COUNT; 73406ee9f85SBarry Smith } 73506ee9f85SBarry Smith 73606ee9f85SBarry Smith if (it && !*reason) { 73706ee9f85SBarry Smith if (fnorm <= snes->ttol) { 7389566063dSJacob Faibussowitsch PetscCall(PetscInfo(snes, "Converged due to function norm %14.12e < %14.12e (relative tolerance)\n", (double)fnorm, (double)snes->ttol)); 73906ee9f85SBarry Smith *reason = SNES_CONVERGED_FNORM_RELATIVE; 740c60f73f4SPeter Brune } else if (snorm < snes->stol * xnorm) { 7419566063dSJacob Faibussowitsch PetscCall(PetscInfo(snes, "Converged due to small update length: %14.12e < %14.12e * %14.12e\n", (double)snorm, (double)snes->stol, (double)xnorm)); 742c60f73f4SPeter Brune *reason = SNES_CONVERGED_SNORM_RELATIVE; 743e4d06f11SPatrick Farrell } else if (snes->divtol > 0 && (fnorm > snes->divtol * snes->rnorm0)) { 7449566063dSJacob Faibussowitsch PetscCall(PetscInfo(snes, "Diverged due to increase in function norm: %14.12e > %14.12e * %14.12e\n", (double)fnorm, (double)snes->divtol, (double)snes->rnorm0)); 745e37c518bSBarry Smith *reason = SNES_DIVERGED_DTOL; 74606ee9f85SBarry Smith } 747e7e93795SLois Curfman McInnes } 7483a40ed3dSBarry Smith PetscFunctionReturn(0); 749e7e93795SLois Curfman McInnes } 7503f149594SLisandro Dalcin 7513f149594SLisandro Dalcin /*@C 752*f6dfbefdSBarry Smith SNESConvergedSkip - Convergence test for `SNES` that NEVER returns as 7533f149594SLisandro Dalcin converged, UNLESS the maximum number of iteration have been reached. 7543f149594SLisandro Dalcin 755*f6dfbefdSBarry Smith Logically Collective on snes 7563f149594SLisandro Dalcin 7573f149594SLisandro Dalcin Input Parameters: 758*f6dfbefdSBarry Smith + snes - the `SNES` context 7593f149594SLisandro Dalcin . it - the iteration (0 indicates before any Newton steps) 7603f149594SLisandro Dalcin . xnorm - 2-norm of current iterate 761c60f73f4SPeter Brune . snorm - 2-norm of current step 7623f149594SLisandro Dalcin . fnorm - 2-norm of function at current iterate 7633f149594SLisandro Dalcin - dummy - unused context 7643f149594SLisandro Dalcin 7653f149594SLisandro Dalcin Output Parameter: 766*f6dfbefdSBarry Smith . reason - `SNES_CONVERGED_ITERATING`, `SNES_CONVERGED_ITS`, or `SNES_DIVERGED_FNORM_NAN` 7673f149594SLisandro Dalcin 768*f6dfbefdSBarry Smith Options Database Key: 769*f6dfbefdSBarry Smith . -snes_convergence_test skip - see `SNESSetFromOptions()` 770f362779dSJed Brown 7713f149594SLisandro Dalcin Level: advanced 7723f149594SLisandro Dalcin 773*f6dfbefdSBarry Smith .seealso: `SNES`, `SNESSolve()`, `SNESConvergedDefault()`, `SNESSetConvergenceTest()` 7743f149594SLisandro Dalcin @*/ 7759371c9d4SSatish Balay PetscErrorCode SNESConvergedSkip(SNES snes, PetscInt it, PetscReal xnorm, PetscReal snorm, PetscReal fnorm, SNESConvergedReason *reason, void *dummy) { 7763f149594SLisandro Dalcin PetscFunctionBegin; 7770700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 7783f149594SLisandro Dalcin PetscValidPointer(reason, 6); 7793f149594SLisandro Dalcin 7803f149594SLisandro Dalcin *reason = SNES_CONVERGED_ITERATING; 7813f149594SLisandro Dalcin 7823f149594SLisandro Dalcin if (fnorm != fnorm) { 7839566063dSJacob Faibussowitsch PetscCall(PetscInfo(snes, "Failed to converged, function norm is NaN\n")); 7843f149594SLisandro Dalcin *reason = SNES_DIVERGED_FNORM_NAN; 7853f149594SLisandro Dalcin } else if (it == snes->max_its) { 7863f149594SLisandro Dalcin *reason = SNES_CONVERGED_ITS; 7873f149594SLisandro Dalcin } 7883f149594SLisandro Dalcin PetscFunctionReturn(0); 7893f149594SLisandro Dalcin } 7903f149594SLisandro Dalcin 7918d359177SBarry Smith /*@C 792*f6dfbefdSBarry Smith SNESSetWorkVecs - Gets a number of work vectors to be used internally by `SNES` solvers 79358c9b817SLisandro Dalcin 79458c9b817SLisandro Dalcin Input Parameters: 795*f6dfbefdSBarry Smith + snes - the `SNES` context 796a2b725a8SWilliam Gropp - nw - number of work vectors to allocate 79758c9b817SLisandro Dalcin 79858c9b817SLisandro Dalcin Level: developer 799fa0ddf94SBarry Smith 80098acb6afSMatthew G Knepley @*/ 8019371c9d4SSatish Balay PetscErrorCode SNESSetWorkVecs(SNES snes, PetscInt nw) { 802c5ed8070SMatthew G. Knepley DM dm; 803c5ed8070SMatthew G. Knepley Vec v; 80458c9b817SLisandro Dalcin 80558c9b817SLisandro Dalcin PetscFunctionBegin; 8069566063dSJacob Faibussowitsch if (snes->work) PetscCall(VecDestroyVecs(snes->nwork, &snes->work)); 80758c9b817SLisandro Dalcin snes->nwork = nw; 808f5af7f23SKarl Rupp 8099566063dSJacob Faibussowitsch PetscCall(SNESGetDM(snes, &dm)); 8109566063dSJacob Faibussowitsch PetscCall(DMGetGlobalVector(dm, &v)); 8119566063dSJacob Faibussowitsch PetscCall(VecDuplicateVecs(v, snes->nwork, &snes->work)); 8129566063dSJacob Faibussowitsch PetscCall(DMRestoreGlobalVector(dm, &v)); 8139566063dSJacob Faibussowitsch PetscCall(PetscLogObjectParents(snes, nw, snes->work)); 81458c9b817SLisandro Dalcin PetscFunctionReturn(0); 81558c9b817SLisandro Dalcin } 816