xref: /petsc/src/snes/interface/snesut.c (revision e4094ef18e7e53fda86cf35f3a47fda48a8e77d8)
1e7e93795SLois Curfman McInnes 
2af0996ceSBarry Smith #include <petsc/private/snesimpl.h> /*I   "petsc/private/snesimpl.h"   I*/
3636fd056SMatthew G. Knepley #include <petscdm.h>
4ea844a1aSMatthew Knepley #include <petscsection.h>
52e7541e6SPeter Brune #include <petscblaslapack.h>
6e7e93795SLois Curfman McInnes 
73f1db9ecSBarry Smith /*@C
8f6dfbefdSBarry Smith   SNESMonitorSolution - Monitors progress of the `SNES` solvers by calling
9f6dfbefdSBarry Smith   `VecView()` for the approximate solution at each iteration.
103f1db9ecSBarry Smith 
11c3339decSBarry Smith   Collective
123f1db9ecSBarry Smith 
133f1db9ecSBarry Smith   Input Parameters:
14f6dfbefdSBarry Smith + snes   - the `SNES` context
153f1db9ecSBarry Smith . its    - iteration number
164b27c08aSLois Curfman McInnes . fgnorm - 2-norm of residual
17*e4094ef1SJacob Faibussowitsch - vf     - a viewer
183f1db9ecSBarry Smith 
19f6dfbefdSBarry Smith   Options Database Key:
20ee32d87aSMatthew G. Knepley . -snes_monitor_solution [ascii binary draw][:filename][:viewer format] - plots solution at each iteration
21ee32d87aSMatthew G. Knepley 
22dc4c0fb0SBarry Smith   Level: intermediate
23dc4c0fb0SBarry Smith 
24f6dfbefdSBarry Smith   Note:
253a61192cSBarry Smith   This is not called directly by users, rather one calls `SNESMonitorSet()`, with this function as an argument, to cause the monitor
26f6dfbefdSBarry Smith   to be used during the `SNESSolve()`
273a61192cSBarry Smith 
281cc06b55SBarry Smith .seealso: [](ch_snes), `SNES`, `SNESMonitorSet()`, `SNESMonitorDefault()`, `VecView()`
293f1db9ecSBarry Smith @*/
30d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESMonitorSolution(SNES snes, PetscInt its, PetscReal fgnorm, PetscViewerAndFormat *vf)
31d71ae5a4SJacob Faibussowitsch {
323f1db9ecSBarry Smith   Vec         x;
33d43b4f6eSBarry Smith   PetscViewer viewer = vf->viewer;
343f1db9ecSBarry Smith 
353f1db9ecSBarry Smith   PetscFunctionBegin;
364d4332d5SBarry Smith   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 4);
379566063dSJacob Faibussowitsch   PetscCall(SNESGetSolution(snes, &x));
389566063dSJacob Faibussowitsch   PetscCall(PetscViewerPushFormat(viewer, vf->format));
399566063dSJacob Faibussowitsch   PetscCall(VecView(x, viewer));
409566063dSJacob Faibussowitsch   PetscCall(PetscViewerPopFormat(viewer));
413ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
423f1db9ecSBarry Smith }
433f1db9ecSBarry Smith 
445ed2d596SBarry Smith /*@C
45f6dfbefdSBarry Smith   SNESMonitorResidual - Monitors progress of the `SNES` solvers by calling
46f6dfbefdSBarry Smith   `VecView()` for the residual at each iteration.
475ed2d596SBarry Smith 
48c3339decSBarry Smith   Collective
495ed2d596SBarry Smith 
505ed2d596SBarry Smith   Input Parameters:
51f6dfbefdSBarry Smith + snes   - the `SNES` context
525ed2d596SBarry Smith . its    - iteration number
534b27c08aSLois Curfman McInnes . fgnorm - 2-norm of residual
54*e4094ef1SJacob Faibussowitsch - vf     - a viewer
555ed2d596SBarry Smith 
56f6dfbefdSBarry Smith   Options Database Key:
57ee32d87aSMatthew G. Knepley . -snes_monitor_residual [ascii binary draw][:filename][:viewer format] - plots residual (not its norm) at each iteration
58ee32d87aSMatthew G. Knepley 
595ed2d596SBarry Smith   Level: intermediate
605ed2d596SBarry Smith 
61dc4c0fb0SBarry Smith   Note:
62dc4c0fb0SBarry Smith   This is not called directly by users, rather one calls `SNESMonitorSet()`, with this function as an argument, to cause the monitor
63dc4c0fb0SBarry Smith   to be used during the `SNES` solve.
64dc4c0fb0SBarry Smith 
651cc06b55SBarry Smith .seealso: [](ch_snes), `SNES`, `SNESMonitorSet()`, `SNESMonitorDefault()`, `VecView()`, `SNESMonitor()`
665ed2d596SBarry Smith @*/
67d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESMonitorResidual(SNES snes, PetscInt its, PetscReal fgnorm, PetscViewerAndFormat *vf)
68d71ae5a4SJacob Faibussowitsch {
695ed2d596SBarry Smith   Vec x;
705ed2d596SBarry Smith 
715ed2d596SBarry Smith   PetscFunctionBegin;
72f6dfbefdSBarry Smith   PetscValidHeaderSpecific(vf->viewer, PETSC_VIEWER_CLASSID, 4);
739566063dSJacob Faibussowitsch   PetscCall(SNESGetFunction(snes, &x, NULL, NULL));
74f6dfbefdSBarry Smith   PetscCall(PetscViewerPushFormat(vf->viewer, vf->format));
75f6dfbefdSBarry Smith   PetscCall(VecView(x, vf->viewer));
76f6dfbefdSBarry Smith   PetscCall(PetscViewerPopFormat(vf->viewer));
773ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
785ed2d596SBarry Smith }
795ed2d596SBarry Smith 
80d132466eSBarry Smith /*@C
81f6dfbefdSBarry Smith   SNESMonitorSolutionUpdate - Monitors progress of the `SNES` solvers by calling
82f6dfbefdSBarry Smith   `VecView()` for the UPDATE to the solution at each iteration.
83d132466eSBarry Smith 
84c3339decSBarry Smith   Collective
85d132466eSBarry Smith 
86d132466eSBarry Smith   Input Parameters:
87f6dfbefdSBarry Smith + snes   - the `SNES` context
88d132466eSBarry Smith . its    - iteration number
894b27c08aSLois Curfman McInnes . fgnorm - 2-norm of residual
90*e4094ef1SJacob Faibussowitsch - vf     - a viewer
91d132466eSBarry Smith 
92f6dfbefdSBarry Smith   Options Database Key:
93ee32d87aSMatthew G. Knepley . -snes_monitor_solution_update [ascii binary draw][:filename][:viewer format] - plots update to solution at each iteration
94ee32d87aSMatthew G. Knepley 
95d132466eSBarry Smith   Level: intermediate
96d132466eSBarry Smith 
97dc4c0fb0SBarry Smith   Note:
98dc4c0fb0SBarry Smith   This is not called directly by users, rather one calls `SNESMonitorSet()`, with this function as an argument, to cause the monitor
99dc4c0fb0SBarry Smith   to be used during the `SNES` solve.
100dc4c0fb0SBarry Smith 
101*e4094ef1SJacob Faibussowitsch .seealso: [](ch_snes), `SNESMonitorSet()`, `SNESMonitorDefault()`, `VecView()`, `SNESMonitor()`
102d132466eSBarry Smith @*/
103d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESMonitorSolutionUpdate(SNES snes, PetscInt its, PetscReal fgnorm, PetscViewerAndFormat *vf)
104d71ae5a4SJacob Faibussowitsch {
105d132466eSBarry Smith   Vec         x;
106d43b4f6eSBarry Smith   PetscViewer viewer = vf->viewer;
107d132466eSBarry Smith 
108d132466eSBarry Smith   PetscFunctionBegin;
1094d4332d5SBarry Smith   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 4);
1109566063dSJacob Faibussowitsch   PetscCall(SNESGetSolutionUpdate(snes, &x));
1119566063dSJacob Faibussowitsch   PetscCall(PetscViewerPushFormat(viewer, vf->format));
1129566063dSJacob Faibussowitsch   PetscCall(VecView(x, viewer));
1139566063dSJacob Faibussowitsch   PetscCall(PetscViewerPopFormat(viewer));
1143ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
115d132466eSBarry Smith }
116d132466eSBarry Smith 
117798534f6SMatthew G. Knepley #include <petscdraw.h>
118a5c2985bSBarry Smith 
119798534f6SMatthew G. Knepley /*@C
120f6dfbefdSBarry Smith   KSPMonitorSNESResidual - Prints the `SNES` residual norm, as well as the `KSP` residual norm, at each iteration of an iterative solver.
121798534f6SMatthew G. Knepley 
122c3339decSBarry Smith   Collective
123a5c2985bSBarry Smith 
124a5c2985bSBarry Smith   Input Parameters:
125a5c2985bSBarry Smith + ksp   - iterative context
126a5c2985bSBarry Smith . n     - iteration number
127a5c2985bSBarry Smith . rnorm - 2-norm (preconditioned) residual value (may be estimated).
128798534f6SMatthew G. Knepley - vf    - The viewer context
129798534f6SMatthew G. Knepley 
130798534f6SMatthew G. Knepley   Options Database Key:
131f6dfbefdSBarry Smith . -snes_monitor_ksp - Activates `KSPMonitorSNESResidual()`
132a5c2985bSBarry Smith 
133a5c2985bSBarry Smith   Level: intermediate
134a5c2985bSBarry Smith 
135dc4c0fb0SBarry Smith   Note:
136dc4c0fb0SBarry Smith   This is not called directly by users, rather one calls `KSPMonitorSet()`, with this function as an argument, to cause the monitor
137dc4c0fb0SBarry Smith   to be used during the `KSP` solve.
138dc4c0fb0SBarry Smith 
1391cc06b55SBarry Smith .seealso: [](ch_snes), `KSPMonitorSet()`, `KSPMonitorResidual()`, `KSPMonitorTrueResidualMaxNorm()`, `KSPMonitor()`, `SNESMonitor()`
140a5c2985bSBarry Smith @*/
141d71ae5a4SJacob Faibussowitsch PetscErrorCode KSPMonitorSNESResidual(KSP ksp, PetscInt n, PetscReal rnorm, PetscViewerAndFormat *vf)
142d71ae5a4SJacob Faibussowitsch {
143798534f6SMatthew G. Knepley   PetscViewer       viewer = vf->viewer;
144798534f6SMatthew G. Knepley   PetscViewerFormat format = vf->format;
145798534f6SMatthew G. Knepley   SNES              snes   = (SNES)vf->data;
146a5c2985bSBarry Smith   Vec               snes_solution, work1, work2;
147a5c2985bSBarry Smith   PetscReal         snorm;
148798534f6SMatthew G. Knepley   PetscInt          tablevel;
149798534f6SMatthew G. Knepley   const char       *prefix;
150a5c2985bSBarry Smith 
151a5c2985bSBarry Smith   PetscFunctionBegin;
152798534f6SMatthew G. Knepley   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 4);
1539566063dSJacob Faibussowitsch   PetscCall(SNESGetSolution(snes, &snes_solution));
1549566063dSJacob Faibussowitsch   PetscCall(VecDuplicate(snes_solution, &work1));
1559566063dSJacob Faibussowitsch   PetscCall(VecDuplicate(snes_solution, &work2));
1569566063dSJacob Faibussowitsch   PetscCall(KSPBuildSolution(ksp, work1, NULL));
1579566063dSJacob Faibussowitsch   PetscCall(VecAYPX(work1, -1.0, snes_solution));
1589566063dSJacob Faibussowitsch   PetscCall(SNESComputeFunction(snes, work1, work2));
1599566063dSJacob Faibussowitsch   PetscCall(VecNorm(work2, NORM_2, &snorm));
1609566063dSJacob Faibussowitsch   PetscCall(VecDestroy(&work1));
1619566063dSJacob Faibussowitsch   PetscCall(VecDestroy(&work2));
162a5c2985bSBarry Smith 
1639566063dSJacob Faibussowitsch   PetscCall(PetscObjectGetTabLevel((PetscObject)ksp, &tablevel));
1649566063dSJacob Faibussowitsch   PetscCall(PetscObjectGetOptionsPrefix((PetscObject)ksp, &prefix));
1659566063dSJacob Faibussowitsch   PetscCall(PetscViewerPushFormat(viewer, format));
1669566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIIAddTab(viewer, tablevel));
1679566063dSJacob Faibussowitsch   if (n == 0 && prefix) PetscCall(PetscViewerASCIIPrintf(viewer, "  Residual norms for %s solve.\n", prefix));
16863a3b9bcSJacob Faibussowitsch   PetscCall(PetscViewerASCIIPrintf(viewer, "%3" PetscInt_FMT " SNES Residual norm %5.3e KSP Residual norm %5.3e \n", n, (double)snorm, (double)rnorm));
1699566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIISubtractTab(viewer, tablevel));
1709566063dSJacob Faibussowitsch   PetscCall(PetscViewerPopFormat(viewer));
1713ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
172a5c2985bSBarry Smith }
173a5c2985bSBarry Smith 
174e5f7ee39SBarry Smith /*@C
175f6dfbefdSBarry Smith   KSPMonitorSNESResidualDrawLG - Plots the linear `KSP` residual norm and the `SNES` residual norm at each iteration of an iterative solver.
176e5f7ee39SBarry Smith 
177c3339decSBarry Smith   Collective
178e5f7ee39SBarry Smith 
179e5f7ee39SBarry Smith   Input Parameters:
180798534f6SMatthew G. Knepley + ksp   - iterative context
181798534f6SMatthew G. Knepley . n     - iteration number
182798534f6SMatthew G. Knepley . rnorm - 2-norm (preconditioned) residual value (may be estimated).
183f6dfbefdSBarry Smith - vf    - The viewer context, created with `KSPMonitorSNESResidualDrawLGCreate()`
184e5f7ee39SBarry Smith 
185e5f7ee39SBarry Smith   Options Database Key:
186f6dfbefdSBarry Smith . -snes_monitor_ksp draw::draw_lg - Activates `KSPMonitorSNESResidualDrawLG()`
187e5f7ee39SBarry Smith 
188dc4c0fb0SBarry Smith   Level: intermediate
189dc4c0fb0SBarry Smith 
190f6dfbefdSBarry Smith   Note:
1913a61192cSBarry Smith   This is not called directly by users, rather one calls `SNESMonitorSet()`, with this function as an argument, to cause the monitor
192f6dfbefdSBarry Smith   to be used during the `SNESSolve()`
1933a61192cSBarry Smith 
1941cc06b55SBarry Smith .seealso: [](ch_snes), `KSPMonitorSet()`, `KSPMonitorTrueResidual()`, `SNESMonitor()`, `KSPMonitor()`, `KSPMonitorSNESResidualDrawLGCreate()`
195e5f7ee39SBarry Smith @*/
196d71ae5a4SJacob Faibussowitsch PetscErrorCode KSPMonitorSNESResidualDrawLG(KSP ksp, PetscInt n, PetscReal rnorm, PetscViewerAndFormat *vf)
197d71ae5a4SJacob Faibussowitsch {
198798534f6SMatthew G. Knepley   PetscViewer        viewer = vf->viewer;
199798534f6SMatthew G. Knepley   PetscViewerFormat  format = vf->format;
200798534f6SMatthew G. Knepley   PetscDrawLG        lg     = vf->lg;
201798534f6SMatthew G. Knepley   SNES               snes   = (SNES)vf->data;
202e5f7ee39SBarry Smith   Vec                snes_solution, work1, work2;
203798534f6SMatthew G. Knepley   PetscReal          snorm;
204798534f6SMatthew G. Knepley   KSPConvergedReason reason;
205798534f6SMatthew G. Knepley   PetscReal          x[2], y[2];
206e5f7ee39SBarry Smith 
207e5f7ee39SBarry Smith   PetscFunctionBegin;
208798534f6SMatthew G. Knepley   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 4);
209064a246eSJacob Faibussowitsch   PetscValidHeaderSpecific(lg, PETSC_DRAWLG_CLASSID, 4);
2109566063dSJacob Faibussowitsch   PetscCall(SNESGetSolution(snes, &snes_solution));
2119566063dSJacob Faibussowitsch   PetscCall(VecDuplicate(snes_solution, &work1));
2129566063dSJacob Faibussowitsch   PetscCall(VecDuplicate(snes_solution, &work2));
2139566063dSJacob Faibussowitsch   PetscCall(KSPBuildSolution(ksp, work1, NULL));
2149566063dSJacob Faibussowitsch   PetscCall(VecAYPX(work1, -1.0, snes_solution));
2159566063dSJacob Faibussowitsch   PetscCall(SNESComputeFunction(snes, work1, work2));
2169566063dSJacob Faibussowitsch   PetscCall(VecNorm(work2, NORM_2, &snorm));
2179566063dSJacob Faibussowitsch   PetscCall(VecDestroy(&work1));
2189566063dSJacob Faibussowitsch   PetscCall(VecDestroy(&work2));
219e5f7ee39SBarry Smith 
2209566063dSJacob Faibussowitsch   PetscCall(PetscViewerPushFormat(viewer, format));
2219566063dSJacob Faibussowitsch   if (!n) PetscCall(PetscDrawLGReset(lg));
222798534f6SMatthew G. Knepley   x[0] = (PetscReal)n;
223798534f6SMatthew G. Knepley   if (rnorm > 0.0) y[0] = PetscLog10Real(rnorm);
224798534f6SMatthew G. Knepley   else y[0] = -15.0;
225798534f6SMatthew G. Knepley   x[1] = (PetscReal)n;
226798534f6SMatthew G. Knepley   if (snorm > 0.0) y[1] = PetscLog10Real(snorm);
227798534f6SMatthew G. Knepley   else y[1] = -15.0;
2289566063dSJacob Faibussowitsch   PetscCall(PetscDrawLGAddPoint(lg, x, y));
2299566063dSJacob Faibussowitsch   PetscCall(KSPGetConvergedReason(ksp, &reason));
230798534f6SMatthew G. Knepley   if (n <= 20 || !(n % 5) || reason) {
2319566063dSJacob Faibussowitsch     PetscCall(PetscDrawLGDraw(lg));
2329566063dSJacob Faibussowitsch     PetscCall(PetscDrawLGSave(lg));
233e5f7ee39SBarry Smith   }
2349566063dSJacob Faibussowitsch   PetscCall(PetscViewerPopFormat(viewer));
2353ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
236e5f7ee39SBarry Smith }
237e5f7ee39SBarry Smith 
238798534f6SMatthew G. Knepley /*@C
239f6dfbefdSBarry Smith   KSPMonitorSNESResidualDrawLGCreate - Creates the `PetscViewer` used by `KSPMonitorSNESResidualDrawLG()`
240e5f7ee39SBarry Smith 
241c3339decSBarry Smith   Collective
242e5f7ee39SBarry Smith 
243798534f6SMatthew G. Knepley   Input Parameters:
244dc4c0fb0SBarry Smith + viewer - The `PetscViewer`
245798534f6SMatthew G. Knepley . format - The viewer format
246798534f6SMatthew G. Knepley - ctx    - An optional user context
247798534f6SMatthew G. Knepley 
248798534f6SMatthew G. Knepley   Output Parameter:
249798534f6SMatthew G. Knepley . vf - The viewer context
250e5f7ee39SBarry Smith 
251e5f7ee39SBarry Smith   Level: intermediate
252e5f7ee39SBarry Smith 
2531cc06b55SBarry Smith .seealso: [](ch_snes), `KSP`, `SNES`, `PetscViewerFormat`, `PetscViewerAndFormat`, `KSPMonitorSet()`, `KSPMonitorTrueResidual()`
254e5f7ee39SBarry Smith @*/
255d71ae5a4SJacob Faibussowitsch PetscErrorCode KSPMonitorSNESResidualDrawLGCreate(PetscViewer viewer, PetscViewerFormat format, void *ctx, PetscViewerAndFormat **vf)
256d71ae5a4SJacob Faibussowitsch {
257798534f6SMatthew G. Knepley   const char *names[] = {"linear", "nonlinear"};
258e5f7ee39SBarry Smith 
259e5f7ee39SBarry Smith   PetscFunctionBegin;
2609566063dSJacob Faibussowitsch   PetscCall(PetscViewerAndFormatCreate(viewer, format, vf));
261798534f6SMatthew G. Knepley   (*vf)->data = ctx;
2629566063dSJacob Faibussowitsch   PetscCall(KSPMonitorLGCreate(PetscObjectComm((PetscObject)viewer), NULL, NULL, "Log Residual Norm", 2, names, PETSC_DECIDE, PETSC_DECIDE, 400, 300, &(*vf)->lg));
2633ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
264e5f7ee39SBarry Smith }
265e5f7ee39SBarry Smith 
266d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESMonitorDefaultSetUp(SNES snes, PetscViewerAndFormat *vf)
267d71ae5a4SJacob Faibussowitsch {
268fbcc4530SMatthew G. Knepley   PetscFunctionBegin;
26948a46eb9SPierre Jolivet   if (vf->format == PETSC_VIEWER_DRAW_LG) PetscCall(KSPMonitorLGCreate(PetscObjectComm((PetscObject)vf->viewer), NULL, NULL, "Log Residual Norm", 1, NULL, PETSC_DECIDE, PETSC_DECIDE, 400, 300, &vf->lg));
2703ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
271fbcc4530SMatthew G. Knepley }
272fbcc4530SMatthew G. Knepley 
2734b828684SBarry Smith /*@C
274f6dfbefdSBarry Smith   SNESMonitorDefault - Monitors progress of the `SNES` solvers (default).
275e7e93795SLois Curfman McInnes 
276c3339decSBarry Smith   Collective
277c7afd0dbSLois Curfman McInnes 
278e7e93795SLois Curfman McInnes   Input Parameters:
279f6dfbefdSBarry Smith + snes   - the `SNES` context
280e7e93795SLois Curfman McInnes . its    - iteration number
2814b27c08aSLois Curfman McInnes . fgnorm - 2-norm of residual
282d43b4f6eSBarry Smith - vf     - viewer and format structure
283fee21e36SBarry Smith 
2843c7db156SBarry Smith   Options Database Key:
2853a61192cSBarry Smith . -snes_monitor - use this function to monitor the convergence of the nonlinear solver
2863a61192cSBarry Smith 
287dc4c0fb0SBarry Smith   Level: intermediate
288dc4c0fb0SBarry Smith 
289e7e93795SLois Curfman McInnes   Notes:
2904b27c08aSLois Curfman McInnes   This routine prints the residual norm at each iteration.
291e7e93795SLois Curfman McInnes 
2923a61192cSBarry Smith   This is not called directly by users, rather one calls `SNESMonitorSet()`, with this function as an argument, to cause the monitor
293f6dfbefdSBarry Smith   to be used during the `SNES` solve.
2943a61192cSBarry Smith 
295*e4094ef1SJacob Faibussowitsch .seealso: [](ch_snes), `SNESMonitorSet()`, `SNESMonitorSolution()`, `SNESMonitorFunction()`, `SNESMonitorResidual()`,
2963a61192cSBarry Smith           `SNESMonitorSolutionUpdate()`, `SNESMonitorDefault()`, `SNESMonitorScaling()`, `SNESMonitorRange()`, `SNESMonitorRatio()`,
2972fe279fdSBarry Smith           `SNESMonitorDefaultField()`, `PetscViewerFormat`, `PetscViewerAndFormat`
298e7e93795SLois Curfman McInnes @*/
299d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESMonitorDefault(SNES snes, PetscInt its, PetscReal fgnorm, PetscViewerAndFormat *vf)
300d71ae5a4SJacob Faibussowitsch {
301d43b4f6eSBarry Smith   PetscViewer       viewer = vf->viewer;
302798534f6SMatthew G. Knepley   PetscViewerFormat format = vf->format;
303798534f6SMatthew G. Knepley   PetscBool         isascii, isdraw;
304d132466eSBarry Smith 
3053a40ed3dSBarry Smith   PetscFunctionBegin;
3064d4332d5SBarry Smith   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 4);
3079566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &isascii));
3089566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERDRAW, &isdraw));
3099566063dSJacob Faibussowitsch   PetscCall(PetscViewerPushFormat(viewer, format));
310798534f6SMatthew G. Knepley   if (isascii) {
3119566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIAddTab(viewer, ((PetscObject)snes)->tablevel));
3129814a27eSStefano Zampini     if (format == PETSC_VIEWER_ASCII_INFO_DETAIL) {
3139814a27eSStefano Zampini       Vec       dx;
3149814a27eSStefano Zampini       PetscReal upnorm;
3159814a27eSStefano Zampini       PetscErrorCode (*objective)(SNES, Vec, PetscReal *, void *);
3169814a27eSStefano Zampini 
3179814a27eSStefano Zampini       PetscCall(SNESGetSolutionUpdate(snes, &dx));
3189814a27eSStefano Zampini       PetscCall(VecNorm(dx, NORM_2, &upnorm));
3199814a27eSStefano Zampini       PetscCall(SNESGetObjective(snes, &objective, NULL));
3209814a27eSStefano Zampini       if (objective) {
3219814a27eSStefano Zampini         Vec       x;
3229814a27eSStefano Zampini         PetscReal obj;
3239814a27eSStefano Zampini 
3249814a27eSStefano Zampini         PetscCall(SNESGetSolution(snes, &x));
3259814a27eSStefano Zampini         PetscCall(SNESComputeObjective(snes, x, &obj));
3269814a27eSStefano Zampini         PetscCall(PetscViewerASCIIPrintf(viewer, "%3" PetscInt_FMT " SNES Function norm %14.12e, Update norm %14.12e, Objective %14.12e\n", its, (double)fgnorm, (double)upnorm, (double)obj));
3279814a27eSStefano Zampini       } else {
3289814a27eSStefano Zampini         PetscCall(PetscViewerASCIIPrintf(viewer, "%3" PetscInt_FMT " SNES Function norm %14.12e, Update norm %14.12e\n", its, (double)fgnorm, (double)upnorm));
3299814a27eSStefano Zampini       }
3309814a27eSStefano Zampini     } else {
33163a3b9bcSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(viewer, "%3" PetscInt_FMT " SNES Function norm %14.12e \n", its, (double)fgnorm));
3329814a27eSStefano Zampini     }
3339566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIISubtractTab(viewer, ((PetscObject)snes)->tablevel));
334798534f6SMatthew G. Knepley   } else if (isdraw) {
335798534f6SMatthew G. Knepley     if (format == PETSC_VIEWER_DRAW_LG) {
336798534f6SMatthew G. Knepley       PetscDrawLG lg = (PetscDrawLG)vf->lg;
337798534f6SMatthew G. Knepley       PetscReal   x, y;
338798534f6SMatthew G. Knepley 
339798534f6SMatthew G. Knepley       PetscValidHeaderSpecific(lg, PETSC_DRAWLG_CLASSID, 4);
3409566063dSJacob Faibussowitsch       if (!its) PetscCall(PetscDrawLGReset(lg));
341798534f6SMatthew G. Knepley       x = (PetscReal)its;
342798534f6SMatthew G. Knepley       if (fgnorm > 0.0) y = PetscLog10Real(fgnorm);
343798534f6SMatthew G. Knepley       else y = -15.0;
3449566063dSJacob Faibussowitsch       PetscCall(PetscDrawLGAddPoint(lg, &x, &y));
345798534f6SMatthew G. Knepley       if (its <= 20 || !(its % 5) || snes->reason) {
3469566063dSJacob Faibussowitsch         PetscCall(PetscDrawLGDraw(lg));
3479566063dSJacob Faibussowitsch         PetscCall(PetscDrawLGSave(lg));
348798534f6SMatthew G. Knepley       }
349798534f6SMatthew G. Knepley     }
350798534f6SMatthew G. Knepley   }
3519566063dSJacob Faibussowitsch   PetscCall(PetscViewerPopFormat(viewer));
3523ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
353e7e93795SLois Curfman McInnes }
3543f1db9ecSBarry Smith 
3551f60017eSBarry Smith /*@C
3561f60017eSBarry Smith   SNESMonitorScaling - Monitors the largest value in each row of the Jacobian.
3571f60017eSBarry Smith 
358c3339decSBarry Smith   Collective
3591f60017eSBarry Smith 
3601f60017eSBarry Smith   Input Parameters:
361f6dfbefdSBarry Smith + snes   - the `SNES` context
3621f60017eSBarry Smith . its    - iteration number
3631f60017eSBarry Smith . fgnorm - 2-norm of residual
3641f60017eSBarry Smith - vf     - viewer and format structure
3651f60017eSBarry Smith 
366dc4c0fb0SBarry Smith   Level: intermediate
367dc4c0fb0SBarry Smith 
3681f60017eSBarry Smith   Notes:
3691f60017eSBarry Smith   This routine prints the largest value in each row of the Jacobian
3701f60017eSBarry Smith 
3713a61192cSBarry Smith   This is not called directly by users, rather one calls `SNESMonitorSet()`, with this function as an argument, to cause the monitor
372f6dfbefdSBarry Smith   to be used during the `SNES` solve.
3733a61192cSBarry Smith 
3741cc06b55SBarry Smith .seealso: [](ch_snes), `SNESMonitorSet()`, `SNESMonitorSolution()`, `SNESMonitorRange()`, `SNESMonitorJacUpdateSpectrum()`,
3752fe279fdSBarry Smith           `PetscViewerFormat`, `PetscViewerAndFormat`
3761f60017eSBarry Smith @*/
377d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESMonitorScaling(SNES snes, PetscInt its, PetscReal fgnorm, PetscViewerAndFormat *vf)
378d71ae5a4SJacob Faibussowitsch {
3791f60017eSBarry Smith   PetscViewer viewer = vf->viewer;
3801f60017eSBarry Smith   KSP         ksp;
3811f60017eSBarry Smith   Mat         J;
3821f60017eSBarry Smith   Vec         v;
3831f60017eSBarry Smith 
3841f60017eSBarry Smith   PetscFunctionBegin;
3851f60017eSBarry Smith   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 4);
3869566063dSJacob Faibussowitsch   PetscCall(SNESGetKSP(snes, &ksp));
3879566063dSJacob Faibussowitsch   PetscCall(KSPGetOperators(ksp, &J, NULL));
3889566063dSJacob Faibussowitsch   PetscCall(MatCreateVecs(J, &v, NULL));
3899566063dSJacob Faibussowitsch   PetscCall(MatGetRowMaxAbs(J, v, NULL));
3909566063dSJacob Faibussowitsch   PetscCall(PetscViewerPushFormat(viewer, vf->format));
3919566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIIAddTab(viewer, ((PetscObject)snes)->tablevel));
39263a3b9bcSJacob Faibussowitsch   PetscCall(PetscViewerASCIIPrintf(viewer, "SNES Jacobian maximum row entries\n"));
3939566063dSJacob Faibussowitsch   PetscCall(VecView(v, viewer));
3949566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIISubtractTab(viewer, ((PetscObject)snes)->tablevel));
3959566063dSJacob Faibussowitsch   PetscCall(PetscViewerPopFormat(viewer));
3969566063dSJacob Faibussowitsch   PetscCall(VecDestroy(&v));
3973ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
3981f60017eSBarry Smith }
3991f60017eSBarry Smith 
400f6dfbefdSBarry Smith /*@C
401f6dfbefdSBarry Smith   SNESMonitorJacUpdateSpectrum - Monitors the spectrun of the change in the Jacobian from the last Jacobian evaluation
402f6dfbefdSBarry Smith 
403c3339decSBarry Smith   Collective
404f6dfbefdSBarry Smith 
405f6dfbefdSBarry Smith   Input Parameters:
406f6dfbefdSBarry Smith + snes  - the `SNES` context
407*e4094ef1SJacob Faibussowitsch . it    - iteration number
408*e4094ef1SJacob Faibussowitsch . fnorm - 2-norm of residual
409f6dfbefdSBarry Smith - vf    - viewer and format structure
410f6dfbefdSBarry Smith 
4112fe279fdSBarry Smith   Options Database Key:
412f6dfbefdSBarry Smith . -snes_monitor_jacupdate_spectrum - activates this monitor
413f6dfbefdSBarry Smith 
414dc4c0fb0SBarry Smith   Level: intermediate
415dc4c0fb0SBarry Smith 
416f6dfbefdSBarry Smith   Notes:
417f6dfbefdSBarry Smith   This routine prints the eigenvalues of the difference in the Jacobians
418f6dfbefdSBarry Smith 
419f6dfbefdSBarry Smith   This is not called directly by users, rather one calls `SNESMonitorSet()`, with this function as an argument, to cause the monitor
420f6dfbefdSBarry Smith   to be used during the `SNES` solve.
421f6dfbefdSBarry Smith 
4221cc06b55SBarry Smith .seealso: [](ch_snes), `SNESMonitorSet()`, `SNESMonitorSolution()`, `SNESMonitorRange()`, `PetscViewerFormat`, `PetscViewerAndFormat`
423f6dfbefdSBarry Smith @*/
424d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESMonitorJacUpdateSpectrum(SNES snes, PetscInt it, PetscReal fnorm, PetscViewerAndFormat *vf)
425d71ae5a4SJacob Faibussowitsch {
4262e7541e6SPeter Brune   Vec X;
4272e7541e6SPeter Brune   Mat J, dJ, dJdense;
428d1e9a80fSBarry Smith   PetscErrorCode (*func)(SNES, Vec, Mat, Mat, void *);
4292f96bde4SJose E. Roman   PetscInt     n;
43023fff9afSBarry Smith   PetscBLASInt nb = 0, lwork;
4312e7541e6SPeter Brune   PetscReal   *eigr, *eigi;
4322e7541e6SPeter Brune   PetscScalar *work;
4332e7541e6SPeter Brune   PetscScalar *a;
4342e7541e6SPeter Brune 
4352e7541e6SPeter Brune   PetscFunctionBegin;
4363ba16761SJacob Faibussowitsch   if (it == 0) PetscFunctionReturn(PETSC_SUCCESS);
437f6dfbefdSBarry Smith   /* create the difference between the current update and the current Jacobian */
4389566063dSJacob Faibussowitsch   PetscCall(SNESGetSolution(snes, &X));
4399566063dSJacob Faibussowitsch   PetscCall(SNESGetJacobian(snes, NULL, &J, &func, NULL));
4409566063dSJacob Faibussowitsch   PetscCall(MatDuplicate(J, MAT_COPY_VALUES, &dJ));
4419566063dSJacob Faibussowitsch   PetscCall(SNESComputeJacobian(snes, X, dJ, dJ));
4429566063dSJacob Faibussowitsch   PetscCall(MatAXPY(dJ, -1.0, J, SAME_NONZERO_PATTERN));
443f5af7f23SKarl Rupp 
4442e7541e6SPeter Brune   /* compute the spectrum directly */
4459566063dSJacob Faibussowitsch   PetscCall(MatConvert(dJ, MATSEQDENSE, MAT_INITIAL_MATRIX, &dJdense));
4469566063dSJacob Faibussowitsch   PetscCall(MatGetSize(dJ, &n, NULL));
4479566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(n, &nb));
4482e7541e6SPeter Brune   lwork = 3 * nb;
4499566063dSJacob Faibussowitsch   PetscCall(PetscMalloc1(n, &eigr));
4509566063dSJacob Faibussowitsch   PetscCall(PetscMalloc1(n, &eigi));
4519566063dSJacob Faibussowitsch   PetscCall(PetscMalloc1(lwork, &work));
4529566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArray(dJdense, &a));
4532e7541e6SPeter Brune #if !defined(PETSC_USE_COMPLEX)
4542e7541e6SPeter Brune   {
4552e7541e6SPeter Brune     PetscBLASInt lierr;
4562f96bde4SJose E. Roman     PetscInt     i;
4579566063dSJacob Faibussowitsch     PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF));
458792fecdfSBarry Smith     PetscCallBLAS("LAPACKgeev", LAPACKgeev_("N", "N", &nb, a, &nb, eigr, eigi, NULL, &nb, NULL, &nb, work, &lwork, &lierr));
45963a3b9bcSJacob Faibussowitsch     PetscCheck(!lierr, PETSC_COMM_SELF, PETSC_ERR_LIB, "geev() error %" PetscBLASInt_FMT, lierr);
4609566063dSJacob Faibussowitsch     PetscCall(PetscFPTrapPop());
46163a3b9bcSJacob Faibussowitsch     PetscCall(PetscPrintf(PetscObjectComm((PetscObject)snes), "Eigenvalues of J_%" PetscInt_FMT " - J_%" PetscInt_FMT ":\n", it, it - 1));
46248a46eb9SPierre 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]));
4632f96bde4SJose E. Roman   }
4649566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArray(dJdense, &a));
4659566063dSJacob Faibussowitsch   PetscCall(MatDestroy(&dJ));
4669566063dSJacob Faibussowitsch   PetscCall(MatDestroy(&dJdense));
4679566063dSJacob Faibussowitsch   PetscCall(PetscFree(eigr));
4689566063dSJacob Faibussowitsch   PetscCall(PetscFree(eigi));
4699566063dSJacob Faibussowitsch   PetscCall(PetscFree(work));
4703ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
4712f96bde4SJose E. Roman #else
4722f96bde4SJose E. Roman   SETERRQ(PETSC_COMM_SELF, PETSC_ERR_SUP, "Not coded for complex");
4732f96bde4SJose E. Roman #endif
4742e7541e6SPeter Brune }
4752e7541e6SPeter Brune 
4766ba87a44SLisandro Dalcin PETSC_INTERN PetscErrorCode SNESMonitorRange_Private(SNES, PetscInt, PetscReal *);
4776ba87a44SLisandro Dalcin 
478d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESMonitorRange_Private(SNES snes, PetscInt it, PetscReal *per)
479d71ae5a4SJacob Faibussowitsch {
480b271bb04SBarry Smith   Vec          resid;
481b271bb04SBarry Smith   PetscReal    rmax, pwork;
482b271bb04SBarry Smith   PetscInt     i, n, N;
483b271bb04SBarry Smith   PetscScalar *r;
484b271bb04SBarry Smith 
485b271bb04SBarry Smith   PetscFunctionBegin;
4869566063dSJacob Faibussowitsch   PetscCall(SNESGetFunction(snes, &resid, NULL, NULL));
4879566063dSJacob Faibussowitsch   PetscCall(VecNorm(resid, NORM_INFINITY, &rmax));
4889566063dSJacob Faibussowitsch   PetscCall(VecGetLocalSize(resid, &n));
4899566063dSJacob Faibussowitsch   PetscCall(VecGetSize(resid, &N));
4909566063dSJacob Faibussowitsch   PetscCall(VecGetArray(resid, &r));
491b271bb04SBarry Smith   pwork = 0.0;
492ad540459SPierre Jolivet   for (i = 0; i < n; i++) pwork += (PetscAbsScalar(r[i]) > .20 * rmax);
4931c2dc1cbSBarry Smith   PetscCall(MPIU_Allreduce(&pwork, per, 1, MPIU_REAL, MPIU_SUM, PetscObjectComm((PetscObject)snes)));
4949566063dSJacob Faibussowitsch   PetscCall(VecRestoreArray(resid, &r));
495b271bb04SBarry Smith   *per = *per / N;
4963ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
497b271bb04SBarry Smith }
498b271bb04SBarry Smith 
499b271bb04SBarry Smith /*@C
500f6dfbefdSBarry Smith   SNESMonitorRange - Prints the percentage of residual elements that are more then 10 percent of the maximum entry in the residual
501b271bb04SBarry Smith 
502c3339decSBarry Smith   Collective
503b271bb04SBarry Smith 
504b271bb04SBarry Smith   Input Parameters:
505b271bb04SBarry Smith + snes  - iterative context
506b271bb04SBarry Smith . it    - iteration number
507b271bb04SBarry Smith . rnorm - 2-norm (preconditioned) residual value (may be estimated).
508*e4094ef1SJacob Faibussowitsch - vf    - unused monitor context
509b271bb04SBarry Smith 
510b271bb04SBarry Smith   Options Database Key:
511f6dfbefdSBarry Smith . -snes_monitor_range - Activates `SNESMonitorRange()`
512b271bb04SBarry Smith 
513dc4c0fb0SBarry Smith   Level: intermediate
514dc4c0fb0SBarry Smith 
515f6dfbefdSBarry Smith   Note:
5163a61192cSBarry Smith   This is not called directly by users, rather one calls `SNESMonitorSet()`, with this function as an argument, to cause the monitor
517f6dfbefdSBarry Smith   to be used during the `SNES` solve.
5183a61192cSBarry Smith 
5191cc06b55SBarry Smith .seealso: [](ch_snes), `SNESMonitorSet()`, `SNESMonitorDefault()`, `SNESMonitorLGCreate()`, `SNESMonitorScaling()`, `PetscViewerFormat`, `PetscViewerAndFormat`
520b271bb04SBarry Smith @*/
521d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESMonitorRange(SNES snes, PetscInt it, PetscReal rnorm, PetscViewerAndFormat *vf)
522d71ae5a4SJacob Faibussowitsch {
523b271bb04SBarry Smith   PetscReal   perc, rel;
524d43b4f6eSBarry Smith   PetscViewer viewer = vf->viewer;
525b271bb04SBarry Smith   /* should be in a MonitorRangeContext */
526b271bb04SBarry Smith   static PetscReal prev;
527b271bb04SBarry Smith 
528b271bb04SBarry Smith   PetscFunctionBegin;
5294d4332d5SBarry Smith   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 4);
530b271bb04SBarry Smith   if (!it) prev = rnorm;
5319566063dSJacob Faibussowitsch   PetscCall(SNESMonitorRange_Private(snes, it, &perc));
532b271bb04SBarry Smith 
533b271bb04SBarry Smith   rel  = (prev - rnorm) / prev;
534b271bb04SBarry Smith   prev = rnorm;
5359566063dSJacob Faibussowitsch   PetscCall(PetscViewerPushFormat(viewer, vf->format));
5369566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIIAddTab(viewer, ((PetscObject)snes)->tablevel));
53763a3b9bcSJacob 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)));
5389566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIISubtractTab(viewer, ((PetscObject)snes)->tablevel));
5399566063dSJacob Faibussowitsch   PetscCall(PetscViewerPopFormat(viewer));
5403ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
541b271bb04SBarry Smith }
542b271bb04SBarry Smith 
5433a7fca6bSBarry Smith /*@C
544f6dfbefdSBarry Smith   SNESMonitorRatio - Monitors progress of the `SNES` solvers by printing the ratio
5454b27c08aSLois Curfman McInnes   of residual norm at each iteration to the previous.
5463a7fca6bSBarry Smith 
547c3339decSBarry Smith   Collective
5483a7fca6bSBarry Smith 
5493a7fca6bSBarry Smith   Input Parameters:
550f6dfbefdSBarry Smith + snes   - the `SNES` context
5513a7fca6bSBarry Smith . its    - iteration number
5523a7fca6bSBarry Smith . fgnorm - 2-norm of residual (or gradient)
553*e4094ef1SJacob Faibussowitsch - vf     - context of monitor
5543a7fca6bSBarry Smith 
5552fe279fdSBarry Smith   Options Database Key:
556f6dfbefdSBarry Smith . -snes_monitor_ratio - activate this monitor
557f6dfbefdSBarry Smith 
5583a7fca6bSBarry Smith   Level: intermediate
5593a7fca6bSBarry Smith 
56095452b02SPatrick Sanan   Notes:
5613a61192cSBarry Smith   This is not called directly by users, rather one calls `SNESMonitorSet()`, with this function as an argument, to cause the monitor
562f6dfbefdSBarry Smith   to be used during the `SNES` solve.
5633a61192cSBarry Smith 
564f6dfbefdSBarry Smith   Be sure to call `SNESMonitorRationSetUp()` before using this monitor.
5653a61192cSBarry Smith 
5661cc06b55SBarry Smith .seealso: [](ch_snes), `SNESMonitorRationSetUp()`, `SNESMonitorSet()`, `SNESMonitorSolution()`, `SNESMonitorDefault()`, `PetscViewerFormat`, `PetscViewerAndFormat`
5673a7fca6bSBarry Smith @*/
568d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESMonitorRatio(SNES snes, PetscInt its, PetscReal fgnorm, PetscViewerAndFormat *vf)
569d71ae5a4SJacob Faibussowitsch {
57077431f27SBarry Smith   PetscInt    len;
57187828ca2SBarry Smith   PetscReal  *history;
572d43b4f6eSBarry Smith   PetscViewer viewer = vf->viewer;
5733a7fca6bSBarry Smith 
5743a7fca6bSBarry Smith   PetscFunctionBegin;
5759566063dSJacob Faibussowitsch   PetscCall(SNESGetConvergenceHistory(snes, &history, NULL, &len));
5769566063dSJacob Faibussowitsch   PetscCall(PetscViewerPushFormat(viewer, vf->format));
5779566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIIAddTab(viewer, ((PetscObject)snes)->tablevel));
578958c9bccSBarry Smith   if (!its || !history || its > len) {
57963a3b9bcSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer, "%3" PetscInt_FMT " SNES Function norm %14.12e \n", its, (double)fgnorm));
5803a7fca6bSBarry Smith   } else {
58187828ca2SBarry Smith     PetscReal ratio = fgnorm / history[its - 1];
58263a3b9bcSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer, "%3" PetscInt_FMT " SNES Function norm %14.12e %14.12e \n", its, (double)fgnorm, (double)ratio));
5833a7fca6bSBarry Smith   }
5849566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIISubtractTab(viewer, ((PetscObject)snes)->tablevel));
5859566063dSJacob Faibussowitsch   PetscCall(PetscViewerPopFormat(viewer));
5863ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
5873a7fca6bSBarry Smith }
5883a7fca6bSBarry Smith 
5893a7fca6bSBarry Smith /*@C
590f6dfbefdSBarry Smith   SNESMonitorRatioSetUp - Insures the `SNES` object is saving its history since this monitor needs access to it
5913a7fca6bSBarry Smith 
592c3339decSBarry Smith   Collective
5933a7fca6bSBarry Smith 
5943a7fca6bSBarry Smith   Input Parameters:
595f6dfbefdSBarry Smith + snes - the `SNES` context
596*e4094ef1SJacob Faibussowitsch - vf   - the `PetscViewer` object (ignored)
5973a7fca6bSBarry Smith 
5983a7fca6bSBarry Smith   Level: intermediate
5993a7fca6bSBarry Smith 
6001cc06b55SBarry Smith .seealso: [](ch_snes), `SNESMonitorSet()`, `SNESMonitorSolution()`, `SNESMonitorDefault()`, `SNESMonitorRatio()`, `PetscViewerFormat`, `PetscViewerAndFormat`
6013a7fca6bSBarry Smith @*/
602d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESMonitorRatioSetUp(SNES snes, PetscViewerAndFormat *vf)
603d71ae5a4SJacob Faibussowitsch {
60487828ca2SBarry Smith   PetscReal *history;
6053a7fca6bSBarry Smith 
6063a7fca6bSBarry Smith   PetscFunctionBegin;
6079566063dSJacob Faibussowitsch   PetscCall(SNESGetConvergenceHistory(snes, &history, NULL, NULL));
60848a46eb9SPierre Jolivet   if (!history) PetscCall(SNESSetConvergenceHistory(snes, NULL, NULL, 100, PETSC_TRUE));
6093ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
6103a7fca6bSBarry Smith }
6113a7fca6bSBarry Smith 
612be1f7002SBarry Smith /*
613a6570f20SBarry Smith      Default (short) SNES Monitor, same as SNESMonitorDefault() except
614be1f7002SBarry Smith   it prints fewer digits of the residual as the residual gets smaller.
615be1f7002SBarry Smith   This is because the later digits are meaningless and are often
616be1f7002SBarry Smith   different on different machines; by using this routine different
617be1f7002SBarry Smith   machines will usually generate the same output.
618dec21524SBarry Smith 
619dec21524SBarry Smith   Deprecated: Intentionally has no manual page
620be1f7002SBarry Smith */
621d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESMonitorDefaultShort(SNES snes, PetscInt its, PetscReal fgnorm, PetscViewerAndFormat *vf)
622d71ae5a4SJacob Faibussowitsch {
623d43b4f6eSBarry Smith   PetscViewer viewer = vf->viewer;
624d132466eSBarry Smith 
6253a40ed3dSBarry Smith   PetscFunctionBegin;
6264d4332d5SBarry Smith   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 4);
6279566063dSJacob Faibussowitsch   PetscCall(PetscViewerPushFormat(viewer, vf->format));
6289566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIIAddTab(viewer, ((PetscObject)snes)->tablevel));
6298f240d10SBarry Smith   if (fgnorm > 1.e-9) {
63063a3b9bcSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer, "%3" PetscInt_FMT " SNES Function norm %g \n", its, (double)fgnorm));
6313a40ed3dSBarry Smith   } else if (fgnorm > 1.e-11) {
63263a3b9bcSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer, "%3" PetscInt_FMT " SNES Function norm %5.3e \n", its, (double)fgnorm));
6333a40ed3dSBarry Smith   } else {
63463a3b9bcSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer, "%3" PetscInt_FMT " SNES Function norm < 1.e-11\n", its));
635a34d58ebSBarry Smith   }
6369566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIISubtractTab(viewer, ((PetscObject)snes)->tablevel));
6379566063dSJacob Faibussowitsch   PetscCall(PetscViewerPopFormat(viewer));
6383ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
639e7e93795SLois Curfman McInnes }
6402db13446SMatthew G. Knepley 
6412db13446SMatthew G. Knepley /*@C
642f6dfbefdSBarry Smith   SNESMonitorDefaultField - Monitors progress of the `SNES` solvers, separated into fields.
6432db13446SMatthew G. Knepley 
644c3339decSBarry Smith   Collective
6452db13446SMatthew G. Knepley 
6462db13446SMatthew G. Knepley   Input Parameters:
647f6dfbefdSBarry Smith + snes   - the `SNES` context
6482db13446SMatthew G. Knepley . its    - iteration number
6492db13446SMatthew G. Knepley . fgnorm - 2-norm of residual
650*e4094ef1SJacob Faibussowitsch - vf     - the PetscViewer
6512db13446SMatthew G. Knepley 
6522fe279fdSBarry Smith   Options Database Key:
653f6dfbefdSBarry Smith . -snes_monitor_field - activate this monitor
654f6dfbefdSBarry Smith 
655dc4c0fb0SBarry Smith   Level: intermediate
656dc4c0fb0SBarry Smith 
6572db13446SMatthew G. Knepley   Notes:
658f6dfbefdSBarry Smith   This routine uses the `DM` attached to the residual vector to define the fields.
6593a61192cSBarry Smith 
6603a61192cSBarry Smith   This is not called directly by users, rather one calls `SNESMonitorSet()`, with this function as an argument, to cause the monitor
661f6dfbefdSBarry Smith   to be used during the `SNES` solve.
6622db13446SMatthew G. Knepley 
6631cc06b55SBarry Smith .seealso: [](ch_snes), `SNESMonitorSet()`, `SNESMonitorSolution()`, `SNESMonitorDefault()`, `PetscViewerFormat`, `PetscViewerAndFormat`
6642db13446SMatthew G. Knepley @*/
665d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESMonitorDefaultField(SNES snes, PetscInt its, PetscReal fgnorm, PetscViewerAndFormat *vf)
666d71ae5a4SJacob Faibussowitsch {
667d43b4f6eSBarry Smith   PetscViewer viewer = vf->viewer;
6682db13446SMatthew G. Knepley   Vec         r;
6692db13446SMatthew G. Knepley   DM          dm;
6702db13446SMatthew G. Knepley   PetscReal   res[256];
6712db13446SMatthew G. Knepley   PetscInt    tablevel;
6722db13446SMatthew G. Knepley 
6732db13446SMatthew G. Knepley   PetscFunctionBegin;
6744d4332d5SBarry Smith   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 4);
6759566063dSJacob Faibussowitsch   PetscCall(SNESGetFunction(snes, &r, NULL, NULL));
6769566063dSJacob Faibussowitsch   PetscCall(VecGetDM(r, &dm));
6779566063dSJacob Faibussowitsch   if (!dm) PetscCall(SNESMonitorDefault(snes, its, fgnorm, vf));
6782db13446SMatthew G. Knepley   else {
6792db13446SMatthew G. Knepley     PetscSection s, gs;
6802db13446SMatthew G. Knepley     PetscInt     Nf, f;
6812db13446SMatthew G. Knepley 
6829566063dSJacob Faibussowitsch     PetscCall(DMGetLocalSection(dm, &s));
6839566063dSJacob Faibussowitsch     PetscCall(DMGetGlobalSection(dm, &gs));
6849566063dSJacob Faibussowitsch     if (!s || !gs) PetscCall(SNESMonitorDefault(snes, its, fgnorm, vf));
6859566063dSJacob Faibussowitsch     PetscCall(PetscSectionGetNumFields(s, &Nf));
68663a3b9bcSJacob Faibussowitsch     PetscCheck(Nf <= 256, PetscObjectComm((PetscObject)snes), PETSC_ERR_SUP, "Do not support %" PetscInt_FMT " fields > 256", Nf);
6879566063dSJacob Faibussowitsch     PetscCall(PetscSectionVecNorm(s, gs, r, NORM_2, res));
6889566063dSJacob Faibussowitsch     PetscCall(PetscObjectGetTabLevel((PetscObject)snes, &tablevel));
6899566063dSJacob Faibussowitsch     PetscCall(PetscViewerPushFormat(viewer, vf->format));
6909566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIAddTab(viewer, tablevel));
69163a3b9bcSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer, "%3" PetscInt_FMT " SNES Function norm %14.12e [", its, (double)fgnorm));
6922db13446SMatthew G. Knepley     for (f = 0; f < Nf; ++f) {
6939566063dSJacob Faibussowitsch       if (f) PetscCall(PetscViewerASCIIPrintf(viewer, ", "));
69463a3b9bcSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(viewer, "%14.12e", (double)res[f]));
6952db13446SMatthew G. Knepley     }
6969566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer, "] \n"));
6979566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIISubtractTab(viewer, tablevel));
6989566063dSJacob Faibussowitsch     PetscCall(PetscViewerPopFormat(viewer));
6992db13446SMatthew G. Knepley   }
7003ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
7012db13446SMatthew G. Knepley }
702f6dfbefdSBarry Smith 
7034b828684SBarry Smith /*@C
704c34cbdceSBarry Smith   SNESConvergedDefault - Default onvergence test of the solvers for
705c34cbdceSBarry Smith   systems of nonlinear equations.
706e7e93795SLois Curfman McInnes 
707c3339decSBarry Smith   Collective
708c7afd0dbSLois Curfman McInnes 
709e7e93795SLois Curfman McInnes   Input Parameters:
710f6dfbefdSBarry Smith + snes  - the `SNES` context
71106ee9f85SBarry Smith . it    - the iteration (0 indicates before any Newton steps)
712e7e93795SLois Curfman McInnes . xnorm - 2-norm of current iterate
713c60f73f4SPeter Brune . snorm - 2-norm of current step
7147f3332b4SBarry Smith . fnorm - 2-norm of function at current iterate
715c7afd0dbSLois Curfman McInnes - dummy - unused context
716e7e93795SLois Curfman McInnes 
717184914b5SBarry Smith   Output Parameter:
718*e4094ef1SJacob Faibussowitsch + reason - one of
719f6dfbefdSBarry Smith .vb
720f6dfbefdSBarry Smith    SNES_CONVERGED_FNORM_ABS       - (fnorm < abstol),
721f6dfbefdSBarry Smith    SNES_CONVERGED_SNORM_RELATIVE  - (snorm < stol*xnorm),
722f6dfbefdSBarry Smith    SNES_CONVERGED_FNORM_RELATIVE  - (fnorm < rtol*fnorm0),
723f6dfbefdSBarry Smith    SNES_DIVERGED_FUNCTION_COUNT   - (nfct > maxf),
724f6dfbefdSBarry Smith    SNES_DIVERGED_FNORM_NAN        - (fnorm == NaN),
725f6dfbefdSBarry Smith    SNES_CONVERGED_ITERATING       - (otherwise),
726f6dfbefdSBarry Smith    SNES_DIVERGED_DTOL             - (fnorm > divtol*snes->fnorm0)
727f6dfbefdSBarry Smith .ve
728e7e93795SLois Curfman McInnes 
729e7e93795SLois Curfman McInnes   where
730*e4094ef1SJacob Faibussowitsch .    maxf - maximum number of function evaluations,  set with `SNESSetTolerances()`
731c7afd0dbSLois Curfman McInnes .    nfct - number of function evaluations,
732f6dfbefdSBarry Smith .    abstol - absolute function norm tolerance, set with `SNESSetTolerances()`
733f6dfbefdSBarry Smith .    rtol - relative function norm tolerance, set with `SNESSetTolerances()`
734f6dfbefdSBarry Smith .    divtol - divergence tolerance, set with `SNESSetDivergenceTolerance()`
735c34cbdceSBarry Smith -    fnorm0 - 2-norm of the function at the initial solution (initial guess; zeroth iteration)
736c34cbdceSBarry Smith 
737c34cbdceSBarry Smith   Options Database Keys:
738f6dfbefdSBarry Smith + -snes_convergence_test default      - see `SNESSetFromOptions()`
739f362779dSJed Brown . -snes_stol                          - convergence tolerance in terms of the norm  of the change in the solution between steps
740c34cbdceSBarry Smith . -snes_atol <abstol>                 - absolute tolerance of residual norm
741c34cbdceSBarry Smith . -snes_rtol <rtol>                   - relative decrease in tolerance norm from the initial 2-norm of the solution
742c34cbdceSBarry Smith . -snes_divergence_tolerance <divtol> - if the residual goes above divtol*rnorm0, exit with divergence
743c34cbdceSBarry Smith . -snes_max_funcs <max_funcs>         - maximum number of function evaluations
744c34cbdceSBarry Smith . -snes_max_fail <max_fail>           - maximum number of line search failures allowed before stopping, default is none
745f6dfbefdSBarry Smith - -snes_max_linear_solve_fail         - number of linear solver failures before `SNESSolve()` stops
746fee21e36SBarry Smith 
74736851e7fSLois Curfman McInnes   Level: intermediate
74836851e7fSLois Curfman McInnes 
7491cc06b55SBarry Smith .seealso: [](ch_snes), `SNES`, `SNESSolve()`, `SNESSetConvergenceTest()`, `SNESConvergedSkip()`, `SNESSetTolerances()`, `SNESSetDivergenceTolerance()`,
7502fe279fdSBarry Smith           `SNESConvergedReason`
751e7e93795SLois Curfman McInnes @*/
752d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESConvergedDefault(SNES snes, PetscInt it, PetscReal xnorm, PetscReal snorm, PetscReal fnorm, SNESConvergedReason *reason, void *dummy)
753d71ae5a4SJacob Faibussowitsch {
7543a40ed3dSBarry Smith   PetscFunctionBegin;
7550700a824SBarry Smith   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
7563f149594SLisandro Dalcin   PetscValidPointer(reason, 6);
7573f149594SLisandro Dalcin 
75806ee9f85SBarry Smith   *reason = SNES_CONVERGED_ITERATING;
75906ee9f85SBarry Smith   if (!it) {
76006ee9f85SBarry Smith     /* set parameter for default relative tolerance convergence test */
76106ee9f85SBarry Smith     snes->ttol   = fnorm * snes->rtol;
762e37c518bSBarry Smith     snes->rnorm0 = fnorm;
76306ee9f85SBarry Smith   }
7648146f6ebSBarry Smith   if (PetscIsInfOrNanReal(fnorm)) {
7659566063dSJacob Faibussowitsch     PetscCall(PetscInfo(snes, "Failed to converged, function norm is NaN\n"));
766184914b5SBarry Smith     *reason = SNES_DIVERGED_FNORM_NAN;
767be5caee7SBarry Smith   } else if (fnorm < snes->abstol && (it || !snes->forceiteration)) {
7689566063dSJacob Faibussowitsch     PetscCall(PetscInfo(snes, "Converged due to function norm %14.12e < %14.12e\n", (double)fnorm, (double)snes->abstol));
769184914b5SBarry Smith     *reason = SNES_CONVERGED_FNORM_ABS;
770e71169deSBarry Smith   } else if (snes->nfuncs >= snes->max_funcs && snes->max_funcs >= 0) {
77163a3b9bcSJacob Faibussowitsch     PetscCall(PetscInfo(snes, "Exceeded maximum number of function evaluations: %" PetscInt_FMT " > %" PetscInt_FMT "\n", snes->nfuncs, snes->max_funcs));
772184914b5SBarry Smith     *reason = SNES_DIVERGED_FUNCTION_COUNT;
77306ee9f85SBarry Smith   }
77406ee9f85SBarry Smith 
77506ee9f85SBarry Smith   if (it && !*reason) {
77606ee9f85SBarry Smith     if (fnorm <= snes->ttol) {
7779566063dSJacob Faibussowitsch       PetscCall(PetscInfo(snes, "Converged due to function norm %14.12e < %14.12e (relative tolerance)\n", (double)fnorm, (double)snes->ttol));
77806ee9f85SBarry Smith       *reason = SNES_CONVERGED_FNORM_RELATIVE;
779c60f73f4SPeter Brune     } else if (snorm < snes->stol * xnorm) {
7809566063dSJacob Faibussowitsch       PetscCall(PetscInfo(snes, "Converged due to small update length: %14.12e < %14.12e * %14.12e\n", (double)snorm, (double)snes->stol, (double)xnorm));
781c60f73f4SPeter Brune       *reason = SNES_CONVERGED_SNORM_RELATIVE;
782e4d06f11SPatrick Farrell     } else if (snes->divtol > 0 && (fnorm > snes->divtol * snes->rnorm0)) {
7839566063dSJacob 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));
784e37c518bSBarry Smith       *reason = SNES_DIVERGED_DTOL;
78506ee9f85SBarry Smith     }
786e7e93795SLois Curfman McInnes   }
7873ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
788e7e93795SLois Curfman McInnes }
7893f149594SLisandro Dalcin 
7903f149594SLisandro Dalcin /*@C
791f6dfbefdSBarry Smith   SNESConvergedSkip - Convergence test for `SNES` that NEVER returns as
7923f149594SLisandro Dalcin   converged, UNLESS the maximum number of iteration have been reached.
7933f149594SLisandro Dalcin 
794c3339decSBarry Smith   Logically Collective
7953f149594SLisandro Dalcin 
7963f149594SLisandro Dalcin   Input Parameters:
797f6dfbefdSBarry Smith + snes  - the `SNES` context
7983f149594SLisandro Dalcin . it    - the iteration (0 indicates before any Newton steps)
7993f149594SLisandro Dalcin . xnorm - 2-norm of current iterate
800c60f73f4SPeter Brune . snorm - 2-norm of current step
8013f149594SLisandro Dalcin . fnorm - 2-norm of function at current iterate
8023f149594SLisandro Dalcin - dummy - unused context
8033f149594SLisandro Dalcin 
8043f149594SLisandro Dalcin   Output Parameter:
805f6dfbefdSBarry Smith . reason - `SNES_CONVERGED_ITERATING`, `SNES_CONVERGED_ITS`, or `SNES_DIVERGED_FNORM_NAN`
8063f149594SLisandro Dalcin 
807f6dfbefdSBarry Smith   Options Database Key:
808f6dfbefdSBarry Smith . -snes_convergence_test skip - see `SNESSetFromOptions()`
809f362779dSJed Brown 
8103f149594SLisandro Dalcin   Level: advanced
8113f149594SLisandro Dalcin 
8121cc06b55SBarry Smith .seealso: [](ch_snes), `SNES`, `SNESSolve()`, `SNESConvergedDefault()`, `SNESSetConvergenceTest()`, `SNESConvergedReason`
8133f149594SLisandro Dalcin @*/
814d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESConvergedSkip(SNES snes, PetscInt it, PetscReal xnorm, PetscReal snorm, PetscReal fnorm, SNESConvergedReason *reason, void *dummy)
815d71ae5a4SJacob Faibussowitsch {
8163f149594SLisandro Dalcin   PetscFunctionBegin;
8170700a824SBarry Smith   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
8183f149594SLisandro Dalcin   PetscValidPointer(reason, 6);
8193f149594SLisandro Dalcin 
8203f149594SLisandro Dalcin   *reason = SNES_CONVERGED_ITERATING;
8213f149594SLisandro Dalcin 
8223f149594SLisandro Dalcin   if (fnorm != fnorm) {
8239566063dSJacob Faibussowitsch     PetscCall(PetscInfo(snes, "Failed to converged, function norm is NaN\n"));
8243f149594SLisandro Dalcin     *reason = SNES_DIVERGED_FNORM_NAN;
8253f149594SLisandro Dalcin   } else if (it == snes->max_its) {
8263f149594SLisandro Dalcin     *reason = SNES_CONVERGED_ITS;
8273f149594SLisandro Dalcin   }
8283ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
8293f149594SLisandro Dalcin }
8303f149594SLisandro Dalcin 
8318d359177SBarry Smith /*@C
832f6dfbefdSBarry Smith   SNESSetWorkVecs - Gets a number of work vectors to be used internally by `SNES` solvers
83358c9b817SLisandro Dalcin 
83458c9b817SLisandro Dalcin   Input Parameters:
835f6dfbefdSBarry Smith + snes - the `SNES` context
836a2b725a8SWilliam Gropp - nw   - number of work vectors to allocate
83758c9b817SLisandro Dalcin 
83858c9b817SLisandro Dalcin   Level: developer
839fa0ddf94SBarry Smith 
8401cc06b55SBarry Smith .seealso: [](ch_snes), `SNES`
84198acb6afSMatthew G Knepley @*/
842d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESSetWorkVecs(SNES snes, PetscInt nw)
843d71ae5a4SJacob Faibussowitsch {
844c5ed8070SMatthew G. Knepley   DM  dm;
845c5ed8070SMatthew G. Knepley   Vec v;
84658c9b817SLisandro Dalcin 
84758c9b817SLisandro Dalcin   PetscFunctionBegin;
8489566063dSJacob Faibussowitsch   if (snes->work) PetscCall(VecDestroyVecs(snes->nwork, &snes->work));
84958c9b817SLisandro Dalcin   snes->nwork = nw;
850f5af7f23SKarl Rupp 
8519566063dSJacob Faibussowitsch   PetscCall(SNESGetDM(snes, &dm));
8529566063dSJacob Faibussowitsch   PetscCall(DMGetGlobalVector(dm, &v));
8539566063dSJacob Faibussowitsch   PetscCall(VecDuplicateVecs(v, snes->nwork, &snes->work));
8549566063dSJacob Faibussowitsch   PetscCall(DMRestoreGlobalVector(dm, &v));
8553ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
85658c9b817SLisandro Dalcin }
857