xref: /petsc/src/snes/interface/snesut.c (revision f6dfbefd03961ab3be6f06be75c96cbf27a49667)
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
8*f6dfbefdSBarry Smith    SNESMonitorSolution - Monitors progress of the `SNES` solvers by calling
9*f6dfbefdSBarry Smith    `VecView()` for the approximate solution at each iteration.
103f1db9ecSBarry Smith 
11*f6dfbefdSBarry Smith    Collective on snes
123f1db9ecSBarry Smith 
133f1db9ecSBarry Smith    Input Parameters:
14*f6dfbefdSBarry 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 
19*f6dfbefdSBarry 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*f6dfbefdSBarry Smith    Note:
233a61192cSBarry Smith    This is not called directly by users, rather one calls `SNESMonitorSet()`, with this function as an argument, to cause the monitor
24*f6dfbefdSBarry Smith    to be used during the `SNESSolve()`
253a61192cSBarry Smith 
2636851e7fSLois Curfman McInnes    Level: intermediate
273f1db9ecSBarry Smith 
28*f6dfbefdSBarry Smith .seealso: `SNES`, `SNESMonitorSet()`, `SNESMonitorDefault()`, `VecView()`
293f1db9ecSBarry Smith @*/
309371c9d4SSatish Balay PetscErrorCode SNESMonitorSolution(SNES snes, PetscInt its, PetscReal fgnorm, PetscViewerAndFormat *vf) {
313f1db9ecSBarry Smith   Vec         x;
32d43b4f6eSBarry Smith   PetscViewer viewer = vf->viewer;
333f1db9ecSBarry Smith 
343f1db9ecSBarry Smith   PetscFunctionBegin;
354d4332d5SBarry Smith   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 4);
369566063dSJacob Faibussowitsch   PetscCall(SNESGetSolution(snes, &x));
379566063dSJacob Faibussowitsch   PetscCall(PetscViewerPushFormat(viewer, vf->format));
389566063dSJacob Faibussowitsch   PetscCall(VecView(x, viewer));
399566063dSJacob Faibussowitsch   PetscCall(PetscViewerPopFormat(viewer));
403f1db9ecSBarry Smith   PetscFunctionReturn(0);
413f1db9ecSBarry Smith }
423f1db9ecSBarry Smith 
435ed2d596SBarry Smith /*@C
44*f6dfbefdSBarry Smith    SNESMonitorResidual - Monitors progress of the `SNES` solvers by calling
45*f6dfbefdSBarry Smith    `VecView()` for the residual at each iteration.
465ed2d596SBarry Smith 
47*f6dfbefdSBarry Smith    Collective on snes
485ed2d596SBarry Smith 
495ed2d596SBarry Smith    Input Parameters:
50*f6dfbefdSBarry Smith +  snes - the `SNES` context
515ed2d596SBarry Smith .  its - iteration number
524b27c08aSLois Curfman McInnes .  fgnorm - 2-norm of residual
53f55353a2SBarry Smith -  dummy -  a viewer
545ed2d596SBarry Smith 
55*f6dfbefdSBarry Smith    Options Database Key:
56ee32d87aSMatthew G. Knepley .  -snes_monitor_residual [ascii binary draw][:filename][:viewer format] - plots residual (not its norm) at each iteration
57ee32d87aSMatthew G. Knepley 
58*f6dfbefdSBarry Smith    Note:
593a61192cSBarry Smith    This is not called directly by users, rather one calls `SNESMonitorSet()`, with this function as an argument, to cause the monitor
603a61192cSBarry Smith    to be used during the SNES solve.
613a61192cSBarry Smith 
625ed2d596SBarry Smith    Level: intermediate
635ed2d596SBarry Smith 
64*f6dfbefdSBarry Smith .seealso: `SNESMonitorSet()`, `SNESMonitorDefault()`, `VecView()`, `SNESMonitor()`
655ed2d596SBarry Smith @*/
669371c9d4SSatish Balay PetscErrorCode SNESMonitorResidual(SNES snes, PetscInt its, PetscReal fgnorm, PetscViewerAndFormat *vf) {
675ed2d596SBarry Smith   Vec x;
685ed2d596SBarry Smith 
695ed2d596SBarry Smith   PetscFunctionBegin;
70*f6dfbefdSBarry Smith   PetscValidHeaderSpecific(vf->viewer, PETSC_VIEWER_CLASSID, 4);
719566063dSJacob Faibussowitsch   PetscCall(SNESGetFunction(snes, &x, NULL, NULL));
72*f6dfbefdSBarry Smith   PetscCall(PetscViewerPushFormat(vf->viewer, vf->format));
73*f6dfbefdSBarry Smith   PetscCall(VecView(x, vf->viewer));
74*f6dfbefdSBarry Smith   PetscCall(PetscViewerPopFormat(vf->viewer));
755ed2d596SBarry Smith   PetscFunctionReturn(0);
765ed2d596SBarry Smith }
775ed2d596SBarry Smith 
78d132466eSBarry Smith /*@C
79*f6dfbefdSBarry Smith    SNESMonitorSolutionUpdate - Monitors progress of the `SNES` solvers by calling
80*f6dfbefdSBarry Smith    `VecView()` for the UPDATE to the solution at each iteration.
81d132466eSBarry Smith 
82*f6dfbefdSBarry Smith    Collective on snes
83d132466eSBarry Smith 
84d132466eSBarry Smith    Input Parameters:
85*f6dfbefdSBarry Smith +  snes - the `SNES` context
86d132466eSBarry Smith .  its - iteration number
874b27c08aSLois Curfman McInnes .  fgnorm - 2-norm of residual
88f55353a2SBarry Smith -  dummy - a viewer
89d132466eSBarry Smith 
90*f6dfbefdSBarry Smith    Options Database Key:
91ee32d87aSMatthew G. Knepley .  -snes_monitor_solution_update [ascii binary draw][:filename][:viewer format] - plots update to solution at each iteration
92ee32d87aSMatthew G. Knepley 
93*f6dfbefdSBarry Smith    Note:
943a61192cSBarry Smith    This is not called directly by users, rather one calls `SNESMonitorSet()`, with this function as an argument, to cause the monitor
953a61192cSBarry Smith    to be used during the SNES solve.
963a61192cSBarry Smith 
97d132466eSBarry Smith    Level: intermediate
98d132466eSBarry Smith 
99*f6dfbefdSBarry Smith .seealso: `SNESMonitorSet()`, `SNESMonitorDefault()`, `VecView()`, `SNESMonitor()`, `SNESMonitor()`
100d132466eSBarry Smith @*/
1019371c9d4SSatish Balay PetscErrorCode SNESMonitorSolutionUpdate(SNES snes, PetscInt its, PetscReal fgnorm, PetscViewerAndFormat *vf) {
102d132466eSBarry Smith   Vec         x;
103d43b4f6eSBarry Smith   PetscViewer viewer = vf->viewer;
104d132466eSBarry Smith 
105d132466eSBarry Smith   PetscFunctionBegin;
1064d4332d5SBarry Smith   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 4);
1079566063dSJacob Faibussowitsch   PetscCall(SNESGetSolutionUpdate(snes, &x));
1089566063dSJacob Faibussowitsch   PetscCall(PetscViewerPushFormat(viewer, vf->format));
1099566063dSJacob Faibussowitsch   PetscCall(VecView(x, viewer));
1109566063dSJacob Faibussowitsch   PetscCall(PetscViewerPopFormat(viewer));
111d132466eSBarry Smith   PetscFunctionReturn(0);
112d132466eSBarry Smith }
113d132466eSBarry Smith 
114798534f6SMatthew G. Knepley #include <petscdraw.h>
115a5c2985bSBarry Smith 
116798534f6SMatthew G. Knepley /*@C
117*f6dfbefdSBarry Smith   KSPMonitorSNESResidual - Prints the `SNES` residual norm, as well as the `KSP` residual norm, at each iteration of an iterative solver.
118798534f6SMatthew G. Knepley 
119798534f6SMatthew G. Knepley   Collective on ksp
120a5c2985bSBarry Smith 
121a5c2985bSBarry Smith   Input Parameters:
122a5c2985bSBarry Smith + ksp   - iterative context
123a5c2985bSBarry Smith . n     - iteration number
124a5c2985bSBarry Smith . rnorm - 2-norm (preconditioned) residual value (may be estimated).
125798534f6SMatthew G. Knepley - vf    - The viewer context
126798534f6SMatthew G. Knepley 
127798534f6SMatthew G. Knepley   Options Database Key:
128*f6dfbefdSBarry Smith . -snes_monitor_ksp - Activates `KSPMonitorSNESResidual()`
129a5c2985bSBarry Smith 
130*f6dfbefdSBarry Smith    Note:
1313a61192cSBarry Smith    This is not called directly by users, rather one calls `KSPMonitorSet()`, with this function as an argument, to cause the monitor
1323a61192cSBarry Smith    to be used during the KSP solve.
1333a61192cSBarry Smith 
134a5c2985bSBarry Smith   Level: intermediate
135a5c2985bSBarry Smith 
136*f6dfbefdSBarry Smith .seealso: `KSPMonitorSet()`, `KSPMonitorResidual()`, `KSPMonitorTrueResidualMaxNorm()`, `KSPMonitor()`, `SNESMonitor()`
137a5c2985bSBarry Smith @*/
1389371c9d4SSatish Balay PetscErrorCode KSPMonitorSNESResidual(KSP ksp, PetscInt n, PetscReal rnorm, PetscViewerAndFormat *vf) {
139798534f6SMatthew G. Knepley   PetscViewer       viewer = vf->viewer;
140798534f6SMatthew G. Knepley   PetscViewerFormat format = vf->format;
141798534f6SMatthew G. Knepley   SNES              snes   = (SNES)vf->data;
142a5c2985bSBarry Smith   Vec               snes_solution, work1, work2;
143a5c2985bSBarry Smith   PetscReal         snorm;
144798534f6SMatthew G. Knepley   PetscInt          tablevel;
145798534f6SMatthew G. Knepley   const char       *prefix;
146a5c2985bSBarry Smith 
147a5c2985bSBarry Smith   PetscFunctionBegin;
148798534f6SMatthew G. Knepley   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 4);
1499566063dSJacob Faibussowitsch   PetscCall(SNESGetSolution(snes, &snes_solution));
1509566063dSJacob Faibussowitsch   PetscCall(VecDuplicate(snes_solution, &work1));
1519566063dSJacob Faibussowitsch   PetscCall(VecDuplicate(snes_solution, &work2));
1529566063dSJacob Faibussowitsch   PetscCall(KSPBuildSolution(ksp, work1, NULL));
1539566063dSJacob Faibussowitsch   PetscCall(VecAYPX(work1, -1.0, snes_solution));
1549566063dSJacob Faibussowitsch   PetscCall(SNESComputeFunction(snes, work1, work2));
1559566063dSJacob Faibussowitsch   PetscCall(VecNorm(work2, NORM_2, &snorm));
1569566063dSJacob Faibussowitsch   PetscCall(VecDestroy(&work1));
1579566063dSJacob Faibussowitsch   PetscCall(VecDestroy(&work2));
158a5c2985bSBarry Smith 
1599566063dSJacob Faibussowitsch   PetscCall(PetscObjectGetTabLevel((PetscObject)ksp, &tablevel));
1609566063dSJacob Faibussowitsch   PetscCall(PetscObjectGetOptionsPrefix((PetscObject)ksp, &prefix));
1619566063dSJacob Faibussowitsch   PetscCall(PetscViewerPushFormat(viewer, format));
1629566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIIAddTab(viewer, tablevel));
1639566063dSJacob Faibussowitsch   if (n == 0 && prefix) PetscCall(PetscViewerASCIIPrintf(viewer, "  Residual norms for %s solve.\n", prefix));
16463a3b9bcSJacob Faibussowitsch   PetscCall(PetscViewerASCIIPrintf(viewer, "%3" PetscInt_FMT " SNES Residual norm %5.3e KSP Residual norm %5.3e \n", n, (double)snorm, (double)rnorm));
1659566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIISubtractTab(viewer, tablevel));
1669566063dSJacob Faibussowitsch   PetscCall(PetscViewerPopFormat(viewer));
167a5c2985bSBarry Smith   PetscFunctionReturn(0);
168a5c2985bSBarry Smith }
169a5c2985bSBarry Smith 
170e5f7ee39SBarry Smith /*@C
171*f6dfbefdSBarry Smith   KSPMonitorSNESResidualDrawLG - Plots the linear `KSP` residual norm and the `SNES` residual norm at each iteration of an iterative solver.
172e5f7ee39SBarry Smith 
173798534f6SMatthew G. Knepley   Collective on ksp
174e5f7ee39SBarry Smith 
175e5f7ee39SBarry Smith   Input Parameters:
176798534f6SMatthew G. Knepley + ksp   - iterative context
177798534f6SMatthew G. Knepley . n     - iteration number
178798534f6SMatthew G. Knepley . rnorm - 2-norm (preconditioned) residual value (may be estimated).
179*f6dfbefdSBarry Smith - vf    - The viewer context, created with `KSPMonitorSNESResidualDrawLGCreate()`
180e5f7ee39SBarry Smith 
181e5f7ee39SBarry Smith   Options Database Key:
182*f6dfbefdSBarry Smith . -snes_monitor_ksp draw::draw_lg - Activates `KSPMonitorSNESResidualDrawLG()`
183e5f7ee39SBarry Smith 
184*f6dfbefdSBarry Smith    Note:
1853a61192cSBarry Smith    This is not called directly by users, rather one calls `SNESMonitorSet()`, with this function as an argument, to cause the monitor
186*f6dfbefdSBarry Smith    to be used during the `SNESSolve()`
1873a61192cSBarry Smith 
188e5f7ee39SBarry Smith   Level: intermediate
189e5f7ee39SBarry Smith 
190*f6dfbefdSBarry Smith .seealso: `KSPMonitorSet()`, `KSPMonitorTrueResidual()`, `SNESMonitor()`, `KSPMonitor()`, `KSPMonitorSNESResidualDrawLGCreate()`
191e5f7ee39SBarry Smith @*/
1929371c9d4SSatish Balay PetscErrorCode KSPMonitorSNESResidualDrawLG(KSP ksp, PetscInt n, PetscReal rnorm, PetscViewerAndFormat *vf) {
193798534f6SMatthew G. Knepley   PetscViewer        viewer = vf->viewer;
194798534f6SMatthew G. Knepley   PetscViewerFormat  format = vf->format;
195798534f6SMatthew G. Knepley   PetscDrawLG        lg     = vf->lg;
196798534f6SMatthew G. Knepley   SNES               snes   = (SNES)vf->data;
197e5f7ee39SBarry Smith   Vec                snes_solution, work1, work2;
198798534f6SMatthew G. Knepley   PetscReal          snorm;
199798534f6SMatthew G. Knepley   KSPConvergedReason reason;
200798534f6SMatthew G. Knepley   PetscReal          x[2], y[2];
201e5f7ee39SBarry Smith 
202e5f7ee39SBarry Smith   PetscFunctionBegin;
203798534f6SMatthew G. Knepley   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 4);
204064a246eSJacob Faibussowitsch   PetscValidHeaderSpecific(lg, PETSC_DRAWLG_CLASSID, 4);
2059566063dSJacob Faibussowitsch   PetscCall(SNESGetSolution(snes, &snes_solution));
2069566063dSJacob Faibussowitsch   PetscCall(VecDuplicate(snes_solution, &work1));
2079566063dSJacob Faibussowitsch   PetscCall(VecDuplicate(snes_solution, &work2));
2089566063dSJacob Faibussowitsch   PetscCall(KSPBuildSolution(ksp, work1, NULL));
2099566063dSJacob Faibussowitsch   PetscCall(VecAYPX(work1, -1.0, snes_solution));
2109566063dSJacob Faibussowitsch   PetscCall(SNESComputeFunction(snes, work1, work2));
2119566063dSJacob Faibussowitsch   PetscCall(VecNorm(work2, NORM_2, &snorm));
2129566063dSJacob Faibussowitsch   PetscCall(VecDestroy(&work1));
2139566063dSJacob Faibussowitsch   PetscCall(VecDestroy(&work2));
214e5f7ee39SBarry Smith 
2159566063dSJacob Faibussowitsch   PetscCall(PetscViewerPushFormat(viewer, format));
2169566063dSJacob Faibussowitsch   if (!n) PetscCall(PetscDrawLGReset(lg));
217798534f6SMatthew G. Knepley   x[0] = (PetscReal)n;
218798534f6SMatthew G. Knepley   if (rnorm > 0.0) y[0] = PetscLog10Real(rnorm);
219798534f6SMatthew G. Knepley   else y[0] = -15.0;
220798534f6SMatthew G. Knepley   x[1] = (PetscReal)n;
221798534f6SMatthew G. Knepley   if (snorm > 0.0) y[1] = PetscLog10Real(snorm);
222798534f6SMatthew G. Knepley   else y[1] = -15.0;
2239566063dSJacob Faibussowitsch   PetscCall(PetscDrawLGAddPoint(lg, x, y));
2249566063dSJacob Faibussowitsch   PetscCall(KSPGetConvergedReason(ksp, &reason));
225798534f6SMatthew G. Knepley   if (n <= 20 || !(n % 5) || reason) {
2269566063dSJacob Faibussowitsch     PetscCall(PetscDrawLGDraw(lg));
2279566063dSJacob Faibussowitsch     PetscCall(PetscDrawLGSave(lg));
228e5f7ee39SBarry Smith   }
2299566063dSJacob Faibussowitsch   PetscCall(PetscViewerPopFormat(viewer));
230e5f7ee39SBarry Smith   PetscFunctionReturn(0);
231e5f7ee39SBarry Smith }
232e5f7ee39SBarry Smith 
233798534f6SMatthew G. Knepley /*@C
234*f6dfbefdSBarry Smith   KSPMonitorSNESResidualDrawLGCreate - Creates the `PetscViewer` used by `KSPMonitorSNESResidualDrawLG()`
235e5f7ee39SBarry Smith 
236798534f6SMatthew G. Knepley   Collective on ksp
237e5f7ee39SBarry Smith 
238798534f6SMatthew G. Knepley   Input Parameters:
239b693eab9SMatthew G. Knepley + viewer - The PetscViewer
240798534f6SMatthew G. Knepley . format - The viewer format
241798534f6SMatthew G. Knepley - ctx    - An optional user context
242798534f6SMatthew G. Knepley 
243798534f6SMatthew G. Knepley   Output Parameter:
244798534f6SMatthew G. Knepley . vf    - The viewer context
245e5f7ee39SBarry Smith 
246e5f7ee39SBarry Smith   Level: intermediate
247e5f7ee39SBarry Smith 
248*f6dfbefdSBarry Smith .seealso: `KSP`, `SNES`, `KSPMonitorSet()`, `KSPMonitorTrueResidual()`
249e5f7ee39SBarry Smith @*/
2509371c9d4SSatish Balay PetscErrorCode KSPMonitorSNESResidualDrawLGCreate(PetscViewer viewer, PetscViewerFormat format, void *ctx, PetscViewerAndFormat **vf) {
251798534f6SMatthew G. Knepley   const char *names[] = {"linear", "nonlinear"};
252e5f7ee39SBarry Smith 
253e5f7ee39SBarry Smith   PetscFunctionBegin;
2549566063dSJacob Faibussowitsch   PetscCall(PetscViewerAndFormatCreate(viewer, format, vf));
255798534f6SMatthew G. Knepley   (*vf)->data = ctx;
2569566063dSJacob Faibussowitsch   PetscCall(KSPMonitorLGCreate(PetscObjectComm((PetscObject)viewer), NULL, NULL, "Log Residual Norm", 2, names, PETSC_DECIDE, PETSC_DECIDE, 400, 300, &(*vf)->lg));
257e5f7ee39SBarry Smith   PetscFunctionReturn(0);
258e5f7ee39SBarry Smith }
259e5f7ee39SBarry Smith 
2609371c9d4SSatish Balay PetscErrorCode SNESMonitorDefaultSetUp(SNES snes, PetscViewerAndFormat *vf) {
261fbcc4530SMatthew G. Knepley   PetscFunctionBegin;
26248a46eb9SPierre Jolivet   if (vf->format == PETSC_VIEWER_DRAW_LG) PetscCall(KSPMonitorLGCreate(PetscObjectComm((PetscObject)vf->viewer), NULL, NULL, "Log Residual Norm", 1, NULL, PETSC_DECIDE, PETSC_DECIDE, 400, 300, &vf->lg));
263fbcc4530SMatthew G. Knepley   PetscFunctionReturn(0);
264fbcc4530SMatthew G. Knepley }
265fbcc4530SMatthew G. Knepley 
2664b828684SBarry Smith /*@C
267*f6dfbefdSBarry Smith    SNESMonitorDefault - Monitors progress of the `SNES` solvers (default).
268e7e93795SLois Curfman McInnes 
269*f6dfbefdSBarry Smith    Collective on snes
270c7afd0dbSLois Curfman McInnes 
271e7e93795SLois Curfman McInnes    Input Parameters:
272*f6dfbefdSBarry Smith +  snes - the `SNES` context
273e7e93795SLois Curfman McInnes .  its - iteration number
2744b27c08aSLois Curfman McInnes .  fgnorm - 2-norm of residual
275d43b4f6eSBarry Smith -  vf - viewer and format structure
276fee21e36SBarry Smith 
2773a61192cSBarry Smith    Options Database:
2783a61192cSBarry Smith .  -snes_monitor - use this function to monitor the convergence of the nonlinear solver
2793a61192cSBarry Smith 
280e7e93795SLois Curfman McInnes    Notes:
2814b27c08aSLois Curfman McInnes    This routine prints the residual norm at each iteration.
282e7e93795SLois Curfman McInnes 
2833a61192cSBarry Smith    This is not called directly by users, rather one calls `SNESMonitorSet()`, with this function as an argument, to cause the monitor
284*f6dfbefdSBarry Smith    to be used during the `SNES` solve.
2853a61192cSBarry Smith 
28636851e7fSLois Curfman McInnes    Level: intermediate
28736851e7fSLois Curfman McInnes 
2883a61192cSBarry Smith .seealso: `SNESMonitorSet()`, `SNESMonitorSolution()`, `SNESMonitorFunction()`, `SNESMonitorSolution()`, `SNESMonitorResidual()`,
2893a61192cSBarry Smith           `SNESMonitorSolutionUpdate()`, `SNESMonitorDefault()`, `SNESMonitorScaling()`, `SNESMonitorRange()`, `SNESMonitorRatio()`,
2903a61192cSBarry Smith           `SNESMonitorDefaultField()`
291e7e93795SLois Curfman McInnes @*/
2929371c9d4SSatish Balay PetscErrorCode SNESMonitorDefault(SNES snes, PetscInt its, PetscReal fgnorm, PetscViewerAndFormat *vf) {
293d43b4f6eSBarry Smith   PetscViewer       viewer = vf->viewer;
294798534f6SMatthew G. Knepley   PetscViewerFormat format = vf->format;
295798534f6SMatthew G. Knepley   PetscBool         isascii, isdraw;
296d132466eSBarry Smith 
2973a40ed3dSBarry Smith   PetscFunctionBegin;
2984d4332d5SBarry Smith   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 4);
2999566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &isascii));
3009566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERDRAW, &isdraw));
3019566063dSJacob Faibussowitsch   PetscCall(PetscViewerPushFormat(viewer, format));
302798534f6SMatthew G. Knepley   if (isascii) {
3039566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIAddTab(viewer, ((PetscObject)snes)->tablevel));
30463a3b9bcSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer, "%3" PetscInt_FMT " SNES Function norm %14.12e \n", its, (double)fgnorm));
3059566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIISubtractTab(viewer, ((PetscObject)snes)->tablevel));
306798534f6SMatthew G. Knepley   } else if (isdraw) {
307798534f6SMatthew G. Knepley     if (format == PETSC_VIEWER_DRAW_LG) {
308798534f6SMatthew G. Knepley       PetscDrawLG lg = (PetscDrawLG)vf->lg;
309798534f6SMatthew G. Knepley       PetscReal   x, y;
310798534f6SMatthew G. Knepley 
311798534f6SMatthew G. Knepley       PetscValidHeaderSpecific(lg, PETSC_DRAWLG_CLASSID, 4);
3129566063dSJacob Faibussowitsch       if (!its) PetscCall(PetscDrawLGReset(lg));
313798534f6SMatthew G. Knepley       x = (PetscReal)its;
314798534f6SMatthew G. Knepley       if (fgnorm > 0.0) y = PetscLog10Real(fgnorm);
315798534f6SMatthew G. Knepley       else y = -15.0;
3169566063dSJacob Faibussowitsch       PetscCall(PetscDrawLGAddPoint(lg, &x, &y));
317798534f6SMatthew G. Knepley       if (its <= 20 || !(its % 5) || snes->reason) {
3189566063dSJacob Faibussowitsch         PetscCall(PetscDrawLGDraw(lg));
3199566063dSJacob Faibussowitsch         PetscCall(PetscDrawLGSave(lg));
320798534f6SMatthew G. Knepley       }
321798534f6SMatthew G. Knepley     }
322798534f6SMatthew G. Knepley   }
3239566063dSJacob Faibussowitsch   PetscCall(PetscViewerPopFormat(viewer));
3243a40ed3dSBarry Smith   PetscFunctionReturn(0);
325e7e93795SLois Curfman McInnes }
3263f1db9ecSBarry Smith 
3271f60017eSBarry Smith /*@C
3281f60017eSBarry Smith    SNESMonitorScaling - Monitors the largest value in each row of the Jacobian.
3291f60017eSBarry Smith 
330*f6dfbefdSBarry Smith    Collective on snes
3311f60017eSBarry Smith 
3321f60017eSBarry Smith    Input Parameters:
333*f6dfbefdSBarry Smith +  snes - the `SNES` context
3341f60017eSBarry Smith .  its - iteration number
3351f60017eSBarry Smith .  fgnorm - 2-norm of residual
3361f60017eSBarry Smith -  vf - viewer and format structure
3371f60017eSBarry Smith 
3381f60017eSBarry Smith    Notes:
3391f60017eSBarry Smith    This routine prints the largest value in each row of the Jacobian
3401f60017eSBarry Smith 
3413a61192cSBarry Smith    This is not called directly by users, rather one calls `SNESMonitorSet()`, with this function as an argument, to cause the monitor
342*f6dfbefdSBarry Smith    to be used during the `SNES` solve.
3433a61192cSBarry Smith 
3441f60017eSBarry Smith    Level: intermediate
3451f60017eSBarry Smith 
346*f6dfbefdSBarry Smith .seealso: `SNESMonitorSet()`, `SNESMonitorSolution()`, `SNESMonitorRange()`, `SNESMonitorJacUpdateSpectrum()`
3471f60017eSBarry Smith @*/
3489371c9d4SSatish Balay PetscErrorCode SNESMonitorScaling(SNES snes, PetscInt its, PetscReal fgnorm, PetscViewerAndFormat *vf) {
3491f60017eSBarry Smith   PetscViewer viewer = vf->viewer;
3501f60017eSBarry Smith   KSP         ksp;
3511f60017eSBarry Smith   Mat         J;
3521f60017eSBarry Smith   Vec         v;
3531f60017eSBarry Smith 
3541f60017eSBarry Smith   PetscFunctionBegin;
3551f60017eSBarry Smith   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 4);
3569566063dSJacob Faibussowitsch   PetscCall(SNESGetKSP(snes, &ksp));
3579566063dSJacob Faibussowitsch   PetscCall(KSPGetOperators(ksp, &J, NULL));
3589566063dSJacob Faibussowitsch   PetscCall(MatCreateVecs(J, &v, NULL));
3599566063dSJacob Faibussowitsch   PetscCall(MatGetRowMaxAbs(J, v, NULL));
3609566063dSJacob Faibussowitsch   PetscCall(PetscViewerPushFormat(viewer, vf->format));
3619566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIIAddTab(viewer, ((PetscObject)snes)->tablevel));
36263a3b9bcSJacob Faibussowitsch   PetscCall(PetscViewerASCIIPrintf(viewer, "SNES Jacobian maximum row entries\n"));
3639566063dSJacob Faibussowitsch   PetscCall(VecView(v, viewer));
3649566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIISubtractTab(viewer, ((PetscObject)snes)->tablevel));
3659566063dSJacob Faibussowitsch   PetscCall(PetscViewerPopFormat(viewer));
3669566063dSJacob Faibussowitsch   PetscCall(VecDestroy(&v));
3671f60017eSBarry Smith   PetscFunctionReturn(0);
3681f60017eSBarry Smith }
3691f60017eSBarry Smith 
370*f6dfbefdSBarry Smith /*@C
371*f6dfbefdSBarry Smith    SNESMonitorJacUpdateSpectrum - Monitors the spectrun of the change in the Jacobian from the last Jacobian evaluation
372*f6dfbefdSBarry Smith 
373*f6dfbefdSBarry Smith    Collective on snes
374*f6dfbefdSBarry Smith 
375*f6dfbefdSBarry Smith    Input Parameters:
376*f6dfbefdSBarry Smith +  snes - the `SNES` context
377*f6dfbefdSBarry Smith .  its - iteration number
378*f6dfbefdSBarry Smith .  fgnorm - 2-norm of residual
379*f6dfbefdSBarry Smith -  vf - viewer and format structure
380*f6dfbefdSBarry Smith 
381*f6dfbefdSBarry Smith    Option Database Key:
382*f6dfbefdSBarry Smith .  -snes_monitor_jacupdate_spectrum - activates this monitor
383*f6dfbefdSBarry Smith 
384*f6dfbefdSBarry Smith    Notes:
385*f6dfbefdSBarry Smith    This routine prints the eigenvalues of the difference in the Jacobians
386*f6dfbefdSBarry Smith 
387*f6dfbefdSBarry Smith    This is not called directly by users, rather one calls `SNESMonitorSet()`, with this function as an argument, to cause the monitor
388*f6dfbefdSBarry Smith    to be used during the `SNES` solve.
389*f6dfbefdSBarry Smith 
390*f6dfbefdSBarry Smith    Level: intermediate
391*f6dfbefdSBarry Smith 
392*f6dfbefdSBarry Smith .seealso: `SNESMonitorSet()`, `SNESMonitorSolution()`, `SNESMonitorRange()`
393*f6dfbefdSBarry Smith @*/
3949371c9d4SSatish Balay PetscErrorCode SNESMonitorJacUpdateSpectrum(SNES snes, PetscInt it, PetscReal fnorm, PetscViewerAndFormat *vf) {
3952e7541e6SPeter Brune   Vec X;
3962e7541e6SPeter Brune   Mat J, dJ, dJdense;
397d1e9a80fSBarry Smith   PetscErrorCode (*func)(SNES, Vec, Mat, Mat, void *);
3982f96bde4SJose E. Roman   PetscInt     n;
39923fff9afSBarry Smith   PetscBLASInt nb = 0, lwork;
4002e7541e6SPeter Brune   PetscReal   *eigr, *eigi;
4012e7541e6SPeter Brune   PetscScalar *work;
4022e7541e6SPeter Brune   PetscScalar *a;
4032e7541e6SPeter Brune 
4042e7541e6SPeter Brune   PetscFunctionBegin;
4052e7541e6SPeter Brune   if (it == 0) PetscFunctionReturn(0);
406*f6dfbefdSBarry Smith   /* create the difference between the current update and the current Jacobian */
4079566063dSJacob Faibussowitsch   PetscCall(SNESGetSolution(snes, &X));
4089566063dSJacob Faibussowitsch   PetscCall(SNESGetJacobian(snes, NULL, &J, &func, NULL));
4099566063dSJacob Faibussowitsch   PetscCall(MatDuplicate(J, MAT_COPY_VALUES, &dJ));
4109566063dSJacob Faibussowitsch   PetscCall(SNESComputeJacobian(snes, X, dJ, dJ));
4119566063dSJacob Faibussowitsch   PetscCall(MatAXPY(dJ, -1.0, J, SAME_NONZERO_PATTERN));
412f5af7f23SKarl Rupp 
4132e7541e6SPeter Brune   /* compute the spectrum directly */
4149566063dSJacob Faibussowitsch   PetscCall(MatConvert(dJ, MATSEQDENSE, MAT_INITIAL_MATRIX, &dJdense));
4159566063dSJacob Faibussowitsch   PetscCall(MatGetSize(dJ, &n, NULL));
4169566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(n, &nb));
4172e7541e6SPeter Brune   lwork = 3 * nb;
4189566063dSJacob Faibussowitsch   PetscCall(PetscMalloc1(n, &eigr));
4199566063dSJacob Faibussowitsch   PetscCall(PetscMalloc1(n, &eigi));
4209566063dSJacob Faibussowitsch   PetscCall(PetscMalloc1(lwork, &work));
4219566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArray(dJdense, &a));
4222e7541e6SPeter Brune #if !defined(PETSC_USE_COMPLEX)
4232e7541e6SPeter Brune   {
4242e7541e6SPeter Brune     PetscBLASInt lierr;
4252f96bde4SJose E. Roman     PetscInt     i;
4269566063dSJacob Faibussowitsch     PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF));
427792fecdfSBarry Smith     PetscCallBLAS("LAPACKgeev", LAPACKgeev_("N", "N", &nb, a, &nb, eigr, eigi, NULL, &nb, NULL, &nb, work, &lwork, &lierr));
42863a3b9bcSJacob Faibussowitsch     PetscCheck(!lierr, PETSC_COMM_SELF, PETSC_ERR_LIB, "geev() error %" PetscBLASInt_FMT, lierr);
4299566063dSJacob Faibussowitsch     PetscCall(PetscFPTrapPop());
43063a3b9bcSJacob Faibussowitsch     PetscCall(PetscPrintf(PetscObjectComm((PetscObject)snes), "Eigenvalues of J_%" PetscInt_FMT " - J_%" PetscInt_FMT ":\n", it, it - 1));
43148a46eb9SPierre 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]));
4322f96bde4SJose E. Roman   }
4339566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArray(dJdense, &a));
4349566063dSJacob Faibussowitsch   PetscCall(MatDestroy(&dJ));
4359566063dSJacob Faibussowitsch   PetscCall(MatDestroy(&dJdense));
4369566063dSJacob Faibussowitsch   PetscCall(PetscFree(eigr));
4379566063dSJacob Faibussowitsch   PetscCall(PetscFree(eigi));
4389566063dSJacob Faibussowitsch   PetscCall(PetscFree(work));
4392e7541e6SPeter Brune   PetscFunctionReturn(0);
4402f96bde4SJose E. Roman #else
4412f96bde4SJose E. Roman   SETERRQ(PETSC_COMM_SELF, PETSC_ERR_SUP, "Not coded for complex");
4422f96bde4SJose E. Roman #endif
4432e7541e6SPeter Brune }
4442e7541e6SPeter Brune 
4456ba87a44SLisandro Dalcin PETSC_INTERN PetscErrorCode SNESMonitorRange_Private(SNES, PetscInt, PetscReal *);
4466ba87a44SLisandro Dalcin 
4479371c9d4SSatish Balay PetscErrorCode SNESMonitorRange_Private(SNES snes, PetscInt it, PetscReal *per) {
448b271bb04SBarry Smith   Vec          resid;
449b271bb04SBarry Smith   PetscReal    rmax, pwork;
450b271bb04SBarry Smith   PetscInt     i, n, N;
451b271bb04SBarry Smith   PetscScalar *r;
452b271bb04SBarry Smith 
453b271bb04SBarry Smith   PetscFunctionBegin;
4549566063dSJacob Faibussowitsch   PetscCall(SNESGetFunction(snes, &resid, NULL, NULL));
4559566063dSJacob Faibussowitsch   PetscCall(VecNorm(resid, NORM_INFINITY, &rmax));
4569566063dSJacob Faibussowitsch   PetscCall(VecGetLocalSize(resid, &n));
4579566063dSJacob Faibussowitsch   PetscCall(VecGetSize(resid, &N));
4589566063dSJacob Faibussowitsch   PetscCall(VecGetArray(resid, &r));
459b271bb04SBarry Smith   pwork = 0.0;
460ad540459SPierre Jolivet   for (i = 0; i < n; i++) pwork += (PetscAbsScalar(r[i]) > .20 * rmax);
4611c2dc1cbSBarry Smith   PetscCall(MPIU_Allreduce(&pwork, per, 1, MPIU_REAL, MPIU_SUM, PetscObjectComm((PetscObject)snes)));
4629566063dSJacob Faibussowitsch   PetscCall(VecRestoreArray(resid, &r));
463b271bb04SBarry Smith   *per = *per / N;
464b271bb04SBarry Smith   PetscFunctionReturn(0);
465b271bb04SBarry Smith }
466b271bb04SBarry Smith 
467b271bb04SBarry Smith /*@C
468*f6dfbefdSBarry Smith    SNESMonitorRange - Prints the percentage of residual elements that are more then 10 percent of the maximum entry in the residual
469b271bb04SBarry Smith 
470*f6dfbefdSBarry Smith    Collective on snes
471b271bb04SBarry Smith 
472b271bb04SBarry Smith    Input Parameters:
473b271bb04SBarry Smith +  snes   - iterative context
474b271bb04SBarry Smith .  it    - iteration number
475b271bb04SBarry Smith .  rnorm - 2-norm (preconditioned) residual value (may be estimated).
476b271bb04SBarry Smith -  dummy - unused monitor context
477b271bb04SBarry Smith 
478b271bb04SBarry Smith    Options Database Key:
479*f6dfbefdSBarry Smith .  -snes_monitor_range - Activates `SNESMonitorRange()`
480b271bb04SBarry Smith 
481*f6dfbefdSBarry Smith    Note:
4823a61192cSBarry Smith    This is not called directly by users, rather one calls `SNESMonitorSet()`, with this function as an argument, to cause the monitor
483*f6dfbefdSBarry Smith    to be used during the `SNES` solve.
4843a61192cSBarry Smith 
485b271bb04SBarry Smith    Level: intermediate
486b271bb04SBarry Smith 
487*f6dfbefdSBarry Smith .seealso: `SNESMonitorSet()`, `SNESMonitorDefault()`, `SNESMonitorLGCreate()`, `SNESMonitorScaling()`
488b271bb04SBarry Smith @*/
4899371c9d4SSatish Balay PetscErrorCode SNESMonitorRange(SNES snes, PetscInt it, PetscReal rnorm, PetscViewerAndFormat *vf) {
490b271bb04SBarry Smith   PetscReal        perc, rel;
491d43b4f6eSBarry Smith   PetscViewer      viewer = vf->viewer;
492b271bb04SBarry Smith   /* should be in a MonitorRangeContext */
493b271bb04SBarry Smith   static PetscReal prev;
494b271bb04SBarry Smith 
495b271bb04SBarry Smith   PetscFunctionBegin;
4964d4332d5SBarry Smith   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 4);
497b271bb04SBarry Smith   if (!it) prev = rnorm;
4989566063dSJacob Faibussowitsch   PetscCall(SNESMonitorRange_Private(snes, it, &perc));
499b271bb04SBarry Smith 
500b271bb04SBarry Smith   rel  = (prev - rnorm) / prev;
501b271bb04SBarry Smith   prev = rnorm;
5029566063dSJacob Faibussowitsch   PetscCall(PetscViewerPushFormat(viewer, vf->format));
5039566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIIAddTab(viewer, ((PetscObject)snes)->tablevel));
50463a3b9bcSJacob 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)));
5059566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIISubtractTab(viewer, ((PetscObject)snes)->tablevel));
5069566063dSJacob Faibussowitsch   PetscCall(PetscViewerPopFormat(viewer));
507b271bb04SBarry Smith   PetscFunctionReturn(0);
508b271bb04SBarry Smith }
509b271bb04SBarry Smith 
5103a7fca6bSBarry Smith /*@C
511*f6dfbefdSBarry Smith    SNESMonitorRatio - Monitors progress of the `SNES` solvers by printing the ratio
5124b27c08aSLois Curfman McInnes    of residual norm at each iteration to the previous.
5133a7fca6bSBarry Smith 
514*f6dfbefdSBarry Smith    Collective on snes
5153a7fca6bSBarry Smith 
5163a7fca6bSBarry Smith    Input Parameters:
517*f6dfbefdSBarry Smith +  snes - the `SNES` context
5183a7fca6bSBarry Smith .  its - iteration number
5193a7fca6bSBarry Smith .  fgnorm - 2-norm of residual (or gradient)
520eabae89aSBarry Smith -  dummy -  context of monitor
5213a7fca6bSBarry Smith 
522*f6dfbefdSBarry Smith    Option Database Key:
523*f6dfbefdSBarry Smith .  -snes_monitor_ratio - activate this monitor
524*f6dfbefdSBarry Smith 
5253a7fca6bSBarry Smith    Level: intermediate
5263a7fca6bSBarry Smith 
52795452b02SPatrick Sanan    Notes:
5283a61192cSBarry Smith    This is not called directly by users, rather one calls `SNESMonitorSet()`, with this function as an argument, to cause the monitor
529*f6dfbefdSBarry Smith    to be used during the `SNES` solve.
5303a61192cSBarry Smith 
531*f6dfbefdSBarry Smith    Be sure to call `SNESMonitorRationSetUp()` before using this monitor.
5323a61192cSBarry Smith 
533*f6dfbefdSBarry Smith .seealso: `SNESMonitorRationSetUp()`, `SNESMonitorSet()`, `SNESMonitorSolution()`, `SNESMonitorDefault()`
5343a7fca6bSBarry Smith @*/
5359371c9d4SSatish Balay PetscErrorCode SNESMonitorRatio(SNES snes, PetscInt its, PetscReal fgnorm, PetscViewerAndFormat *vf) {
53677431f27SBarry Smith   PetscInt    len;
53787828ca2SBarry Smith   PetscReal  *history;
538d43b4f6eSBarry Smith   PetscViewer viewer = vf->viewer;
5393a7fca6bSBarry Smith 
5403a7fca6bSBarry Smith   PetscFunctionBegin;
5419566063dSJacob Faibussowitsch   PetscCall(SNESGetConvergenceHistory(snes, &history, NULL, &len));
5429566063dSJacob Faibussowitsch   PetscCall(PetscViewerPushFormat(viewer, vf->format));
5439566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIIAddTab(viewer, ((PetscObject)snes)->tablevel));
544958c9bccSBarry Smith   if (!its || !history || its > len) {
54563a3b9bcSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer, "%3" PetscInt_FMT " SNES Function norm %14.12e \n", its, (double)fgnorm));
5463a7fca6bSBarry Smith   } else {
54787828ca2SBarry Smith     PetscReal ratio = fgnorm / history[its - 1];
54863a3b9bcSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer, "%3" PetscInt_FMT " SNES Function norm %14.12e %14.12e \n", its, (double)fgnorm, (double)ratio));
5493a7fca6bSBarry Smith   }
5509566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIISubtractTab(viewer, ((PetscObject)snes)->tablevel));
5519566063dSJacob Faibussowitsch   PetscCall(PetscViewerPopFormat(viewer));
5523a7fca6bSBarry Smith   PetscFunctionReturn(0);
5533a7fca6bSBarry Smith }
5543a7fca6bSBarry Smith 
5553a7fca6bSBarry Smith /*@C
556*f6dfbefdSBarry Smith    SNESMonitorRatioSetUp - Insures the `SNES` object is saving its history since this monitor needs access to it
5573a7fca6bSBarry Smith 
558*f6dfbefdSBarry Smith    Collective on snes
5593a7fca6bSBarry Smith 
5603a7fca6bSBarry Smith    Input Parameters:
561*f6dfbefdSBarry Smith +   snes - the `SNES` context
562*f6dfbefdSBarry Smith -   viewer - the `PetscViewer` object (ignored)
5633a7fca6bSBarry Smith 
5643a7fca6bSBarry Smith    Level: intermediate
5653a7fca6bSBarry Smith 
566db781477SPatrick Sanan .seealso: `SNESMonitorSet()`, `SNESMonitorSolution()`, `SNESMonitorDefault()`, `SNESMonitorRatio()`
5673a7fca6bSBarry Smith @*/
5689371c9d4SSatish Balay PetscErrorCode SNESMonitorRatioSetUp(SNES snes, PetscViewerAndFormat *vf) {
56987828ca2SBarry Smith   PetscReal *history;
5703a7fca6bSBarry Smith 
5713a7fca6bSBarry Smith   PetscFunctionBegin;
5729566063dSJacob Faibussowitsch   PetscCall(SNESGetConvergenceHistory(snes, &history, NULL, NULL));
57348a46eb9SPierre Jolivet   if (!history) PetscCall(SNESSetConvergenceHistory(snes, NULL, NULL, 100, PETSC_TRUE));
5743a7fca6bSBarry Smith   PetscFunctionReturn(0);
5753a7fca6bSBarry Smith }
5763a7fca6bSBarry Smith 
577be1f7002SBarry Smith /*
578a6570f20SBarry Smith      Default (short) SNES Monitor, same as SNESMonitorDefault() except
579be1f7002SBarry Smith   it prints fewer digits of the residual as the residual gets smaller.
580be1f7002SBarry Smith   This is because the later digits are meaningless and are often
581be1f7002SBarry Smith   different on different machines; by using this routine different
582be1f7002SBarry Smith   machines will usually generate the same output.
583dec21524SBarry Smith 
584dec21524SBarry Smith   Deprecated: Intentionally has no manual page
585be1f7002SBarry Smith */
5869371c9d4SSatish Balay PetscErrorCode SNESMonitorDefaultShort(SNES snes, PetscInt its, PetscReal fgnorm, PetscViewerAndFormat *vf) {
587d43b4f6eSBarry Smith   PetscViewer viewer = vf->viewer;
588d132466eSBarry Smith 
5893a40ed3dSBarry Smith   PetscFunctionBegin;
5904d4332d5SBarry Smith   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 4);
5919566063dSJacob Faibussowitsch   PetscCall(PetscViewerPushFormat(viewer, vf->format));
5929566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIIAddTab(viewer, ((PetscObject)snes)->tablevel));
5938f240d10SBarry Smith   if (fgnorm > 1.e-9) {
59463a3b9bcSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer, "%3" PetscInt_FMT " SNES Function norm %g \n", its, (double)fgnorm));
5953a40ed3dSBarry Smith   } else if (fgnorm > 1.e-11) {
59663a3b9bcSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer, "%3" PetscInt_FMT " SNES Function norm %5.3e \n", its, (double)fgnorm));
5973a40ed3dSBarry Smith   } else {
59863a3b9bcSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer, "%3" PetscInt_FMT " SNES Function norm < 1.e-11\n", its));
599a34d58ebSBarry Smith   }
6009566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIISubtractTab(viewer, ((PetscObject)snes)->tablevel));
6019566063dSJacob Faibussowitsch   PetscCall(PetscViewerPopFormat(viewer));
6023a40ed3dSBarry Smith   PetscFunctionReturn(0);
603e7e93795SLois Curfman McInnes }
6042db13446SMatthew G. Knepley 
6052db13446SMatthew G. Knepley /*@C
606*f6dfbefdSBarry Smith   SNESMonitorDefaultField - Monitors progress of the `SNES` solvers, separated into fields.
6072db13446SMatthew G. Knepley 
608*f6dfbefdSBarry Smith   Collective on snes
6092db13446SMatthew G. Knepley 
6102db13446SMatthew G. Knepley   Input Parameters:
611*f6dfbefdSBarry Smith + snes   - the `SNES` context
6122db13446SMatthew G. Knepley . its    - iteration number
6132db13446SMatthew G. Knepley . fgnorm - 2-norm of residual
6142db13446SMatthew G. Knepley - ctx    - the PetscViewer
6152db13446SMatthew G. Knepley 
616*f6dfbefdSBarry Smith    Option Database Key:
617*f6dfbefdSBarry Smith .  -snes_monitor_field - activate this monitor
618*f6dfbefdSBarry Smith 
6192db13446SMatthew G. Knepley   Notes:
620*f6dfbefdSBarry Smith   This routine uses the `DM` attached to the residual vector to define the fields.
6213a61192cSBarry Smith 
6223a61192cSBarry Smith   This is not called directly by users, rather one calls `SNESMonitorSet()`, with this function as an argument, to cause the monitor
623*f6dfbefdSBarry Smith   to be used during the `SNES` solve.
6242db13446SMatthew G. Knepley 
6252db13446SMatthew G. Knepley   Level: intermediate
6262db13446SMatthew G. Knepley 
627db781477SPatrick Sanan .seealso: `SNESMonitorSet()`, `SNESMonitorSolution()`, `SNESMonitorDefault()`
6282db13446SMatthew G. Knepley @*/
6299371c9d4SSatish Balay PetscErrorCode SNESMonitorDefaultField(SNES snes, PetscInt its, PetscReal fgnorm, PetscViewerAndFormat *vf) {
630d43b4f6eSBarry Smith   PetscViewer viewer = vf->viewer;
6312db13446SMatthew G. Knepley   Vec         r;
6322db13446SMatthew G. Knepley   DM          dm;
6332db13446SMatthew G. Knepley   PetscReal   res[256];
6342db13446SMatthew G. Knepley   PetscInt    tablevel;
6352db13446SMatthew G. Knepley 
6362db13446SMatthew G. Knepley   PetscFunctionBegin;
6374d4332d5SBarry Smith   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 4);
6389566063dSJacob Faibussowitsch   PetscCall(SNESGetFunction(snes, &r, NULL, NULL));
6399566063dSJacob Faibussowitsch   PetscCall(VecGetDM(r, &dm));
6409566063dSJacob Faibussowitsch   if (!dm) PetscCall(SNESMonitorDefault(snes, its, fgnorm, vf));
6412db13446SMatthew G. Knepley   else {
6422db13446SMatthew G. Knepley     PetscSection s, gs;
6432db13446SMatthew G. Knepley     PetscInt     Nf, f;
6442db13446SMatthew G. Knepley 
6459566063dSJacob Faibussowitsch     PetscCall(DMGetLocalSection(dm, &s));
6469566063dSJacob Faibussowitsch     PetscCall(DMGetGlobalSection(dm, &gs));
6479566063dSJacob Faibussowitsch     if (!s || !gs) PetscCall(SNESMonitorDefault(snes, its, fgnorm, vf));
6489566063dSJacob Faibussowitsch     PetscCall(PetscSectionGetNumFields(s, &Nf));
64963a3b9bcSJacob Faibussowitsch     PetscCheck(Nf <= 256, PetscObjectComm((PetscObject)snes), PETSC_ERR_SUP, "Do not support %" PetscInt_FMT " fields > 256", Nf);
6509566063dSJacob Faibussowitsch     PetscCall(PetscSectionVecNorm(s, gs, r, NORM_2, res));
6519566063dSJacob Faibussowitsch     PetscCall(PetscObjectGetTabLevel((PetscObject)snes, &tablevel));
6529566063dSJacob Faibussowitsch     PetscCall(PetscViewerPushFormat(viewer, vf->format));
6539566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIAddTab(viewer, tablevel));
65463a3b9bcSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer, "%3" PetscInt_FMT " SNES Function norm %14.12e [", its, (double)fgnorm));
6552db13446SMatthew G. Knepley     for (f = 0; f < Nf; ++f) {
6569566063dSJacob Faibussowitsch       if (f) PetscCall(PetscViewerASCIIPrintf(viewer, ", "));
65763a3b9bcSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(viewer, "%14.12e", (double)res[f]));
6582db13446SMatthew G. Knepley     }
6599566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer, "] \n"));
6609566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIISubtractTab(viewer, tablevel));
6619566063dSJacob Faibussowitsch     PetscCall(PetscViewerPopFormat(viewer));
6622db13446SMatthew G. Knepley   }
6632db13446SMatthew G. Knepley   PetscFunctionReturn(0);
6642db13446SMatthew G. Knepley }
665*f6dfbefdSBarry Smith 
6664b828684SBarry Smith /*@C
667c34cbdceSBarry Smith    SNESConvergedDefault - Default onvergence test of the solvers for
668c34cbdceSBarry Smith    systems of nonlinear equations.
669e7e93795SLois Curfman McInnes 
670*f6dfbefdSBarry Smith    Collective on snes
671c7afd0dbSLois Curfman McInnes 
672e7e93795SLois Curfman McInnes    Input Parameters:
673*f6dfbefdSBarry Smith +  snes - the `SNES` context
67406ee9f85SBarry Smith .  it - the iteration (0 indicates before any Newton steps)
675e7e93795SLois Curfman McInnes .  xnorm - 2-norm of current iterate
676c60f73f4SPeter Brune .  snorm - 2-norm of current step
6777f3332b4SBarry Smith .  fnorm - 2-norm of function at current iterate
678c7afd0dbSLois Curfman McInnes -  dummy - unused context
679e7e93795SLois Curfman McInnes 
680184914b5SBarry Smith    Output Parameter:
681184914b5SBarry Smith .   reason  - one of
682*f6dfbefdSBarry Smith .vb
683*f6dfbefdSBarry Smith    SNES_CONVERGED_FNORM_ABS       - (fnorm < abstol),
684*f6dfbefdSBarry Smith    SNES_CONVERGED_SNORM_RELATIVE  - (snorm < stol*xnorm),
685*f6dfbefdSBarry Smith    SNES_CONVERGED_FNORM_RELATIVE  - (fnorm < rtol*fnorm0),
686*f6dfbefdSBarry Smith    SNES_DIVERGED_FUNCTION_COUNT   - (nfct > maxf),
687*f6dfbefdSBarry Smith    SNES_DIVERGED_FNORM_NAN        - (fnorm == NaN),
688*f6dfbefdSBarry Smith    SNES_CONVERGED_ITERATING       - (otherwise),
689*f6dfbefdSBarry Smith    SNES_DIVERGED_DTOL             - (fnorm > divtol*snes->fnorm0)
690*f6dfbefdSBarry Smith .ve
691e7e93795SLois Curfman McInnes 
692e7e93795SLois Curfman McInnes    where
693*f6dfbefdSBarry Smith +    maxf - maximum number of function evaluations,  set with `SNESSetTolerances()`
694c7afd0dbSLois Curfman McInnes .    nfct - number of function evaluations,
695*f6dfbefdSBarry Smith .    abstol - absolute function norm tolerance, set with `SNESSetTolerances()`
696*f6dfbefdSBarry Smith .    rtol - relative function norm tolerance, set with `SNESSetTolerances()`
697*f6dfbefdSBarry Smith .    divtol - divergence tolerance, set with `SNESSetDivergenceTolerance()`
698c34cbdceSBarry Smith -    fnorm0 - 2-norm of the function at the initial solution (initial guess; zeroth iteration)
699c34cbdceSBarry Smith 
700c34cbdceSBarry Smith   Options Database Keys:
701*f6dfbefdSBarry Smith +  -snes_convergence_test default - see `SNESSetFromOptions()`
702f362779dSJed Brown .  -snes_stol - convergence tolerance in terms of the norm  of the change in the solution between steps
703c34cbdceSBarry Smith .  -snes_atol <abstol> - absolute tolerance of residual norm
704c34cbdceSBarry Smith .  -snes_rtol <rtol> - relative decrease in tolerance norm from the initial 2-norm of the solution
705c34cbdceSBarry Smith .  -snes_divergence_tolerance <divtol> - if the residual goes above divtol*rnorm0, exit with divergence
706c34cbdceSBarry Smith .  -snes_max_funcs <max_funcs> - maximum number of function evaluations
707c34cbdceSBarry Smith .  -snes_max_fail <max_fail> - maximum number of line search failures allowed before stopping, default is none
708*f6dfbefdSBarry Smith -  -snes_max_linear_solve_fail - number of linear solver failures before `SNESSolve()` stops
709fee21e36SBarry Smith 
71036851e7fSLois Curfman McInnes    Level: intermediate
71136851e7fSLois Curfman McInnes 
712*f6dfbefdSBarry Smith .seealso: `SNES`, `SNESSolve()`, `SNESSetConvergenceTest()`, `SNESConvergedSkip()`, `SNESSetTolerances()`, `SNESSetDivergenceTolerance()`
713e7e93795SLois Curfman McInnes @*/
7149371c9d4SSatish Balay PetscErrorCode SNESConvergedDefault(SNES snes, PetscInt it, PetscReal xnorm, PetscReal snorm, PetscReal fnorm, SNESConvergedReason *reason, void *dummy) {
7153a40ed3dSBarry Smith   PetscFunctionBegin;
7160700a824SBarry Smith   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
7173f149594SLisandro Dalcin   PetscValidPointer(reason, 6);
7183f149594SLisandro Dalcin 
71906ee9f85SBarry Smith   *reason = SNES_CONVERGED_ITERATING;
72006ee9f85SBarry Smith   if (!it) {
72106ee9f85SBarry Smith     /* set parameter for default relative tolerance convergence test */
72206ee9f85SBarry Smith     snes->ttol   = fnorm * snes->rtol;
723e37c518bSBarry Smith     snes->rnorm0 = fnorm;
72406ee9f85SBarry Smith   }
7258146f6ebSBarry Smith   if (PetscIsInfOrNanReal(fnorm)) {
7269566063dSJacob Faibussowitsch     PetscCall(PetscInfo(snes, "Failed to converged, function norm is NaN\n"));
727184914b5SBarry Smith     *reason = SNES_DIVERGED_FNORM_NAN;
728be5caee7SBarry Smith   } else if (fnorm < snes->abstol && (it || !snes->forceiteration)) {
7299566063dSJacob Faibussowitsch     PetscCall(PetscInfo(snes, "Converged due to function norm %14.12e < %14.12e\n", (double)fnorm, (double)snes->abstol));
730184914b5SBarry Smith     *reason = SNES_CONVERGED_FNORM_ABS;
731e71169deSBarry Smith   } else if (snes->nfuncs >= snes->max_funcs && snes->max_funcs >= 0) {
73263a3b9bcSJacob Faibussowitsch     PetscCall(PetscInfo(snes, "Exceeded maximum number of function evaluations: %" PetscInt_FMT " > %" PetscInt_FMT "\n", snes->nfuncs, snes->max_funcs));
733184914b5SBarry Smith     *reason = SNES_DIVERGED_FUNCTION_COUNT;
73406ee9f85SBarry Smith   }
73506ee9f85SBarry Smith 
73606ee9f85SBarry Smith   if (it && !*reason) {
73706ee9f85SBarry Smith     if (fnorm <= snes->ttol) {
7389566063dSJacob Faibussowitsch       PetscCall(PetscInfo(snes, "Converged due to function norm %14.12e < %14.12e (relative tolerance)\n", (double)fnorm, (double)snes->ttol));
73906ee9f85SBarry Smith       *reason = SNES_CONVERGED_FNORM_RELATIVE;
740c60f73f4SPeter Brune     } else if (snorm < snes->stol * xnorm) {
7419566063dSJacob Faibussowitsch       PetscCall(PetscInfo(snes, "Converged due to small update length: %14.12e < %14.12e * %14.12e\n", (double)snorm, (double)snes->stol, (double)xnorm));
742c60f73f4SPeter Brune       *reason = SNES_CONVERGED_SNORM_RELATIVE;
743e4d06f11SPatrick Farrell     } else if (snes->divtol > 0 && (fnorm > snes->divtol * snes->rnorm0)) {
7449566063dSJacob 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));
745e37c518bSBarry Smith       *reason = SNES_DIVERGED_DTOL;
74606ee9f85SBarry Smith     }
747e7e93795SLois Curfman McInnes   }
7483a40ed3dSBarry Smith   PetscFunctionReturn(0);
749e7e93795SLois Curfman McInnes }
7503f149594SLisandro Dalcin 
7513f149594SLisandro Dalcin /*@C
752*f6dfbefdSBarry Smith    SNESConvergedSkip - Convergence test for `SNES` that NEVER returns as
7533f149594SLisandro Dalcin    converged, UNLESS the maximum number of iteration have been reached.
7543f149594SLisandro Dalcin 
755*f6dfbefdSBarry Smith    Logically Collective on snes
7563f149594SLisandro Dalcin 
7573f149594SLisandro Dalcin    Input Parameters:
758*f6dfbefdSBarry Smith +  snes - the `SNES` context
7593f149594SLisandro Dalcin .  it - the iteration (0 indicates before any Newton steps)
7603f149594SLisandro Dalcin .  xnorm - 2-norm of current iterate
761c60f73f4SPeter Brune .  snorm - 2-norm of current step
7623f149594SLisandro Dalcin .  fnorm - 2-norm of function at current iterate
7633f149594SLisandro Dalcin -  dummy - unused context
7643f149594SLisandro Dalcin 
7653f149594SLisandro Dalcin    Output Parameter:
766*f6dfbefdSBarry Smith .   reason  - `SNES_CONVERGED_ITERATING`, `SNES_CONVERGED_ITS`, or `SNES_DIVERGED_FNORM_NAN`
7673f149594SLisandro Dalcin 
768*f6dfbefdSBarry Smith    Options Database Key:
769*f6dfbefdSBarry Smith .  -snes_convergence_test skip - see `SNESSetFromOptions()`
770f362779dSJed Brown 
7713f149594SLisandro Dalcin    Level: advanced
7723f149594SLisandro Dalcin 
773*f6dfbefdSBarry Smith .seealso: `SNES`, `SNESSolve()`, `SNESConvergedDefault()`, `SNESSetConvergenceTest()`
7743f149594SLisandro Dalcin @*/
7759371c9d4SSatish Balay PetscErrorCode SNESConvergedSkip(SNES snes, PetscInt it, PetscReal xnorm, PetscReal snorm, PetscReal fnorm, SNESConvergedReason *reason, void *dummy) {
7763f149594SLisandro Dalcin   PetscFunctionBegin;
7770700a824SBarry Smith   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
7783f149594SLisandro Dalcin   PetscValidPointer(reason, 6);
7793f149594SLisandro Dalcin 
7803f149594SLisandro Dalcin   *reason = SNES_CONVERGED_ITERATING;
7813f149594SLisandro Dalcin 
7823f149594SLisandro Dalcin   if (fnorm != fnorm) {
7839566063dSJacob Faibussowitsch     PetscCall(PetscInfo(snes, "Failed to converged, function norm is NaN\n"));
7843f149594SLisandro Dalcin     *reason = SNES_DIVERGED_FNORM_NAN;
7853f149594SLisandro Dalcin   } else if (it == snes->max_its) {
7863f149594SLisandro Dalcin     *reason = SNES_CONVERGED_ITS;
7873f149594SLisandro Dalcin   }
7883f149594SLisandro Dalcin   PetscFunctionReturn(0);
7893f149594SLisandro Dalcin }
7903f149594SLisandro Dalcin 
7918d359177SBarry Smith /*@C
792*f6dfbefdSBarry Smith   SNESSetWorkVecs - Gets a number of work vectors to be used internally by `SNES` solvers
79358c9b817SLisandro Dalcin 
79458c9b817SLisandro Dalcin   Input Parameters:
795*f6dfbefdSBarry Smith + snes  - the `SNES` context
796a2b725a8SWilliam Gropp - nw - number of work vectors to allocate
79758c9b817SLisandro Dalcin 
79858c9b817SLisandro Dalcin   Level: developer
799fa0ddf94SBarry Smith 
80098acb6afSMatthew G Knepley @*/
8019371c9d4SSatish Balay PetscErrorCode SNESSetWorkVecs(SNES snes, PetscInt nw) {
802c5ed8070SMatthew G. Knepley   DM  dm;
803c5ed8070SMatthew G. Knepley   Vec v;
80458c9b817SLisandro Dalcin 
80558c9b817SLisandro Dalcin   PetscFunctionBegin;
8069566063dSJacob Faibussowitsch   if (snes->work) PetscCall(VecDestroyVecs(snes->nwork, &snes->work));
80758c9b817SLisandro Dalcin   snes->nwork = nw;
808f5af7f23SKarl Rupp 
8099566063dSJacob Faibussowitsch   PetscCall(SNESGetDM(snes, &dm));
8109566063dSJacob Faibussowitsch   PetscCall(DMGetGlobalVector(dm, &v));
8119566063dSJacob Faibussowitsch   PetscCall(VecDuplicateVecs(v, snes->nwork, &snes->work));
8129566063dSJacob Faibussowitsch   PetscCall(DMRestoreGlobalVector(dm, &v));
8139566063dSJacob Faibussowitsch   PetscCall(PetscLogObjectParents(snes, nw, snes->work));
81458c9b817SLisandro Dalcin   PetscFunctionReturn(0);
81558c9b817SLisandro Dalcin }
816