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 8a6570f20SBarry Smith SNESMonitorSolution - Monitors progress of the SNES solvers by calling 936851e7fSLois Curfman McInnes VecView() for the approximate solution at each iteration. 103f1db9ecSBarry Smith 113f1db9ecSBarry Smith Collective on SNES 123f1db9ecSBarry Smith 133f1db9ecSBarry Smith Input Parameters: 143f1db9ecSBarry Smith + snes - the SNES context 153f1db9ecSBarry Smith . its - iteration number 164b27c08aSLois Curfman McInnes . fgnorm - 2-norm of residual 17f55353a2SBarry Smith - dummy - a viewer 183f1db9ecSBarry Smith 19ee32d87aSMatthew G. Knepley Options Database Keys: 20ee32d87aSMatthew G. Knepley . -snes_monitor_solution [ascii binary draw][:filename][:viewer format] - plots solution at each iteration 21ee32d87aSMatthew G. Knepley 223a61192cSBarry Smith This is not called directly by users, rather one calls `SNESMonitorSet()`, with this function as an argument, to cause the monitor 233a61192cSBarry Smith to be used during the SNES solve. 243a61192cSBarry Smith 2536851e7fSLois Curfman McInnes Level: intermediate 263f1db9ecSBarry Smith 27db781477SPatrick Sanan .seealso: `SNESMonitorSet()`, `SNESMonitorDefault()`, `VecView()` 283f1db9ecSBarry Smith @*/ 299371c9d4SSatish Balay PetscErrorCode SNESMonitorSolution(SNES snes, PetscInt its, PetscReal fgnorm, PetscViewerAndFormat *vf) { 303f1db9ecSBarry Smith Vec x; 31d43b4f6eSBarry Smith PetscViewer viewer = vf->viewer; 323f1db9ecSBarry Smith 333f1db9ecSBarry Smith PetscFunctionBegin; 344d4332d5SBarry Smith PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 4); 359566063dSJacob Faibussowitsch PetscCall(SNESGetSolution(snes, &x)); 369566063dSJacob Faibussowitsch PetscCall(PetscViewerPushFormat(viewer, vf->format)); 379566063dSJacob Faibussowitsch PetscCall(VecView(x, viewer)); 389566063dSJacob Faibussowitsch PetscCall(PetscViewerPopFormat(viewer)); 393f1db9ecSBarry Smith PetscFunctionReturn(0); 403f1db9ecSBarry Smith } 413f1db9ecSBarry Smith 425ed2d596SBarry Smith /*@C 43a6570f20SBarry Smith SNESMonitorResidual - Monitors progress of the SNES solvers by calling 445ed2d596SBarry Smith VecView() for the residual at each iteration. 455ed2d596SBarry Smith 465ed2d596SBarry Smith Collective on SNES 475ed2d596SBarry Smith 485ed2d596SBarry Smith Input Parameters: 495ed2d596SBarry Smith + snes - the SNES context 505ed2d596SBarry Smith . its - iteration number 514b27c08aSLois Curfman McInnes . fgnorm - 2-norm of residual 52f55353a2SBarry Smith - dummy - a viewer 535ed2d596SBarry Smith 54ee32d87aSMatthew G. Knepley Options Database Keys: 55ee32d87aSMatthew G. Knepley . -snes_monitor_residual [ascii binary draw][:filename][:viewer format] - plots residual (not its norm) at each iteration 56ee32d87aSMatthew G. Knepley 573a61192cSBarry Smith Notes: 583a61192cSBarry Smith This is not called directly by users, rather one calls `SNESMonitorSet()`, with this function as an argument, to cause the monitor 593a61192cSBarry Smith to be used during the SNES solve. 603a61192cSBarry Smith 615ed2d596SBarry Smith Level: intermediate 625ed2d596SBarry Smith 63db781477SPatrick Sanan .seealso: `SNESMonitorSet()`, `SNESMonitorDefault()`, `VecView()` 645ed2d596SBarry Smith @*/ 659371c9d4SSatish Balay PetscErrorCode SNESMonitorResidual(SNES snes, PetscInt its, PetscReal fgnorm, PetscViewerAndFormat *vf) { 665ed2d596SBarry Smith Vec x; 67d43b4f6eSBarry Smith PetscViewer viewer = vf->viewer; 685ed2d596SBarry Smith 695ed2d596SBarry Smith PetscFunctionBegin; 704d4332d5SBarry Smith PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 4); 719566063dSJacob Faibussowitsch PetscCall(SNESGetFunction(snes, &x, NULL, NULL)); 729566063dSJacob Faibussowitsch PetscCall(PetscViewerPushFormat(viewer, vf->format)); 739566063dSJacob Faibussowitsch PetscCall(VecView(x, viewer)); 749566063dSJacob Faibussowitsch PetscCall(PetscViewerPopFormat(viewer)); 755ed2d596SBarry Smith PetscFunctionReturn(0); 765ed2d596SBarry Smith } 775ed2d596SBarry Smith 78d132466eSBarry Smith /*@C 79a6570f20SBarry Smith SNESMonitorSolutionUpdate - Monitors progress of the SNES solvers by calling 80d132466eSBarry Smith VecView() for the UPDATE to the solution at each iteration. 81d132466eSBarry Smith 82d132466eSBarry Smith Collective on SNES 83d132466eSBarry Smith 84d132466eSBarry Smith Input Parameters: 85d132466eSBarry 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 90ee32d87aSMatthew G. Knepley Options Database Keys: 91ee32d87aSMatthew G. Knepley . -snes_monitor_solution_update [ascii binary draw][:filename][:viewer format] - plots update to solution at each iteration 92ee32d87aSMatthew G. Knepley 933a61192cSBarry Smith Notes: 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 99db781477SPatrick Sanan .seealso: `SNESMonitorSet()`, `SNESMonitorDefault()`, `VecView()` 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 117798534f6SMatthew G. Knepley KSPMonitorSNESResidual - Prints the SNES residual norm, as well as the linear 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: 128798534f6SMatthew G. Knepley . -snes_monitor_ksp - Activates KSPMonitorSNESResidual() 129a5c2985bSBarry Smith 1303a61192cSBarry Smith Notes: 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 136c2e3fba1SPatrick Sanan .seealso: `KSPMonitorSet()`, `KSPMonitorResidual()`, `KSPMonitorTrueResidualMaxNorm()` 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 171798534f6SMatthew G. Knepley KSPMonitorSNESResidualDrawLG - Plots the linear 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). 179798534f6SMatthew G. Knepley - vf - The viewer context 180e5f7ee39SBarry Smith 181e5f7ee39SBarry Smith Options Database Key: 182798534f6SMatthew G. Knepley . -snes_monitor_ksp draw::draw_lg - Activates KSPMonitorSNESResidualDrawLG() 183e5f7ee39SBarry Smith 1843a61192cSBarry Smith Notes: 1853a61192cSBarry Smith This is not called directly by users, rather one calls `SNESMonitorSet()`, with this function as an argument, to cause the monitor 1863a61192cSBarry Smith to be used during the SNES solve. 1873a61192cSBarry Smith 188e5f7ee39SBarry Smith Level: intermediate 189e5f7ee39SBarry Smith 190db781477SPatrick Sanan .seealso: `KSPMonitorSet()`, `KSPMonitorTrueResidual()` 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 234798534f6SMatthew G. Knepley KSPMonitorSNESResidualDrawLGCreate - Creates the plotter for the linear SNES residual. 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 248db781477SPatrick Sanan .seealso: `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; 262*48a46eb9SPierre 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 267a6570f20SBarry Smith SNESMonitorDefault - Monitors progress of the SNES solvers (default). 268e7e93795SLois Curfman McInnes 269c7afd0dbSLois Curfman McInnes Collective on SNES 270c7afd0dbSLois Curfman McInnes 271e7e93795SLois Curfman McInnes Input Parameters: 272c7afd0dbSLois Curfman McInnes + 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 2843a61192cSBarry 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 3301f60017eSBarry Smith Collective on SNES 3311f60017eSBarry Smith 3321f60017eSBarry Smith Input Parameters: 3331f60017eSBarry 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 3423a61192cSBarry Smith to be used during the SNES solve. 3433a61192cSBarry Smith 3441f60017eSBarry Smith Level: intermediate 3451f60017eSBarry Smith 346db781477SPatrick Sanan .seealso: `SNESMonitorSet()`, `SNESMonitorSolution()` 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 3709371c9d4SSatish Balay PetscErrorCode SNESMonitorJacUpdateSpectrum(SNES snes, PetscInt it, PetscReal fnorm, PetscViewerAndFormat *vf) { 3712e7541e6SPeter Brune Vec X; 3722e7541e6SPeter Brune Mat J, dJ, dJdense; 373d1e9a80fSBarry Smith PetscErrorCode (*func)(SNES, Vec, Mat, Mat, void *); 3742f96bde4SJose E. Roman PetscInt n; 37523fff9afSBarry Smith PetscBLASInt nb = 0, lwork; 3762e7541e6SPeter Brune PetscReal *eigr, *eigi; 3772e7541e6SPeter Brune PetscScalar *work; 3782e7541e6SPeter Brune PetscScalar *a; 3792e7541e6SPeter Brune 3802e7541e6SPeter Brune PetscFunctionBegin; 3812e7541e6SPeter Brune if (it == 0) PetscFunctionReturn(0); 3822e7541e6SPeter Brune /* create the difference between the current update and the current jacobian */ 3839566063dSJacob Faibussowitsch PetscCall(SNESGetSolution(snes, &X)); 3849566063dSJacob Faibussowitsch PetscCall(SNESGetJacobian(snes, NULL, &J, &func, NULL)); 3859566063dSJacob Faibussowitsch PetscCall(MatDuplicate(J, MAT_COPY_VALUES, &dJ)); 3869566063dSJacob Faibussowitsch PetscCall(SNESComputeJacobian(snes, X, dJ, dJ)); 3879566063dSJacob Faibussowitsch PetscCall(MatAXPY(dJ, -1.0, J, SAME_NONZERO_PATTERN)); 388f5af7f23SKarl Rupp 3892e7541e6SPeter Brune /* compute the spectrum directly */ 3909566063dSJacob Faibussowitsch PetscCall(MatConvert(dJ, MATSEQDENSE, MAT_INITIAL_MATRIX, &dJdense)); 3919566063dSJacob Faibussowitsch PetscCall(MatGetSize(dJ, &n, NULL)); 3929566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(n, &nb)); 3932e7541e6SPeter Brune lwork = 3 * nb; 3949566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(n, &eigr)); 3959566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(n, &eigi)); 3969566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(lwork, &work)); 3979566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(dJdense, &a)); 3982e7541e6SPeter Brune #if !defined(PETSC_USE_COMPLEX) 3992e7541e6SPeter Brune { 4002e7541e6SPeter Brune PetscBLASInt lierr; 4012f96bde4SJose E. Roman PetscInt i; 4029566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF)); 403792fecdfSBarry Smith PetscCallBLAS("LAPACKgeev", LAPACKgeev_("N", "N", &nb, a, &nb, eigr, eigi, NULL, &nb, NULL, &nb, work, &lwork, &lierr)); 40463a3b9bcSJacob Faibussowitsch PetscCheck(!lierr, PETSC_COMM_SELF, PETSC_ERR_LIB, "geev() error %" PetscBLASInt_FMT, lierr); 4059566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPop()); 40663a3b9bcSJacob Faibussowitsch PetscCall(PetscPrintf(PetscObjectComm((PetscObject)snes), "Eigenvalues of J_%" PetscInt_FMT " - J_%" PetscInt_FMT ":\n", it, it - 1)); 407*48a46eb9SPierre 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])); 4082f96bde4SJose E. Roman } 4099566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArray(dJdense, &a)); 4109566063dSJacob Faibussowitsch PetscCall(MatDestroy(&dJ)); 4119566063dSJacob Faibussowitsch PetscCall(MatDestroy(&dJdense)); 4129566063dSJacob Faibussowitsch PetscCall(PetscFree(eigr)); 4139566063dSJacob Faibussowitsch PetscCall(PetscFree(eigi)); 4149566063dSJacob Faibussowitsch PetscCall(PetscFree(work)); 4152e7541e6SPeter Brune PetscFunctionReturn(0); 4162f96bde4SJose E. Roman #else 4172f96bde4SJose E. Roman SETERRQ(PETSC_COMM_SELF, PETSC_ERR_SUP, "Not coded for complex"); 4182f96bde4SJose E. Roman #endif 4192e7541e6SPeter Brune } 4202e7541e6SPeter Brune 4216ba87a44SLisandro Dalcin PETSC_INTERN PetscErrorCode SNESMonitorRange_Private(SNES, PetscInt, PetscReal *); 4226ba87a44SLisandro Dalcin 4239371c9d4SSatish Balay PetscErrorCode SNESMonitorRange_Private(SNES snes, PetscInt it, PetscReal *per) { 424b271bb04SBarry Smith Vec resid; 425b271bb04SBarry Smith PetscReal rmax, pwork; 426b271bb04SBarry Smith PetscInt i, n, N; 427b271bb04SBarry Smith PetscScalar *r; 428b271bb04SBarry Smith 429b271bb04SBarry Smith PetscFunctionBegin; 4309566063dSJacob Faibussowitsch PetscCall(SNESGetFunction(snes, &resid, NULL, NULL)); 4319566063dSJacob Faibussowitsch PetscCall(VecNorm(resid, NORM_INFINITY, &rmax)); 4329566063dSJacob Faibussowitsch PetscCall(VecGetLocalSize(resid, &n)); 4339566063dSJacob Faibussowitsch PetscCall(VecGetSize(resid, &N)); 4349566063dSJacob Faibussowitsch PetscCall(VecGetArray(resid, &r)); 435b271bb04SBarry Smith pwork = 0.0; 4369371c9d4SSatish Balay for (i = 0; i < n; i++) { pwork += (PetscAbsScalar(r[i]) > .20 * rmax); } 4371c2dc1cbSBarry Smith PetscCall(MPIU_Allreduce(&pwork, per, 1, MPIU_REAL, MPIU_SUM, PetscObjectComm((PetscObject)snes))); 4389566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(resid, &r)); 439b271bb04SBarry Smith *per = *per / N; 440b271bb04SBarry Smith PetscFunctionReturn(0); 441b271bb04SBarry Smith } 442b271bb04SBarry Smith 443b271bb04SBarry Smith /*@C 444b271bb04SBarry Smith SNESMonitorRange - Prints the percentage of residual elements that are more then 10 percent of the maximum value. 445b271bb04SBarry Smith 446b271bb04SBarry Smith Collective on SNES 447b271bb04SBarry Smith 448b271bb04SBarry Smith Input Parameters: 449b271bb04SBarry Smith + snes - iterative context 450b271bb04SBarry Smith . it - iteration number 451b271bb04SBarry Smith . rnorm - 2-norm (preconditioned) residual value (may be estimated). 452b271bb04SBarry Smith - dummy - unused monitor context 453b271bb04SBarry Smith 454b271bb04SBarry Smith Options Database Key: 455b271bb04SBarry Smith . -snes_monitor_range - Activates SNESMonitorRange() 456b271bb04SBarry Smith 4573a61192cSBarry Smith Notes: 4583a61192cSBarry Smith This is not called directly by users, rather one calls `SNESMonitorSet()`, with this function as an argument, to cause the monitor 4593a61192cSBarry Smith to be used during the SNES solve. 4603a61192cSBarry Smith 461b271bb04SBarry Smith Level: intermediate 462b271bb04SBarry Smith 463db781477SPatrick Sanan .seealso: `SNESMonitorSet()`, `SNESMonitorDefault()`, `SNESMonitorLGCreate()` 464b271bb04SBarry Smith @*/ 4659371c9d4SSatish Balay PetscErrorCode SNESMonitorRange(SNES snes, PetscInt it, PetscReal rnorm, PetscViewerAndFormat *vf) { 466b271bb04SBarry Smith PetscReal perc, rel; 467d43b4f6eSBarry Smith PetscViewer viewer = vf->viewer; 468b271bb04SBarry Smith /* should be in a MonitorRangeContext */ 469b271bb04SBarry Smith static PetscReal prev; 470b271bb04SBarry Smith 471b271bb04SBarry Smith PetscFunctionBegin; 4724d4332d5SBarry Smith PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 4); 473b271bb04SBarry Smith if (!it) prev = rnorm; 4749566063dSJacob Faibussowitsch PetscCall(SNESMonitorRange_Private(snes, it, &perc)); 475b271bb04SBarry Smith 476b271bb04SBarry Smith rel = (prev - rnorm) / prev; 477b271bb04SBarry Smith prev = rnorm; 4789566063dSJacob Faibussowitsch PetscCall(PetscViewerPushFormat(viewer, vf->format)); 4799566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIAddTab(viewer, ((PetscObject)snes)->tablevel)); 48063a3b9bcSJacob 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))); 4819566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIISubtractTab(viewer, ((PetscObject)snes)->tablevel)); 4829566063dSJacob Faibussowitsch PetscCall(PetscViewerPopFormat(viewer)); 483b271bb04SBarry Smith PetscFunctionReturn(0); 484b271bb04SBarry Smith } 485b271bb04SBarry Smith 4863a7fca6bSBarry Smith /*@C 487a6570f20SBarry Smith SNESMonitorRatio - Monitors progress of the SNES solvers by printing the ratio 4884b27c08aSLois Curfman McInnes of residual norm at each iteration to the previous. 4893a7fca6bSBarry Smith 4903a7fca6bSBarry Smith Collective on SNES 4913a7fca6bSBarry Smith 4923a7fca6bSBarry Smith Input Parameters: 4933a7fca6bSBarry Smith + snes - the SNES context 4943a7fca6bSBarry Smith . its - iteration number 4953a7fca6bSBarry Smith . fgnorm - 2-norm of residual (or gradient) 496eabae89aSBarry Smith - dummy - context of monitor 4973a7fca6bSBarry Smith 4983a7fca6bSBarry Smith Level: intermediate 4993a7fca6bSBarry Smith 50095452b02SPatrick Sanan Notes: 5013a61192cSBarry Smith This is not called directly by users, rather one calls `SNESMonitorSet()`, with this function as an argument, to cause the monitor 5023a61192cSBarry Smith to be used during the SNES solve. 5033a61192cSBarry Smith 5043a61192cSBarry Smith Be sure to call SNESMonitorRationSetUp() before using this monitor. 5053a61192cSBarry Smith 5063a61192cSBarry Smith .seealso: `SNESMonitorSet()`, `SNESMonitorSolution()`, `SNESMonitorDefault()` 5073a7fca6bSBarry Smith @*/ 5089371c9d4SSatish Balay PetscErrorCode SNESMonitorRatio(SNES snes, PetscInt its, PetscReal fgnorm, PetscViewerAndFormat *vf) { 50977431f27SBarry Smith PetscInt len; 51087828ca2SBarry Smith PetscReal *history; 511d43b4f6eSBarry Smith PetscViewer viewer = vf->viewer; 5123a7fca6bSBarry Smith 5133a7fca6bSBarry Smith PetscFunctionBegin; 5149566063dSJacob Faibussowitsch PetscCall(SNESGetConvergenceHistory(snes, &history, NULL, &len)); 5159566063dSJacob Faibussowitsch PetscCall(PetscViewerPushFormat(viewer, vf->format)); 5169566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIAddTab(viewer, ((PetscObject)snes)->tablevel)); 517958c9bccSBarry Smith if (!its || !history || its > len) { 51863a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "%3" PetscInt_FMT " SNES Function norm %14.12e \n", its, (double)fgnorm)); 5193a7fca6bSBarry Smith } else { 52087828ca2SBarry Smith PetscReal ratio = fgnorm / history[its - 1]; 52163a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "%3" PetscInt_FMT " SNES Function norm %14.12e %14.12e \n", its, (double)fgnorm, (double)ratio)); 5223a7fca6bSBarry Smith } 5239566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIISubtractTab(viewer, ((PetscObject)snes)->tablevel)); 5249566063dSJacob Faibussowitsch PetscCall(PetscViewerPopFormat(viewer)); 5253a7fca6bSBarry Smith PetscFunctionReturn(0); 5263a7fca6bSBarry Smith } 5273a7fca6bSBarry Smith 5283a7fca6bSBarry Smith /*@C 529fde5950dSBarry Smith SNESMonitorRatioSetUp - Insures the SNES object is saving its history since this monitor needs access to it 5303a7fca6bSBarry Smith 5313a7fca6bSBarry Smith Collective on SNES 5323a7fca6bSBarry Smith 5333a7fca6bSBarry Smith Input Parameters: 534eabae89aSBarry Smith + snes - the SNES context 535fde5950dSBarry Smith - viewer - the PetscViewer object (ignored) 5363a7fca6bSBarry Smith 5373a7fca6bSBarry Smith Level: intermediate 5383a7fca6bSBarry Smith 539db781477SPatrick Sanan .seealso: `SNESMonitorSet()`, `SNESMonitorSolution()`, `SNESMonitorDefault()`, `SNESMonitorRatio()` 5403a7fca6bSBarry Smith @*/ 5419371c9d4SSatish Balay PetscErrorCode SNESMonitorRatioSetUp(SNES snes, PetscViewerAndFormat *vf) { 54287828ca2SBarry Smith PetscReal *history; 5433a7fca6bSBarry Smith 5443a7fca6bSBarry Smith PetscFunctionBegin; 5459566063dSJacob Faibussowitsch PetscCall(SNESGetConvergenceHistory(snes, &history, NULL, NULL)); 546*48a46eb9SPierre Jolivet if (!history) PetscCall(SNESSetConvergenceHistory(snes, NULL, NULL, 100, PETSC_TRUE)); 5473a7fca6bSBarry Smith PetscFunctionReturn(0); 5483a7fca6bSBarry Smith } 5493a7fca6bSBarry Smith 550e7e93795SLois Curfman McInnes /* ---------------------------------------------------------------- */ 551be1f7002SBarry Smith /* 552a6570f20SBarry Smith Default (short) SNES Monitor, same as SNESMonitorDefault() except 553be1f7002SBarry Smith it prints fewer digits of the residual as the residual gets smaller. 554be1f7002SBarry Smith This is because the later digits are meaningless and are often 555be1f7002SBarry Smith different on different machines; by using this routine different 556be1f7002SBarry Smith machines will usually generate the same output. 557dec21524SBarry Smith 558dec21524SBarry Smith Deprecated: Intentionally has no manual page 559be1f7002SBarry Smith */ 5609371c9d4SSatish Balay PetscErrorCode SNESMonitorDefaultShort(SNES snes, PetscInt its, PetscReal fgnorm, PetscViewerAndFormat *vf) { 561d43b4f6eSBarry Smith PetscViewer viewer = vf->viewer; 562d132466eSBarry Smith 5633a40ed3dSBarry Smith PetscFunctionBegin; 5644d4332d5SBarry Smith PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 4); 5659566063dSJacob Faibussowitsch PetscCall(PetscViewerPushFormat(viewer, vf->format)); 5669566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIAddTab(viewer, ((PetscObject)snes)->tablevel)); 5678f240d10SBarry Smith if (fgnorm > 1.e-9) { 56863a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "%3" PetscInt_FMT " SNES Function norm %g \n", its, (double)fgnorm)); 5693a40ed3dSBarry Smith } else if (fgnorm > 1.e-11) { 57063a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "%3" PetscInt_FMT " SNES Function norm %5.3e \n", its, (double)fgnorm)); 5713a40ed3dSBarry Smith } else { 57263a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "%3" PetscInt_FMT " SNES Function norm < 1.e-11\n", its)); 573a34d58ebSBarry Smith } 5749566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIISubtractTab(viewer, ((PetscObject)snes)->tablevel)); 5759566063dSJacob Faibussowitsch PetscCall(PetscViewerPopFormat(viewer)); 5763a40ed3dSBarry Smith PetscFunctionReturn(0); 577e7e93795SLois Curfman McInnes } 5782db13446SMatthew G. Knepley 5792db13446SMatthew G. Knepley /*@C 5802db13446SMatthew G. Knepley SNESMonitorDefaultField - Monitors progress of the SNES solvers, separated into fields. 5812db13446SMatthew G. Knepley 5822db13446SMatthew G. Knepley Collective on SNES 5832db13446SMatthew G. Knepley 5842db13446SMatthew G. Knepley Input Parameters: 5852db13446SMatthew G. Knepley + snes - the SNES context 5862db13446SMatthew G. Knepley . its - iteration number 5872db13446SMatthew G. Knepley . fgnorm - 2-norm of residual 5882db13446SMatthew G. Knepley - ctx - the PetscViewer 5892db13446SMatthew G. Knepley 5902db13446SMatthew G. Knepley Notes: 5913a61192cSBarry Smith This routine uses the DM attached to the residual vector to define the fields. 5923a61192cSBarry Smith 5933a61192cSBarry Smith This is not called directly by users, rather one calls `SNESMonitorSet()`, with this function as an argument, to cause the monitor 5943a61192cSBarry Smith to be used during the SNES solve. 5952db13446SMatthew G. Knepley 5962db13446SMatthew G. Knepley Level: intermediate 5972db13446SMatthew G. Knepley 598db781477SPatrick Sanan .seealso: `SNESMonitorSet()`, `SNESMonitorSolution()`, `SNESMonitorDefault()` 5992db13446SMatthew G. Knepley @*/ 6009371c9d4SSatish Balay PetscErrorCode SNESMonitorDefaultField(SNES snes, PetscInt its, PetscReal fgnorm, PetscViewerAndFormat *vf) { 601d43b4f6eSBarry Smith PetscViewer viewer = vf->viewer; 6022db13446SMatthew G. Knepley Vec r; 6032db13446SMatthew G. Knepley DM dm; 6042db13446SMatthew G. Knepley PetscReal res[256]; 6052db13446SMatthew G. Knepley PetscInt tablevel; 6062db13446SMatthew G. Knepley 6072db13446SMatthew G. Knepley PetscFunctionBegin; 6084d4332d5SBarry Smith PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 4); 6099566063dSJacob Faibussowitsch PetscCall(SNESGetFunction(snes, &r, NULL, NULL)); 6109566063dSJacob Faibussowitsch PetscCall(VecGetDM(r, &dm)); 6119566063dSJacob Faibussowitsch if (!dm) PetscCall(SNESMonitorDefault(snes, its, fgnorm, vf)); 6122db13446SMatthew G. Knepley else { 6132db13446SMatthew G. Knepley PetscSection s, gs; 6142db13446SMatthew G. Knepley PetscInt Nf, f; 6152db13446SMatthew G. Knepley 6169566063dSJacob Faibussowitsch PetscCall(DMGetLocalSection(dm, &s)); 6179566063dSJacob Faibussowitsch PetscCall(DMGetGlobalSection(dm, &gs)); 6189566063dSJacob Faibussowitsch if (!s || !gs) PetscCall(SNESMonitorDefault(snes, its, fgnorm, vf)); 6199566063dSJacob Faibussowitsch PetscCall(PetscSectionGetNumFields(s, &Nf)); 62063a3b9bcSJacob Faibussowitsch PetscCheck(Nf <= 256, PetscObjectComm((PetscObject)snes), PETSC_ERR_SUP, "Do not support %" PetscInt_FMT " fields > 256", Nf); 6219566063dSJacob Faibussowitsch PetscCall(PetscSectionVecNorm(s, gs, r, NORM_2, res)); 6229566063dSJacob Faibussowitsch PetscCall(PetscObjectGetTabLevel((PetscObject)snes, &tablevel)); 6239566063dSJacob Faibussowitsch PetscCall(PetscViewerPushFormat(viewer, vf->format)); 6249566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIAddTab(viewer, tablevel)); 62563a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "%3" PetscInt_FMT " SNES Function norm %14.12e [", its, (double)fgnorm)); 6262db13446SMatthew G. Knepley for (f = 0; f < Nf; ++f) { 6279566063dSJacob Faibussowitsch if (f) PetscCall(PetscViewerASCIIPrintf(viewer, ", ")); 62863a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "%14.12e", (double)res[f])); 6292db13446SMatthew G. Knepley } 6309566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "] \n")); 6319566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIISubtractTab(viewer, tablevel)); 6329566063dSJacob Faibussowitsch PetscCall(PetscViewerPopFormat(viewer)); 6332db13446SMatthew G. Knepley } 6342db13446SMatthew G. Knepley PetscFunctionReturn(0); 6352db13446SMatthew G. Knepley } 636e7e93795SLois Curfman McInnes /* ---------------------------------------------------------------- */ 6374b828684SBarry Smith /*@C 638c34cbdceSBarry Smith SNESConvergedDefault - Default onvergence test of the solvers for 639c34cbdceSBarry Smith systems of nonlinear equations. 640e7e93795SLois Curfman McInnes 641c7afd0dbSLois Curfman McInnes Collective on SNES 642c7afd0dbSLois Curfman McInnes 643e7e93795SLois Curfman McInnes Input Parameters: 644c7afd0dbSLois Curfman McInnes + snes - the SNES context 64506ee9f85SBarry Smith . it - the iteration (0 indicates before any Newton steps) 646e7e93795SLois Curfman McInnes . xnorm - 2-norm of current iterate 647c60f73f4SPeter Brune . snorm - 2-norm of current step 6487f3332b4SBarry Smith . fnorm - 2-norm of function at current iterate 649c7afd0dbSLois Curfman McInnes - dummy - unused context 650e7e93795SLois Curfman McInnes 651184914b5SBarry Smith Output Parameter: 652184914b5SBarry Smith . reason - one of 65370441072SBarry Smith $ SNES_CONVERGED_FNORM_ABS - (fnorm < abstol), 654c60f73f4SPeter Brune $ SNES_CONVERGED_SNORM_RELATIVE - (snorm < stol*xnorm), 655184914b5SBarry Smith $ SNES_CONVERGED_FNORM_RELATIVE - (fnorm < rtol*fnorm0), 656184914b5SBarry Smith $ SNES_DIVERGED_FUNCTION_COUNT - (nfct > maxf), 657184914b5SBarry Smith $ SNES_DIVERGED_FNORM_NAN - (fnorm == NaN), 658184914b5SBarry Smith $ SNES_CONVERGED_ITERATING - (otherwise), 659c34cbdceSBarry Smith $ SNES_DIVERGED_DTOL - (fnorm > divtol*snes->fnorm0) 660e7e93795SLois Curfman McInnes 661e7e93795SLois Curfman McInnes where 662c34cbdceSBarry Smith + maxf - maximum number of function evaluations, set with SNESSetTolerances() 663c7afd0dbSLois Curfman McInnes . nfct - number of function evaluations, 664c34cbdceSBarry Smith . abstol - absolute function norm tolerance, set with SNESSetTolerances() 665c34cbdceSBarry Smith . rtol - relative function norm tolerance, set with SNESSetTolerances() 666c34cbdceSBarry Smith . divtol - divergence tolerance, set with SNESSetDivergenceTolerance() 667c34cbdceSBarry Smith - fnorm0 - 2-norm of the function at the initial solution (initial guess; zeroth iteration) 668c34cbdceSBarry Smith 669c34cbdceSBarry Smith Options Database Keys: 670f362779dSJed Brown + -snes_convergence_test default - see SNESSetFromOptions() 671f362779dSJed Brown . -snes_stol - convergence tolerance in terms of the norm of the change in the solution between steps 672c34cbdceSBarry Smith . -snes_atol <abstol> - absolute tolerance of residual norm 673c34cbdceSBarry Smith . -snes_rtol <rtol> - relative decrease in tolerance norm from the initial 2-norm of the solution 674c34cbdceSBarry Smith . -snes_divergence_tolerance <divtol> - if the residual goes above divtol*rnorm0, exit with divergence 675c34cbdceSBarry Smith . -snes_max_funcs <max_funcs> - maximum number of function evaluations 676c34cbdceSBarry Smith . -snes_max_fail <max_fail> - maximum number of line search failures allowed before stopping, default is none 677c34cbdceSBarry Smith - -snes_max_linear_solve_fail - number of linear solver failures before SNESSolve() stops 678fee21e36SBarry Smith 67936851e7fSLois Curfman McInnes Level: intermediate 68036851e7fSLois Curfman McInnes 681db781477SPatrick Sanan .seealso: `SNESSetConvergenceTest()`, `SNESConvergedSkip()`, `SNESSetTolerances()`, `SNESSetDivergenceTolerance()` 682e7e93795SLois Curfman McInnes @*/ 6839371c9d4SSatish Balay PetscErrorCode SNESConvergedDefault(SNES snes, PetscInt it, PetscReal xnorm, PetscReal snorm, PetscReal fnorm, SNESConvergedReason *reason, void *dummy) { 6843a40ed3dSBarry Smith PetscFunctionBegin; 6850700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 6863f149594SLisandro Dalcin PetscValidPointer(reason, 6); 6873f149594SLisandro Dalcin 68806ee9f85SBarry Smith *reason = SNES_CONVERGED_ITERATING; 68906ee9f85SBarry Smith 69006ee9f85SBarry Smith if (!it) { 69106ee9f85SBarry Smith /* set parameter for default relative tolerance convergence test */ 69206ee9f85SBarry Smith snes->ttol = fnorm * snes->rtol; 693e37c518bSBarry Smith snes->rnorm0 = fnorm; 69406ee9f85SBarry Smith } 6958146f6ebSBarry Smith if (PetscIsInfOrNanReal(fnorm)) { 6969566063dSJacob Faibussowitsch PetscCall(PetscInfo(snes, "Failed to converged, function norm is NaN\n")); 697184914b5SBarry Smith *reason = SNES_DIVERGED_FNORM_NAN; 698be5caee7SBarry Smith } else if (fnorm < snes->abstol && (it || !snes->forceiteration)) { 6999566063dSJacob Faibussowitsch PetscCall(PetscInfo(snes, "Converged due to function norm %14.12e < %14.12e\n", (double)fnorm, (double)snes->abstol)); 700184914b5SBarry Smith *reason = SNES_CONVERGED_FNORM_ABS; 701e71169deSBarry Smith } else if (snes->nfuncs >= snes->max_funcs && snes->max_funcs >= 0) { 70263a3b9bcSJacob Faibussowitsch PetscCall(PetscInfo(snes, "Exceeded maximum number of function evaluations: %" PetscInt_FMT " > %" PetscInt_FMT "\n", snes->nfuncs, snes->max_funcs)); 703184914b5SBarry Smith *reason = SNES_DIVERGED_FUNCTION_COUNT; 70406ee9f85SBarry Smith } 70506ee9f85SBarry Smith 70606ee9f85SBarry Smith if (it && !*reason) { 70706ee9f85SBarry Smith if (fnorm <= snes->ttol) { 7089566063dSJacob Faibussowitsch PetscCall(PetscInfo(snes, "Converged due to function norm %14.12e < %14.12e (relative tolerance)\n", (double)fnorm, (double)snes->ttol)); 70906ee9f85SBarry Smith *reason = SNES_CONVERGED_FNORM_RELATIVE; 710c60f73f4SPeter Brune } else if (snorm < snes->stol * xnorm) { 7119566063dSJacob Faibussowitsch PetscCall(PetscInfo(snes, "Converged due to small update length: %14.12e < %14.12e * %14.12e\n", (double)snorm, (double)snes->stol, (double)xnorm)); 712c60f73f4SPeter Brune *reason = SNES_CONVERGED_SNORM_RELATIVE; 713e4d06f11SPatrick Farrell } else if (snes->divtol > 0 && (fnorm > snes->divtol * snes->rnorm0)) { 7149566063dSJacob 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)); 715e37c518bSBarry Smith *reason = SNES_DIVERGED_DTOL; 71606ee9f85SBarry Smith } 717e7e93795SLois Curfman McInnes } 7183a40ed3dSBarry Smith PetscFunctionReturn(0); 719e7e93795SLois Curfman McInnes } 7203f149594SLisandro Dalcin 7213f149594SLisandro Dalcin /*@C 722e2a6519dSDmitry Karpeev SNESConvergedSkip - Convergence test for SNES that NEVER returns as 7233f149594SLisandro Dalcin converged, UNLESS the maximum number of iteration have been reached. 7243f149594SLisandro Dalcin 7253f9fe445SBarry Smith Logically Collective on SNES 7263f149594SLisandro Dalcin 7273f149594SLisandro Dalcin Input Parameters: 7283f149594SLisandro Dalcin + snes - the SNES context 7293f149594SLisandro Dalcin . it - the iteration (0 indicates before any Newton steps) 7303f149594SLisandro Dalcin . xnorm - 2-norm of current iterate 731c60f73f4SPeter Brune . snorm - 2-norm of current step 7323f149594SLisandro Dalcin . fnorm - 2-norm of function at current iterate 7333f149594SLisandro Dalcin - dummy - unused context 7343f149594SLisandro Dalcin 7353f149594SLisandro Dalcin Output Parameter: 73685385478SLisandro Dalcin . reason - SNES_CONVERGED_ITERATING, SNES_CONVERGED_ITS, or SNES_DIVERGED_FNORM_NAN 7373f149594SLisandro Dalcin 7383f149594SLisandro Dalcin Notes: 7393f149594SLisandro Dalcin Convergence is then declared after a fixed number of iterations have been used. 7403f149594SLisandro Dalcin 741f362779dSJed Brown Options Database Keys: 742f362779dSJed Brown . -snes_convergence_test default - see SNESSetFromOptions() 743f362779dSJed Brown 7443f149594SLisandro Dalcin Level: advanced 7453f149594SLisandro Dalcin 746db781477SPatrick Sanan .seealso: `SNESConvergedDefault()`, `SNESSetConvergenceTest()` 7473f149594SLisandro Dalcin @*/ 7489371c9d4SSatish Balay PetscErrorCode SNESConvergedSkip(SNES snes, PetscInt it, PetscReal xnorm, PetscReal snorm, PetscReal fnorm, SNESConvergedReason *reason, void *dummy) { 7493f149594SLisandro Dalcin PetscFunctionBegin; 7500700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 7513f149594SLisandro Dalcin PetscValidPointer(reason, 6); 7523f149594SLisandro Dalcin 7533f149594SLisandro Dalcin *reason = SNES_CONVERGED_ITERATING; 7543f149594SLisandro Dalcin 7553f149594SLisandro Dalcin if (fnorm != fnorm) { 7569566063dSJacob Faibussowitsch PetscCall(PetscInfo(snes, "Failed to converged, function norm is NaN\n")); 7573f149594SLisandro Dalcin *reason = SNES_DIVERGED_FNORM_NAN; 7583f149594SLisandro Dalcin } else if (it == snes->max_its) { 7593f149594SLisandro Dalcin *reason = SNES_CONVERGED_ITS; 7603f149594SLisandro Dalcin } 7613f149594SLisandro Dalcin PetscFunctionReturn(0); 7623f149594SLisandro Dalcin } 7633f149594SLisandro Dalcin 7648d359177SBarry Smith /*@C 765fa0ddf94SBarry Smith SNESSetWorkVecs - Gets a number of work vectors. 76658c9b817SLisandro Dalcin 76758c9b817SLisandro Dalcin Input Parameters: 768a2b725a8SWilliam Gropp + snes - the SNES context 769a2b725a8SWilliam Gropp - nw - number of work vectors to allocate 77058c9b817SLisandro Dalcin 77158c9b817SLisandro Dalcin Level: developer 772fa0ddf94SBarry Smith 77398acb6afSMatthew G Knepley @*/ 7749371c9d4SSatish Balay PetscErrorCode SNESSetWorkVecs(SNES snes, PetscInt nw) { 775c5ed8070SMatthew G. Knepley DM dm; 776c5ed8070SMatthew G. Knepley Vec v; 77758c9b817SLisandro Dalcin 77858c9b817SLisandro Dalcin PetscFunctionBegin; 7799566063dSJacob Faibussowitsch if (snes->work) PetscCall(VecDestroyVecs(snes->nwork, &snes->work)); 78058c9b817SLisandro Dalcin snes->nwork = nw; 781f5af7f23SKarl Rupp 7829566063dSJacob Faibussowitsch PetscCall(SNESGetDM(snes, &dm)); 7839566063dSJacob Faibussowitsch PetscCall(DMGetGlobalVector(dm, &v)); 7849566063dSJacob Faibussowitsch PetscCall(VecDuplicateVecs(v, snes->nwork, &snes->work)); 7859566063dSJacob Faibussowitsch PetscCall(DMRestoreGlobalVector(dm, &v)); 7869566063dSJacob Faibussowitsch PetscCall(PetscLogObjectParents(snes, nw, snes->work)); 78758c9b817SLisandro Dalcin PetscFunctionReturn(0); 78858c9b817SLisandro Dalcin } 789