xref: /petsc/src/snes/interface/snesut.c (revision dc4c0fb0d12fea86f250fc6da7e50c6579cf47ac)
1e7e93795SLois Curfman McInnes 
2af0996ceSBarry Smith #include <petsc/private/snesimpl.h> /*I   "petsc/private/snesimpl.h"   I*/
3636fd056SMatthew G. Knepley #include <petscdm.h>
4ea844a1aSMatthew Knepley #include <petscsection.h>
52e7541e6SPeter Brune #include <petscblaslapack.h>
6e7e93795SLois Curfman McInnes 
73f1db9ecSBarry Smith /*@C
8f6dfbefdSBarry Smith    SNESMonitorSolution - Monitors progress of the `SNES` solvers by calling
9f6dfbefdSBarry Smith    `VecView()` for the approximate solution at each iteration.
103f1db9ecSBarry Smith 
11c3339decSBarry Smith    Collective
123f1db9ecSBarry Smith 
133f1db9ecSBarry Smith    Input Parameters:
14f6dfbefdSBarry Smith +  snes - the `SNES` context
153f1db9ecSBarry Smith .  its - iteration number
164b27c08aSLois Curfman McInnes .  fgnorm - 2-norm of residual
17f55353a2SBarry Smith -  dummy -  a viewer
183f1db9ecSBarry Smith 
19f6dfbefdSBarry Smith    Options Database Key:
20ee32d87aSMatthew G. Knepley .  -snes_monitor_solution [ascii binary draw][:filename][:viewer format] - plots solution at each iteration
21ee32d87aSMatthew G. Knepley 
22*dc4c0fb0SBarry Smith    Level: intermediate
23*dc4c0fb0SBarry 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 
28*dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNES`, `SNESMonitorSet()`, `SNESMonitorDefault()`, `VecView()`
293f1db9ecSBarry Smith @*/
30d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESMonitorSolution(SNES snes, PetscInt its, PetscReal fgnorm, PetscViewerAndFormat *vf)
31d71ae5a4SJacob Faibussowitsch {
323f1db9ecSBarry Smith   Vec         x;
33d43b4f6eSBarry Smith   PetscViewer viewer = vf->viewer;
343f1db9ecSBarry Smith 
353f1db9ecSBarry Smith   PetscFunctionBegin;
364d4332d5SBarry Smith   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 4);
379566063dSJacob Faibussowitsch   PetscCall(SNESGetSolution(snes, &x));
389566063dSJacob Faibussowitsch   PetscCall(PetscViewerPushFormat(viewer, vf->format));
399566063dSJacob Faibussowitsch   PetscCall(VecView(x, viewer));
409566063dSJacob Faibussowitsch   PetscCall(PetscViewerPopFormat(viewer));
413ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
423f1db9ecSBarry Smith }
433f1db9ecSBarry Smith 
445ed2d596SBarry Smith /*@C
45f6dfbefdSBarry Smith    SNESMonitorResidual - Monitors progress of the `SNES` solvers by calling
46f6dfbefdSBarry Smith    `VecView()` for the residual at each iteration.
475ed2d596SBarry Smith 
48c3339decSBarry Smith    Collective
495ed2d596SBarry Smith 
505ed2d596SBarry Smith    Input Parameters:
51f6dfbefdSBarry Smith +  snes - the `SNES` context
525ed2d596SBarry Smith .  its - iteration number
534b27c08aSLois Curfman McInnes .  fgnorm - 2-norm of residual
54f55353a2SBarry Smith -  dummy -  a viewer
555ed2d596SBarry Smith 
56f6dfbefdSBarry Smith    Options Database Key:
57ee32d87aSMatthew G. Knepley .  -snes_monitor_residual [ascii binary draw][:filename][:viewer format] - plots residual (not its norm) at each iteration
58ee32d87aSMatthew G. Knepley 
595ed2d596SBarry Smith    Level: intermediate
605ed2d596SBarry Smith 
61*dc4c0fb0SBarry Smith    Note:
62*dc4c0fb0SBarry Smith    This is not called directly by users, rather one calls `SNESMonitorSet()`, with this function as an argument, to cause the monitor
63*dc4c0fb0SBarry Smith    to be used during the `SNES` solve.
64*dc4c0fb0SBarry Smith 
65*dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNES`, `SNESMonitorSet()`, `SNESMonitorDefault()`, `VecView()`, `SNESMonitor()`
665ed2d596SBarry Smith @*/
67d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESMonitorResidual(SNES snes, PetscInt its, PetscReal fgnorm, PetscViewerAndFormat *vf)
68d71ae5a4SJacob Faibussowitsch {
695ed2d596SBarry Smith   Vec x;
705ed2d596SBarry Smith 
715ed2d596SBarry Smith   PetscFunctionBegin;
72f6dfbefdSBarry Smith   PetscValidHeaderSpecific(vf->viewer, PETSC_VIEWER_CLASSID, 4);
739566063dSJacob Faibussowitsch   PetscCall(SNESGetFunction(snes, &x, NULL, NULL));
74f6dfbefdSBarry Smith   PetscCall(PetscViewerPushFormat(vf->viewer, vf->format));
75f6dfbefdSBarry Smith   PetscCall(VecView(x, vf->viewer));
76f6dfbefdSBarry Smith   PetscCall(PetscViewerPopFormat(vf->viewer));
773ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
785ed2d596SBarry Smith }
795ed2d596SBarry Smith 
80d132466eSBarry Smith /*@C
81f6dfbefdSBarry Smith    SNESMonitorSolutionUpdate - Monitors progress of the `SNES` solvers by calling
82f6dfbefdSBarry Smith    `VecView()` for the UPDATE to the solution at each iteration.
83d132466eSBarry Smith 
84c3339decSBarry Smith    Collective
85d132466eSBarry Smith 
86d132466eSBarry Smith    Input Parameters:
87f6dfbefdSBarry Smith +  snes - the `SNES` context
88d132466eSBarry Smith .  its - iteration number
894b27c08aSLois Curfman McInnes .  fgnorm - 2-norm of residual
90f55353a2SBarry Smith -  dummy - a viewer
91d132466eSBarry Smith 
92f6dfbefdSBarry Smith    Options Database Key:
93ee32d87aSMatthew G. Knepley .  -snes_monitor_solution_update [ascii binary draw][:filename][:viewer format] - plots update to solution at each iteration
94ee32d87aSMatthew G. Knepley 
95d132466eSBarry Smith    Level: intermediate
96d132466eSBarry Smith 
97*dc4c0fb0SBarry Smith    Note:
98*dc4c0fb0SBarry Smith    This is not called directly by users, rather one calls `SNESMonitorSet()`, with this function as an argument, to cause the monitor
99*dc4c0fb0SBarry Smith    to be used during the `SNES` solve.
100*dc4c0fb0SBarry Smith 
101*dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNESMonitorSet()`, `SNESMonitorDefault()`, `VecView()`, `SNESMonitor()`, `SNESMonitor()`
102d132466eSBarry Smith @*/
103d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESMonitorSolutionUpdate(SNES snes, PetscInt its, PetscReal fgnorm, PetscViewerAndFormat *vf)
104d71ae5a4SJacob Faibussowitsch {
105d132466eSBarry Smith   Vec         x;
106d43b4f6eSBarry Smith   PetscViewer viewer = vf->viewer;
107d132466eSBarry Smith 
108d132466eSBarry Smith   PetscFunctionBegin;
1094d4332d5SBarry Smith   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 4);
1109566063dSJacob Faibussowitsch   PetscCall(SNESGetSolutionUpdate(snes, &x));
1119566063dSJacob Faibussowitsch   PetscCall(PetscViewerPushFormat(viewer, vf->format));
1129566063dSJacob Faibussowitsch   PetscCall(VecView(x, viewer));
1139566063dSJacob Faibussowitsch   PetscCall(PetscViewerPopFormat(viewer));
1143ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
115d132466eSBarry Smith }
116d132466eSBarry Smith 
117798534f6SMatthew G. Knepley #include <petscdraw.h>
118a5c2985bSBarry Smith 
119798534f6SMatthew G. Knepley /*@C
120f6dfbefdSBarry Smith   KSPMonitorSNESResidual - Prints the `SNES` residual norm, as well as the `KSP` residual norm, at each iteration of an iterative solver.
121798534f6SMatthew G. Knepley 
122c3339decSBarry Smith   Collective
123a5c2985bSBarry Smith 
124a5c2985bSBarry Smith   Input Parameters:
125a5c2985bSBarry Smith + ksp   - iterative context
126a5c2985bSBarry Smith . n     - iteration number
127a5c2985bSBarry Smith . rnorm - 2-norm (preconditioned) residual value (may be estimated).
128798534f6SMatthew G. Knepley - vf    - The viewer context
129798534f6SMatthew G. Knepley 
130798534f6SMatthew G. Knepley   Options Database Key:
131f6dfbefdSBarry Smith . -snes_monitor_ksp - Activates `KSPMonitorSNESResidual()`
132a5c2985bSBarry Smith 
133a5c2985bSBarry Smith   Level: intermediate
134a5c2985bSBarry Smith 
135*dc4c0fb0SBarry Smith    Note:
136*dc4c0fb0SBarry Smith    This is not called directly by users, rather one calls `KSPMonitorSet()`, with this function as an argument, to cause the monitor
137*dc4c0fb0SBarry Smith    to be used during the `KSP` solve.
138*dc4c0fb0SBarry Smith 
139*dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `KSPMonitorSet()`, `KSPMonitorResidual()`, `KSPMonitorTrueResidualMaxNorm()`, `KSPMonitor()`, `SNESMonitor()`
140a5c2985bSBarry Smith @*/
141d71ae5a4SJacob Faibussowitsch PetscErrorCode KSPMonitorSNESResidual(KSP ksp, PetscInt n, PetscReal rnorm, PetscViewerAndFormat *vf)
142d71ae5a4SJacob Faibussowitsch {
143798534f6SMatthew G. Knepley   PetscViewer       viewer = vf->viewer;
144798534f6SMatthew G. Knepley   PetscViewerFormat format = vf->format;
145798534f6SMatthew G. Knepley   SNES              snes   = (SNES)vf->data;
146a5c2985bSBarry Smith   Vec               snes_solution, work1, work2;
147a5c2985bSBarry Smith   PetscReal         snorm;
148798534f6SMatthew G. Knepley   PetscInt          tablevel;
149798534f6SMatthew G. Knepley   const char       *prefix;
150a5c2985bSBarry Smith 
151a5c2985bSBarry Smith   PetscFunctionBegin;
152798534f6SMatthew G. Knepley   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 4);
1539566063dSJacob Faibussowitsch   PetscCall(SNESGetSolution(snes, &snes_solution));
1549566063dSJacob Faibussowitsch   PetscCall(VecDuplicate(snes_solution, &work1));
1559566063dSJacob Faibussowitsch   PetscCall(VecDuplicate(snes_solution, &work2));
1569566063dSJacob Faibussowitsch   PetscCall(KSPBuildSolution(ksp, work1, NULL));
1579566063dSJacob Faibussowitsch   PetscCall(VecAYPX(work1, -1.0, snes_solution));
1589566063dSJacob Faibussowitsch   PetscCall(SNESComputeFunction(snes, work1, work2));
1599566063dSJacob Faibussowitsch   PetscCall(VecNorm(work2, NORM_2, &snorm));
1609566063dSJacob Faibussowitsch   PetscCall(VecDestroy(&work1));
1619566063dSJacob Faibussowitsch   PetscCall(VecDestroy(&work2));
162a5c2985bSBarry Smith 
1639566063dSJacob Faibussowitsch   PetscCall(PetscObjectGetTabLevel((PetscObject)ksp, &tablevel));
1649566063dSJacob Faibussowitsch   PetscCall(PetscObjectGetOptionsPrefix((PetscObject)ksp, &prefix));
1659566063dSJacob Faibussowitsch   PetscCall(PetscViewerPushFormat(viewer, format));
1669566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIIAddTab(viewer, tablevel));
1679566063dSJacob Faibussowitsch   if (n == 0 && prefix) PetscCall(PetscViewerASCIIPrintf(viewer, "  Residual norms for %s solve.\n", prefix));
16863a3b9bcSJacob Faibussowitsch   PetscCall(PetscViewerASCIIPrintf(viewer, "%3" PetscInt_FMT " SNES Residual norm %5.3e KSP Residual norm %5.3e \n", n, (double)snorm, (double)rnorm));
1699566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIISubtractTab(viewer, tablevel));
1709566063dSJacob Faibussowitsch   PetscCall(PetscViewerPopFormat(viewer));
1713ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
172a5c2985bSBarry Smith }
173a5c2985bSBarry Smith 
174e5f7ee39SBarry Smith /*@C
175f6dfbefdSBarry Smith   KSPMonitorSNESResidualDrawLG - Plots the linear `KSP` residual norm and the `SNES` residual norm at each iteration of an iterative solver.
176e5f7ee39SBarry Smith 
177c3339decSBarry Smith   Collective
178e5f7ee39SBarry Smith 
179e5f7ee39SBarry Smith   Input Parameters:
180798534f6SMatthew G. Knepley + ksp   - iterative context
181798534f6SMatthew G. Knepley . n     - iteration number
182798534f6SMatthew G. Knepley . rnorm - 2-norm (preconditioned) residual value (may be estimated).
183f6dfbefdSBarry Smith - vf    - The viewer context, created with `KSPMonitorSNESResidualDrawLGCreate()`
184e5f7ee39SBarry Smith 
185e5f7ee39SBarry Smith   Options Database Key:
186f6dfbefdSBarry Smith . -snes_monitor_ksp draw::draw_lg - Activates `KSPMonitorSNESResidualDrawLG()`
187e5f7ee39SBarry Smith 
188*dc4c0fb0SBarry Smith   Level: intermediate
189*dc4c0fb0SBarry 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 
194*dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `KSPMonitorSet()`, `KSPMonitorTrueResidual()`, `SNESMonitor()`, `KSPMonitor()`, `KSPMonitorSNESResidualDrawLGCreate()`
195e5f7ee39SBarry Smith @*/
196d71ae5a4SJacob Faibussowitsch PetscErrorCode KSPMonitorSNESResidualDrawLG(KSP ksp, PetscInt n, PetscReal rnorm, PetscViewerAndFormat *vf)
197d71ae5a4SJacob Faibussowitsch {
198798534f6SMatthew G. Knepley   PetscViewer        viewer = vf->viewer;
199798534f6SMatthew G. Knepley   PetscViewerFormat  format = vf->format;
200798534f6SMatthew G. Knepley   PetscDrawLG        lg     = vf->lg;
201798534f6SMatthew G. Knepley   SNES               snes   = (SNES)vf->data;
202e5f7ee39SBarry Smith   Vec                snes_solution, work1, work2;
203798534f6SMatthew G. Knepley   PetscReal          snorm;
204798534f6SMatthew G. Knepley   KSPConvergedReason reason;
205798534f6SMatthew G. Knepley   PetscReal          x[2], y[2];
206e5f7ee39SBarry Smith 
207e5f7ee39SBarry Smith   PetscFunctionBegin;
208798534f6SMatthew G. Knepley   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 4);
209064a246eSJacob Faibussowitsch   PetscValidHeaderSpecific(lg, PETSC_DRAWLG_CLASSID, 4);
2109566063dSJacob Faibussowitsch   PetscCall(SNESGetSolution(snes, &snes_solution));
2119566063dSJacob Faibussowitsch   PetscCall(VecDuplicate(snes_solution, &work1));
2129566063dSJacob Faibussowitsch   PetscCall(VecDuplicate(snes_solution, &work2));
2139566063dSJacob Faibussowitsch   PetscCall(KSPBuildSolution(ksp, work1, NULL));
2149566063dSJacob Faibussowitsch   PetscCall(VecAYPX(work1, -1.0, snes_solution));
2159566063dSJacob Faibussowitsch   PetscCall(SNESComputeFunction(snes, work1, work2));
2169566063dSJacob Faibussowitsch   PetscCall(VecNorm(work2, NORM_2, &snorm));
2179566063dSJacob Faibussowitsch   PetscCall(VecDestroy(&work1));
2189566063dSJacob Faibussowitsch   PetscCall(VecDestroy(&work2));
219e5f7ee39SBarry Smith 
2209566063dSJacob Faibussowitsch   PetscCall(PetscViewerPushFormat(viewer, format));
2219566063dSJacob Faibussowitsch   if (!n) PetscCall(PetscDrawLGReset(lg));
222798534f6SMatthew G. Knepley   x[0] = (PetscReal)n;
223798534f6SMatthew G. Knepley   if (rnorm > 0.0) y[0] = PetscLog10Real(rnorm);
224798534f6SMatthew G. Knepley   else y[0] = -15.0;
225798534f6SMatthew G. Knepley   x[1] = (PetscReal)n;
226798534f6SMatthew G. Knepley   if (snorm > 0.0) y[1] = PetscLog10Real(snorm);
227798534f6SMatthew G. Knepley   else y[1] = -15.0;
2289566063dSJacob Faibussowitsch   PetscCall(PetscDrawLGAddPoint(lg, x, y));
2299566063dSJacob Faibussowitsch   PetscCall(KSPGetConvergedReason(ksp, &reason));
230798534f6SMatthew G. Knepley   if (n <= 20 || !(n % 5) || reason) {
2319566063dSJacob Faibussowitsch     PetscCall(PetscDrawLGDraw(lg));
2329566063dSJacob Faibussowitsch     PetscCall(PetscDrawLGSave(lg));
233e5f7ee39SBarry Smith   }
2349566063dSJacob Faibussowitsch   PetscCall(PetscViewerPopFormat(viewer));
2353ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
236e5f7ee39SBarry Smith }
237e5f7ee39SBarry Smith 
238798534f6SMatthew G. Knepley /*@C
239f6dfbefdSBarry Smith   KSPMonitorSNESResidualDrawLGCreate - Creates the `PetscViewer` used by `KSPMonitorSNESResidualDrawLG()`
240e5f7ee39SBarry Smith 
241c3339decSBarry Smith   Collective
242e5f7ee39SBarry Smith 
243798534f6SMatthew G. Knepley   Input Parameters:
244*dc4c0fb0SBarry 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 
253*dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `KSP`, `SNES`, `KSPMonitorSet()`, `KSPMonitorTrueResidual()`
254e5f7ee39SBarry Smith @*/
255d71ae5a4SJacob Faibussowitsch PetscErrorCode KSPMonitorSNESResidualDrawLGCreate(PetscViewer viewer, PetscViewerFormat format, void *ctx, PetscViewerAndFormat **vf)
256d71ae5a4SJacob Faibussowitsch {
257798534f6SMatthew G. Knepley   const char *names[] = {"linear", "nonlinear"};
258e5f7ee39SBarry Smith 
259e5f7ee39SBarry Smith   PetscFunctionBegin;
2609566063dSJacob Faibussowitsch   PetscCall(PetscViewerAndFormatCreate(viewer, format, vf));
261798534f6SMatthew G. Knepley   (*vf)->data = ctx;
2629566063dSJacob Faibussowitsch   PetscCall(KSPMonitorLGCreate(PetscObjectComm((PetscObject)viewer), NULL, NULL, "Log Residual Norm", 2, names, PETSC_DECIDE, PETSC_DECIDE, 400, 300, &(*vf)->lg));
2633ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
264e5f7ee39SBarry Smith }
265e5f7ee39SBarry Smith 
266d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESMonitorDefaultSetUp(SNES snes, PetscViewerAndFormat *vf)
267d71ae5a4SJacob Faibussowitsch {
268fbcc4530SMatthew G. Knepley   PetscFunctionBegin;
26948a46eb9SPierre Jolivet   if (vf->format == PETSC_VIEWER_DRAW_LG) PetscCall(KSPMonitorLGCreate(PetscObjectComm((PetscObject)vf->viewer), NULL, NULL, "Log Residual Norm", 1, NULL, PETSC_DECIDE, PETSC_DECIDE, 400, 300, &vf->lg));
2703ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
271fbcc4530SMatthew G. Knepley }
272fbcc4530SMatthew G. Knepley 
2734b828684SBarry Smith /*@C
274f6dfbefdSBarry Smith    SNESMonitorDefault - Monitors progress of the `SNES` solvers (default).
275e7e93795SLois Curfman McInnes 
276c3339decSBarry Smith    Collective
277c7afd0dbSLois Curfman McInnes 
278e7e93795SLois Curfman McInnes    Input Parameters:
279f6dfbefdSBarry Smith +  snes - the `SNES` context
280e7e93795SLois Curfman McInnes .  its - iteration number
2814b27c08aSLois Curfman McInnes .  fgnorm - 2-norm of residual
282d43b4f6eSBarry Smith -  vf - viewer and format structure
283fee21e36SBarry Smith 
2843c7db156SBarry Smith    Options Database Key:
2853a61192cSBarry Smith .  -snes_monitor - use this function to monitor the convergence of the nonlinear solver
2863a61192cSBarry Smith 
287*dc4c0fb0SBarry Smith    Level: intermediate
288*dc4c0fb0SBarry 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*dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNESMonitorSet()`, `SNESMonitorSolution()`, `SNESMonitorFunction()`, `SNESMonitorSolution()`, `SNESMonitorResidual()`,
2963a61192cSBarry Smith           `SNESMonitorSolutionUpdate()`, `SNESMonitorDefault()`, `SNESMonitorScaling()`, `SNESMonitorRange()`, `SNESMonitorRatio()`,
2973a61192cSBarry Smith           `SNESMonitorDefaultField()`
298e7e93795SLois Curfman McInnes @*/
299d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESMonitorDefault(SNES snes, PetscInt its, PetscReal fgnorm, PetscViewerAndFormat *vf)
300d71ae5a4SJacob Faibussowitsch {
301d43b4f6eSBarry Smith   PetscViewer       viewer = vf->viewer;
302798534f6SMatthew G. Knepley   PetscViewerFormat format = vf->format;
303798534f6SMatthew G. Knepley   PetscBool         isascii, isdraw;
304d132466eSBarry Smith 
3053a40ed3dSBarry Smith   PetscFunctionBegin;
3064d4332d5SBarry Smith   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 4);
3079566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &isascii));
3089566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERDRAW, &isdraw));
3099566063dSJacob Faibussowitsch   PetscCall(PetscViewerPushFormat(viewer, format));
310798534f6SMatthew G. Knepley   if (isascii) {
3119566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIAddTab(viewer, ((PetscObject)snes)->tablevel));
31263a3b9bcSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer, "%3" PetscInt_FMT " SNES Function norm %14.12e \n", its, (double)fgnorm));
3139566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIISubtractTab(viewer, ((PetscObject)snes)->tablevel));
314798534f6SMatthew G. Knepley   } else if (isdraw) {
315798534f6SMatthew G. Knepley     if (format == PETSC_VIEWER_DRAW_LG) {
316798534f6SMatthew G. Knepley       PetscDrawLG lg = (PetscDrawLG)vf->lg;
317798534f6SMatthew G. Knepley       PetscReal   x, y;
318798534f6SMatthew G. Knepley 
319798534f6SMatthew G. Knepley       PetscValidHeaderSpecific(lg, PETSC_DRAWLG_CLASSID, 4);
3209566063dSJacob Faibussowitsch       if (!its) PetscCall(PetscDrawLGReset(lg));
321798534f6SMatthew G. Knepley       x = (PetscReal)its;
322798534f6SMatthew G. Knepley       if (fgnorm > 0.0) y = PetscLog10Real(fgnorm);
323798534f6SMatthew G. Knepley       else y = -15.0;
3249566063dSJacob Faibussowitsch       PetscCall(PetscDrawLGAddPoint(lg, &x, &y));
325798534f6SMatthew G. Knepley       if (its <= 20 || !(its % 5) || snes->reason) {
3269566063dSJacob Faibussowitsch         PetscCall(PetscDrawLGDraw(lg));
3279566063dSJacob Faibussowitsch         PetscCall(PetscDrawLGSave(lg));
328798534f6SMatthew G. Knepley       }
329798534f6SMatthew G. Knepley     }
330798534f6SMatthew G. Knepley   }
3319566063dSJacob Faibussowitsch   PetscCall(PetscViewerPopFormat(viewer));
3323ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
333e7e93795SLois Curfman McInnes }
3343f1db9ecSBarry Smith 
3351f60017eSBarry Smith /*@C
3361f60017eSBarry Smith    SNESMonitorScaling - Monitors the largest value in each row of the Jacobian.
3371f60017eSBarry Smith 
338c3339decSBarry Smith    Collective
3391f60017eSBarry Smith 
3401f60017eSBarry Smith    Input Parameters:
341f6dfbefdSBarry Smith +  snes - the `SNES` context
3421f60017eSBarry Smith .  its - iteration number
3431f60017eSBarry Smith .  fgnorm - 2-norm of residual
3441f60017eSBarry Smith -  vf - viewer and format structure
3451f60017eSBarry Smith 
346*dc4c0fb0SBarry Smith    Level: intermediate
347*dc4c0fb0SBarry 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
352f6dfbefdSBarry Smith    to be used during the `SNES` solve.
3533a61192cSBarry Smith 
354*dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNESMonitorSet()`, `SNESMonitorSolution()`, `SNESMonitorRange()`, `SNESMonitorJacUpdateSpectrum()`
3551f60017eSBarry Smith @*/
356d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESMonitorScaling(SNES snes, PetscInt its, PetscReal fgnorm, PetscViewerAndFormat *vf)
357d71ae5a4SJacob Faibussowitsch {
3581f60017eSBarry Smith   PetscViewer viewer = vf->viewer;
3591f60017eSBarry Smith   KSP         ksp;
3601f60017eSBarry Smith   Mat         J;
3611f60017eSBarry Smith   Vec         v;
3621f60017eSBarry Smith 
3631f60017eSBarry Smith   PetscFunctionBegin;
3641f60017eSBarry Smith   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 4);
3659566063dSJacob Faibussowitsch   PetscCall(SNESGetKSP(snes, &ksp));
3669566063dSJacob Faibussowitsch   PetscCall(KSPGetOperators(ksp, &J, NULL));
3679566063dSJacob Faibussowitsch   PetscCall(MatCreateVecs(J, &v, NULL));
3689566063dSJacob Faibussowitsch   PetscCall(MatGetRowMaxAbs(J, v, NULL));
3699566063dSJacob Faibussowitsch   PetscCall(PetscViewerPushFormat(viewer, vf->format));
3709566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIIAddTab(viewer, ((PetscObject)snes)->tablevel));
37163a3b9bcSJacob Faibussowitsch   PetscCall(PetscViewerASCIIPrintf(viewer, "SNES Jacobian maximum row entries\n"));
3729566063dSJacob Faibussowitsch   PetscCall(VecView(v, viewer));
3739566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIISubtractTab(viewer, ((PetscObject)snes)->tablevel));
3749566063dSJacob Faibussowitsch   PetscCall(PetscViewerPopFormat(viewer));
3759566063dSJacob Faibussowitsch   PetscCall(VecDestroy(&v));
3763ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
3771f60017eSBarry Smith }
3781f60017eSBarry Smith 
379f6dfbefdSBarry Smith /*@C
380f6dfbefdSBarry Smith    SNESMonitorJacUpdateSpectrum - Monitors the spectrun of the change in the Jacobian from the last Jacobian evaluation
381f6dfbefdSBarry Smith 
382c3339decSBarry Smith    Collective
383f6dfbefdSBarry Smith 
384f6dfbefdSBarry Smith    Input Parameters:
385f6dfbefdSBarry Smith +  snes - the `SNES` context
386f6dfbefdSBarry Smith .  its - iteration number
387f6dfbefdSBarry Smith .  fgnorm - 2-norm of residual
388f6dfbefdSBarry Smith -  vf - viewer and format structure
389f6dfbefdSBarry Smith 
390f6dfbefdSBarry Smith    Option Database Key:
391f6dfbefdSBarry Smith .  -snes_monitor_jacupdate_spectrum - activates this monitor
392f6dfbefdSBarry Smith 
393*dc4c0fb0SBarry Smith    Level: intermediate
394*dc4c0fb0SBarry Smith 
395f6dfbefdSBarry Smith    Notes:
396f6dfbefdSBarry Smith    This routine prints the eigenvalues of the difference in the Jacobians
397f6dfbefdSBarry Smith 
398f6dfbefdSBarry Smith    This is not called directly by users, rather one calls `SNESMonitorSet()`, with this function as an argument, to cause the monitor
399f6dfbefdSBarry Smith    to be used during the `SNES` solve.
400f6dfbefdSBarry Smith 
401*dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNESMonitorSet()`, `SNESMonitorSolution()`, `SNESMonitorRange()`
402f6dfbefdSBarry Smith @*/
403d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESMonitorJacUpdateSpectrum(SNES snes, PetscInt it, PetscReal fnorm, PetscViewerAndFormat *vf)
404d71ae5a4SJacob Faibussowitsch {
4052e7541e6SPeter Brune   Vec X;
4062e7541e6SPeter Brune   Mat J, dJ, dJdense;
407d1e9a80fSBarry Smith   PetscErrorCode (*func)(SNES, Vec, Mat, Mat, void *);
4082f96bde4SJose E. Roman   PetscInt     n;
40923fff9afSBarry Smith   PetscBLASInt nb = 0, lwork;
4102e7541e6SPeter Brune   PetscReal   *eigr, *eigi;
4112e7541e6SPeter Brune   PetscScalar *work;
4122e7541e6SPeter Brune   PetscScalar *a;
4132e7541e6SPeter Brune 
4142e7541e6SPeter Brune   PetscFunctionBegin;
4153ba16761SJacob Faibussowitsch   if (it == 0) PetscFunctionReturn(PETSC_SUCCESS);
416f6dfbefdSBarry Smith   /* create the difference between the current update and the current Jacobian */
4179566063dSJacob Faibussowitsch   PetscCall(SNESGetSolution(snes, &X));
4189566063dSJacob Faibussowitsch   PetscCall(SNESGetJacobian(snes, NULL, &J, &func, NULL));
4199566063dSJacob Faibussowitsch   PetscCall(MatDuplicate(J, MAT_COPY_VALUES, &dJ));
4209566063dSJacob Faibussowitsch   PetscCall(SNESComputeJacobian(snes, X, dJ, dJ));
4219566063dSJacob Faibussowitsch   PetscCall(MatAXPY(dJ, -1.0, J, SAME_NONZERO_PATTERN));
422f5af7f23SKarl Rupp 
4232e7541e6SPeter Brune   /* compute the spectrum directly */
4249566063dSJacob Faibussowitsch   PetscCall(MatConvert(dJ, MATSEQDENSE, MAT_INITIAL_MATRIX, &dJdense));
4259566063dSJacob Faibussowitsch   PetscCall(MatGetSize(dJ, &n, NULL));
4269566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(n, &nb));
4272e7541e6SPeter Brune   lwork = 3 * nb;
4289566063dSJacob Faibussowitsch   PetscCall(PetscMalloc1(n, &eigr));
4299566063dSJacob Faibussowitsch   PetscCall(PetscMalloc1(n, &eigi));
4309566063dSJacob Faibussowitsch   PetscCall(PetscMalloc1(lwork, &work));
4319566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArray(dJdense, &a));
4322e7541e6SPeter Brune #if !defined(PETSC_USE_COMPLEX)
4332e7541e6SPeter Brune   {
4342e7541e6SPeter Brune     PetscBLASInt lierr;
4352f96bde4SJose E. Roman     PetscInt     i;
4369566063dSJacob Faibussowitsch     PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF));
437792fecdfSBarry Smith     PetscCallBLAS("LAPACKgeev", LAPACKgeev_("N", "N", &nb, a, &nb, eigr, eigi, NULL, &nb, NULL, &nb, work, &lwork, &lierr));
43863a3b9bcSJacob Faibussowitsch     PetscCheck(!lierr, PETSC_COMM_SELF, PETSC_ERR_LIB, "geev() error %" PetscBLASInt_FMT, lierr);
4399566063dSJacob Faibussowitsch     PetscCall(PetscFPTrapPop());
44063a3b9bcSJacob Faibussowitsch     PetscCall(PetscPrintf(PetscObjectComm((PetscObject)snes), "Eigenvalues of J_%" PetscInt_FMT " - J_%" PetscInt_FMT ":\n", it, it - 1));
44148a46eb9SPierre 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]));
4422f96bde4SJose E. Roman   }
4439566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArray(dJdense, &a));
4449566063dSJacob Faibussowitsch   PetscCall(MatDestroy(&dJ));
4459566063dSJacob Faibussowitsch   PetscCall(MatDestroy(&dJdense));
4469566063dSJacob Faibussowitsch   PetscCall(PetscFree(eigr));
4479566063dSJacob Faibussowitsch   PetscCall(PetscFree(eigi));
4489566063dSJacob Faibussowitsch   PetscCall(PetscFree(work));
4493ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
4502f96bde4SJose E. Roman #else
4512f96bde4SJose E. Roman   SETERRQ(PETSC_COMM_SELF, PETSC_ERR_SUP, "Not coded for complex");
4522f96bde4SJose E. Roman #endif
4532e7541e6SPeter Brune }
4542e7541e6SPeter Brune 
4556ba87a44SLisandro Dalcin PETSC_INTERN PetscErrorCode SNESMonitorRange_Private(SNES, PetscInt, PetscReal *);
4566ba87a44SLisandro Dalcin 
457d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESMonitorRange_Private(SNES snes, PetscInt it, PetscReal *per)
458d71ae5a4SJacob Faibussowitsch {
459b271bb04SBarry Smith   Vec          resid;
460b271bb04SBarry Smith   PetscReal    rmax, pwork;
461b271bb04SBarry Smith   PetscInt     i, n, N;
462b271bb04SBarry Smith   PetscScalar *r;
463b271bb04SBarry Smith 
464b271bb04SBarry Smith   PetscFunctionBegin;
4659566063dSJacob Faibussowitsch   PetscCall(SNESGetFunction(snes, &resid, NULL, NULL));
4669566063dSJacob Faibussowitsch   PetscCall(VecNorm(resid, NORM_INFINITY, &rmax));
4679566063dSJacob Faibussowitsch   PetscCall(VecGetLocalSize(resid, &n));
4689566063dSJacob Faibussowitsch   PetscCall(VecGetSize(resid, &N));
4699566063dSJacob Faibussowitsch   PetscCall(VecGetArray(resid, &r));
470b271bb04SBarry Smith   pwork = 0.0;
471ad540459SPierre Jolivet   for (i = 0; i < n; i++) pwork += (PetscAbsScalar(r[i]) > .20 * rmax);
4721c2dc1cbSBarry Smith   PetscCall(MPIU_Allreduce(&pwork, per, 1, MPIU_REAL, MPIU_SUM, PetscObjectComm((PetscObject)snes)));
4739566063dSJacob Faibussowitsch   PetscCall(VecRestoreArray(resid, &r));
474b271bb04SBarry Smith   *per = *per / N;
4753ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
476b271bb04SBarry Smith }
477b271bb04SBarry Smith 
478b271bb04SBarry Smith /*@C
479f6dfbefdSBarry Smith    SNESMonitorRange - Prints the percentage of residual elements that are more then 10 percent of the maximum entry in the residual
480b271bb04SBarry Smith 
481c3339decSBarry Smith    Collective
482b271bb04SBarry Smith 
483b271bb04SBarry Smith    Input Parameters:
484b271bb04SBarry Smith +  snes   - iterative context
485b271bb04SBarry Smith .  it    - iteration number
486b271bb04SBarry Smith .  rnorm - 2-norm (preconditioned) residual value (may be estimated).
487b271bb04SBarry Smith -  dummy - unused monitor context
488b271bb04SBarry Smith 
489b271bb04SBarry Smith    Options Database Key:
490f6dfbefdSBarry Smith .  -snes_monitor_range - Activates `SNESMonitorRange()`
491b271bb04SBarry Smith 
492*dc4c0fb0SBarry Smith    Level: intermediate
493*dc4c0fb0SBarry Smith 
494f6dfbefdSBarry Smith    Note:
4953a61192cSBarry Smith    This is not called directly by users, rather one calls `SNESMonitorSet()`, with this function as an argument, to cause the monitor
496f6dfbefdSBarry Smith    to be used during the `SNES` solve.
4973a61192cSBarry Smith 
498*dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNESMonitorSet()`, `SNESMonitorDefault()`, `SNESMonitorLGCreate()`, `SNESMonitorScaling()`
499b271bb04SBarry Smith @*/
500d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESMonitorRange(SNES snes, PetscInt it, PetscReal rnorm, PetscViewerAndFormat *vf)
501d71ae5a4SJacob Faibussowitsch {
502b271bb04SBarry Smith   PetscReal   perc, rel;
503d43b4f6eSBarry Smith   PetscViewer viewer = vf->viewer;
504b271bb04SBarry Smith   /* should be in a MonitorRangeContext */
505b271bb04SBarry Smith   static PetscReal prev;
506b271bb04SBarry Smith 
507b271bb04SBarry Smith   PetscFunctionBegin;
5084d4332d5SBarry Smith   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 4);
509b271bb04SBarry Smith   if (!it) prev = rnorm;
5109566063dSJacob Faibussowitsch   PetscCall(SNESMonitorRange_Private(snes, it, &perc));
511b271bb04SBarry Smith 
512b271bb04SBarry Smith   rel  = (prev - rnorm) / prev;
513b271bb04SBarry Smith   prev = rnorm;
5149566063dSJacob Faibussowitsch   PetscCall(PetscViewerPushFormat(viewer, vf->format));
5159566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIIAddTab(viewer, ((PetscObject)snes)->tablevel));
51663a3b9bcSJacob 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)));
5179566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIISubtractTab(viewer, ((PetscObject)snes)->tablevel));
5189566063dSJacob Faibussowitsch   PetscCall(PetscViewerPopFormat(viewer));
5193ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
520b271bb04SBarry Smith }
521b271bb04SBarry Smith 
5223a7fca6bSBarry Smith /*@C
523f6dfbefdSBarry Smith    SNESMonitorRatio - Monitors progress of the `SNES` solvers by printing the ratio
5244b27c08aSLois Curfman McInnes    of residual norm at each iteration to the previous.
5253a7fca6bSBarry Smith 
526c3339decSBarry Smith    Collective
5273a7fca6bSBarry Smith 
5283a7fca6bSBarry Smith    Input Parameters:
529f6dfbefdSBarry Smith +  snes - the `SNES` context
5303a7fca6bSBarry Smith .  its - iteration number
5313a7fca6bSBarry Smith .  fgnorm - 2-norm of residual (or gradient)
532eabae89aSBarry Smith -  dummy -  context of monitor
5333a7fca6bSBarry Smith 
534f6dfbefdSBarry Smith    Option Database Key:
535f6dfbefdSBarry Smith .  -snes_monitor_ratio - activate this monitor
536f6dfbefdSBarry Smith 
5373a7fca6bSBarry Smith    Level: intermediate
5383a7fca6bSBarry Smith 
53995452b02SPatrick Sanan    Notes:
5403a61192cSBarry Smith    This is not called directly by users, rather one calls `SNESMonitorSet()`, with this function as an argument, to cause the monitor
541f6dfbefdSBarry Smith    to be used during the `SNES` solve.
5423a61192cSBarry Smith 
543f6dfbefdSBarry Smith    Be sure to call `SNESMonitorRationSetUp()` before using this monitor.
5443a61192cSBarry Smith 
545*dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNESMonitorRationSetUp()`, `SNESMonitorSet()`, `SNESMonitorSolution()`, `SNESMonitorDefault()`
5463a7fca6bSBarry Smith @*/
547d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESMonitorRatio(SNES snes, PetscInt its, PetscReal fgnorm, PetscViewerAndFormat *vf)
548d71ae5a4SJacob Faibussowitsch {
54977431f27SBarry Smith   PetscInt    len;
55087828ca2SBarry Smith   PetscReal  *history;
551d43b4f6eSBarry Smith   PetscViewer viewer = vf->viewer;
5523a7fca6bSBarry Smith 
5533a7fca6bSBarry Smith   PetscFunctionBegin;
5549566063dSJacob Faibussowitsch   PetscCall(SNESGetConvergenceHistory(snes, &history, NULL, &len));
5559566063dSJacob Faibussowitsch   PetscCall(PetscViewerPushFormat(viewer, vf->format));
5569566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIIAddTab(viewer, ((PetscObject)snes)->tablevel));
557958c9bccSBarry Smith   if (!its || !history || its > len) {
55863a3b9bcSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer, "%3" PetscInt_FMT " SNES Function norm %14.12e \n", its, (double)fgnorm));
5593a7fca6bSBarry Smith   } else {
56087828ca2SBarry Smith     PetscReal ratio = fgnorm / history[its - 1];
56163a3b9bcSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer, "%3" PetscInt_FMT " SNES Function norm %14.12e %14.12e \n", its, (double)fgnorm, (double)ratio));
5623a7fca6bSBarry Smith   }
5639566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIISubtractTab(viewer, ((PetscObject)snes)->tablevel));
5649566063dSJacob Faibussowitsch   PetscCall(PetscViewerPopFormat(viewer));
5653ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
5663a7fca6bSBarry Smith }
5673a7fca6bSBarry Smith 
5683a7fca6bSBarry Smith /*@C
569f6dfbefdSBarry Smith    SNESMonitorRatioSetUp - Insures the `SNES` object is saving its history since this monitor needs access to it
5703a7fca6bSBarry Smith 
571c3339decSBarry Smith    Collective
5723a7fca6bSBarry Smith 
5733a7fca6bSBarry Smith    Input Parameters:
574f6dfbefdSBarry Smith +   snes - the `SNES` context
575f6dfbefdSBarry Smith -   viewer - the `PetscViewer` object (ignored)
5763a7fca6bSBarry Smith 
5773a7fca6bSBarry Smith    Level: intermediate
5783a7fca6bSBarry Smith 
579*dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNESMonitorSet()`, `SNESMonitorSolution()`, `SNESMonitorDefault()`, `SNESMonitorRatio()`
5803a7fca6bSBarry Smith @*/
581d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESMonitorRatioSetUp(SNES snes, PetscViewerAndFormat *vf)
582d71ae5a4SJacob Faibussowitsch {
58387828ca2SBarry Smith   PetscReal *history;
5843a7fca6bSBarry Smith 
5853a7fca6bSBarry Smith   PetscFunctionBegin;
5869566063dSJacob Faibussowitsch   PetscCall(SNESGetConvergenceHistory(snes, &history, NULL, NULL));
58748a46eb9SPierre Jolivet   if (!history) PetscCall(SNESSetConvergenceHistory(snes, NULL, NULL, 100, PETSC_TRUE));
5883ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
5893a7fca6bSBarry Smith }
5903a7fca6bSBarry Smith 
591be1f7002SBarry Smith /*
592a6570f20SBarry Smith      Default (short) SNES Monitor, same as SNESMonitorDefault() except
593be1f7002SBarry Smith   it prints fewer digits of the residual as the residual gets smaller.
594be1f7002SBarry Smith   This is because the later digits are meaningless and are often
595be1f7002SBarry Smith   different on different machines; by using this routine different
596be1f7002SBarry Smith   machines will usually generate the same output.
597dec21524SBarry Smith 
598dec21524SBarry Smith   Deprecated: Intentionally has no manual page
599be1f7002SBarry Smith */
600d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESMonitorDefaultShort(SNES snes, PetscInt its, PetscReal fgnorm, PetscViewerAndFormat *vf)
601d71ae5a4SJacob Faibussowitsch {
602d43b4f6eSBarry Smith   PetscViewer viewer = vf->viewer;
603d132466eSBarry Smith 
6043a40ed3dSBarry Smith   PetscFunctionBegin;
6054d4332d5SBarry Smith   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 4);
6069566063dSJacob Faibussowitsch   PetscCall(PetscViewerPushFormat(viewer, vf->format));
6079566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIIAddTab(viewer, ((PetscObject)snes)->tablevel));
6088f240d10SBarry Smith   if (fgnorm > 1.e-9) {
60963a3b9bcSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer, "%3" PetscInt_FMT " SNES Function norm %g \n", its, (double)fgnorm));
6103a40ed3dSBarry Smith   } else if (fgnorm > 1.e-11) {
61163a3b9bcSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer, "%3" PetscInt_FMT " SNES Function norm %5.3e \n", its, (double)fgnorm));
6123a40ed3dSBarry Smith   } else {
61363a3b9bcSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer, "%3" PetscInt_FMT " SNES Function norm < 1.e-11\n", its));
614a34d58ebSBarry Smith   }
6159566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIISubtractTab(viewer, ((PetscObject)snes)->tablevel));
6169566063dSJacob Faibussowitsch   PetscCall(PetscViewerPopFormat(viewer));
6173ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
618e7e93795SLois Curfman McInnes }
6192db13446SMatthew G. Knepley 
6202db13446SMatthew G. Knepley /*@C
621f6dfbefdSBarry Smith   SNESMonitorDefaultField - Monitors progress of the `SNES` solvers, separated into fields.
6222db13446SMatthew G. Knepley 
623c3339decSBarry Smith   Collective
6242db13446SMatthew G. Knepley 
6252db13446SMatthew G. Knepley   Input Parameters:
626f6dfbefdSBarry Smith + snes   - the `SNES` context
6272db13446SMatthew G. Knepley . its    - iteration number
6282db13446SMatthew G. Knepley . fgnorm - 2-norm of residual
6292db13446SMatthew G. Knepley - ctx    - the PetscViewer
6302db13446SMatthew G. Knepley 
631f6dfbefdSBarry Smith    Option Database Key:
632f6dfbefdSBarry Smith .  -snes_monitor_field - activate this monitor
633f6dfbefdSBarry Smith 
634*dc4c0fb0SBarry Smith   Level: intermediate
635*dc4c0fb0SBarry Smith 
6362db13446SMatthew G. Knepley   Notes:
637f6dfbefdSBarry Smith   This routine uses the `DM` attached to the residual vector to define the fields.
6383a61192cSBarry Smith 
6393a61192cSBarry Smith   This is not called directly by users, rather one calls `SNESMonitorSet()`, with this function as an argument, to cause the monitor
640f6dfbefdSBarry Smith   to be used during the `SNES` solve.
6412db13446SMatthew G. Knepley 
642*dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNESMonitorSet()`, `SNESMonitorSolution()`, `SNESMonitorDefault()`
6432db13446SMatthew G. Knepley @*/
644d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESMonitorDefaultField(SNES snes, PetscInt its, PetscReal fgnorm, PetscViewerAndFormat *vf)
645d71ae5a4SJacob Faibussowitsch {
646d43b4f6eSBarry Smith   PetscViewer viewer = vf->viewer;
6472db13446SMatthew G. Knepley   Vec         r;
6482db13446SMatthew G. Knepley   DM          dm;
6492db13446SMatthew G. Knepley   PetscReal   res[256];
6502db13446SMatthew G. Knepley   PetscInt    tablevel;
6512db13446SMatthew G. Knepley 
6522db13446SMatthew G. Knepley   PetscFunctionBegin;
6534d4332d5SBarry Smith   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 4);
6549566063dSJacob Faibussowitsch   PetscCall(SNESGetFunction(snes, &r, NULL, NULL));
6559566063dSJacob Faibussowitsch   PetscCall(VecGetDM(r, &dm));
6569566063dSJacob Faibussowitsch   if (!dm) PetscCall(SNESMonitorDefault(snes, its, fgnorm, vf));
6572db13446SMatthew G. Knepley   else {
6582db13446SMatthew G. Knepley     PetscSection s, gs;
6592db13446SMatthew G. Knepley     PetscInt     Nf, f;
6602db13446SMatthew G. Knepley 
6619566063dSJacob Faibussowitsch     PetscCall(DMGetLocalSection(dm, &s));
6629566063dSJacob Faibussowitsch     PetscCall(DMGetGlobalSection(dm, &gs));
6639566063dSJacob Faibussowitsch     if (!s || !gs) PetscCall(SNESMonitorDefault(snes, its, fgnorm, vf));
6649566063dSJacob Faibussowitsch     PetscCall(PetscSectionGetNumFields(s, &Nf));
66563a3b9bcSJacob Faibussowitsch     PetscCheck(Nf <= 256, PetscObjectComm((PetscObject)snes), PETSC_ERR_SUP, "Do not support %" PetscInt_FMT " fields > 256", Nf);
6669566063dSJacob Faibussowitsch     PetscCall(PetscSectionVecNorm(s, gs, r, NORM_2, res));
6679566063dSJacob Faibussowitsch     PetscCall(PetscObjectGetTabLevel((PetscObject)snes, &tablevel));
6689566063dSJacob Faibussowitsch     PetscCall(PetscViewerPushFormat(viewer, vf->format));
6699566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIAddTab(viewer, tablevel));
67063a3b9bcSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer, "%3" PetscInt_FMT " SNES Function norm %14.12e [", its, (double)fgnorm));
6712db13446SMatthew G. Knepley     for (f = 0; f < Nf; ++f) {
6729566063dSJacob Faibussowitsch       if (f) PetscCall(PetscViewerASCIIPrintf(viewer, ", "));
67363a3b9bcSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(viewer, "%14.12e", (double)res[f]));
6742db13446SMatthew G. Knepley     }
6759566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer, "] \n"));
6769566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIISubtractTab(viewer, tablevel));
6779566063dSJacob Faibussowitsch     PetscCall(PetscViewerPopFormat(viewer));
6782db13446SMatthew G. Knepley   }
6793ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
6802db13446SMatthew G. Knepley }
681f6dfbefdSBarry Smith 
6824b828684SBarry Smith /*@C
683c34cbdceSBarry Smith    SNESConvergedDefault - Default onvergence test of the solvers for
684c34cbdceSBarry Smith    systems of nonlinear equations.
685e7e93795SLois Curfman McInnes 
686c3339decSBarry Smith    Collective
687c7afd0dbSLois Curfman McInnes 
688e7e93795SLois Curfman McInnes    Input Parameters:
689f6dfbefdSBarry Smith +  snes - the `SNES` context
69006ee9f85SBarry Smith .  it - the iteration (0 indicates before any Newton steps)
691e7e93795SLois Curfman McInnes .  xnorm - 2-norm of current iterate
692c60f73f4SPeter Brune .  snorm - 2-norm of current step
6937f3332b4SBarry Smith .  fnorm - 2-norm of function at current iterate
694c7afd0dbSLois Curfman McInnes -  dummy - unused context
695e7e93795SLois Curfman McInnes 
696184914b5SBarry Smith    Output Parameter:
697184914b5SBarry Smith .   reason  - one of
698f6dfbefdSBarry Smith .vb
699f6dfbefdSBarry Smith    SNES_CONVERGED_FNORM_ABS       - (fnorm < abstol),
700f6dfbefdSBarry Smith    SNES_CONVERGED_SNORM_RELATIVE  - (snorm < stol*xnorm),
701f6dfbefdSBarry Smith    SNES_CONVERGED_FNORM_RELATIVE  - (fnorm < rtol*fnorm0),
702f6dfbefdSBarry Smith    SNES_DIVERGED_FUNCTION_COUNT   - (nfct > maxf),
703f6dfbefdSBarry Smith    SNES_DIVERGED_FNORM_NAN        - (fnorm == NaN),
704f6dfbefdSBarry Smith    SNES_CONVERGED_ITERATING       - (otherwise),
705f6dfbefdSBarry Smith    SNES_DIVERGED_DTOL             - (fnorm > divtol*snes->fnorm0)
706f6dfbefdSBarry Smith .ve
707e7e93795SLois Curfman McInnes 
708e7e93795SLois Curfman McInnes    where
709f6dfbefdSBarry Smith +    maxf - maximum number of function evaluations,  set with `SNESSetTolerances()`
710c7afd0dbSLois Curfman McInnes .    nfct - number of function evaluations,
711f6dfbefdSBarry Smith .    abstol - absolute function norm tolerance, set with `SNESSetTolerances()`
712f6dfbefdSBarry Smith .    rtol - relative function norm tolerance, set with `SNESSetTolerances()`
713f6dfbefdSBarry Smith .    divtol - divergence tolerance, set with `SNESSetDivergenceTolerance()`
714c34cbdceSBarry Smith -    fnorm0 - 2-norm of the function at the initial solution (initial guess; zeroth iteration)
715c34cbdceSBarry Smith 
716c34cbdceSBarry Smith   Options Database Keys:
717f6dfbefdSBarry Smith +  -snes_convergence_test default - see `SNESSetFromOptions()`
718f362779dSJed Brown .  -snes_stol - convergence tolerance in terms of the norm  of the change in the solution between steps
719c34cbdceSBarry Smith .  -snes_atol <abstol> - absolute tolerance of residual norm
720c34cbdceSBarry Smith .  -snes_rtol <rtol> - relative decrease in tolerance norm from the initial 2-norm of the solution
721c34cbdceSBarry Smith .  -snes_divergence_tolerance <divtol> - if the residual goes above divtol*rnorm0, exit with divergence
722c34cbdceSBarry Smith .  -snes_max_funcs <max_funcs> - maximum number of function evaluations
723c34cbdceSBarry Smith .  -snes_max_fail <max_fail> - maximum number of line search failures allowed before stopping, default is none
724f6dfbefdSBarry Smith -  -snes_max_linear_solve_fail - number of linear solver failures before `SNESSolve()` stops
725fee21e36SBarry Smith 
72636851e7fSLois Curfman McInnes    Level: intermediate
72736851e7fSLois Curfman McInnes 
728*dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNES`, `SNESSolve()`, `SNESSetConvergenceTest()`, `SNESConvergedSkip()`, `SNESSetTolerances()`, `SNESSetDivergenceTolerance()`
729e7e93795SLois Curfman McInnes @*/
730d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESConvergedDefault(SNES snes, PetscInt it, PetscReal xnorm, PetscReal snorm, PetscReal fnorm, SNESConvergedReason *reason, void *dummy)
731d71ae5a4SJacob Faibussowitsch {
7323a40ed3dSBarry Smith   PetscFunctionBegin;
7330700a824SBarry Smith   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
7343f149594SLisandro Dalcin   PetscValidPointer(reason, 6);
7353f149594SLisandro Dalcin 
73606ee9f85SBarry Smith   *reason = SNES_CONVERGED_ITERATING;
73706ee9f85SBarry Smith   if (!it) {
73806ee9f85SBarry Smith     /* set parameter for default relative tolerance convergence test */
73906ee9f85SBarry Smith     snes->ttol   = fnorm * snes->rtol;
740e37c518bSBarry Smith     snes->rnorm0 = fnorm;
74106ee9f85SBarry Smith   }
7428146f6ebSBarry Smith   if (PetscIsInfOrNanReal(fnorm)) {
7439566063dSJacob Faibussowitsch     PetscCall(PetscInfo(snes, "Failed to converged, function norm is NaN\n"));
744184914b5SBarry Smith     *reason = SNES_DIVERGED_FNORM_NAN;
745be5caee7SBarry Smith   } else if (fnorm < snes->abstol && (it || !snes->forceiteration)) {
7469566063dSJacob Faibussowitsch     PetscCall(PetscInfo(snes, "Converged due to function norm %14.12e < %14.12e\n", (double)fnorm, (double)snes->abstol));
747184914b5SBarry Smith     *reason = SNES_CONVERGED_FNORM_ABS;
748e71169deSBarry Smith   } else if (snes->nfuncs >= snes->max_funcs && snes->max_funcs >= 0) {
74963a3b9bcSJacob Faibussowitsch     PetscCall(PetscInfo(snes, "Exceeded maximum number of function evaluations: %" PetscInt_FMT " > %" PetscInt_FMT "\n", snes->nfuncs, snes->max_funcs));
750184914b5SBarry Smith     *reason = SNES_DIVERGED_FUNCTION_COUNT;
75106ee9f85SBarry Smith   }
75206ee9f85SBarry Smith 
75306ee9f85SBarry Smith   if (it && !*reason) {
75406ee9f85SBarry Smith     if (fnorm <= snes->ttol) {
7559566063dSJacob Faibussowitsch       PetscCall(PetscInfo(snes, "Converged due to function norm %14.12e < %14.12e (relative tolerance)\n", (double)fnorm, (double)snes->ttol));
75606ee9f85SBarry Smith       *reason = SNES_CONVERGED_FNORM_RELATIVE;
757c60f73f4SPeter Brune     } else if (snorm < snes->stol * xnorm) {
7589566063dSJacob Faibussowitsch       PetscCall(PetscInfo(snes, "Converged due to small update length: %14.12e < %14.12e * %14.12e\n", (double)snorm, (double)snes->stol, (double)xnorm));
759c60f73f4SPeter Brune       *reason = SNES_CONVERGED_SNORM_RELATIVE;
760e4d06f11SPatrick Farrell     } else if (snes->divtol > 0 && (fnorm > snes->divtol * snes->rnorm0)) {
7619566063dSJacob 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));
762e37c518bSBarry Smith       *reason = SNES_DIVERGED_DTOL;
76306ee9f85SBarry Smith     }
764e7e93795SLois Curfman McInnes   }
7653ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
766e7e93795SLois Curfman McInnes }
7673f149594SLisandro Dalcin 
7683f149594SLisandro Dalcin /*@C
769f6dfbefdSBarry Smith    SNESConvergedSkip - Convergence test for `SNES` that NEVER returns as
7703f149594SLisandro Dalcin    converged, UNLESS the maximum number of iteration have been reached.
7713f149594SLisandro Dalcin 
772c3339decSBarry Smith    Logically Collective
7733f149594SLisandro Dalcin 
7743f149594SLisandro Dalcin    Input Parameters:
775f6dfbefdSBarry Smith +  snes - the `SNES` context
7763f149594SLisandro Dalcin .  it - the iteration (0 indicates before any Newton steps)
7773f149594SLisandro Dalcin .  xnorm - 2-norm of current iterate
778c60f73f4SPeter Brune .  snorm - 2-norm of current step
7793f149594SLisandro Dalcin .  fnorm - 2-norm of function at current iterate
7803f149594SLisandro Dalcin -  dummy - unused context
7813f149594SLisandro Dalcin 
7823f149594SLisandro Dalcin    Output Parameter:
783f6dfbefdSBarry Smith .   reason  - `SNES_CONVERGED_ITERATING`, `SNES_CONVERGED_ITS`, or `SNES_DIVERGED_FNORM_NAN`
7843f149594SLisandro Dalcin 
785f6dfbefdSBarry Smith    Options Database Key:
786f6dfbefdSBarry Smith .  -snes_convergence_test skip - see `SNESSetFromOptions()`
787f362779dSJed Brown 
7883f149594SLisandro Dalcin    Level: advanced
7893f149594SLisandro Dalcin 
790*dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNES`, `SNESSolve()`, `SNESConvergedDefault()`, `SNESSetConvergenceTest()`
7913f149594SLisandro Dalcin @*/
792d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESConvergedSkip(SNES snes, PetscInt it, PetscReal xnorm, PetscReal snorm, PetscReal fnorm, SNESConvergedReason *reason, void *dummy)
793d71ae5a4SJacob Faibussowitsch {
7943f149594SLisandro Dalcin   PetscFunctionBegin;
7950700a824SBarry Smith   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
7963f149594SLisandro Dalcin   PetscValidPointer(reason, 6);
7973f149594SLisandro Dalcin 
7983f149594SLisandro Dalcin   *reason = SNES_CONVERGED_ITERATING;
7993f149594SLisandro Dalcin 
8003f149594SLisandro Dalcin   if (fnorm != fnorm) {
8019566063dSJacob Faibussowitsch     PetscCall(PetscInfo(snes, "Failed to converged, function norm is NaN\n"));
8023f149594SLisandro Dalcin     *reason = SNES_DIVERGED_FNORM_NAN;
8033f149594SLisandro Dalcin   } else if (it == snes->max_its) {
8043f149594SLisandro Dalcin     *reason = SNES_CONVERGED_ITS;
8053f149594SLisandro Dalcin   }
8063ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
8073f149594SLisandro Dalcin }
8083f149594SLisandro Dalcin 
8098d359177SBarry Smith /*@C
810f6dfbefdSBarry Smith   SNESSetWorkVecs - Gets a number of work vectors to be used internally by `SNES` solvers
81158c9b817SLisandro Dalcin 
81258c9b817SLisandro Dalcin   Input Parameters:
813f6dfbefdSBarry Smith + snes  - the `SNES` context
814a2b725a8SWilliam Gropp - nw - number of work vectors to allocate
81558c9b817SLisandro Dalcin 
81658c9b817SLisandro Dalcin   Level: developer
817fa0ddf94SBarry Smith 
818*dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNES`
81998acb6afSMatthew G Knepley @*/
820d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESSetWorkVecs(SNES snes, PetscInt nw)
821d71ae5a4SJacob Faibussowitsch {
822c5ed8070SMatthew G. Knepley   DM  dm;
823c5ed8070SMatthew G. Knepley   Vec v;
82458c9b817SLisandro Dalcin 
82558c9b817SLisandro Dalcin   PetscFunctionBegin;
8269566063dSJacob Faibussowitsch   if (snes->work) PetscCall(VecDestroyVecs(snes->nwork, &snes->work));
82758c9b817SLisandro Dalcin   snes->nwork = nw;
828f5af7f23SKarl Rupp 
8299566063dSJacob Faibussowitsch   PetscCall(SNESGetDM(snes, &dm));
8309566063dSJacob Faibussowitsch   PetscCall(DMGetGlobalVector(dm, &v));
8319566063dSJacob Faibussowitsch   PetscCall(VecDuplicateVecs(v, snes->nwork, &snes->work));
8329566063dSJacob Faibussowitsch   PetscCall(DMRestoreGlobalVector(dm, &v));
8333ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
83458c9b817SLisandro Dalcin }
835