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 8f6dfbefdSBarry Smith SNESMonitorSolution - Monitors progress of the `SNES` solvers by calling 9f6dfbefdSBarry Smith `VecView()` for the approximate solution at each iteration. 103f1db9ecSBarry Smith 11c3339decSBarry Smith Collective 123f1db9ecSBarry Smith 133f1db9ecSBarry Smith Input Parameters: 14f6dfbefdSBarry 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 19f6dfbefdSBarry Smith Options Database Key: 20ee32d87aSMatthew G. Knepley . -snes_monitor_solution [ascii binary draw][:filename][:viewer format] - plots solution at each iteration 21ee32d87aSMatthew G. Knepley 22dc4c0fb0SBarry Smith Level: intermediate 23dc4c0fb0SBarry Smith 24f6dfbefdSBarry Smith Note: 253a61192cSBarry Smith This is not called directly by users, rather one calls `SNESMonitorSet()`, with this function as an argument, to cause the monitor 26f6dfbefdSBarry Smith to be used during the `SNESSolve()` 273a61192cSBarry Smith 28dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNES`, `SNESMonitorSet()`, `SNESMonitorDefault()`, `VecView()` 293f1db9ecSBarry Smith @*/ 30d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESMonitorSolution(SNES snes, PetscInt its, PetscReal fgnorm, PetscViewerAndFormat *vf) 31d71ae5a4SJacob Faibussowitsch { 323f1db9ecSBarry Smith Vec x; 33d43b4f6eSBarry Smith PetscViewer viewer = vf->viewer; 343f1db9ecSBarry Smith 353f1db9ecSBarry Smith PetscFunctionBegin; 364d4332d5SBarry Smith PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 4); 379566063dSJacob Faibussowitsch PetscCall(SNESGetSolution(snes, &x)); 389566063dSJacob Faibussowitsch PetscCall(PetscViewerPushFormat(viewer, vf->format)); 399566063dSJacob Faibussowitsch PetscCall(VecView(x, viewer)); 409566063dSJacob Faibussowitsch PetscCall(PetscViewerPopFormat(viewer)); 413ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 423f1db9ecSBarry Smith } 433f1db9ecSBarry Smith 445ed2d596SBarry Smith /*@C 45f6dfbefdSBarry Smith SNESMonitorResidual - Monitors progress of the `SNES` solvers by calling 46f6dfbefdSBarry Smith `VecView()` for the residual at each iteration. 475ed2d596SBarry Smith 48c3339decSBarry Smith Collective 495ed2d596SBarry Smith 505ed2d596SBarry Smith Input Parameters: 51f6dfbefdSBarry Smith + snes - the `SNES` context 525ed2d596SBarry Smith . its - iteration number 534b27c08aSLois Curfman McInnes . fgnorm - 2-norm of residual 54f55353a2SBarry Smith - dummy - a viewer 555ed2d596SBarry Smith 56f6dfbefdSBarry Smith Options Database Key: 57ee32d87aSMatthew G. Knepley . -snes_monitor_residual [ascii binary draw][:filename][:viewer format] - plots residual (not its norm) at each iteration 58ee32d87aSMatthew G. Knepley 595ed2d596SBarry Smith Level: intermediate 605ed2d596SBarry Smith 61dc4c0fb0SBarry Smith Note: 62dc4c0fb0SBarry Smith This is not called directly by users, rather one calls `SNESMonitorSet()`, with this function as an argument, to cause the monitor 63dc4c0fb0SBarry Smith to be used during the `SNES` solve. 64dc4c0fb0SBarry Smith 65dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNES`, `SNESMonitorSet()`, `SNESMonitorDefault()`, `VecView()`, `SNESMonitor()` 665ed2d596SBarry Smith @*/ 67d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESMonitorResidual(SNES snes, PetscInt its, PetscReal fgnorm, PetscViewerAndFormat *vf) 68d71ae5a4SJacob Faibussowitsch { 695ed2d596SBarry Smith Vec x; 705ed2d596SBarry Smith 715ed2d596SBarry Smith PetscFunctionBegin; 72f6dfbefdSBarry Smith PetscValidHeaderSpecific(vf->viewer, PETSC_VIEWER_CLASSID, 4); 739566063dSJacob Faibussowitsch PetscCall(SNESGetFunction(snes, &x, NULL, NULL)); 74f6dfbefdSBarry Smith PetscCall(PetscViewerPushFormat(vf->viewer, vf->format)); 75f6dfbefdSBarry Smith PetscCall(VecView(x, vf->viewer)); 76f6dfbefdSBarry Smith PetscCall(PetscViewerPopFormat(vf->viewer)); 773ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 785ed2d596SBarry Smith } 795ed2d596SBarry Smith 80d132466eSBarry Smith /*@C 81f6dfbefdSBarry Smith SNESMonitorSolutionUpdate - Monitors progress of the `SNES` solvers by calling 82f6dfbefdSBarry Smith `VecView()` for the UPDATE to the solution at each iteration. 83d132466eSBarry Smith 84c3339decSBarry Smith Collective 85d132466eSBarry Smith 86d132466eSBarry Smith Input Parameters: 87f6dfbefdSBarry Smith + snes - the `SNES` context 88d132466eSBarry Smith . its - iteration number 894b27c08aSLois Curfman McInnes . fgnorm - 2-norm of residual 90f55353a2SBarry Smith - dummy - a viewer 91d132466eSBarry Smith 92f6dfbefdSBarry Smith Options Database Key: 93ee32d87aSMatthew G. Knepley . -snes_monitor_solution_update [ascii binary draw][:filename][:viewer format] - plots update to solution at each iteration 94ee32d87aSMatthew G. Knepley 95d132466eSBarry Smith Level: intermediate 96d132466eSBarry Smith 97dc4c0fb0SBarry Smith Note: 98dc4c0fb0SBarry Smith This is not called directly by users, rather one calls `SNESMonitorSet()`, with this function as an argument, to cause the monitor 99dc4c0fb0SBarry Smith to be used during the `SNES` solve. 100dc4c0fb0SBarry Smith 101dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNESMonitorSet()`, `SNESMonitorDefault()`, `VecView()`, `SNESMonitor()`, `SNESMonitor()` 102d132466eSBarry Smith @*/ 103d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESMonitorSolutionUpdate(SNES snes, PetscInt its, PetscReal fgnorm, PetscViewerAndFormat *vf) 104d71ae5a4SJacob Faibussowitsch { 105d132466eSBarry Smith Vec x; 106d43b4f6eSBarry Smith PetscViewer viewer = vf->viewer; 107d132466eSBarry Smith 108d132466eSBarry Smith PetscFunctionBegin; 1094d4332d5SBarry Smith PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 4); 1109566063dSJacob Faibussowitsch PetscCall(SNESGetSolutionUpdate(snes, &x)); 1119566063dSJacob Faibussowitsch PetscCall(PetscViewerPushFormat(viewer, vf->format)); 1129566063dSJacob Faibussowitsch PetscCall(VecView(x, viewer)); 1139566063dSJacob Faibussowitsch PetscCall(PetscViewerPopFormat(viewer)); 1143ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 115d132466eSBarry Smith } 116d132466eSBarry Smith 117798534f6SMatthew G. Knepley #include <petscdraw.h> 118a5c2985bSBarry Smith 119798534f6SMatthew G. Knepley /*@C 120f6dfbefdSBarry Smith KSPMonitorSNESResidual - Prints the `SNES` residual norm, as well as the `KSP` residual norm, at each iteration of an iterative solver. 121798534f6SMatthew G. Knepley 122c3339decSBarry Smith Collective 123a5c2985bSBarry Smith 124a5c2985bSBarry Smith Input Parameters: 125a5c2985bSBarry Smith + ksp - iterative context 126a5c2985bSBarry Smith . n - iteration number 127a5c2985bSBarry Smith . rnorm - 2-norm (preconditioned) residual value (may be estimated). 128798534f6SMatthew G. Knepley - vf - The viewer context 129798534f6SMatthew G. Knepley 130798534f6SMatthew G. Knepley Options Database Key: 131f6dfbefdSBarry Smith . -snes_monitor_ksp - Activates `KSPMonitorSNESResidual()` 132a5c2985bSBarry Smith 133a5c2985bSBarry Smith Level: intermediate 134a5c2985bSBarry Smith 135dc4c0fb0SBarry Smith Note: 136dc4c0fb0SBarry Smith This is not called directly by users, rather one calls `KSPMonitorSet()`, with this function as an argument, to cause the monitor 137dc4c0fb0SBarry Smith to be used during the `KSP` solve. 138dc4c0fb0SBarry Smith 139dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `KSPMonitorSet()`, `KSPMonitorResidual()`, `KSPMonitorTrueResidualMaxNorm()`, `KSPMonitor()`, `SNESMonitor()` 140a5c2985bSBarry Smith @*/ 141d71ae5a4SJacob Faibussowitsch PetscErrorCode KSPMonitorSNESResidual(KSP ksp, PetscInt n, PetscReal rnorm, PetscViewerAndFormat *vf) 142d71ae5a4SJacob Faibussowitsch { 143798534f6SMatthew G. Knepley PetscViewer viewer = vf->viewer; 144798534f6SMatthew G. Knepley PetscViewerFormat format = vf->format; 145798534f6SMatthew G. Knepley SNES snes = (SNES)vf->data; 146a5c2985bSBarry Smith Vec snes_solution, work1, work2; 147a5c2985bSBarry Smith PetscReal snorm; 148798534f6SMatthew G. Knepley PetscInt tablevel; 149798534f6SMatthew G. Knepley const char *prefix; 150a5c2985bSBarry Smith 151a5c2985bSBarry Smith PetscFunctionBegin; 152798534f6SMatthew G. Knepley PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 4); 1539566063dSJacob Faibussowitsch PetscCall(SNESGetSolution(snes, &snes_solution)); 1549566063dSJacob Faibussowitsch PetscCall(VecDuplicate(snes_solution, &work1)); 1559566063dSJacob Faibussowitsch PetscCall(VecDuplicate(snes_solution, &work2)); 1569566063dSJacob Faibussowitsch PetscCall(KSPBuildSolution(ksp, work1, NULL)); 1579566063dSJacob Faibussowitsch PetscCall(VecAYPX(work1, -1.0, snes_solution)); 1589566063dSJacob Faibussowitsch PetscCall(SNESComputeFunction(snes, work1, work2)); 1599566063dSJacob Faibussowitsch PetscCall(VecNorm(work2, NORM_2, &snorm)); 1609566063dSJacob Faibussowitsch PetscCall(VecDestroy(&work1)); 1619566063dSJacob Faibussowitsch PetscCall(VecDestroy(&work2)); 162a5c2985bSBarry Smith 1639566063dSJacob Faibussowitsch PetscCall(PetscObjectGetTabLevel((PetscObject)ksp, &tablevel)); 1649566063dSJacob Faibussowitsch PetscCall(PetscObjectGetOptionsPrefix((PetscObject)ksp, &prefix)); 1659566063dSJacob Faibussowitsch PetscCall(PetscViewerPushFormat(viewer, format)); 1669566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIAddTab(viewer, tablevel)); 1679566063dSJacob Faibussowitsch if (n == 0 && prefix) PetscCall(PetscViewerASCIIPrintf(viewer, " Residual norms for %s solve.\n", prefix)); 16863a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "%3" PetscInt_FMT " SNES Residual norm %5.3e KSP Residual norm %5.3e \n", n, (double)snorm, (double)rnorm)); 1699566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIISubtractTab(viewer, tablevel)); 1709566063dSJacob Faibussowitsch PetscCall(PetscViewerPopFormat(viewer)); 1713ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 172a5c2985bSBarry Smith } 173a5c2985bSBarry Smith 174e5f7ee39SBarry Smith /*@C 175f6dfbefdSBarry Smith KSPMonitorSNESResidualDrawLG - Plots the linear `KSP` residual norm and the `SNES` residual norm at each iteration of an iterative solver. 176e5f7ee39SBarry Smith 177c3339decSBarry Smith Collective 178e5f7ee39SBarry Smith 179e5f7ee39SBarry Smith Input Parameters: 180798534f6SMatthew G. Knepley + ksp - iterative context 181798534f6SMatthew G. Knepley . n - iteration number 182798534f6SMatthew G. Knepley . rnorm - 2-norm (preconditioned) residual value (may be estimated). 183f6dfbefdSBarry Smith - vf - The viewer context, created with `KSPMonitorSNESResidualDrawLGCreate()` 184e5f7ee39SBarry Smith 185e5f7ee39SBarry Smith Options Database Key: 186f6dfbefdSBarry Smith . -snes_monitor_ksp draw::draw_lg - Activates `KSPMonitorSNESResidualDrawLG()` 187e5f7ee39SBarry Smith 188dc4c0fb0SBarry Smith Level: intermediate 189dc4c0fb0SBarry Smith 190f6dfbefdSBarry Smith Note: 1913a61192cSBarry Smith This is not called directly by users, rather one calls `SNESMonitorSet()`, with this function as an argument, to cause the monitor 192f6dfbefdSBarry Smith to be used during the `SNESSolve()` 1933a61192cSBarry Smith 194dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `KSPMonitorSet()`, `KSPMonitorTrueResidual()`, `SNESMonitor()`, `KSPMonitor()`, `KSPMonitorSNESResidualDrawLGCreate()` 195e5f7ee39SBarry Smith @*/ 196d71ae5a4SJacob Faibussowitsch PetscErrorCode KSPMonitorSNESResidualDrawLG(KSP ksp, PetscInt n, PetscReal rnorm, PetscViewerAndFormat *vf) 197d71ae5a4SJacob Faibussowitsch { 198798534f6SMatthew G. Knepley PetscViewer viewer = vf->viewer; 199798534f6SMatthew G. Knepley PetscViewerFormat format = vf->format; 200798534f6SMatthew G. Knepley PetscDrawLG lg = vf->lg; 201798534f6SMatthew G. Knepley SNES snes = (SNES)vf->data; 202e5f7ee39SBarry Smith Vec snes_solution, work1, work2; 203798534f6SMatthew G. Knepley PetscReal snorm; 204798534f6SMatthew G. Knepley KSPConvergedReason reason; 205798534f6SMatthew G. Knepley PetscReal x[2], y[2]; 206e5f7ee39SBarry Smith 207e5f7ee39SBarry Smith PetscFunctionBegin; 208798534f6SMatthew G. Knepley PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 4); 209064a246eSJacob Faibussowitsch PetscValidHeaderSpecific(lg, PETSC_DRAWLG_CLASSID, 4); 2109566063dSJacob Faibussowitsch PetscCall(SNESGetSolution(snes, &snes_solution)); 2119566063dSJacob Faibussowitsch PetscCall(VecDuplicate(snes_solution, &work1)); 2129566063dSJacob Faibussowitsch PetscCall(VecDuplicate(snes_solution, &work2)); 2139566063dSJacob Faibussowitsch PetscCall(KSPBuildSolution(ksp, work1, NULL)); 2149566063dSJacob Faibussowitsch PetscCall(VecAYPX(work1, -1.0, snes_solution)); 2159566063dSJacob Faibussowitsch PetscCall(SNESComputeFunction(snes, work1, work2)); 2169566063dSJacob Faibussowitsch PetscCall(VecNorm(work2, NORM_2, &snorm)); 2179566063dSJacob Faibussowitsch PetscCall(VecDestroy(&work1)); 2189566063dSJacob Faibussowitsch PetscCall(VecDestroy(&work2)); 219e5f7ee39SBarry Smith 2209566063dSJacob Faibussowitsch PetscCall(PetscViewerPushFormat(viewer, format)); 2219566063dSJacob Faibussowitsch if (!n) PetscCall(PetscDrawLGReset(lg)); 222798534f6SMatthew G. Knepley x[0] = (PetscReal)n; 223798534f6SMatthew G. Knepley if (rnorm > 0.0) y[0] = PetscLog10Real(rnorm); 224798534f6SMatthew G. Knepley else y[0] = -15.0; 225798534f6SMatthew G. Knepley x[1] = (PetscReal)n; 226798534f6SMatthew G. Knepley if (snorm > 0.0) y[1] = PetscLog10Real(snorm); 227798534f6SMatthew G. Knepley else y[1] = -15.0; 2289566063dSJacob Faibussowitsch PetscCall(PetscDrawLGAddPoint(lg, x, y)); 2299566063dSJacob Faibussowitsch PetscCall(KSPGetConvergedReason(ksp, &reason)); 230798534f6SMatthew G. Knepley if (n <= 20 || !(n % 5) || reason) { 2319566063dSJacob Faibussowitsch PetscCall(PetscDrawLGDraw(lg)); 2329566063dSJacob Faibussowitsch PetscCall(PetscDrawLGSave(lg)); 233e5f7ee39SBarry Smith } 2349566063dSJacob Faibussowitsch PetscCall(PetscViewerPopFormat(viewer)); 2353ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 236e5f7ee39SBarry Smith } 237e5f7ee39SBarry Smith 238798534f6SMatthew G. Knepley /*@C 239f6dfbefdSBarry Smith KSPMonitorSNESResidualDrawLGCreate - Creates the `PetscViewer` used by `KSPMonitorSNESResidualDrawLG()` 240e5f7ee39SBarry Smith 241c3339decSBarry Smith Collective 242e5f7ee39SBarry Smith 243798534f6SMatthew G. Knepley Input Parameters: 244dc4c0fb0SBarry Smith + viewer - The `PetscViewer` 245798534f6SMatthew G. Knepley . format - The viewer format 246798534f6SMatthew G. Knepley - ctx - An optional user context 247798534f6SMatthew G. Knepley 248798534f6SMatthew G. Knepley Output Parameter: 249798534f6SMatthew G. Knepley . vf - The viewer context 250e5f7ee39SBarry Smith 251e5f7ee39SBarry Smith Level: intermediate 252e5f7ee39SBarry Smith 253dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `KSP`, `SNES`, `KSPMonitorSet()`, `KSPMonitorTrueResidual()` 254e5f7ee39SBarry Smith @*/ 255d71ae5a4SJacob Faibussowitsch PetscErrorCode KSPMonitorSNESResidualDrawLGCreate(PetscViewer viewer, PetscViewerFormat format, void *ctx, PetscViewerAndFormat **vf) 256d71ae5a4SJacob Faibussowitsch { 257798534f6SMatthew G. Knepley const char *names[] = {"linear", "nonlinear"}; 258e5f7ee39SBarry Smith 259e5f7ee39SBarry Smith PetscFunctionBegin; 2609566063dSJacob Faibussowitsch PetscCall(PetscViewerAndFormatCreate(viewer, format, vf)); 261798534f6SMatthew G. Knepley (*vf)->data = ctx; 2629566063dSJacob Faibussowitsch PetscCall(KSPMonitorLGCreate(PetscObjectComm((PetscObject)viewer), NULL, NULL, "Log Residual Norm", 2, names, PETSC_DECIDE, PETSC_DECIDE, 400, 300, &(*vf)->lg)); 2633ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 264e5f7ee39SBarry Smith } 265e5f7ee39SBarry Smith 266d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESMonitorDefaultSetUp(SNES snes, PetscViewerAndFormat *vf) 267d71ae5a4SJacob Faibussowitsch { 268fbcc4530SMatthew G. Knepley PetscFunctionBegin; 26948a46eb9SPierre 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)); 2703ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 271fbcc4530SMatthew G. Knepley } 272fbcc4530SMatthew G. Knepley 2734b828684SBarry Smith /*@C 274f6dfbefdSBarry Smith SNESMonitorDefault - Monitors progress of the `SNES` solvers (default). 275e7e93795SLois Curfman McInnes 276c3339decSBarry Smith Collective 277c7afd0dbSLois Curfman McInnes 278e7e93795SLois Curfman McInnes Input Parameters: 279f6dfbefdSBarry Smith + snes - the `SNES` context 280e7e93795SLois Curfman McInnes . its - iteration number 2814b27c08aSLois Curfman McInnes . fgnorm - 2-norm of residual 282d43b4f6eSBarry Smith - vf - viewer and format structure 283fee21e36SBarry Smith 2843c7db156SBarry Smith Options Database Key: 2853a61192cSBarry Smith . -snes_monitor - use this function to monitor the convergence of the nonlinear solver 2863a61192cSBarry Smith 287dc4c0fb0SBarry Smith Level: intermediate 288dc4c0fb0SBarry Smith 289e7e93795SLois Curfman McInnes Notes: 2904b27c08aSLois Curfman McInnes This routine prints the residual norm at each iteration. 291e7e93795SLois Curfman McInnes 2923a61192cSBarry Smith This is not called directly by users, rather one calls `SNESMonitorSet()`, with this function as an argument, to cause the monitor 293f6dfbefdSBarry Smith to be used during the `SNES` solve. 2943a61192cSBarry Smith 295dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNESMonitorSet()`, `SNESMonitorSolution()`, `SNESMonitorFunction()`, `SNESMonitorSolution()`, `SNESMonitorResidual()`, 2963a61192cSBarry Smith `SNESMonitorSolutionUpdate()`, `SNESMonitorDefault()`, `SNESMonitorScaling()`, `SNESMonitorRange()`, `SNESMonitorRatio()`, 2973a61192cSBarry Smith `SNESMonitorDefaultField()` 298e7e93795SLois Curfman McInnes @*/ 299d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESMonitorDefault(SNES snes, PetscInt its, PetscReal fgnorm, PetscViewerAndFormat *vf) 300d71ae5a4SJacob Faibussowitsch { 301d43b4f6eSBarry Smith PetscViewer viewer = vf->viewer; 302798534f6SMatthew G. Knepley PetscViewerFormat format = vf->format; 303798534f6SMatthew G. Knepley PetscBool isascii, isdraw; 304d132466eSBarry Smith 3053a40ed3dSBarry Smith PetscFunctionBegin; 3064d4332d5SBarry Smith PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 4); 3079566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &isascii)); 3089566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERDRAW, &isdraw)); 3099566063dSJacob Faibussowitsch PetscCall(PetscViewerPushFormat(viewer, format)); 310798534f6SMatthew G. Knepley if (isascii) { 3119566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIAddTab(viewer, ((PetscObject)snes)->tablevel)); 312*9814a27eSStefano Zampini if (format == PETSC_VIEWER_ASCII_INFO_DETAIL) { 313*9814a27eSStefano Zampini Vec dx; 314*9814a27eSStefano Zampini PetscReal upnorm; 315*9814a27eSStefano Zampini PetscErrorCode (*objective)(SNES, Vec, PetscReal *, void *); 316*9814a27eSStefano Zampini 317*9814a27eSStefano Zampini PetscCall(SNESGetSolutionUpdate(snes, &dx)); 318*9814a27eSStefano Zampini PetscCall(VecNorm(dx, NORM_2, &upnorm)); 319*9814a27eSStefano Zampini PetscCall(SNESGetObjective(snes, &objective, NULL)); 320*9814a27eSStefano Zampini if (objective) { 321*9814a27eSStefano Zampini Vec x; 322*9814a27eSStefano Zampini PetscReal obj; 323*9814a27eSStefano Zampini 324*9814a27eSStefano Zampini PetscCall(SNESGetSolution(snes, &x)); 325*9814a27eSStefano Zampini PetscCall(SNESComputeObjective(snes, x, &obj)); 326*9814a27eSStefano Zampini PetscCall(PetscViewerASCIIPrintf(viewer, "%3" PetscInt_FMT " SNES Function norm %14.12e, Update norm %14.12e, Objective %14.12e\n", its, (double)fgnorm, (double)upnorm, (double)obj)); 327*9814a27eSStefano Zampini } else { 328*9814a27eSStefano Zampini PetscCall(PetscViewerASCIIPrintf(viewer, "%3" PetscInt_FMT " SNES Function norm %14.12e, Update norm %14.12e\n", its, (double)fgnorm, (double)upnorm)); 329*9814a27eSStefano Zampini } 330*9814a27eSStefano Zampini } else { 33163a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "%3" PetscInt_FMT " SNES Function norm %14.12e \n", its, (double)fgnorm)); 332*9814a27eSStefano Zampini } 3339566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIISubtractTab(viewer, ((PetscObject)snes)->tablevel)); 334798534f6SMatthew G. Knepley } else if (isdraw) { 335798534f6SMatthew G. Knepley if (format == PETSC_VIEWER_DRAW_LG) { 336798534f6SMatthew G. Knepley PetscDrawLG lg = (PetscDrawLG)vf->lg; 337798534f6SMatthew G. Knepley PetscReal x, y; 338798534f6SMatthew G. Knepley 339798534f6SMatthew G. Knepley PetscValidHeaderSpecific(lg, PETSC_DRAWLG_CLASSID, 4); 3409566063dSJacob Faibussowitsch if (!its) PetscCall(PetscDrawLGReset(lg)); 341798534f6SMatthew G. Knepley x = (PetscReal)its; 342798534f6SMatthew G. Knepley if (fgnorm > 0.0) y = PetscLog10Real(fgnorm); 343798534f6SMatthew G. Knepley else y = -15.0; 3449566063dSJacob Faibussowitsch PetscCall(PetscDrawLGAddPoint(lg, &x, &y)); 345798534f6SMatthew G. Knepley if (its <= 20 || !(its % 5) || snes->reason) { 3469566063dSJacob Faibussowitsch PetscCall(PetscDrawLGDraw(lg)); 3479566063dSJacob Faibussowitsch PetscCall(PetscDrawLGSave(lg)); 348798534f6SMatthew G. Knepley } 349798534f6SMatthew G. Knepley } 350798534f6SMatthew G. Knepley } 3519566063dSJacob Faibussowitsch PetscCall(PetscViewerPopFormat(viewer)); 3523ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 353e7e93795SLois Curfman McInnes } 3543f1db9ecSBarry Smith 3551f60017eSBarry Smith /*@C 3561f60017eSBarry Smith SNESMonitorScaling - Monitors the largest value in each row of the Jacobian. 3571f60017eSBarry Smith 358c3339decSBarry Smith Collective 3591f60017eSBarry Smith 3601f60017eSBarry Smith Input Parameters: 361f6dfbefdSBarry Smith + snes - the `SNES` context 3621f60017eSBarry Smith . its - iteration number 3631f60017eSBarry Smith . fgnorm - 2-norm of residual 3641f60017eSBarry Smith - vf - viewer and format structure 3651f60017eSBarry Smith 366dc4c0fb0SBarry Smith Level: intermediate 367dc4c0fb0SBarry Smith 3681f60017eSBarry Smith Notes: 3691f60017eSBarry Smith This routine prints the largest value in each row of the Jacobian 3701f60017eSBarry Smith 3713a61192cSBarry Smith This is not called directly by users, rather one calls `SNESMonitorSet()`, with this function as an argument, to cause the monitor 372f6dfbefdSBarry Smith to be used during the `SNES` solve. 3733a61192cSBarry Smith 374dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNESMonitorSet()`, `SNESMonitorSolution()`, `SNESMonitorRange()`, `SNESMonitorJacUpdateSpectrum()` 3751f60017eSBarry Smith @*/ 376d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESMonitorScaling(SNES snes, PetscInt its, PetscReal fgnorm, PetscViewerAndFormat *vf) 377d71ae5a4SJacob Faibussowitsch { 3781f60017eSBarry Smith PetscViewer viewer = vf->viewer; 3791f60017eSBarry Smith KSP ksp; 3801f60017eSBarry Smith Mat J; 3811f60017eSBarry Smith Vec v; 3821f60017eSBarry Smith 3831f60017eSBarry Smith PetscFunctionBegin; 3841f60017eSBarry Smith PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 4); 3859566063dSJacob Faibussowitsch PetscCall(SNESGetKSP(snes, &ksp)); 3869566063dSJacob Faibussowitsch PetscCall(KSPGetOperators(ksp, &J, NULL)); 3879566063dSJacob Faibussowitsch PetscCall(MatCreateVecs(J, &v, NULL)); 3889566063dSJacob Faibussowitsch PetscCall(MatGetRowMaxAbs(J, v, NULL)); 3899566063dSJacob Faibussowitsch PetscCall(PetscViewerPushFormat(viewer, vf->format)); 3909566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIAddTab(viewer, ((PetscObject)snes)->tablevel)); 39163a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "SNES Jacobian maximum row entries\n")); 3929566063dSJacob Faibussowitsch PetscCall(VecView(v, viewer)); 3939566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIISubtractTab(viewer, ((PetscObject)snes)->tablevel)); 3949566063dSJacob Faibussowitsch PetscCall(PetscViewerPopFormat(viewer)); 3959566063dSJacob Faibussowitsch PetscCall(VecDestroy(&v)); 3963ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 3971f60017eSBarry Smith } 3981f60017eSBarry Smith 399f6dfbefdSBarry Smith /*@C 400f6dfbefdSBarry Smith SNESMonitorJacUpdateSpectrum - Monitors the spectrun of the change in the Jacobian from the last Jacobian evaluation 401f6dfbefdSBarry Smith 402c3339decSBarry Smith Collective 403f6dfbefdSBarry Smith 404f6dfbefdSBarry Smith Input Parameters: 405f6dfbefdSBarry Smith + snes - the `SNES` context 406f6dfbefdSBarry Smith . its - iteration number 407f6dfbefdSBarry Smith . fgnorm - 2-norm of residual 408f6dfbefdSBarry Smith - vf - viewer and format structure 409f6dfbefdSBarry Smith 410f6dfbefdSBarry Smith Option Database Key: 411f6dfbefdSBarry Smith . -snes_monitor_jacupdate_spectrum - activates this monitor 412f6dfbefdSBarry Smith 413dc4c0fb0SBarry Smith Level: intermediate 414dc4c0fb0SBarry Smith 415f6dfbefdSBarry Smith Notes: 416f6dfbefdSBarry Smith This routine prints the eigenvalues of the difference in the Jacobians 417f6dfbefdSBarry Smith 418f6dfbefdSBarry Smith This is not called directly by users, rather one calls `SNESMonitorSet()`, with this function as an argument, to cause the monitor 419f6dfbefdSBarry Smith to be used during the `SNES` solve. 420f6dfbefdSBarry Smith 421dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNESMonitorSet()`, `SNESMonitorSolution()`, `SNESMonitorRange()` 422f6dfbefdSBarry Smith @*/ 423d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESMonitorJacUpdateSpectrum(SNES snes, PetscInt it, PetscReal fnorm, PetscViewerAndFormat *vf) 424d71ae5a4SJacob Faibussowitsch { 4252e7541e6SPeter Brune Vec X; 4262e7541e6SPeter Brune Mat J, dJ, dJdense; 427d1e9a80fSBarry Smith PetscErrorCode (*func)(SNES, Vec, Mat, Mat, void *); 4282f96bde4SJose E. Roman PetscInt n; 42923fff9afSBarry Smith PetscBLASInt nb = 0, lwork; 4302e7541e6SPeter Brune PetscReal *eigr, *eigi; 4312e7541e6SPeter Brune PetscScalar *work; 4322e7541e6SPeter Brune PetscScalar *a; 4332e7541e6SPeter Brune 4342e7541e6SPeter Brune PetscFunctionBegin; 4353ba16761SJacob Faibussowitsch if (it == 0) PetscFunctionReturn(PETSC_SUCCESS); 436f6dfbefdSBarry Smith /* create the difference between the current update and the current Jacobian */ 4379566063dSJacob Faibussowitsch PetscCall(SNESGetSolution(snes, &X)); 4389566063dSJacob Faibussowitsch PetscCall(SNESGetJacobian(snes, NULL, &J, &func, NULL)); 4399566063dSJacob Faibussowitsch PetscCall(MatDuplicate(J, MAT_COPY_VALUES, &dJ)); 4409566063dSJacob Faibussowitsch PetscCall(SNESComputeJacobian(snes, X, dJ, dJ)); 4419566063dSJacob Faibussowitsch PetscCall(MatAXPY(dJ, -1.0, J, SAME_NONZERO_PATTERN)); 442f5af7f23SKarl Rupp 4432e7541e6SPeter Brune /* compute the spectrum directly */ 4449566063dSJacob Faibussowitsch PetscCall(MatConvert(dJ, MATSEQDENSE, MAT_INITIAL_MATRIX, &dJdense)); 4459566063dSJacob Faibussowitsch PetscCall(MatGetSize(dJ, &n, NULL)); 4469566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(n, &nb)); 4472e7541e6SPeter Brune lwork = 3 * nb; 4489566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(n, &eigr)); 4499566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(n, &eigi)); 4509566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(lwork, &work)); 4519566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(dJdense, &a)); 4522e7541e6SPeter Brune #if !defined(PETSC_USE_COMPLEX) 4532e7541e6SPeter Brune { 4542e7541e6SPeter Brune PetscBLASInt lierr; 4552f96bde4SJose E. Roman PetscInt i; 4569566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF)); 457792fecdfSBarry Smith PetscCallBLAS("LAPACKgeev", LAPACKgeev_("N", "N", &nb, a, &nb, eigr, eigi, NULL, &nb, NULL, &nb, work, &lwork, &lierr)); 45863a3b9bcSJacob Faibussowitsch PetscCheck(!lierr, PETSC_COMM_SELF, PETSC_ERR_LIB, "geev() error %" PetscBLASInt_FMT, lierr); 4599566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPop()); 46063a3b9bcSJacob Faibussowitsch PetscCall(PetscPrintf(PetscObjectComm((PetscObject)snes), "Eigenvalues of J_%" PetscInt_FMT " - J_%" PetscInt_FMT ":\n", it, it - 1)); 46148a46eb9SPierre 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])); 4622f96bde4SJose E. Roman } 4639566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArray(dJdense, &a)); 4649566063dSJacob Faibussowitsch PetscCall(MatDestroy(&dJ)); 4659566063dSJacob Faibussowitsch PetscCall(MatDestroy(&dJdense)); 4669566063dSJacob Faibussowitsch PetscCall(PetscFree(eigr)); 4679566063dSJacob Faibussowitsch PetscCall(PetscFree(eigi)); 4689566063dSJacob Faibussowitsch PetscCall(PetscFree(work)); 4693ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 4702f96bde4SJose E. Roman #else 4712f96bde4SJose E. Roman SETERRQ(PETSC_COMM_SELF, PETSC_ERR_SUP, "Not coded for complex"); 4722f96bde4SJose E. Roman #endif 4732e7541e6SPeter Brune } 4742e7541e6SPeter Brune 4756ba87a44SLisandro Dalcin PETSC_INTERN PetscErrorCode SNESMonitorRange_Private(SNES, PetscInt, PetscReal *); 4766ba87a44SLisandro Dalcin 477d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESMonitorRange_Private(SNES snes, PetscInt it, PetscReal *per) 478d71ae5a4SJacob Faibussowitsch { 479b271bb04SBarry Smith Vec resid; 480b271bb04SBarry Smith PetscReal rmax, pwork; 481b271bb04SBarry Smith PetscInt i, n, N; 482b271bb04SBarry Smith PetscScalar *r; 483b271bb04SBarry Smith 484b271bb04SBarry Smith PetscFunctionBegin; 4859566063dSJacob Faibussowitsch PetscCall(SNESGetFunction(snes, &resid, NULL, NULL)); 4869566063dSJacob Faibussowitsch PetscCall(VecNorm(resid, NORM_INFINITY, &rmax)); 4879566063dSJacob Faibussowitsch PetscCall(VecGetLocalSize(resid, &n)); 4889566063dSJacob Faibussowitsch PetscCall(VecGetSize(resid, &N)); 4899566063dSJacob Faibussowitsch PetscCall(VecGetArray(resid, &r)); 490b271bb04SBarry Smith pwork = 0.0; 491ad540459SPierre Jolivet for (i = 0; i < n; i++) pwork += (PetscAbsScalar(r[i]) > .20 * rmax); 4921c2dc1cbSBarry Smith PetscCall(MPIU_Allreduce(&pwork, per, 1, MPIU_REAL, MPIU_SUM, PetscObjectComm((PetscObject)snes))); 4939566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(resid, &r)); 494b271bb04SBarry Smith *per = *per / N; 4953ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 496b271bb04SBarry Smith } 497b271bb04SBarry Smith 498b271bb04SBarry Smith /*@C 499f6dfbefdSBarry Smith SNESMonitorRange - Prints the percentage of residual elements that are more then 10 percent of the maximum entry in the residual 500b271bb04SBarry Smith 501c3339decSBarry Smith Collective 502b271bb04SBarry Smith 503b271bb04SBarry Smith Input Parameters: 504b271bb04SBarry Smith + snes - iterative context 505b271bb04SBarry Smith . it - iteration number 506b271bb04SBarry Smith . rnorm - 2-norm (preconditioned) residual value (may be estimated). 507b271bb04SBarry Smith - dummy - unused monitor context 508b271bb04SBarry Smith 509b271bb04SBarry Smith Options Database Key: 510f6dfbefdSBarry Smith . -snes_monitor_range - Activates `SNESMonitorRange()` 511b271bb04SBarry Smith 512dc4c0fb0SBarry Smith Level: intermediate 513dc4c0fb0SBarry Smith 514f6dfbefdSBarry Smith Note: 5153a61192cSBarry Smith This is not called directly by users, rather one calls `SNESMonitorSet()`, with this function as an argument, to cause the monitor 516f6dfbefdSBarry Smith to be used during the `SNES` solve. 5173a61192cSBarry Smith 518dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNESMonitorSet()`, `SNESMonitorDefault()`, `SNESMonitorLGCreate()`, `SNESMonitorScaling()` 519b271bb04SBarry Smith @*/ 520d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESMonitorRange(SNES snes, PetscInt it, PetscReal rnorm, PetscViewerAndFormat *vf) 521d71ae5a4SJacob Faibussowitsch { 522b271bb04SBarry Smith PetscReal perc, rel; 523d43b4f6eSBarry Smith PetscViewer viewer = vf->viewer; 524b271bb04SBarry Smith /* should be in a MonitorRangeContext */ 525b271bb04SBarry Smith static PetscReal prev; 526b271bb04SBarry Smith 527b271bb04SBarry Smith PetscFunctionBegin; 5284d4332d5SBarry Smith PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 4); 529b271bb04SBarry Smith if (!it) prev = rnorm; 5309566063dSJacob Faibussowitsch PetscCall(SNESMonitorRange_Private(snes, it, &perc)); 531b271bb04SBarry Smith 532b271bb04SBarry Smith rel = (prev - rnorm) / prev; 533b271bb04SBarry Smith prev = rnorm; 5349566063dSJacob Faibussowitsch PetscCall(PetscViewerPushFormat(viewer, vf->format)); 5359566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIAddTab(viewer, ((PetscObject)snes)->tablevel)); 53663a3b9bcSJacob 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))); 5379566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIISubtractTab(viewer, ((PetscObject)snes)->tablevel)); 5389566063dSJacob Faibussowitsch PetscCall(PetscViewerPopFormat(viewer)); 5393ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 540b271bb04SBarry Smith } 541b271bb04SBarry Smith 5423a7fca6bSBarry Smith /*@C 543f6dfbefdSBarry Smith SNESMonitorRatio - Monitors progress of the `SNES` solvers by printing the ratio 5444b27c08aSLois Curfman McInnes of residual norm at each iteration to the previous. 5453a7fca6bSBarry Smith 546c3339decSBarry Smith Collective 5473a7fca6bSBarry Smith 5483a7fca6bSBarry Smith Input Parameters: 549f6dfbefdSBarry Smith + snes - the `SNES` context 5503a7fca6bSBarry Smith . its - iteration number 5513a7fca6bSBarry Smith . fgnorm - 2-norm of residual (or gradient) 552eabae89aSBarry Smith - dummy - context of monitor 5533a7fca6bSBarry Smith 554f6dfbefdSBarry Smith Option Database Key: 555f6dfbefdSBarry Smith . -snes_monitor_ratio - activate this monitor 556f6dfbefdSBarry Smith 5573a7fca6bSBarry Smith Level: intermediate 5583a7fca6bSBarry Smith 55995452b02SPatrick Sanan Notes: 5603a61192cSBarry Smith This is not called directly by users, rather one calls `SNESMonitorSet()`, with this function as an argument, to cause the monitor 561f6dfbefdSBarry Smith to be used during the `SNES` solve. 5623a61192cSBarry Smith 563f6dfbefdSBarry Smith Be sure to call `SNESMonitorRationSetUp()` before using this monitor. 5643a61192cSBarry Smith 565dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNESMonitorRationSetUp()`, `SNESMonitorSet()`, `SNESMonitorSolution()`, `SNESMonitorDefault()` 5663a7fca6bSBarry Smith @*/ 567d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESMonitorRatio(SNES snes, PetscInt its, PetscReal fgnorm, PetscViewerAndFormat *vf) 568d71ae5a4SJacob Faibussowitsch { 56977431f27SBarry Smith PetscInt len; 57087828ca2SBarry Smith PetscReal *history; 571d43b4f6eSBarry Smith PetscViewer viewer = vf->viewer; 5723a7fca6bSBarry Smith 5733a7fca6bSBarry Smith PetscFunctionBegin; 5749566063dSJacob Faibussowitsch PetscCall(SNESGetConvergenceHistory(snes, &history, NULL, &len)); 5759566063dSJacob Faibussowitsch PetscCall(PetscViewerPushFormat(viewer, vf->format)); 5769566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIAddTab(viewer, ((PetscObject)snes)->tablevel)); 577958c9bccSBarry Smith if (!its || !history || its > len) { 57863a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "%3" PetscInt_FMT " SNES Function norm %14.12e \n", its, (double)fgnorm)); 5793a7fca6bSBarry Smith } else { 58087828ca2SBarry Smith PetscReal ratio = fgnorm / history[its - 1]; 58163a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "%3" PetscInt_FMT " SNES Function norm %14.12e %14.12e \n", its, (double)fgnorm, (double)ratio)); 5823a7fca6bSBarry Smith } 5839566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIISubtractTab(viewer, ((PetscObject)snes)->tablevel)); 5849566063dSJacob Faibussowitsch PetscCall(PetscViewerPopFormat(viewer)); 5853ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 5863a7fca6bSBarry Smith } 5873a7fca6bSBarry Smith 5883a7fca6bSBarry Smith /*@C 589f6dfbefdSBarry Smith SNESMonitorRatioSetUp - Insures the `SNES` object is saving its history since this monitor needs access to it 5903a7fca6bSBarry Smith 591c3339decSBarry Smith Collective 5923a7fca6bSBarry Smith 5933a7fca6bSBarry Smith Input Parameters: 594f6dfbefdSBarry Smith + snes - the `SNES` context 595f6dfbefdSBarry Smith - viewer - the `PetscViewer` object (ignored) 5963a7fca6bSBarry Smith 5973a7fca6bSBarry Smith Level: intermediate 5983a7fca6bSBarry Smith 599dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNESMonitorSet()`, `SNESMonitorSolution()`, `SNESMonitorDefault()`, `SNESMonitorRatio()` 6003a7fca6bSBarry Smith @*/ 601d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESMonitorRatioSetUp(SNES snes, PetscViewerAndFormat *vf) 602d71ae5a4SJacob Faibussowitsch { 60387828ca2SBarry Smith PetscReal *history; 6043a7fca6bSBarry Smith 6053a7fca6bSBarry Smith PetscFunctionBegin; 6069566063dSJacob Faibussowitsch PetscCall(SNESGetConvergenceHistory(snes, &history, NULL, NULL)); 60748a46eb9SPierre Jolivet if (!history) PetscCall(SNESSetConvergenceHistory(snes, NULL, NULL, 100, PETSC_TRUE)); 6083ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 6093a7fca6bSBarry Smith } 6103a7fca6bSBarry Smith 611be1f7002SBarry Smith /* 612a6570f20SBarry Smith Default (short) SNES Monitor, same as SNESMonitorDefault() except 613be1f7002SBarry Smith it prints fewer digits of the residual as the residual gets smaller. 614be1f7002SBarry Smith This is because the later digits are meaningless and are often 615be1f7002SBarry Smith different on different machines; by using this routine different 616be1f7002SBarry Smith machines will usually generate the same output. 617dec21524SBarry Smith 618dec21524SBarry Smith Deprecated: Intentionally has no manual page 619be1f7002SBarry Smith */ 620d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESMonitorDefaultShort(SNES snes, PetscInt its, PetscReal fgnorm, PetscViewerAndFormat *vf) 621d71ae5a4SJacob Faibussowitsch { 622d43b4f6eSBarry Smith PetscViewer viewer = vf->viewer; 623d132466eSBarry Smith 6243a40ed3dSBarry Smith PetscFunctionBegin; 6254d4332d5SBarry Smith PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 4); 6269566063dSJacob Faibussowitsch PetscCall(PetscViewerPushFormat(viewer, vf->format)); 6279566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIAddTab(viewer, ((PetscObject)snes)->tablevel)); 6288f240d10SBarry Smith if (fgnorm > 1.e-9) { 62963a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "%3" PetscInt_FMT " SNES Function norm %g \n", its, (double)fgnorm)); 6303a40ed3dSBarry Smith } else if (fgnorm > 1.e-11) { 63163a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "%3" PetscInt_FMT " SNES Function norm %5.3e \n", its, (double)fgnorm)); 6323a40ed3dSBarry Smith } else { 63363a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "%3" PetscInt_FMT " SNES Function norm < 1.e-11\n", its)); 634a34d58ebSBarry Smith } 6359566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIISubtractTab(viewer, ((PetscObject)snes)->tablevel)); 6369566063dSJacob Faibussowitsch PetscCall(PetscViewerPopFormat(viewer)); 6373ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 638e7e93795SLois Curfman McInnes } 6392db13446SMatthew G. Knepley 6402db13446SMatthew G. Knepley /*@C 641f6dfbefdSBarry Smith SNESMonitorDefaultField - Monitors progress of the `SNES` solvers, separated into fields. 6422db13446SMatthew G. Knepley 643c3339decSBarry Smith Collective 6442db13446SMatthew G. Knepley 6452db13446SMatthew G. Knepley Input Parameters: 646f6dfbefdSBarry Smith + snes - the `SNES` context 6472db13446SMatthew G. Knepley . its - iteration number 6482db13446SMatthew G. Knepley . fgnorm - 2-norm of residual 6492db13446SMatthew G. Knepley - ctx - the PetscViewer 6502db13446SMatthew G. Knepley 651f6dfbefdSBarry Smith Option Database Key: 652f6dfbefdSBarry Smith . -snes_monitor_field - activate this monitor 653f6dfbefdSBarry Smith 654dc4c0fb0SBarry Smith Level: intermediate 655dc4c0fb0SBarry Smith 6562db13446SMatthew G. Knepley Notes: 657f6dfbefdSBarry Smith This routine uses the `DM` attached to the residual vector to define the fields. 6583a61192cSBarry Smith 6593a61192cSBarry Smith This is not called directly by users, rather one calls `SNESMonitorSet()`, with this function as an argument, to cause the monitor 660f6dfbefdSBarry Smith to be used during the `SNES` solve. 6612db13446SMatthew G. Knepley 662dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNESMonitorSet()`, `SNESMonitorSolution()`, `SNESMonitorDefault()` 6632db13446SMatthew G. Knepley @*/ 664d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESMonitorDefaultField(SNES snes, PetscInt its, PetscReal fgnorm, PetscViewerAndFormat *vf) 665d71ae5a4SJacob Faibussowitsch { 666d43b4f6eSBarry Smith PetscViewer viewer = vf->viewer; 6672db13446SMatthew G. Knepley Vec r; 6682db13446SMatthew G. Knepley DM dm; 6692db13446SMatthew G. Knepley PetscReal res[256]; 6702db13446SMatthew G. Knepley PetscInt tablevel; 6712db13446SMatthew G. Knepley 6722db13446SMatthew G. Knepley PetscFunctionBegin; 6734d4332d5SBarry Smith PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 4); 6749566063dSJacob Faibussowitsch PetscCall(SNESGetFunction(snes, &r, NULL, NULL)); 6759566063dSJacob Faibussowitsch PetscCall(VecGetDM(r, &dm)); 6769566063dSJacob Faibussowitsch if (!dm) PetscCall(SNESMonitorDefault(snes, its, fgnorm, vf)); 6772db13446SMatthew G. Knepley else { 6782db13446SMatthew G. Knepley PetscSection s, gs; 6792db13446SMatthew G. Knepley PetscInt Nf, f; 6802db13446SMatthew G. Knepley 6819566063dSJacob Faibussowitsch PetscCall(DMGetLocalSection(dm, &s)); 6829566063dSJacob Faibussowitsch PetscCall(DMGetGlobalSection(dm, &gs)); 6839566063dSJacob Faibussowitsch if (!s || !gs) PetscCall(SNESMonitorDefault(snes, its, fgnorm, vf)); 6849566063dSJacob Faibussowitsch PetscCall(PetscSectionGetNumFields(s, &Nf)); 68563a3b9bcSJacob Faibussowitsch PetscCheck(Nf <= 256, PetscObjectComm((PetscObject)snes), PETSC_ERR_SUP, "Do not support %" PetscInt_FMT " fields > 256", Nf); 6869566063dSJacob Faibussowitsch PetscCall(PetscSectionVecNorm(s, gs, r, NORM_2, res)); 6879566063dSJacob Faibussowitsch PetscCall(PetscObjectGetTabLevel((PetscObject)snes, &tablevel)); 6889566063dSJacob Faibussowitsch PetscCall(PetscViewerPushFormat(viewer, vf->format)); 6899566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIAddTab(viewer, tablevel)); 69063a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "%3" PetscInt_FMT " SNES Function norm %14.12e [", its, (double)fgnorm)); 6912db13446SMatthew G. Knepley for (f = 0; f < Nf; ++f) { 6929566063dSJacob Faibussowitsch if (f) PetscCall(PetscViewerASCIIPrintf(viewer, ", ")); 69363a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "%14.12e", (double)res[f])); 6942db13446SMatthew G. Knepley } 6959566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "] \n")); 6969566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIISubtractTab(viewer, tablevel)); 6979566063dSJacob Faibussowitsch PetscCall(PetscViewerPopFormat(viewer)); 6982db13446SMatthew G. Knepley } 6993ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 7002db13446SMatthew G. Knepley } 701f6dfbefdSBarry Smith 7024b828684SBarry Smith /*@C 703c34cbdceSBarry Smith SNESConvergedDefault - Default onvergence test of the solvers for 704c34cbdceSBarry Smith systems of nonlinear equations. 705e7e93795SLois Curfman McInnes 706c3339decSBarry Smith Collective 707c7afd0dbSLois Curfman McInnes 708e7e93795SLois Curfman McInnes Input Parameters: 709f6dfbefdSBarry Smith + snes - the `SNES` context 71006ee9f85SBarry Smith . it - the iteration (0 indicates before any Newton steps) 711e7e93795SLois Curfman McInnes . xnorm - 2-norm of current iterate 712c60f73f4SPeter Brune . snorm - 2-norm of current step 7137f3332b4SBarry Smith . fnorm - 2-norm of function at current iterate 714c7afd0dbSLois Curfman McInnes - dummy - unused context 715e7e93795SLois Curfman McInnes 716184914b5SBarry Smith Output Parameter: 717184914b5SBarry Smith . reason - one of 718f6dfbefdSBarry Smith .vb 719f6dfbefdSBarry Smith SNES_CONVERGED_FNORM_ABS - (fnorm < abstol), 720f6dfbefdSBarry Smith SNES_CONVERGED_SNORM_RELATIVE - (snorm < stol*xnorm), 721f6dfbefdSBarry Smith SNES_CONVERGED_FNORM_RELATIVE - (fnorm < rtol*fnorm0), 722f6dfbefdSBarry Smith SNES_DIVERGED_FUNCTION_COUNT - (nfct > maxf), 723f6dfbefdSBarry Smith SNES_DIVERGED_FNORM_NAN - (fnorm == NaN), 724f6dfbefdSBarry Smith SNES_CONVERGED_ITERATING - (otherwise), 725f6dfbefdSBarry Smith SNES_DIVERGED_DTOL - (fnorm > divtol*snes->fnorm0) 726f6dfbefdSBarry Smith .ve 727e7e93795SLois Curfman McInnes 728e7e93795SLois Curfman McInnes where 729f6dfbefdSBarry Smith + maxf - maximum number of function evaluations, set with `SNESSetTolerances()` 730c7afd0dbSLois Curfman McInnes . nfct - number of function evaluations, 731f6dfbefdSBarry Smith . abstol - absolute function norm tolerance, set with `SNESSetTolerances()` 732f6dfbefdSBarry Smith . rtol - relative function norm tolerance, set with `SNESSetTolerances()` 733f6dfbefdSBarry Smith . divtol - divergence tolerance, set with `SNESSetDivergenceTolerance()` 734c34cbdceSBarry Smith - fnorm0 - 2-norm of the function at the initial solution (initial guess; zeroth iteration) 735c34cbdceSBarry Smith 736c34cbdceSBarry Smith Options Database Keys: 737f6dfbefdSBarry Smith + -snes_convergence_test default - see `SNESSetFromOptions()` 738f362779dSJed Brown . -snes_stol - convergence tolerance in terms of the norm of the change in the solution between steps 739c34cbdceSBarry Smith . -snes_atol <abstol> - absolute tolerance of residual norm 740c34cbdceSBarry Smith . -snes_rtol <rtol> - relative decrease in tolerance norm from the initial 2-norm of the solution 741c34cbdceSBarry Smith . -snes_divergence_tolerance <divtol> - if the residual goes above divtol*rnorm0, exit with divergence 742c34cbdceSBarry Smith . -snes_max_funcs <max_funcs> - maximum number of function evaluations 743c34cbdceSBarry Smith . -snes_max_fail <max_fail> - maximum number of line search failures allowed before stopping, default is none 744f6dfbefdSBarry Smith - -snes_max_linear_solve_fail - number of linear solver failures before `SNESSolve()` stops 745fee21e36SBarry Smith 74636851e7fSLois Curfman McInnes Level: intermediate 74736851e7fSLois Curfman McInnes 748dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNES`, `SNESSolve()`, `SNESSetConvergenceTest()`, `SNESConvergedSkip()`, `SNESSetTolerances()`, `SNESSetDivergenceTolerance()` 749e7e93795SLois Curfman McInnes @*/ 750d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESConvergedDefault(SNES snes, PetscInt it, PetscReal xnorm, PetscReal snorm, PetscReal fnorm, SNESConvergedReason *reason, void *dummy) 751d71ae5a4SJacob Faibussowitsch { 7523a40ed3dSBarry Smith PetscFunctionBegin; 7530700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 7543f149594SLisandro Dalcin PetscValidPointer(reason, 6); 7553f149594SLisandro Dalcin 75606ee9f85SBarry Smith *reason = SNES_CONVERGED_ITERATING; 75706ee9f85SBarry Smith if (!it) { 75806ee9f85SBarry Smith /* set parameter for default relative tolerance convergence test */ 75906ee9f85SBarry Smith snes->ttol = fnorm * snes->rtol; 760e37c518bSBarry Smith snes->rnorm0 = fnorm; 76106ee9f85SBarry Smith } 7628146f6ebSBarry Smith if (PetscIsInfOrNanReal(fnorm)) { 7639566063dSJacob Faibussowitsch PetscCall(PetscInfo(snes, "Failed to converged, function norm is NaN\n")); 764184914b5SBarry Smith *reason = SNES_DIVERGED_FNORM_NAN; 765be5caee7SBarry Smith } else if (fnorm < snes->abstol && (it || !snes->forceiteration)) { 7669566063dSJacob Faibussowitsch PetscCall(PetscInfo(snes, "Converged due to function norm %14.12e < %14.12e\n", (double)fnorm, (double)snes->abstol)); 767184914b5SBarry Smith *reason = SNES_CONVERGED_FNORM_ABS; 768e71169deSBarry Smith } else if (snes->nfuncs >= snes->max_funcs && snes->max_funcs >= 0) { 76963a3b9bcSJacob Faibussowitsch PetscCall(PetscInfo(snes, "Exceeded maximum number of function evaluations: %" PetscInt_FMT " > %" PetscInt_FMT "\n", snes->nfuncs, snes->max_funcs)); 770184914b5SBarry Smith *reason = SNES_DIVERGED_FUNCTION_COUNT; 77106ee9f85SBarry Smith } 77206ee9f85SBarry Smith 77306ee9f85SBarry Smith if (it && !*reason) { 77406ee9f85SBarry Smith if (fnorm <= snes->ttol) { 7759566063dSJacob Faibussowitsch PetscCall(PetscInfo(snes, "Converged due to function norm %14.12e < %14.12e (relative tolerance)\n", (double)fnorm, (double)snes->ttol)); 77606ee9f85SBarry Smith *reason = SNES_CONVERGED_FNORM_RELATIVE; 777c60f73f4SPeter Brune } else if (snorm < snes->stol * xnorm) { 7789566063dSJacob Faibussowitsch PetscCall(PetscInfo(snes, "Converged due to small update length: %14.12e < %14.12e * %14.12e\n", (double)snorm, (double)snes->stol, (double)xnorm)); 779c60f73f4SPeter Brune *reason = SNES_CONVERGED_SNORM_RELATIVE; 780e4d06f11SPatrick Farrell } else if (snes->divtol > 0 && (fnorm > snes->divtol * snes->rnorm0)) { 7819566063dSJacob 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)); 782e37c518bSBarry Smith *reason = SNES_DIVERGED_DTOL; 78306ee9f85SBarry Smith } 784e7e93795SLois Curfman McInnes } 7853ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 786e7e93795SLois Curfman McInnes } 7873f149594SLisandro Dalcin 7883f149594SLisandro Dalcin /*@C 789f6dfbefdSBarry Smith SNESConvergedSkip - Convergence test for `SNES` that NEVER returns as 7903f149594SLisandro Dalcin converged, UNLESS the maximum number of iteration have been reached. 7913f149594SLisandro Dalcin 792c3339decSBarry Smith Logically Collective 7933f149594SLisandro Dalcin 7943f149594SLisandro Dalcin Input Parameters: 795f6dfbefdSBarry Smith + snes - the `SNES` context 7963f149594SLisandro Dalcin . it - the iteration (0 indicates before any Newton steps) 7973f149594SLisandro Dalcin . xnorm - 2-norm of current iterate 798c60f73f4SPeter Brune . snorm - 2-norm of current step 7993f149594SLisandro Dalcin . fnorm - 2-norm of function at current iterate 8003f149594SLisandro Dalcin - dummy - unused context 8013f149594SLisandro Dalcin 8023f149594SLisandro Dalcin Output Parameter: 803f6dfbefdSBarry Smith . reason - `SNES_CONVERGED_ITERATING`, `SNES_CONVERGED_ITS`, or `SNES_DIVERGED_FNORM_NAN` 8043f149594SLisandro Dalcin 805f6dfbefdSBarry Smith Options Database Key: 806f6dfbefdSBarry Smith . -snes_convergence_test skip - see `SNESSetFromOptions()` 807f362779dSJed Brown 8083f149594SLisandro Dalcin Level: advanced 8093f149594SLisandro Dalcin 810dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNES`, `SNESSolve()`, `SNESConvergedDefault()`, `SNESSetConvergenceTest()` 8113f149594SLisandro Dalcin @*/ 812d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESConvergedSkip(SNES snes, PetscInt it, PetscReal xnorm, PetscReal snorm, PetscReal fnorm, SNESConvergedReason *reason, void *dummy) 813d71ae5a4SJacob Faibussowitsch { 8143f149594SLisandro Dalcin PetscFunctionBegin; 8150700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 8163f149594SLisandro Dalcin PetscValidPointer(reason, 6); 8173f149594SLisandro Dalcin 8183f149594SLisandro Dalcin *reason = SNES_CONVERGED_ITERATING; 8193f149594SLisandro Dalcin 8203f149594SLisandro Dalcin if (fnorm != fnorm) { 8219566063dSJacob Faibussowitsch PetscCall(PetscInfo(snes, "Failed to converged, function norm is NaN\n")); 8223f149594SLisandro Dalcin *reason = SNES_DIVERGED_FNORM_NAN; 8233f149594SLisandro Dalcin } else if (it == snes->max_its) { 8243f149594SLisandro Dalcin *reason = SNES_CONVERGED_ITS; 8253f149594SLisandro Dalcin } 8263ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 8273f149594SLisandro Dalcin } 8283f149594SLisandro Dalcin 8298d359177SBarry Smith /*@C 830f6dfbefdSBarry Smith SNESSetWorkVecs - Gets a number of work vectors to be used internally by `SNES` solvers 83158c9b817SLisandro Dalcin 83258c9b817SLisandro Dalcin Input Parameters: 833f6dfbefdSBarry Smith + snes - the `SNES` context 834a2b725a8SWilliam Gropp - nw - number of work vectors to allocate 83558c9b817SLisandro Dalcin 83658c9b817SLisandro Dalcin Level: developer 837fa0ddf94SBarry Smith 838dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNES` 83998acb6afSMatthew G Knepley @*/ 840d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESSetWorkVecs(SNES snes, PetscInt nw) 841d71ae5a4SJacob Faibussowitsch { 842c5ed8070SMatthew G. Knepley DM dm; 843c5ed8070SMatthew G. Knepley Vec v; 84458c9b817SLisandro Dalcin 84558c9b817SLisandro Dalcin PetscFunctionBegin; 8469566063dSJacob Faibussowitsch if (snes->work) PetscCall(VecDestroyVecs(snes->nwork, &snes->work)); 84758c9b817SLisandro Dalcin snes->nwork = nw; 848f5af7f23SKarl Rupp 8499566063dSJacob Faibussowitsch PetscCall(SNESGetDM(snes, &dm)); 8509566063dSJacob Faibussowitsch PetscCall(DMGetGlobalVector(dm, &v)); 8519566063dSJacob Faibussowitsch PetscCall(VecDuplicateVecs(v, snes->nwork, &snes->work)); 8529566063dSJacob Faibussowitsch PetscCall(DMRestoreGlobalVector(dm, &v)); 8533ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 85458c9b817SLisandro Dalcin } 855