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 @*/ 29d43b4f6eSBarry Smith PetscErrorCode SNESMonitorSolution(SNES snes,PetscInt its,PetscReal fgnorm,PetscViewerAndFormat *vf) 303f1db9ecSBarry Smith { 313f1db9ecSBarry Smith Vec x; 32d43b4f6eSBarry Smith PetscViewer viewer = vf->viewer; 333f1db9ecSBarry Smith 343f1db9ecSBarry Smith PetscFunctionBegin; 354d4332d5SBarry Smith PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,4); 369566063dSJacob Faibussowitsch PetscCall(SNESGetSolution(snes,&x)); 379566063dSJacob Faibussowitsch PetscCall(PetscViewerPushFormat(viewer,vf->format)); 389566063dSJacob Faibussowitsch PetscCall(VecView(x,viewer)); 399566063dSJacob Faibussowitsch PetscCall(PetscViewerPopFormat(viewer)); 403f1db9ecSBarry Smith PetscFunctionReturn(0); 413f1db9ecSBarry Smith } 423f1db9ecSBarry Smith 435ed2d596SBarry Smith /*@C 44a6570f20SBarry Smith SNESMonitorResidual - Monitors progress of the SNES solvers by calling 455ed2d596SBarry Smith VecView() for the residual at each iteration. 465ed2d596SBarry Smith 475ed2d596SBarry Smith Collective on SNES 485ed2d596SBarry Smith 495ed2d596SBarry Smith Input Parameters: 505ed2d596SBarry Smith + snes - the SNES context 515ed2d596SBarry Smith . its - iteration number 524b27c08aSLois Curfman McInnes . fgnorm - 2-norm of residual 53f55353a2SBarry Smith - dummy - a viewer 545ed2d596SBarry Smith 55ee32d87aSMatthew G. Knepley Options Database Keys: 56ee32d87aSMatthew G. Knepley . -snes_monitor_residual [ascii binary draw][:filename][:viewer format] - plots residual (not its norm) at each iteration 57ee32d87aSMatthew G. Knepley 583a61192cSBarry Smith Notes: 593a61192cSBarry Smith This is not called directly by users, rather one calls `SNESMonitorSet()`, with this function as an argument, to cause the monitor 603a61192cSBarry Smith to be used during the SNES solve. 613a61192cSBarry Smith 625ed2d596SBarry Smith Level: intermediate 635ed2d596SBarry Smith 64db781477SPatrick Sanan .seealso: `SNESMonitorSet()`, `SNESMonitorDefault()`, `VecView()` 655ed2d596SBarry Smith @*/ 66d43b4f6eSBarry Smith PetscErrorCode SNESMonitorResidual(SNES snes,PetscInt its,PetscReal fgnorm,PetscViewerAndFormat *vf) 675ed2d596SBarry Smith { 685ed2d596SBarry Smith Vec x; 69d43b4f6eSBarry Smith PetscViewer viewer = vf->viewer; 705ed2d596SBarry Smith 715ed2d596SBarry Smith PetscFunctionBegin; 724d4332d5SBarry Smith PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,4); 739566063dSJacob Faibussowitsch PetscCall(SNESGetFunction(snes,&x,NULL,NULL)); 749566063dSJacob Faibussowitsch PetscCall(PetscViewerPushFormat(viewer,vf->format)); 759566063dSJacob Faibussowitsch PetscCall(VecView(x,viewer)); 769566063dSJacob Faibussowitsch PetscCall(PetscViewerPopFormat(viewer)); 775ed2d596SBarry Smith PetscFunctionReturn(0); 785ed2d596SBarry Smith } 795ed2d596SBarry Smith 80d132466eSBarry Smith /*@C 81a6570f20SBarry Smith SNESMonitorSolutionUpdate - Monitors progress of the SNES solvers by calling 82d132466eSBarry Smith VecView() for the UPDATE to the solution at each iteration. 83d132466eSBarry Smith 84d132466eSBarry Smith Collective on SNES 85d132466eSBarry Smith 86d132466eSBarry Smith Input Parameters: 87d132466eSBarry 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 92ee32d87aSMatthew G. Knepley Options Database Keys: 93ee32d87aSMatthew G. Knepley . -snes_monitor_solution_update [ascii binary draw][:filename][:viewer format] - plots update to solution at each iteration 94ee32d87aSMatthew G. Knepley 953a61192cSBarry Smith Notes: 963a61192cSBarry Smith This is not called directly by users, rather one calls `SNESMonitorSet()`, with this function as an argument, to cause the monitor 973a61192cSBarry Smith to be used during the SNES solve. 983a61192cSBarry Smith 99d132466eSBarry Smith Level: intermediate 100d132466eSBarry Smith 101db781477SPatrick Sanan .seealso: `SNESMonitorSet()`, `SNESMonitorDefault()`, `VecView()` 102d132466eSBarry Smith @*/ 103d43b4f6eSBarry Smith PetscErrorCode SNESMonitorSolutionUpdate(SNES snes,PetscInt its,PetscReal fgnorm,PetscViewerAndFormat *vf) 104d132466eSBarry Smith { 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)); 114d132466eSBarry Smith PetscFunctionReturn(0); 115d132466eSBarry Smith } 116d132466eSBarry Smith 117798534f6SMatthew G. Knepley #include <petscdraw.h> 118a5c2985bSBarry Smith 119798534f6SMatthew G. Knepley /*@C 120798534f6SMatthew G. Knepley KSPMonitorSNESResidual - Prints the SNES residual norm, as well as the linear residual norm, at each iteration of an iterative solver. 121798534f6SMatthew G. Knepley 122798534f6SMatthew G. Knepley Collective on ksp 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: 131798534f6SMatthew G. Knepley . -snes_monitor_ksp - Activates KSPMonitorSNESResidual() 132a5c2985bSBarry Smith 1333a61192cSBarry Smith Notes: 1343a61192cSBarry Smith This is not called directly by users, rather one calls `KSPMonitorSet()`, with this function as an argument, to cause the monitor 1353a61192cSBarry Smith to be used during the KSP solve. 1363a61192cSBarry Smith 137a5c2985bSBarry Smith Level: intermediate 138a5c2985bSBarry Smith 139c2e3fba1SPatrick Sanan .seealso: `KSPMonitorSet()`, `KSPMonitorResidual()`, `KSPMonitorTrueResidualMaxNorm()` 140a5c2985bSBarry Smith @*/ 141798534f6SMatthew G. Knepley PetscErrorCode KSPMonitorSNESResidual(KSP ksp, PetscInt n, PetscReal rnorm, PetscViewerAndFormat *vf) 142a5c2985bSBarry Smith { 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)); 171a5c2985bSBarry Smith PetscFunctionReturn(0); 172a5c2985bSBarry Smith } 173a5c2985bSBarry Smith 174e5f7ee39SBarry Smith /*@C 175798534f6SMatthew G. Knepley KSPMonitorSNESResidualDrawLG - Plots the linear SNES residual norm at each iteration of an iterative solver. 176e5f7ee39SBarry Smith 177798534f6SMatthew G. Knepley Collective on ksp 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). 183798534f6SMatthew G. Knepley - vf - The viewer context 184e5f7ee39SBarry Smith 185e5f7ee39SBarry Smith Options Database Key: 186798534f6SMatthew G. Knepley . -snes_monitor_ksp draw::draw_lg - Activates KSPMonitorSNESResidualDrawLG() 187e5f7ee39SBarry Smith 1883a61192cSBarry Smith Notes: 1893a61192cSBarry Smith This is not called directly by users, rather one calls `SNESMonitorSet()`, with this function as an argument, to cause the monitor 1903a61192cSBarry Smith to be used during the SNES solve. 1913a61192cSBarry Smith 192e5f7ee39SBarry Smith Level: intermediate 193e5f7ee39SBarry Smith 194db781477SPatrick Sanan .seealso: `KSPMonitorSet()`, `KSPMonitorTrueResidual()` 195e5f7ee39SBarry Smith @*/ 196798534f6SMatthew G. Knepley PetscErrorCode KSPMonitorSNESResidualDrawLG(KSP ksp, PetscInt n, PetscReal rnorm, PetscViewerAndFormat *vf) 197e5f7ee39SBarry Smith { 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)); 235e5f7ee39SBarry Smith PetscFunctionReturn(0); 236e5f7ee39SBarry Smith } 237e5f7ee39SBarry Smith 238798534f6SMatthew G. Knepley /*@C 239798534f6SMatthew G. Knepley KSPMonitorSNESResidualDrawLGCreate - Creates the plotter for the linear SNES residual. 240e5f7ee39SBarry Smith 241798534f6SMatthew G. Knepley Collective on ksp 242e5f7ee39SBarry Smith 243798534f6SMatthew G. Knepley Input Parameters: 244b693eab9SMatthew G. Knepley + 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 253db781477SPatrick Sanan .seealso: `KSPMonitorSet()`, `KSPMonitorTrueResidual()` 254e5f7ee39SBarry Smith @*/ 255798534f6SMatthew G. Knepley PetscErrorCode KSPMonitorSNESResidualDrawLGCreate(PetscViewer viewer, PetscViewerFormat format, void *ctx, PetscViewerAndFormat **vf) 256e5f7ee39SBarry Smith { 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)); 263e5f7ee39SBarry Smith PetscFunctionReturn(0); 264e5f7ee39SBarry Smith } 265e5f7ee39SBarry Smith 266fbcc4530SMatthew G. Knepley PetscErrorCode SNESMonitorDefaultSetUp(SNES snes, PetscViewerAndFormat *vf) 267fbcc4530SMatthew G. Knepley { 268fbcc4530SMatthew G. Knepley PetscFunctionBegin; 269fbcc4530SMatthew G. Knepley if (vf->format == PETSC_VIEWER_DRAW_LG) { 2709566063dSJacob Faibussowitsch PetscCall(KSPMonitorLGCreate(PetscObjectComm((PetscObject) vf->viewer), NULL, NULL, "Log Residual Norm", 1, NULL, PETSC_DECIDE, PETSC_DECIDE, 400, 300, &vf->lg)); 271fbcc4530SMatthew G. Knepley } 272fbcc4530SMatthew G. Knepley PetscFunctionReturn(0); 273fbcc4530SMatthew G. Knepley } 274fbcc4530SMatthew G. Knepley 2754b828684SBarry Smith /*@C 276a6570f20SBarry Smith SNESMonitorDefault - Monitors progress of the SNES solvers (default). 277e7e93795SLois Curfman McInnes 278c7afd0dbSLois Curfman McInnes Collective on SNES 279c7afd0dbSLois Curfman McInnes 280e7e93795SLois Curfman McInnes Input Parameters: 281c7afd0dbSLois Curfman McInnes + snes - the SNES context 282e7e93795SLois Curfman McInnes . its - iteration number 2834b27c08aSLois Curfman McInnes . fgnorm - 2-norm of residual 284d43b4f6eSBarry Smith - vf - viewer and format structure 285fee21e36SBarry Smith 2863a61192cSBarry Smith Options Database: 2873a61192cSBarry Smith . -snes_monitor - use this function to monitor the convergence of the nonlinear solver 2883a61192cSBarry 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 2933a61192cSBarry Smith to be used during the SNES solve. 2943a61192cSBarry Smith 29536851e7fSLois Curfman McInnes Level: intermediate 29636851e7fSLois Curfman McInnes 2973a61192cSBarry Smith .seealso: `SNESMonitorSet()`, `SNESMonitorSolution()`, `SNESMonitorFunction()`, `SNESMonitorSolution()`, `SNESMonitorResidual()`, 2983a61192cSBarry Smith `SNESMonitorSolutionUpdate()`, `SNESMonitorDefault()`, `SNESMonitorScaling()`, `SNESMonitorRange()`, `SNESMonitorRatio()`, 2993a61192cSBarry Smith `SNESMonitorDefaultField()` 300e7e93795SLois Curfman McInnes @*/ 301d43b4f6eSBarry Smith PetscErrorCode SNESMonitorDefault(SNES snes,PetscInt its,PetscReal fgnorm,PetscViewerAndFormat *vf) 302e7e93795SLois Curfman McInnes { 303d43b4f6eSBarry Smith PetscViewer viewer = vf->viewer; 304798534f6SMatthew G. Knepley PetscViewerFormat format = vf->format; 305798534f6SMatthew G. Knepley PetscBool isascii, isdraw; 306d132466eSBarry Smith 3073a40ed3dSBarry Smith PetscFunctionBegin; 3084d4332d5SBarry Smith PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,4); 3099566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject) viewer, PETSCVIEWERASCII, &isascii)); 3109566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject) viewer, PETSCVIEWERDRAW, &isdraw)); 3119566063dSJacob Faibussowitsch PetscCall(PetscViewerPushFormat(viewer,format)); 312798534f6SMatthew G. Knepley if (isascii) { 3139566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIAddTab(viewer,((PetscObject)snes)->tablevel)); 31463a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer,"%3" PetscInt_FMT " SNES Function norm %14.12e \n",its,(double)fgnorm)); 3159566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIISubtractTab(viewer,((PetscObject)snes)->tablevel)); 316798534f6SMatthew G. Knepley } else if (isdraw) { 317798534f6SMatthew G. Knepley if (format == PETSC_VIEWER_DRAW_LG) { 318798534f6SMatthew G. Knepley PetscDrawLG lg = (PetscDrawLG) vf->lg; 319798534f6SMatthew G. Knepley PetscReal x, y; 320798534f6SMatthew G. Knepley 321798534f6SMatthew G. Knepley PetscValidHeaderSpecific(lg,PETSC_DRAWLG_CLASSID,4); 3229566063dSJacob Faibussowitsch if (!its) PetscCall(PetscDrawLGReset(lg)); 323798534f6SMatthew G. Knepley x = (PetscReal) its; 324798534f6SMatthew G. Knepley if (fgnorm > 0.0) y = PetscLog10Real(fgnorm); 325798534f6SMatthew G. Knepley else y = -15.0; 3269566063dSJacob Faibussowitsch PetscCall(PetscDrawLGAddPoint(lg,&x,&y)); 327798534f6SMatthew G. Knepley if (its <= 20 || !(its % 5) || snes->reason) { 3289566063dSJacob Faibussowitsch PetscCall(PetscDrawLGDraw(lg)); 3299566063dSJacob Faibussowitsch PetscCall(PetscDrawLGSave(lg)); 330798534f6SMatthew G. Knepley } 331798534f6SMatthew G. Knepley } 332798534f6SMatthew G. Knepley } 3339566063dSJacob Faibussowitsch PetscCall(PetscViewerPopFormat(viewer)); 3343a40ed3dSBarry Smith PetscFunctionReturn(0); 335e7e93795SLois Curfman McInnes } 3363f1db9ecSBarry Smith 3371f60017eSBarry Smith /*@C 3381f60017eSBarry Smith SNESMonitorScaling - Monitors the largest value in each row of the Jacobian. 3391f60017eSBarry Smith 3401f60017eSBarry Smith Collective on SNES 3411f60017eSBarry Smith 3421f60017eSBarry Smith Input Parameters: 3431f60017eSBarry Smith + snes - the SNES context 3441f60017eSBarry Smith . its - iteration number 3451f60017eSBarry Smith . fgnorm - 2-norm of residual 3461f60017eSBarry Smith - vf - viewer and format structure 3471f60017eSBarry Smith 3481f60017eSBarry Smith Notes: 3491f60017eSBarry Smith This routine prints the largest value in each row of the Jacobian 3501f60017eSBarry Smith 3513a61192cSBarry Smith This is not called directly by users, rather one calls `SNESMonitorSet()`, with this function as an argument, to cause the monitor 3523a61192cSBarry Smith to be used during the SNES solve. 3533a61192cSBarry Smith 3541f60017eSBarry Smith Level: intermediate 3551f60017eSBarry Smith 356db781477SPatrick Sanan .seealso: `SNESMonitorSet()`, `SNESMonitorSolution()` 3571f60017eSBarry Smith @*/ 3581f60017eSBarry Smith PetscErrorCode SNESMonitorScaling(SNES snes,PetscInt its,PetscReal fgnorm,PetscViewerAndFormat *vf) 3591f60017eSBarry Smith { 3601f60017eSBarry Smith PetscViewer viewer = vf->viewer; 3611f60017eSBarry Smith KSP ksp; 3621f60017eSBarry Smith Mat J; 3631f60017eSBarry Smith Vec v; 3641f60017eSBarry Smith 3651f60017eSBarry Smith PetscFunctionBegin; 3661f60017eSBarry Smith PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,4); 3679566063dSJacob Faibussowitsch PetscCall(SNESGetKSP(snes,&ksp)); 3689566063dSJacob Faibussowitsch PetscCall(KSPGetOperators(ksp,&J,NULL)); 3699566063dSJacob Faibussowitsch PetscCall(MatCreateVecs(J,&v,NULL)); 3709566063dSJacob Faibussowitsch PetscCall(MatGetRowMaxAbs(J,v,NULL)); 3719566063dSJacob Faibussowitsch PetscCall(PetscViewerPushFormat(viewer,vf->format)); 3729566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIAddTab(viewer,((PetscObject)snes)->tablevel)); 37363a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer,"SNES Jacobian maximum row entries\n")); 3749566063dSJacob Faibussowitsch PetscCall(VecView(v,viewer)); 3759566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIISubtractTab(viewer,((PetscObject)snes)->tablevel)); 3769566063dSJacob Faibussowitsch PetscCall(PetscViewerPopFormat(viewer)); 3779566063dSJacob Faibussowitsch PetscCall(VecDestroy(&v)); 3781f60017eSBarry Smith PetscFunctionReturn(0); 3791f60017eSBarry Smith } 3801f60017eSBarry Smith 381d43b4f6eSBarry Smith PetscErrorCode SNESMonitorJacUpdateSpectrum(SNES snes,PetscInt it,PetscReal fnorm,PetscViewerAndFormat *vf) 382a80ad3e0SBarry Smith { 3832e7541e6SPeter Brune Vec X; 3842e7541e6SPeter Brune Mat J,dJ,dJdense; 385d1e9a80fSBarry Smith PetscErrorCode (*func)(SNES,Vec,Mat,Mat,void*); 3862f96bde4SJose E. Roman PetscInt n; 38723fff9afSBarry Smith PetscBLASInt nb = 0,lwork; 3882e7541e6SPeter Brune PetscReal *eigr,*eigi; 3892e7541e6SPeter Brune PetscScalar *work; 3902e7541e6SPeter Brune PetscScalar *a; 3912e7541e6SPeter Brune 3922e7541e6SPeter Brune PetscFunctionBegin; 3932e7541e6SPeter Brune if (it == 0) PetscFunctionReturn(0); 3942e7541e6SPeter Brune /* create the difference between the current update and the current jacobian */ 3959566063dSJacob Faibussowitsch PetscCall(SNESGetSolution(snes,&X)); 3969566063dSJacob Faibussowitsch PetscCall(SNESGetJacobian(snes,NULL,&J,&func,NULL)); 3979566063dSJacob Faibussowitsch PetscCall(MatDuplicate(J,MAT_COPY_VALUES,&dJ)); 3989566063dSJacob Faibussowitsch PetscCall(SNESComputeJacobian(snes,X,dJ,dJ)); 3999566063dSJacob Faibussowitsch PetscCall(MatAXPY(dJ,-1.0,J,SAME_NONZERO_PATTERN)); 400f5af7f23SKarl Rupp 4012e7541e6SPeter Brune /* compute the spectrum directly */ 4029566063dSJacob Faibussowitsch PetscCall(MatConvert(dJ,MATSEQDENSE,MAT_INITIAL_MATRIX,&dJdense)); 4039566063dSJacob Faibussowitsch PetscCall(MatGetSize(dJ,&n,NULL)); 4049566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(n,&nb)); 4052e7541e6SPeter Brune lwork = 3*nb; 4069566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(n,&eigr)); 4079566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(n,&eigi)); 4089566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(lwork,&work)); 4099566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(dJdense,&a)); 4102e7541e6SPeter Brune #if !defined(PETSC_USE_COMPLEX) 4112e7541e6SPeter Brune { 4122e7541e6SPeter Brune PetscBLASInt lierr; 4132f96bde4SJose E. Roman PetscInt i; 4149566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF)); 415*792fecdfSBarry Smith PetscCallBLAS("LAPACKgeev",LAPACKgeev_("N","N",&nb,a,&nb,eigr,eigi,NULL,&nb,NULL,&nb,work,&lwork,&lierr)); 41663a3b9bcSJacob Faibussowitsch PetscCheck(!lierr,PETSC_COMM_SELF,PETSC_ERR_LIB,"geev() error %" PetscBLASInt_FMT,lierr); 4179566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPop()); 41863a3b9bcSJacob Faibussowitsch PetscCall(PetscPrintf(PetscObjectComm((PetscObject)snes),"Eigenvalues of J_%" PetscInt_FMT " - J_%" PetscInt_FMT ":\n",it,it-1)); 4192e7541e6SPeter Brune for (i=0;i<n;i++) { 42063a3b9bcSJacob Faibussowitsch PetscCall(PetscPrintf(PetscObjectComm((PetscObject)snes),"%5" PetscInt_FMT ": %20.5g + %20.5gi\n",i,(double)eigr[i],(double)eigi[i])); 4212e7541e6SPeter Brune } 4222f96bde4SJose E. Roman } 4239566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArray(dJdense,&a)); 4249566063dSJacob Faibussowitsch PetscCall(MatDestroy(&dJ)); 4259566063dSJacob Faibussowitsch PetscCall(MatDestroy(&dJdense)); 4269566063dSJacob Faibussowitsch PetscCall(PetscFree(eigr)); 4279566063dSJacob Faibussowitsch PetscCall(PetscFree(eigi)); 4289566063dSJacob Faibussowitsch PetscCall(PetscFree(work)); 4292e7541e6SPeter Brune PetscFunctionReturn(0); 4302f96bde4SJose E. Roman #else 4312f96bde4SJose E. Roman SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not coded for complex"); 4322f96bde4SJose E. Roman #endif 4332e7541e6SPeter Brune } 4342e7541e6SPeter Brune 4356ba87a44SLisandro Dalcin PETSC_INTERN PetscErrorCode SNESMonitorRange_Private(SNES,PetscInt,PetscReal*); 4366ba87a44SLisandro Dalcin 4377087cfbeSBarry Smith PetscErrorCode SNESMonitorRange_Private(SNES snes,PetscInt it,PetscReal *per) 438b271bb04SBarry Smith { 439b271bb04SBarry Smith Vec resid; 440b271bb04SBarry Smith PetscReal rmax,pwork; 441b271bb04SBarry Smith PetscInt i,n,N; 442b271bb04SBarry Smith PetscScalar *r; 443b271bb04SBarry Smith 444b271bb04SBarry Smith PetscFunctionBegin; 4459566063dSJacob Faibussowitsch PetscCall(SNESGetFunction(snes,&resid,NULL,NULL)); 4469566063dSJacob Faibussowitsch PetscCall(VecNorm(resid,NORM_INFINITY,&rmax)); 4479566063dSJacob Faibussowitsch PetscCall(VecGetLocalSize(resid,&n)); 4489566063dSJacob Faibussowitsch PetscCall(VecGetSize(resid,&N)); 4499566063dSJacob Faibussowitsch PetscCall(VecGetArray(resid,&r)); 450b271bb04SBarry Smith pwork = 0.0; 451b271bb04SBarry Smith for (i=0; i<n; i++) { 452b271bb04SBarry Smith pwork += (PetscAbsScalar(r[i]) > .20*rmax); 453b271bb04SBarry Smith } 4541c2dc1cbSBarry Smith PetscCall(MPIU_Allreduce(&pwork,per,1,MPIU_REAL,MPIU_SUM,PetscObjectComm((PetscObject)snes))); 4559566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(resid,&r)); 456b271bb04SBarry Smith *per = *per/N; 457b271bb04SBarry Smith PetscFunctionReturn(0); 458b271bb04SBarry Smith } 459b271bb04SBarry Smith 460b271bb04SBarry Smith /*@C 461b271bb04SBarry Smith SNESMonitorRange - Prints the percentage of residual elements that are more then 10 percent of the maximum value. 462b271bb04SBarry Smith 463b271bb04SBarry Smith Collective on SNES 464b271bb04SBarry Smith 465b271bb04SBarry Smith Input Parameters: 466b271bb04SBarry Smith + snes - iterative context 467b271bb04SBarry Smith . it - iteration number 468b271bb04SBarry Smith . rnorm - 2-norm (preconditioned) residual value (may be estimated). 469b271bb04SBarry Smith - dummy - unused monitor context 470b271bb04SBarry Smith 471b271bb04SBarry Smith Options Database Key: 472b271bb04SBarry Smith . -snes_monitor_range - Activates SNESMonitorRange() 473b271bb04SBarry Smith 4743a61192cSBarry Smith Notes: 4753a61192cSBarry Smith This is not called directly by users, rather one calls `SNESMonitorSet()`, with this function as an argument, to cause the monitor 4763a61192cSBarry Smith to be used during the SNES solve. 4773a61192cSBarry Smith 478b271bb04SBarry Smith Level: intermediate 479b271bb04SBarry Smith 480db781477SPatrick Sanan .seealso: `SNESMonitorSet()`, `SNESMonitorDefault()`, `SNESMonitorLGCreate()` 481b271bb04SBarry Smith @*/ 482d43b4f6eSBarry Smith PetscErrorCode SNESMonitorRange(SNES snes,PetscInt it,PetscReal rnorm,PetscViewerAndFormat *vf) 483b271bb04SBarry Smith { 484b271bb04SBarry Smith PetscReal perc,rel; 485d43b4f6eSBarry Smith PetscViewer viewer = vf->viewer; 486b271bb04SBarry Smith /* should be in a MonitorRangeContext */ 487b271bb04SBarry Smith static PetscReal prev; 488b271bb04SBarry Smith 489b271bb04SBarry Smith PetscFunctionBegin; 4904d4332d5SBarry Smith PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,4); 491b271bb04SBarry Smith if (!it) prev = rnorm; 4929566063dSJacob Faibussowitsch PetscCall(SNESMonitorRange_Private(snes,it,&perc)); 493b271bb04SBarry Smith 494b271bb04SBarry Smith rel = (prev - rnorm)/prev; 495b271bb04SBarry Smith prev = rnorm; 4969566063dSJacob Faibussowitsch PetscCall(PetscViewerPushFormat(viewer,vf->format)); 4979566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIAddTab(viewer,((PetscObject)snes)->tablevel)); 49863a3b9bcSJacob 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))); 4999566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIISubtractTab(viewer,((PetscObject)snes)->tablevel)); 5009566063dSJacob Faibussowitsch PetscCall(PetscViewerPopFormat(viewer)); 501b271bb04SBarry Smith PetscFunctionReturn(0); 502b271bb04SBarry Smith } 503b271bb04SBarry Smith 5043a7fca6bSBarry Smith /*@C 505a6570f20SBarry Smith SNESMonitorRatio - Monitors progress of the SNES solvers by printing the ratio 5064b27c08aSLois Curfman McInnes of residual norm at each iteration to the previous. 5073a7fca6bSBarry Smith 5083a7fca6bSBarry Smith Collective on SNES 5093a7fca6bSBarry Smith 5103a7fca6bSBarry Smith Input Parameters: 5113a7fca6bSBarry Smith + snes - the SNES context 5123a7fca6bSBarry Smith . its - iteration number 5133a7fca6bSBarry Smith . fgnorm - 2-norm of residual (or gradient) 514eabae89aSBarry Smith - dummy - context of monitor 5153a7fca6bSBarry Smith 5163a7fca6bSBarry Smith Level: intermediate 5173a7fca6bSBarry Smith 51895452b02SPatrick Sanan Notes: 5193a61192cSBarry Smith This is not called directly by users, rather one calls `SNESMonitorSet()`, with this function as an argument, to cause the monitor 5203a61192cSBarry Smith to be used during the SNES solve. 5213a61192cSBarry Smith 5223a61192cSBarry Smith Be sure to call SNESMonitorRationSetUp() before using this monitor. 5233a61192cSBarry Smith 5243a61192cSBarry Smith .seealso: `SNESMonitorSet()`, `SNESMonitorSolution()`, `SNESMonitorDefault()` 5253a7fca6bSBarry Smith @*/ 526d43b4f6eSBarry Smith PetscErrorCode SNESMonitorRatio(SNES snes,PetscInt its,PetscReal fgnorm,PetscViewerAndFormat *vf) 5273a7fca6bSBarry Smith { 52877431f27SBarry Smith PetscInt len; 52987828ca2SBarry Smith PetscReal *history; 530d43b4f6eSBarry Smith PetscViewer viewer = vf->viewer; 5313a7fca6bSBarry Smith 5323a7fca6bSBarry Smith PetscFunctionBegin; 5339566063dSJacob Faibussowitsch PetscCall(SNESGetConvergenceHistory(snes,&history,NULL,&len)); 5349566063dSJacob Faibussowitsch PetscCall(PetscViewerPushFormat(viewer,vf->format)); 5359566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIAddTab(viewer,((PetscObject)snes)->tablevel)); 536958c9bccSBarry Smith if (!its || !history || its > len) { 53763a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer,"%3" PetscInt_FMT " SNES Function norm %14.12e \n",its,(double)fgnorm)); 5383a7fca6bSBarry Smith } else { 53987828ca2SBarry Smith PetscReal ratio = fgnorm/history[its-1]; 54063a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer,"%3" PetscInt_FMT " SNES Function norm %14.12e %14.12e \n",its,(double)fgnorm,(double)ratio)); 5413a7fca6bSBarry Smith } 5429566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIISubtractTab(viewer,((PetscObject)snes)->tablevel)); 5439566063dSJacob Faibussowitsch PetscCall(PetscViewerPopFormat(viewer)); 5443a7fca6bSBarry Smith PetscFunctionReturn(0); 5453a7fca6bSBarry Smith } 5463a7fca6bSBarry Smith 5473a7fca6bSBarry Smith /*@C 548fde5950dSBarry Smith SNESMonitorRatioSetUp - Insures the SNES object is saving its history since this monitor needs access to it 5493a7fca6bSBarry Smith 5503a7fca6bSBarry Smith Collective on SNES 5513a7fca6bSBarry Smith 5523a7fca6bSBarry Smith Input Parameters: 553eabae89aSBarry Smith + snes - the SNES context 554fde5950dSBarry Smith - viewer - the PetscViewer object (ignored) 5553a7fca6bSBarry Smith 5563a7fca6bSBarry Smith Level: intermediate 5573a7fca6bSBarry Smith 558db781477SPatrick Sanan .seealso: `SNESMonitorSet()`, `SNESMonitorSolution()`, `SNESMonitorDefault()`, `SNESMonitorRatio()` 5593a7fca6bSBarry Smith @*/ 560d43b4f6eSBarry Smith PetscErrorCode SNESMonitorRatioSetUp(SNES snes,PetscViewerAndFormat *vf) 5613a7fca6bSBarry Smith { 56287828ca2SBarry Smith PetscReal *history; 5633a7fca6bSBarry Smith 5643a7fca6bSBarry Smith PetscFunctionBegin; 5659566063dSJacob Faibussowitsch PetscCall(SNESGetConvergenceHistory(snes,&history,NULL,NULL)); 5663a7fca6bSBarry Smith if (!history) { 5679566063dSJacob Faibussowitsch PetscCall(SNESSetConvergenceHistory(snes,NULL,NULL,100,PETSC_TRUE)); 5683a7fca6bSBarry Smith } 5693a7fca6bSBarry Smith PetscFunctionReturn(0); 5703a7fca6bSBarry Smith } 5713a7fca6bSBarry Smith 572e7e93795SLois Curfman McInnes /* ---------------------------------------------------------------- */ 573be1f7002SBarry Smith /* 574a6570f20SBarry Smith Default (short) SNES Monitor, same as SNESMonitorDefault() except 575be1f7002SBarry Smith it prints fewer digits of the residual as the residual gets smaller. 576be1f7002SBarry Smith This is because the later digits are meaningless and are often 577be1f7002SBarry Smith different on different machines; by using this routine different 578be1f7002SBarry Smith machines will usually generate the same output. 579dec21524SBarry Smith 580dec21524SBarry Smith Deprecated: Intentionally has no manual page 581be1f7002SBarry Smith */ 582d43b4f6eSBarry Smith PetscErrorCode SNESMonitorDefaultShort(SNES snes,PetscInt its,PetscReal fgnorm,PetscViewerAndFormat *vf) 583e7e93795SLois Curfman McInnes { 584d43b4f6eSBarry Smith PetscViewer viewer = vf->viewer; 585d132466eSBarry Smith 5863a40ed3dSBarry Smith PetscFunctionBegin; 5874d4332d5SBarry Smith PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,4); 5889566063dSJacob Faibussowitsch PetscCall(PetscViewerPushFormat(viewer,vf->format)); 5899566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIAddTab(viewer,((PetscObject)snes)->tablevel)); 5908f240d10SBarry Smith if (fgnorm > 1.e-9) { 59163a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer,"%3" PetscInt_FMT " SNES Function norm %g \n",its,(double)fgnorm)); 5923a40ed3dSBarry Smith } else if (fgnorm > 1.e-11) { 59363a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer,"%3" PetscInt_FMT " SNES Function norm %5.3e \n",its,(double)fgnorm)); 5943a40ed3dSBarry Smith } else { 59563a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer,"%3" PetscInt_FMT " SNES Function norm < 1.e-11\n",its)); 596a34d58ebSBarry Smith } 5979566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIISubtractTab(viewer,((PetscObject)snes)->tablevel)); 5989566063dSJacob Faibussowitsch PetscCall(PetscViewerPopFormat(viewer)); 5993a40ed3dSBarry Smith PetscFunctionReturn(0); 600e7e93795SLois Curfman McInnes } 6012db13446SMatthew G. Knepley 6022db13446SMatthew G. Knepley /*@C 6032db13446SMatthew G. Knepley SNESMonitorDefaultField - Monitors progress of the SNES solvers, separated into fields. 6042db13446SMatthew G. Knepley 6052db13446SMatthew G. Knepley Collective on SNES 6062db13446SMatthew G. Knepley 6072db13446SMatthew G. Knepley Input Parameters: 6082db13446SMatthew G. Knepley + snes - the SNES context 6092db13446SMatthew G. Knepley . its - iteration number 6102db13446SMatthew G. Knepley . fgnorm - 2-norm of residual 6112db13446SMatthew G. Knepley - ctx - the PetscViewer 6122db13446SMatthew G. Knepley 6132db13446SMatthew G. Knepley Notes: 6143a61192cSBarry Smith This routine uses the DM attached to the residual vector to define the fields. 6153a61192cSBarry Smith 6163a61192cSBarry Smith This is not called directly by users, rather one calls `SNESMonitorSet()`, with this function as an argument, to cause the monitor 6173a61192cSBarry Smith to be used during the SNES solve. 6182db13446SMatthew G. Knepley 6192db13446SMatthew G. Knepley Level: intermediate 6202db13446SMatthew G. Knepley 621db781477SPatrick Sanan .seealso: `SNESMonitorSet()`, `SNESMonitorSolution()`, `SNESMonitorDefault()` 6222db13446SMatthew G. Knepley @*/ 623d43b4f6eSBarry Smith PetscErrorCode SNESMonitorDefaultField(SNES snes, PetscInt its, PetscReal fgnorm, PetscViewerAndFormat *vf) 6242db13446SMatthew G. Knepley { 625d43b4f6eSBarry Smith PetscViewer viewer = vf->viewer; 6262db13446SMatthew G. Knepley Vec r; 6272db13446SMatthew G. Knepley DM dm; 6282db13446SMatthew G. Knepley PetscReal res[256]; 6292db13446SMatthew G. Knepley PetscInt tablevel; 6302db13446SMatthew G. Knepley 6312db13446SMatthew G. Knepley PetscFunctionBegin; 6324d4332d5SBarry Smith PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,4); 6339566063dSJacob Faibussowitsch PetscCall(SNESGetFunction(snes, &r, NULL, NULL)); 6349566063dSJacob Faibussowitsch PetscCall(VecGetDM(r, &dm)); 6359566063dSJacob Faibussowitsch if (!dm) PetscCall(SNESMonitorDefault(snes, its, fgnorm, vf)); 6362db13446SMatthew G. Knepley else { 6372db13446SMatthew G. Knepley PetscSection s, gs; 6382db13446SMatthew G. Knepley PetscInt Nf, f; 6392db13446SMatthew G. Knepley 6409566063dSJacob Faibussowitsch PetscCall(DMGetLocalSection(dm, &s)); 6419566063dSJacob Faibussowitsch PetscCall(DMGetGlobalSection(dm, &gs)); 6429566063dSJacob Faibussowitsch if (!s || !gs) PetscCall(SNESMonitorDefault(snes, its, fgnorm, vf)); 6439566063dSJacob Faibussowitsch PetscCall(PetscSectionGetNumFields(s, &Nf)); 64463a3b9bcSJacob Faibussowitsch PetscCheck(Nf <= 256,PetscObjectComm((PetscObject) snes), PETSC_ERR_SUP, "Do not support %" PetscInt_FMT " fields > 256", Nf); 6459566063dSJacob Faibussowitsch PetscCall(PetscSectionVecNorm(s, gs, r, NORM_2, res)); 6469566063dSJacob Faibussowitsch PetscCall(PetscObjectGetTabLevel((PetscObject) snes, &tablevel)); 6479566063dSJacob Faibussowitsch PetscCall(PetscViewerPushFormat(viewer,vf->format)); 6489566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIAddTab(viewer, tablevel)); 64963a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "%3" PetscInt_FMT " SNES Function norm %14.12e [", its, (double) fgnorm)); 6502db13446SMatthew G. Knepley for (f = 0; f < Nf; ++f) { 6519566063dSJacob Faibussowitsch if (f) PetscCall(PetscViewerASCIIPrintf(viewer, ", ")); 65263a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "%14.12e", (double)res[f])); 6532db13446SMatthew G. Knepley } 6549566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "] \n")); 6559566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIISubtractTab(viewer, tablevel)); 6569566063dSJacob Faibussowitsch PetscCall(PetscViewerPopFormat(viewer)); 6572db13446SMatthew G. Knepley } 6582db13446SMatthew G. Knepley PetscFunctionReturn(0); 6592db13446SMatthew G. Knepley } 660e7e93795SLois Curfman McInnes /* ---------------------------------------------------------------- */ 6614b828684SBarry Smith /*@C 662c34cbdceSBarry Smith SNESConvergedDefault - Default onvergence test of the solvers for 663c34cbdceSBarry Smith systems of nonlinear equations. 664e7e93795SLois Curfman McInnes 665c7afd0dbSLois Curfman McInnes Collective on SNES 666c7afd0dbSLois Curfman McInnes 667e7e93795SLois Curfman McInnes Input Parameters: 668c7afd0dbSLois Curfman McInnes + snes - the SNES context 66906ee9f85SBarry Smith . it - the iteration (0 indicates before any Newton steps) 670e7e93795SLois Curfman McInnes . xnorm - 2-norm of current iterate 671c60f73f4SPeter Brune . snorm - 2-norm of current step 6727f3332b4SBarry Smith . fnorm - 2-norm of function at current iterate 673c7afd0dbSLois Curfman McInnes - dummy - unused context 674e7e93795SLois Curfman McInnes 675184914b5SBarry Smith Output Parameter: 676184914b5SBarry Smith . reason - one of 67770441072SBarry Smith $ SNES_CONVERGED_FNORM_ABS - (fnorm < abstol), 678c60f73f4SPeter Brune $ SNES_CONVERGED_SNORM_RELATIVE - (snorm < stol*xnorm), 679184914b5SBarry Smith $ SNES_CONVERGED_FNORM_RELATIVE - (fnorm < rtol*fnorm0), 680184914b5SBarry Smith $ SNES_DIVERGED_FUNCTION_COUNT - (nfct > maxf), 681184914b5SBarry Smith $ SNES_DIVERGED_FNORM_NAN - (fnorm == NaN), 682184914b5SBarry Smith $ SNES_CONVERGED_ITERATING - (otherwise), 683c34cbdceSBarry Smith $ SNES_DIVERGED_DTOL - (fnorm > divtol*snes->fnorm0) 684e7e93795SLois Curfman McInnes 685e7e93795SLois Curfman McInnes where 686c34cbdceSBarry Smith + maxf - maximum number of function evaluations, set with SNESSetTolerances() 687c7afd0dbSLois Curfman McInnes . nfct - number of function evaluations, 688c34cbdceSBarry Smith . abstol - absolute function norm tolerance, set with SNESSetTolerances() 689c34cbdceSBarry Smith . rtol - relative function norm tolerance, set with SNESSetTolerances() 690c34cbdceSBarry Smith . divtol - divergence tolerance, set with SNESSetDivergenceTolerance() 691c34cbdceSBarry Smith - fnorm0 - 2-norm of the function at the initial solution (initial guess; zeroth iteration) 692c34cbdceSBarry Smith 693c34cbdceSBarry Smith Options Database Keys: 694f362779dSJed Brown + -snes_convergence_test default - see SNESSetFromOptions() 695f362779dSJed Brown . -snes_stol - convergence tolerance in terms of the norm of the change in the solution between steps 696c34cbdceSBarry Smith . -snes_atol <abstol> - absolute tolerance of residual norm 697c34cbdceSBarry Smith . -snes_rtol <rtol> - relative decrease in tolerance norm from the initial 2-norm of the solution 698c34cbdceSBarry Smith . -snes_divergence_tolerance <divtol> - if the residual goes above divtol*rnorm0, exit with divergence 699c34cbdceSBarry Smith . -snes_max_funcs <max_funcs> - maximum number of function evaluations 700c34cbdceSBarry Smith . -snes_max_fail <max_fail> - maximum number of line search failures allowed before stopping, default is none 701c34cbdceSBarry Smith - -snes_max_linear_solve_fail - number of linear solver failures before SNESSolve() stops 702fee21e36SBarry Smith 70336851e7fSLois Curfman McInnes Level: intermediate 70436851e7fSLois Curfman McInnes 705db781477SPatrick Sanan .seealso: `SNESSetConvergenceTest()`, `SNESConvergedSkip()`, `SNESSetTolerances()`, `SNESSetDivergenceTolerance()` 706e7e93795SLois Curfman McInnes @*/ 7078d359177SBarry Smith PetscErrorCode SNESConvergedDefault(SNES snes,PetscInt it,PetscReal xnorm,PetscReal snorm,PetscReal fnorm,SNESConvergedReason *reason,void *dummy) 708e7e93795SLois Curfman McInnes { 7093a40ed3dSBarry Smith PetscFunctionBegin; 7100700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 7113f149594SLisandro Dalcin PetscValidPointer(reason,6); 7123f149594SLisandro Dalcin 71306ee9f85SBarry Smith *reason = SNES_CONVERGED_ITERATING; 71406ee9f85SBarry Smith 71506ee9f85SBarry Smith if (!it) { 71606ee9f85SBarry Smith /* set parameter for default relative tolerance convergence test */ 71706ee9f85SBarry Smith snes->ttol = fnorm*snes->rtol; 718e37c518bSBarry Smith snes->rnorm0 = fnorm; 71906ee9f85SBarry Smith } 7208146f6ebSBarry Smith if (PetscIsInfOrNanReal(fnorm)) { 7219566063dSJacob Faibussowitsch PetscCall(PetscInfo(snes,"Failed to converged, function norm is NaN\n")); 722184914b5SBarry Smith *reason = SNES_DIVERGED_FNORM_NAN; 723be5caee7SBarry Smith } else if (fnorm < snes->abstol && (it || !snes->forceiteration)) { 7249566063dSJacob Faibussowitsch PetscCall(PetscInfo(snes,"Converged due to function norm %14.12e < %14.12e\n",(double)fnorm,(double)snes->abstol)); 725184914b5SBarry Smith *reason = SNES_CONVERGED_FNORM_ABS; 726e71169deSBarry Smith } else if (snes->nfuncs >= snes->max_funcs && snes->max_funcs >= 0) { 72763a3b9bcSJacob Faibussowitsch PetscCall(PetscInfo(snes,"Exceeded maximum number of function evaluations: %" PetscInt_FMT " > %" PetscInt_FMT "\n",snes->nfuncs,snes->max_funcs)); 728184914b5SBarry Smith *reason = SNES_DIVERGED_FUNCTION_COUNT; 72906ee9f85SBarry Smith } 73006ee9f85SBarry Smith 73106ee9f85SBarry Smith if (it && !*reason) { 73206ee9f85SBarry Smith if (fnorm <= snes->ttol) { 7339566063dSJacob Faibussowitsch PetscCall(PetscInfo(snes,"Converged due to function norm %14.12e < %14.12e (relative tolerance)\n",(double)fnorm,(double)snes->ttol)); 73406ee9f85SBarry Smith *reason = SNES_CONVERGED_FNORM_RELATIVE; 735c60f73f4SPeter Brune } else if (snorm < snes->stol*xnorm) { 7369566063dSJacob Faibussowitsch PetscCall(PetscInfo(snes,"Converged due to small update length: %14.12e < %14.12e * %14.12e\n",(double)snorm,(double)snes->stol,(double)xnorm)); 737c60f73f4SPeter Brune *reason = SNES_CONVERGED_SNORM_RELATIVE; 738e4d06f11SPatrick Farrell } else if (snes->divtol > 0 && (fnorm > snes->divtol*snes->rnorm0)) { 7399566063dSJacob 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)); 740e37c518bSBarry Smith *reason = SNES_DIVERGED_DTOL; 74106ee9f85SBarry Smith } 742e37c518bSBarry Smith 743e7e93795SLois Curfman McInnes } 7443a40ed3dSBarry Smith PetscFunctionReturn(0); 745e7e93795SLois Curfman McInnes } 7463f149594SLisandro Dalcin 7473f149594SLisandro Dalcin /*@C 748e2a6519dSDmitry Karpeev SNESConvergedSkip - Convergence test for SNES that NEVER returns as 7493f149594SLisandro Dalcin converged, UNLESS the maximum number of iteration have been reached. 7503f149594SLisandro Dalcin 7513f9fe445SBarry Smith Logically Collective on SNES 7523f149594SLisandro Dalcin 7533f149594SLisandro Dalcin Input Parameters: 7543f149594SLisandro Dalcin + snes - the SNES context 7553f149594SLisandro Dalcin . it - the iteration (0 indicates before any Newton steps) 7563f149594SLisandro Dalcin . xnorm - 2-norm of current iterate 757c60f73f4SPeter Brune . snorm - 2-norm of current step 7583f149594SLisandro Dalcin . fnorm - 2-norm of function at current iterate 7593f149594SLisandro Dalcin - dummy - unused context 7603f149594SLisandro Dalcin 7613f149594SLisandro Dalcin Output Parameter: 76285385478SLisandro Dalcin . reason - SNES_CONVERGED_ITERATING, SNES_CONVERGED_ITS, or SNES_DIVERGED_FNORM_NAN 7633f149594SLisandro Dalcin 7643f149594SLisandro Dalcin Notes: 7653f149594SLisandro Dalcin Convergence is then declared after a fixed number of iterations have been used. 7663f149594SLisandro Dalcin 767f362779dSJed Brown Options Database Keys: 768f362779dSJed Brown . -snes_convergence_test default - see SNESSetFromOptions() 769f362779dSJed Brown 7703f149594SLisandro Dalcin Level: advanced 7713f149594SLisandro Dalcin 772db781477SPatrick Sanan .seealso: `SNESConvergedDefault()`, `SNESSetConvergenceTest()` 7733f149594SLisandro Dalcin @*/ 774e2a6519dSDmitry Karpeev PetscErrorCode SNESConvergedSkip(SNES snes,PetscInt it,PetscReal xnorm,PetscReal snorm,PetscReal fnorm,SNESConvergedReason *reason,void *dummy) 7753f149594SLisandro Dalcin { 7763f149594SLisandro Dalcin PetscFunctionBegin; 7770700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 7783f149594SLisandro Dalcin PetscValidPointer(reason,6); 7793f149594SLisandro Dalcin 7803f149594SLisandro Dalcin *reason = SNES_CONVERGED_ITERATING; 7813f149594SLisandro Dalcin 7823f149594SLisandro Dalcin if (fnorm != fnorm) { 7839566063dSJacob Faibussowitsch PetscCall(PetscInfo(snes,"Failed to converged, function norm is NaN\n")); 7843f149594SLisandro Dalcin *reason = SNES_DIVERGED_FNORM_NAN; 7853f149594SLisandro Dalcin } else if (it == snes->max_its) { 7863f149594SLisandro Dalcin *reason = SNES_CONVERGED_ITS; 7873f149594SLisandro Dalcin } 7883f149594SLisandro Dalcin PetscFunctionReturn(0); 7893f149594SLisandro Dalcin } 7903f149594SLisandro Dalcin 7918d359177SBarry Smith /*@C 792fa0ddf94SBarry Smith SNESSetWorkVecs - Gets a number of work vectors. 79358c9b817SLisandro Dalcin 79458c9b817SLisandro Dalcin Input Parameters: 795a2b725a8SWilliam Gropp + snes - the SNES context 796a2b725a8SWilliam Gropp - nw - number of work vectors to allocate 79758c9b817SLisandro Dalcin 79858c9b817SLisandro Dalcin Level: developer 799fa0ddf94SBarry Smith 80098acb6afSMatthew G Knepley @*/ 801fa0ddf94SBarry Smith PetscErrorCode SNESSetWorkVecs(SNES snes,PetscInt nw) 80258c9b817SLisandro Dalcin { 803c5ed8070SMatthew G. Knepley DM dm; 804c5ed8070SMatthew G. Knepley Vec v; 80558c9b817SLisandro Dalcin 80658c9b817SLisandro Dalcin PetscFunctionBegin; 8079566063dSJacob Faibussowitsch if (snes->work) PetscCall(VecDestroyVecs(snes->nwork,&snes->work)); 80858c9b817SLisandro Dalcin snes->nwork = nw; 809f5af7f23SKarl Rupp 8109566063dSJacob Faibussowitsch PetscCall(SNESGetDM(snes, &dm)); 8119566063dSJacob Faibussowitsch PetscCall(DMGetGlobalVector(dm, &v)); 8129566063dSJacob Faibussowitsch PetscCall(VecDuplicateVecs(v,snes->nwork,&snes->work)); 8139566063dSJacob Faibussowitsch PetscCall(DMRestoreGlobalVector(dm, &v)); 8149566063dSJacob Faibussowitsch PetscCall(PetscLogObjectParents(snes,nw,snes->work)); 81558c9b817SLisandro Dalcin PetscFunctionReturn(0); 81658c9b817SLisandro Dalcin } 817