xref: /petsc/src/snes/interface/snesut.c (revision 48a46eb9bd028bec07ec0f396b1a3abb43f14558)
1e7e93795SLois Curfman McInnes 
2af0996ceSBarry Smith #include <petsc/private/snesimpl.h> /*I   "petsc/private/snesimpl.h"   I*/
3636fd056SMatthew G. Knepley #include <petscdm.h>
4ea844a1aSMatthew Knepley #include <petscsection.h>
52e7541e6SPeter Brune #include <petscblaslapack.h>
6e7e93795SLois Curfman McInnes 
73f1db9ecSBarry Smith /*@C
8a6570f20SBarry Smith    SNESMonitorSolution - Monitors progress of the SNES solvers by calling
936851e7fSLois Curfman McInnes    VecView() for the approximate solution at each iteration.
103f1db9ecSBarry Smith 
113f1db9ecSBarry Smith    Collective on SNES
123f1db9ecSBarry Smith 
133f1db9ecSBarry Smith    Input Parameters:
143f1db9ecSBarry Smith +  snes - the SNES context
153f1db9ecSBarry Smith .  its - iteration number
164b27c08aSLois Curfman McInnes .  fgnorm - 2-norm of residual
17f55353a2SBarry Smith -  dummy -  a viewer
183f1db9ecSBarry Smith 
19ee32d87aSMatthew G. Knepley    Options Database Keys:
20ee32d87aSMatthew G. Knepley .  -snes_monitor_solution [ascii binary draw][:filename][:viewer format] - plots solution at each iteration
21ee32d87aSMatthew G. Knepley 
223a61192cSBarry Smith    This is not called directly by users, rather one calls `SNESMonitorSet()`, with this function as an argument, to cause the monitor
233a61192cSBarry Smith    to be used during the SNES solve.
243a61192cSBarry Smith 
2536851e7fSLois Curfman McInnes    Level: intermediate
263f1db9ecSBarry Smith 
27db781477SPatrick Sanan .seealso: `SNESMonitorSet()`, `SNESMonitorDefault()`, `VecView()`
283f1db9ecSBarry Smith @*/
299371c9d4SSatish Balay PetscErrorCode SNESMonitorSolution(SNES snes, PetscInt its, PetscReal fgnorm, PetscViewerAndFormat *vf) {
303f1db9ecSBarry Smith   Vec         x;
31d43b4f6eSBarry Smith   PetscViewer viewer = vf->viewer;
323f1db9ecSBarry Smith 
333f1db9ecSBarry Smith   PetscFunctionBegin;
344d4332d5SBarry Smith   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 4);
359566063dSJacob Faibussowitsch   PetscCall(SNESGetSolution(snes, &x));
369566063dSJacob Faibussowitsch   PetscCall(PetscViewerPushFormat(viewer, vf->format));
379566063dSJacob Faibussowitsch   PetscCall(VecView(x, viewer));
389566063dSJacob Faibussowitsch   PetscCall(PetscViewerPopFormat(viewer));
393f1db9ecSBarry Smith   PetscFunctionReturn(0);
403f1db9ecSBarry Smith }
413f1db9ecSBarry Smith 
425ed2d596SBarry Smith /*@C
43a6570f20SBarry Smith    SNESMonitorResidual - Monitors progress of the SNES solvers by calling
445ed2d596SBarry Smith    VecView() for the residual at each iteration.
455ed2d596SBarry Smith 
465ed2d596SBarry Smith    Collective on SNES
475ed2d596SBarry Smith 
485ed2d596SBarry Smith    Input Parameters:
495ed2d596SBarry Smith +  snes - the SNES context
505ed2d596SBarry Smith .  its - iteration number
514b27c08aSLois Curfman McInnes .  fgnorm - 2-norm of residual
52f55353a2SBarry Smith -  dummy -  a viewer
535ed2d596SBarry Smith 
54ee32d87aSMatthew G. Knepley    Options Database Keys:
55ee32d87aSMatthew G. Knepley .  -snes_monitor_residual [ascii binary draw][:filename][:viewer format] - plots residual (not its norm) at each iteration
56ee32d87aSMatthew G. Knepley 
573a61192cSBarry Smith    Notes:
583a61192cSBarry Smith    This is not called directly by users, rather one calls `SNESMonitorSet()`, with this function as an argument, to cause the monitor
593a61192cSBarry Smith    to be used during the SNES solve.
603a61192cSBarry Smith 
615ed2d596SBarry Smith    Level: intermediate
625ed2d596SBarry Smith 
63db781477SPatrick Sanan .seealso: `SNESMonitorSet()`, `SNESMonitorDefault()`, `VecView()`
645ed2d596SBarry Smith @*/
659371c9d4SSatish Balay PetscErrorCode SNESMonitorResidual(SNES snes, PetscInt its, PetscReal fgnorm, PetscViewerAndFormat *vf) {
665ed2d596SBarry Smith   Vec         x;
67d43b4f6eSBarry Smith   PetscViewer viewer = vf->viewer;
685ed2d596SBarry Smith 
695ed2d596SBarry Smith   PetscFunctionBegin;
704d4332d5SBarry Smith   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 4);
719566063dSJacob Faibussowitsch   PetscCall(SNESGetFunction(snes, &x, NULL, NULL));
729566063dSJacob Faibussowitsch   PetscCall(PetscViewerPushFormat(viewer, vf->format));
739566063dSJacob Faibussowitsch   PetscCall(VecView(x, viewer));
749566063dSJacob Faibussowitsch   PetscCall(PetscViewerPopFormat(viewer));
755ed2d596SBarry Smith   PetscFunctionReturn(0);
765ed2d596SBarry Smith }
775ed2d596SBarry Smith 
78d132466eSBarry Smith /*@C
79a6570f20SBarry Smith    SNESMonitorSolutionUpdate - Monitors progress of the SNES solvers by calling
80d132466eSBarry Smith    VecView() for the UPDATE to the solution at each iteration.
81d132466eSBarry Smith 
82d132466eSBarry Smith    Collective on SNES
83d132466eSBarry Smith 
84d132466eSBarry Smith    Input Parameters:
85d132466eSBarry Smith +  snes - the SNES context
86d132466eSBarry Smith .  its - iteration number
874b27c08aSLois Curfman McInnes .  fgnorm - 2-norm of residual
88f55353a2SBarry Smith -  dummy - a viewer
89d132466eSBarry Smith 
90ee32d87aSMatthew G. Knepley    Options Database Keys:
91ee32d87aSMatthew G. Knepley .  -snes_monitor_solution_update [ascii binary draw][:filename][:viewer format] - plots update to solution at each iteration
92ee32d87aSMatthew G. Knepley 
933a61192cSBarry Smith    Notes:
943a61192cSBarry Smith    This is not called directly by users, rather one calls `SNESMonitorSet()`, with this function as an argument, to cause the monitor
953a61192cSBarry Smith    to be used during the SNES solve.
963a61192cSBarry Smith 
97d132466eSBarry Smith    Level: intermediate
98d132466eSBarry Smith 
99db781477SPatrick Sanan .seealso: `SNESMonitorSet()`, `SNESMonitorDefault()`, `VecView()`
100d132466eSBarry Smith @*/
1019371c9d4SSatish Balay PetscErrorCode SNESMonitorSolutionUpdate(SNES snes, PetscInt its, PetscReal fgnorm, PetscViewerAndFormat *vf) {
102d132466eSBarry Smith   Vec         x;
103d43b4f6eSBarry Smith   PetscViewer viewer = vf->viewer;
104d132466eSBarry Smith 
105d132466eSBarry Smith   PetscFunctionBegin;
1064d4332d5SBarry Smith   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 4);
1079566063dSJacob Faibussowitsch   PetscCall(SNESGetSolutionUpdate(snes, &x));
1089566063dSJacob Faibussowitsch   PetscCall(PetscViewerPushFormat(viewer, vf->format));
1099566063dSJacob Faibussowitsch   PetscCall(VecView(x, viewer));
1109566063dSJacob Faibussowitsch   PetscCall(PetscViewerPopFormat(viewer));
111d132466eSBarry Smith   PetscFunctionReturn(0);
112d132466eSBarry Smith }
113d132466eSBarry Smith 
114798534f6SMatthew G. Knepley #include <petscdraw.h>
115a5c2985bSBarry Smith 
116798534f6SMatthew G. Knepley /*@C
117798534f6SMatthew G. Knepley   KSPMonitorSNESResidual - Prints the SNES residual norm, as well as the linear residual norm, at each iteration of an iterative solver.
118798534f6SMatthew G. Knepley 
119798534f6SMatthew G. Knepley   Collective on ksp
120a5c2985bSBarry Smith 
121a5c2985bSBarry Smith   Input Parameters:
122a5c2985bSBarry Smith + ksp   - iterative context
123a5c2985bSBarry Smith . n     - iteration number
124a5c2985bSBarry Smith . rnorm - 2-norm (preconditioned) residual value (may be estimated).
125798534f6SMatthew G. Knepley - vf    - The viewer context
126798534f6SMatthew G. Knepley 
127798534f6SMatthew G. Knepley   Options Database Key:
128798534f6SMatthew G. Knepley . -snes_monitor_ksp - Activates KSPMonitorSNESResidual()
129a5c2985bSBarry Smith 
1303a61192cSBarry Smith    Notes:
1313a61192cSBarry Smith    This is not called directly by users, rather one calls `KSPMonitorSet()`, with this function as an argument, to cause the monitor
1323a61192cSBarry Smith    to be used during the KSP solve.
1333a61192cSBarry Smith 
134a5c2985bSBarry Smith   Level: intermediate
135a5c2985bSBarry Smith 
136c2e3fba1SPatrick Sanan .seealso: `KSPMonitorSet()`, `KSPMonitorResidual()`, `KSPMonitorTrueResidualMaxNorm()`
137a5c2985bSBarry Smith @*/
1389371c9d4SSatish Balay PetscErrorCode KSPMonitorSNESResidual(KSP ksp, PetscInt n, PetscReal rnorm, PetscViewerAndFormat *vf) {
139798534f6SMatthew G. Knepley   PetscViewer       viewer = vf->viewer;
140798534f6SMatthew G. Knepley   PetscViewerFormat format = vf->format;
141798534f6SMatthew G. Knepley   SNES              snes   = (SNES)vf->data;
142a5c2985bSBarry Smith   Vec               snes_solution, work1, work2;
143a5c2985bSBarry Smith   PetscReal         snorm;
144798534f6SMatthew G. Knepley   PetscInt          tablevel;
145798534f6SMatthew G. Knepley   const char       *prefix;
146a5c2985bSBarry Smith 
147a5c2985bSBarry Smith   PetscFunctionBegin;
148798534f6SMatthew G. Knepley   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 4);
1499566063dSJacob Faibussowitsch   PetscCall(SNESGetSolution(snes, &snes_solution));
1509566063dSJacob Faibussowitsch   PetscCall(VecDuplicate(snes_solution, &work1));
1519566063dSJacob Faibussowitsch   PetscCall(VecDuplicate(snes_solution, &work2));
1529566063dSJacob Faibussowitsch   PetscCall(KSPBuildSolution(ksp, work1, NULL));
1539566063dSJacob Faibussowitsch   PetscCall(VecAYPX(work1, -1.0, snes_solution));
1549566063dSJacob Faibussowitsch   PetscCall(SNESComputeFunction(snes, work1, work2));
1559566063dSJacob Faibussowitsch   PetscCall(VecNorm(work2, NORM_2, &snorm));
1569566063dSJacob Faibussowitsch   PetscCall(VecDestroy(&work1));
1579566063dSJacob Faibussowitsch   PetscCall(VecDestroy(&work2));
158a5c2985bSBarry Smith 
1599566063dSJacob Faibussowitsch   PetscCall(PetscObjectGetTabLevel((PetscObject)ksp, &tablevel));
1609566063dSJacob Faibussowitsch   PetscCall(PetscObjectGetOptionsPrefix((PetscObject)ksp, &prefix));
1619566063dSJacob Faibussowitsch   PetscCall(PetscViewerPushFormat(viewer, format));
1629566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIIAddTab(viewer, tablevel));
1639566063dSJacob Faibussowitsch   if (n == 0 && prefix) PetscCall(PetscViewerASCIIPrintf(viewer, "  Residual norms for %s solve.\n", prefix));
16463a3b9bcSJacob Faibussowitsch   PetscCall(PetscViewerASCIIPrintf(viewer, "%3" PetscInt_FMT " SNES Residual norm %5.3e KSP Residual norm %5.3e \n", n, (double)snorm, (double)rnorm));
1659566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIISubtractTab(viewer, tablevel));
1669566063dSJacob Faibussowitsch   PetscCall(PetscViewerPopFormat(viewer));
167a5c2985bSBarry Smith   PetscFunctionReturn(0);
168a5c2985bSBarry Smith }
169a5c2985bSBarry Smith 
170e5f7ee39SBarry Smith /*@C
171798534f6SMatthew G. Knepley   KSPMonitorSNESResidualDrawLG - Plots the linear SNES residual norm at each iteration of an iterative solver.
172e5f7ee39SBarry Smith 
173798534f6SMatthew G. Knepley   Collective on ksp
174e5f7ee39SBarry Smith 
175e5f7ee39SBarry Smith   Input Parameters:
176798534f6SMatthew G. Knepley + ksp   - iterative context
177798534f6SMatthew G. Knepley . n     - iteration number
178798534f6SMatthew G. Knepley . rnorm - 2-norm (preconditioned) residual value (may be estimated).
179798534f6SMatthew G. Knepley - vf    - The viewer context
180e5f7ee39SBarry Smith 
181e5f7ee39SBarry Smith   Options Database Key:
182798534f6SMatthew G. Knepley . -snes_monitor_ksp draw::draw_lg - Activates KSPMonitorSNESResidualDrawLG()
183e5f7ee39SBarry Smith 
1843a61192cSBarry Smith    Notes:
1853a61192cSBarry Smith    This is not called directly by users, rather one calls `SNESMonitorSet()`, with this function as an argument, to cause the monitor
1863a61192cSBarry Smith    to be used during the SNES solve.
1873a61192cSBarry Smith 
188e5f7ee39SBarry Smith   Level: intermediate
189e5f7ee39SBarry Smith 
190db781477SPatrick Sanan .seealso: `KSPMonitorSet()`, `KSPMonitorTrueResidual()`
191e5f7ee39SBarry Smith @*/
1929371c9d4SSatish Balay PetscErrorCode KSPMonitorSNESResidualDrawLG(KSP ksp, PetscInt n, PetscReal rnorm, PetscViewerAndFormat *vf) {
193798534f6SMatthew G. Knepley   PetscViewer        viewer = vf->viewer;
194798534f6SMatthew G. Knepley   PetscViewerFormat  format = vf->format;
195798534f6SMatthew G. Knepley   PetscDrawLG        lg     = vf->lg;
196798534f6SMatthew G. Knepley   SNES               snes   = (SNES)vf->data;
197e5f7ee39SBarry Smith   Vec                snes_solution, work1, work2;
198798534f6SMatthew G. Knepley   PetscReal          snorm;
199798534f6SMatthew G. Knepley   KSPConvergedReason reason;
200798534f6SMatthew G. Knepley   PetscReal          x[2], y[2];
201e5f7ee39SBarry Smith 
202e5f7ee39SBarry Smith   PetscFunctionBegin;
203798534f6SMatthew G. Knepley   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 4);
204064a246eSJacob Faibussowitsch   PetscValidHeaderSpecific(lg, PETSC_DRAWLG_CLASSID, 4);
2059566063dSJacob Faibussowitsch   PetscCall(SNESGetSolution(snes, &snes_solution));
2069566063dSJacob Faibussowitsch   PetscCall(VecDuplicate(snes_solution, &work1));
2079566063dSJacob Faibussowitsch   PetscCall(VecDuplicate(snes_solution, &work2));
2089566063dSJacob Faibussowitsch   PetscCall(KSPBuildSolution(ksp, work1, NULL));
2099566063dSJacob Faibussowitsch   PetscCall(VecAYPX(work1, -1.0, snes_solution));
2109566063dSJacob Faibussowitsch   PetscCall(SNESComputeFunction(snes, work1, work2));
2119566063dSJacob Faibussowitsch   PetscCall(VecNorm(work2, NORM_2, &snorm));
2129566063dSJacob Faibussowitsch   PetscCall(VecDestroy(&work1));
2139566063dSJacob Faibussowitsch   PetscCall(VecDestroy(&work2));
214e5f7ee39SBarry Smith 
2159566063dSJacob Faibussowitsch   PetscCall(PetscViewerPushFormat(viewer, format));
2169566063dSJacob Faibussowitsch   if (!n) PetscCall(PetscDrawLGReset(lg));
217798534f6SMatthew G. Knepley   x[0] = (PetscReal)n;
218798534f6SMatthew G. Knepley   if (rnorm > 0.0) y[0] = PetscLog10Real(rnorm);
219798534f6SMatthew G. Knepley   else y[0] = -15.0;
220798534f6SMatthew G. Knepley   x[1] = (PetscReal)n;
221798534f6SMatthew G. Knepley   if (snorm > 0.0) y[1] = PetscLog10Real(snorm);
222798534f6SMatthew G. Knepley   else y[1] = -15.0;
2239566063dSJacob Faibussowitsch   PetscCall(PetscDrawLGAddPoint(lg, x, y));
2249566063dSJacob Faibussowitsch   PetscCall(KSPGetConvergedReason(ksp, &reason));
225798534f6SMatthew G. Knepley   if (n <= 20 || !(n % 5) || reason) {
2269566063dSJacob Faibussowitsch     PetscCall(PetscDrawLGDraw(lg));
2279566063dSJacob Faibussowitsch     PetscCall(PetscDrawLGSave(lg));
228e5f7ee39SBarry Smith   }
2299566063dSJacob Faibussowitsch   PetscCall(PetscViewerPopFormat(viewer));
230e5f7ee39SBarry Smith   PetscFunctionReturn(0);
231e5f7ee39SBarry Smith }
232e5f7ee39SBarry Smith 
233798534f6SMatthew G. Knepley /*@C
234798534f6SMatthew G. Knepley   KSPMonitorSNESResidualDrawLGCreate - Creates the plotter for the linear SNES residual.
235e5f7ee39SBarry Smith 
236798534f6SMatthew G. Knepley   Collective on ksp
237e5f7ee39SBarry Smith 
238798534f6SMatthew G. Knepley   Input Parameters:
239b693eab9SMatthew G. Knepley + viewer - The PetscViewer
240798534f6SMatthew G. Knepley . format - The viewer format
241798534f6SMatthew G. Knepley - ctx    - An optional user context
242798534f6SMatthew G. Knepley 
243798534f6SMatthew G. Knepley   Output Parameter:
244798534f6SMatthew G. Knepley . vf    - The viewer context
245e5f7ee39SBarry Smith 
246e5f7ee39SBarry Smith   Level: intermediate
247e5f7ee39SBarry Smith 
248db781477SPatrick Sanan .seealso: `KSPMonitorSet()`, `KSPMonitorTrueResidual()`
249e5f7ee39SBarry Smith @*/
2509371c9d4SSatish Balay PetscErrorCode KSPMonitorSNESResidualDrawLGCreate(PetscViewer viewer, PetscViewerFormat format, void *ctx, PetscViewerAndFormat **vf) {
251798534f6SMatthew G. Knepley   const char *names[] = {"linear", "nonlinear"};
252e5f7ee39SBarry Smith 
253e5f7ee39SBarry Smith   PetscFunctionBegin;
2549566063dSJacob Faibussowitsch   PetscCall(PetscViewerAndFormatCreate(viewer, format, vf));
255798534f6SMatthew G. Knepley   (*vf)->data = ctx;
2569566063dSJacob Faibussowitsch   PetscCall(KSPMonitorLGCreate(PetscObjectComm((PetscObject)viewer), NULL, NULL, "Log Residual Norm", 2, names, PETSC_DECIDE, PETSC_DECIDE, 400, 300, &(*vf)->lg));
257e5f7ee39SBarry Smith   PetscFunctionReturn(0);
258e5f7ee39SBarry Smith }
259e5f7ee39SBarry Smith 
2609371c9d4SSatish Balay PetscErrorCode SNESMonitorDefaultSetUp(SNES snes, PetscViewerAndFormat *vf) {
261fbcc4530SMatthew G. Knepley   PetscFunctionBegin;
262*48a46eb9SPierre Jolivet   if (vf->format == PETSC_VIEWER_DRAW_LG) PetscCall(KSPMonitorLGCreate(PetscObjectComm((PetscObject)vf->viewer), NULL, NULL, "Log Residual Norm", 1, NULL, PETSC_DECIDE, PETSC_DECIDE, 400, 300, &vf->lg));
263fbcc4530SMatthew G. Knepley   PetscFunctionReturn(0);
264fbcc4530SMatthew G. Knepley }
265fbcc4530SMatthew G. Knepley 
2664b828684SBarry Smith /*@C
267a6570f20SBarry Smith    SNESMonitorDefault - Monitors progress of the SNES solvers (default).
268e7e93795SLois Curfman McInnes 
269c7afd0dbSLois Curfman McInnes    Collective on SNES
270c7afd0dbSLois Curfman McInnes 
271e7e93795SLois Curfman McInnes    Input Parameters:
272c7afd0dbSLois Curfman McInnes +  snes - the SNES context
273e7e93795SLois Curfman McInnes .  its - iteration number
2744b27c08aSLois Curfman McInnes .  fgnorm - 2-norm of residual
275d43b4f6eSBarry Smith -  vf - viewer and format structure
276fee21e36SBarry Smith 
2773a61192cSBarry Smith    Options Database:
2783a61192cSBarry Smith .  -snes_monitor - use this function to monitor the convergence of the nonlinear solver
2793a61192cSBarry Smith 
280e7e93795SLois Curfman McInnes    Notes:
2814b27c08aSLois Curfman McInnes    This routine prints the residual norm at each iteration.
282e7e93795SLois Curfman McInnes 
2833a61192cSBarry Smith    This is not called directly by users, rather one calls `SNESMonitorSet()`, with this function as an argument, to cause the monitor
2843a61192cSBarry Smith    to be used during the SNES solve.
2853a61192cSBarry Smith 
28636851e7fSLois Curfman McInnes    Level: intermediate
28736851e7fSLois Curfman McInnes 
2883a61192cSBarry Smith .seealso: `SNESMonitorSet()`, `SNESMonitorSolution()`, `SNESMonitorFunction()`, `SNESMonitorSolution()`, `SNESMonitorResidual()`,
2893a61192cSBarry Smith           `SNESMonitorSolutionUpdate()`, `SNESMonitorDefault()`, `SNESMonitorScaling()`, `SNESMonitorRange()`, `SNESMonitorRatio()`,
2903a61192cSBarry Smith           `SNESMonitorDefaultField()`
291e7e93795SLois Curfman McInnes @*/
2929371c9d4SSatish Balay PetscErrorCode SNESMonitorDefault(SNES snes, PetscInt its, PetscReal fgnorm, PetscViewerAndFormat *vf) {
293d43b4f6eSBarry Smith   PetscViewer       viewer = vf->viewer;
294798534f6SMatthew G. Knepley   PetscViewerFormat format = vf->format;
295798534f6SMatthew G. Knepley   PetscBool         isascii, isdraw;
296d132466eSBarry Smith 
2973a40ed3dSBarry Smith   PetscFunctionBegin;
2984d4332d5SBarry Smith   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 4);
2999566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &isascii));
3009566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERDRAW, &isdraw));
3019566063dSJacob Faibussowitsch   PetscCall(PetscViewerPushFormat(viewer, format));
302798534f6SMatthew G. Knepley   if (isascii) {
3039566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIAddTab(viewer, ((PetscObject)snes)->tablevel));
30463a3b9bcSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer, "%3" PetscInt_FMT " SNES Function norm %14.12e \n", its, (double)fgnorm));
3059566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIISubtractTab(viewer, ((PetscObject)snes)->tablevel));
306798534f6SMatthew G. Knepley   } else if (isdraw) {
307798534f6SMatthew G. Knepley     if (format == PETSC_VIEWER_DRAW_LG) {
308798534f6SMatthew G. Knepley       PetscDrawLG lg = (PetscDrawLG)vf->lg;
309798534f6SMatthew G. Knepley       PetscReal   x, y;
310798534f6SMatthew G. Knepley 
311798534f6SMatthew G. Knepley       PetscValidHeaderSpecific(lg, PETSC_DRAWLG_CLASSID, 4);
3129566063dSJacob Faibussowitsch       if (!its) PetscCall(PetscDrawLGReset(lg));
313798534f6SMatthew G. Knepley       x = (PetscReal)its;
314798534f6SMatthew G. Knepley       if (fgnorm > 0.0) y = PetscLog10Real(fgnorm);
315798534f6SMatthew G. Knepley       else y = -15.0;
3169566063dSJacob Faibussowitsch       PetscCall(PetscDrawLGAddPoint(lg, &x, &y));
317798534f6SMatthew G. Knepley       if (its <= 20 || !(its % 5) || snes->reason) {
3189566063dSJacob Faibussowitsch         PetscCall(PetscDrawLGDraw(lg));
3199566063dSJacob Faibussowitsch         PetscCall(PetscDrawLGSave(lg));
320798534f6SMatthew G. Knepley       }
321798534f6SMatthew G. Knepley     }
322798534f6SMatthew G. Knepley   }
3239566063dSJacob Faibussowitsch   PetscCall(PetscViewerPopFormat(viewer));
3243a40ed3dSBarry Smith   PetscFunctionReturn(0);
325e7e93795SLois Curfman McInnes }
3263f1db9ecSBarry Smith 
3271f60017eSBarry Smith /*@C
3281f60017eSBarry Smith    SNESMonitorScaling - Monitors the largest value in each row of the Jacobian.
3291f60017eSBarry Smith 
3301f60017eSBarry Smith    Collective on SNES
3311f60017eSBarry Smith 
3321f60017eSBarry Smith    Input Parameters:
3331f60017eSBarry Smith +  snes - the SNES context
3341f60017eSBarry Smith .  its - iteration number
3351f60017eSBarry Smith .  fgnorm - 2-norm of residual
3361f60017eSBarry Smith -  vf - viewer and format structure
3371f60017eSBarry Smith 
3381f60017eSBarry Smith    Notes:
3391f60017eSBarry Smith    This routine prints the largest value in each row of the Jacobian
3401f60017eSBarry Smith 
3413a61192cSBarry Smith    This is not called directly by users, rather one calls `SNESMonitorSet()`, with this function as an argument, to cause the monitor
3423a61192cSBarry Smith    to be used during the SNES solve.
3433a61192cSBarry Smith 
3441f60017eSBarry Smith    Level: intermediate
3451f60017eSBarry Smith 
346db781477SPatrick Sanan .seealso: `SNESMonitorSet()`, `SNESMonitorSolution()`
3471f60017eSBarry Smith @*/
3489371c9d4SSatish Balay PetscErrorCode SNESMonitorScaling(SNES snes, PetscInt its, PetscReal fgnorm, PetscViewerAndFormat *vf) {
3491f60017eSBarry Smith   PetscViewer viewer = vf->viewer;
3501f60017eSBarry Smith   KSP         ksp;
3511f60017eSBarry Smith   Mat         J;
3521f60017eSBarry Smith   Vec         v;
3531f60017eSBarry Smith 
3541f60017eSBarry Smith   PetscFunctionBegin;
3551f60017eSBarry Smith   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 4);
3569566063dSJacob Faibussowitsch   PetscCall(SNESGetKSP(snes, &ksp));
3579566063dSJacob Faibussowitsch   PetscCall(KSPGetOperators(ksp, &J, NULL));
3589566063dSJacob Faibussowitsch   PetscCall(MatCreateVecs(J, &v, NULL));
3599566063dSJacob Faibussowitsch   PetscCall(MatGetRowMaxAbs(J, v, NULL));
3609566063dSJacob Faibussowitsch   PetscCall(PetscViewerPushFormat(viewer, vf->format));
3619566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIIAddTab(viewer, ((PetscObject)snes)->tablevel));
36263a3b9bcSJacob Faibussowitsch   PetscCall(PetscViewerASCIIPrintf(viewer, "SNES Jacobian maximum row entries\n"));
3639566063dSJacob Faibussowitsch   PetscCall(VecView(v, viewer));
3649566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIISubtractTab(viewer, ((PetscObject)snes)->tablevel));
3659566063dSJacob Faibussowitsch   PetscCall(PetscViewerPopFormat(viewer));
3669566063dSJacob Faibussowitsch   PetscCall(VecDestroy(&v));
3671f60017eSBarry Smith   PetscFunctionReturn(0);
3681f60017eSBarry Smith }
3691f60017eSBarry Smith 
3709371c9d4SSatish Balay PetscErrorCode SNESMonitorJacUpdateSpectrum(SNES snes, PetscInt it, PetscReal fnorm, PetscViewerAndFormat *vf) {
3712e7541e6SPeter Brune   Vec X;
3722e7541e6SPeter Brune   Mat J, dJ, dJdense;
373d1e9a80fSBarry Smith   PetscErrorCode (*func)(SNES, Vec, Mat, Mat, void *);
3742f96bde4SJose E. Roman   PetscInt     n;
37523fff9afSBarry Smith   PetscBLASInt nb = 0, lwork;
3762e7541e6SPeter Brune   PetscReal   *eigr, *eigi;
3772e7541e6SPeter Brune   PetscScalar *work;
3782e7541e6SPeter Brune   PetscScalar *a;
3792e7541e6SPeter Brune 
3802e7541e6SPeter Brune   PetscFunctionBegin;
3812e7541e6SPeter Brune   if (it == 0) PetscFunctionReturn(0);
3822e7541e6SPeter Brune   /* create the difference between the current update and the current jacobian */
3839566063dSJacob Faibussowitsch   PetscCall(SNESGetSolution(snes, &X));
3849566063dSJacob Faibussowitsch   PetscCall(SNESGetJacobian(snes, NULL, &J, &func, NULL));
3859566063dSJacob Faibussowitsch   PetscCall(MatDuplicate(J, MAT_COPY_VALUES, &dJ));
3869566063dSJacob Faibussowitsch   PetscCall(SNESComputeJacobian(snes, X, dJ, dJ));
3879566063dSJacob Faibussowitsch   PetscCall(MatAXPY(dJ, -1.0, J, SAME_NONZERO_PATTERN));
388f5af7f23SKarl Rupp 
3892e7541e6SPeter Brune   /* compute the spectrum directly */
3909566063dSJacob Faibussowitsch   PetscCall(MatConvert(dJ, MATSEQDENSE, MAT_INITIAL_MATRIX, &dJdense));
3919566063dSJacob Faibussowitsch   PetscCall(MatGetSize(dJ, &n, NULL));
3929566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(n, &nb));
3932e7541e6SPeter Brune   lwork = 3 * nb;
3949566063dSJacob Faibussowitsch   PetscCall(PetscMalloc1(n, &eigr));
3959566063dSJacob Faibussowitsch   PetscCall(PetscMalloc1(n, &eigi));
3969566063dSJacob Faibussowitsch   PetscCall(PetscMalloc1(lwork, &work));
3979566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArray(dJdense, &a));
3982e7541e6SPeter Brune #if !defined(PETSC_USE_COMPLEX)
3992e7541e6SPeter Brune   {
4002e7541e6SPeter Brune     PetscBLASInt lierr;
4012f96bde4SJose E. Roman     PetscInt     i;
4029566063dSJacob Faibussowitsch     PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF));
403792fecdfSBarry Smith     PetscCallBLAS("LAPACKgeev", LAPACKgeev_("N", "N", &nb, a, &nb, eigr, eigi, NULL, &nb, NULL, &nb, work, &lwork, &lierr));
40463a3b9bcSJacob Faibussowitsch     PetscCheck(!lierr, PETSC_COMM_SELF, PETSC_ERR_LIB, "geev() error %" PetscBLASInt_FMT, lierr);
4059566063dSJacob Faibussowitsch     PetscCall(PetscFPTrapPop());
40663a3b9bcSJacob Faibussowitsch     PetscCall(PetscPrintf(PetscObjectComm((PetscObject)snes), "Eigenvalues of J_%" PetscInt_FMT " - J_%" PetscInt_FMT ":\n", it, it - 1));
407*48a46eb9SPierre Jolivet     for (i = 0; i < n; i++) PetscCall(PetscPrintf(PetscObjectComm((PetscObject)snes), "%5" PetscInt_FMT ": %20.5g + %20.5gi\n", i, (double)eigr[i], (double)eigi[i]));
4082f96bde4SJose E. Roman   }
4099566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArray(dJdense, &a));
4109566063dSJacob Faibussowitsch   PetscCall(MatDestroy(&dJ));
4119566063dSJacob Faibussowitsch   PetscCall(MatDestroy(&dJdense));
4129566063dSJacob Faibussowitsch   PetscCall(PetscFree(eigr));
4139566063dSJacob Faibussowitsch   PetscCall(PetscFree(eigi));
4149566063dSJacob Faibussowitsch   PetscCall(PetscFree(work));
4152e7541e6SPeter Brune   PetscFunctionReturn(0);
4162f96bde4SJose E. Roman #else
4172f96bde4SJose E. Roman   SETERRQ(PETSC_COMM_SELF, PETSC_ERR_SUP, "Not coded for complex");
4182f96bde4SJose E. Roman #endif
4192e7541e6SPeter Brune }
4202e7541e6SPeter Brune 
4216ba87a44SLisandro Dalcin PETSC_INTERN PetscErrorCode SNESMonitorRange_Private(SNES, PetscInt, PetscReal *);
4226ba87a44SLisandro Dalcin 
4239371c9d4SSatish Balay PetscErrorCode SNESMonitorRange_Private(SNES snes, PetscInt it, PetscReal *per) {
424b271bb04SBarry Smith   Vec          resid;
425b271bb04SBarry Smith   PetscReal    rmax, pwork;
426b271bb04SBarry Smith   PetscInt     i, n, N;
427b271bb04SBarry Smith   PetscScalar *r;
428b271bb04SBarry Smith 
429b271bb04SBarry Smith   PetscFunctionBegin;
4309566063dSJacob Faibussowitsch   PetscCall(SNESGetFunction(snes, &resid, NULL, NULL));
4319566063dSJacob Faibussowitsch   PetscCall(VecNorm(resid, NORM_INFINITY, &rmax));
4329566063dSJacob Faibussowitsch   PetscCall(VecGetLocalSize(resid, &n));
4339566063dSJacob Faibussowitsch   PetscCall(VecGetSize(resid, &N));
4349566063dSJacob Faibussowitsch   PetscCall(VecGetArray(resid, &r));
435b271bb04SBarry Smith   pwork = 0.0;
4369371c9d4SSatish Balay   for (i = 0; i < n; i++) { pwork += (PetscAbsScalar(r[i]) > .20 * rmax); }
4371c2dc1cbSBarry Smith   PetscCall(MPIU_Allreduce(&pwork, per, 1, MPIU_REAL, MPIU_SUM, PetscObjectComm((PetscObject)snes)));
4389566063dSJacob Faibussowitsch   PetscCall(VecRestoreArray(resid, &r));
439b271bb04SBarry Smith   *per = *per / N;
440b271bb04SBarry Smith   PetscFunctionReturn(0);
441b271bb04SBarry Smith }
442b271bb04SBarry Smith 
443b271bb04SBarry Smith /*@C
444b271bb04SBarry Smith    SNESMonitorRange - Prints the percentage of residual elements that are more then 10 percent of the maximum value.
445b271bb04SBarry Smith 
446b271bb04SBarry Smith    Collective on SNES
447b271bb04SBarry Smith 
448b271bb04SBarry Smith    Input Parameters:
449b271bb04SBarry Smith +  snes   - iterative context
450b271bb04SBarry Smith .  it    - iteration number
451b271bb04SBarry Smith .  rnorm - 2-norm (preconditioned) residual value (may be estimated).
452b271bb04SBarry Smith -  dummy - unused monitor context
453b271bb04SBarry Smith 
454b271bb04SBarry Smith    Options Database Key:
455b271bb04SBarry Smith .  -snes_monitor_range - Activates SNESMonitorRange()
456b271bb04SBarry Smith 
4573a61192cSBarry Smith    Notes:
4583a61192cSBarry Smith    This is not called directly by users, rather one calls `SNESMonitorSet()`, with this function as an argument, to cause the monitor
4593a61192cSBarry Smith    to be used during the SNES solve.
4603a61192cSBarry Smith 
461b271bb04SBarry Smith    Level: intermediate
462b271bb04SBarry Smith 
463db781477SPatrick Sanan .seealso: `SNESMonitorSet()`, `SNESMonitorDefault()`, `SNESMonitorLGCreate()`
464b271bb04SBarry Smith @*/
4659371c9d4SSatish Balay PetscErrorCode SNESMonitorRange(SNES snes, PetscInt it, PetscReal rnorm, PetscViewerAndFormat *vf) {
466b271bb04SBarry Smith   PetscReal        perc, rel;
467d43b4f6eSBarry Smith   PetscViewer      viewer = vf->viewer;
468b271bb04SBarry Smith   /* should be in a MonitorRangeContext */
469b271bb04SBarry Smith   static PetscReal prev;
470b271bb04SBarry Smith 
471b271bb04SBarry Smith   PetscFunctionBegin;
4724d4332d5SBarry Smith   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 4);
473b271bb04SBarry Smith   if (!it) prev = rnorm;
4749566063dSJacob Faibussowitsch   PetscCall(SNESMonitorRange_Private(snes, it, &perc));
475b271bb04SBarry Smith 
476b271bb04SBarry Smith   rel  = (prev - rnorm) / prev;
477b271bb04SBarry Smith   prev = rnorm;
4789566063dSJacob Faibussowitsch   PetscCall(PetscViewerPushFormat(viewer, vf->format));
4799566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIIAddTab(viewer, ((PetscObject)snes)->tablevel));
48063a3b9bcSJacob Faibussowitsch   PetscCall(PetscViewerASCIIPrintf(viewer, "%3" PetscInt_FMT " SNES preconditioned resid norm %14.12e Percent values above 20 percent of maximum %5.2g relative decrease %5.2e ratio %5.2e \n", it, (double)rnorm, (double)(100.0 * perc), (double)rel, (double)(rel / perc)));
4819566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIISubtractTab(viewer, ((PetscObject)snes)->tablevel));
4829566063dSJacob Faibussowitsch   PetscCall(PetscViewerPopFormat(viewer));
483b271bb04SBarry Smith   PetscFunctionReturn(0);
484b271bb04SBarry Smith }
485b271bb04SBarry Smith 
4863a7fca6bSBarry Smith /*@C
487a6570f20SBarry Smith    SNESMonitorRatio - Monitors progress of the SNES solvers by printing the ratio
4884b27c08aSLois Curfman McInnes    of residual norm at each iteration to the previous.
4893a7fca6bSBarry Smith 
4903a7fca6bSBarry Smith    Collective on SNES
4913a7fca6bSBarry Smith 
4923a7fca6bSBarry Smith    Input Parameters:
4933a7fca6bSBarry Smith +  snes - the SNES context
4943a7fca6bSBarry Smith .  its - iteration number
4953a7fca6bSBarry Smith .  fgnorm - 2-norm of residual (or gradient)
496eabae89aSBarry Smith -  dummy -  context of monitor
4973a7fca6bSBarry Smith 
4983a7fca6bSBarry Smith    Level: intermediate
4993a7fca6bSBarry Smith 
50095452b02SPatrick Sanan    Notes:
5013a61192cSBarry Smith    This is not called directly by users, rather one calls `SNESMonitorSet()`, with this function as an argument, to cause the monitor
5023a61192cSBarry Smith    to be used during the SNES solve.
5033a61192cSBarry Smith 
5043a61192cSBarry Smith    Be sure to call SNESMonitorRationSetUp() before using this monitor.
5053a61192cSBarry Smith 
5063a61192cSBarry Smith .seealso: `SNESMonitorSet()`, `SNESMonitorSolution()`, `SNESMonitorDefault()`
5073a7fca6bSBarry Smith @*/
5089371c9d4SSatish Balay PetscErrorCode SNESMonitorRatio(SNES snes, PetscInt its, PetscReal fgnorm, PetscViewerAndFormat *vf) {
50977431f27SBarry Smith   PetscInt    len;
51087828ca2SBarry Smith   PetscReal  *history;
511d43b4f6eSBarry Smith   PetscViewer viewer = vf->viewer;
5123a7fca6bSBarry Smith 
5133a7fca6bSBarry Smith   PetscFunctionBegin;
5149566063dSJacob Faibussowitsch   PetscCall(SNESGetConvergenceHistory(snes, &history, NULL, &len));
5159566063dSJacob Faibussowitsch   PetscCall(PetscViewerPushFormat(viewer, vf->format));
5169566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIIAddTab(viewer, ((PetscObject)snes)->tablevel));
517958c9bccSBarry Smith   if (!its || !history || its > len) {
51863a3b9bcSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer, "%3" PetscInt_FMT " SNES Function norm %14.12e \n", its, (double)fgnorm));
5193a7fca6bSBarry Smith   } else {
52087828ca2SBarry Smith     PetscReal ratio = fgnorm / history[its - 1];
52163a3b9bcSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer, "%3" PetscInt_FMT " SNES Function norm %14.12e %14.12e \n", its, (double)fgnorm, (double)ratio));
5223a7fca6bSBarry Smith   }
5239566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIISubtractTab(viewer, ((PetscObject)snes)->tablevel));
5249566063dSJacob Faibussowitsch   PetscCall(PetscViewerPopFormat(viewer));
5253a7fca6bSBarry Smith   PetscFunctionReturn(0);
5263a7fca6bSBarry Smith }
5273a7fca6bSBarry Smith 
5283a7fca6bSBarry Smith /*@C
529fde5950dSBarry Smith    SNESMonitorRatioSetUp - Insures the SNES object is saving its history since this monitor needs access to it
5303a7fca6bSBarry Smith 
5313a7fca6bSBarry Smith    Collective on SNES
5323a7fca6bSBarry Smith 
5333a7fca6bSBarry Smith    Input Parameters:
534eabae89aSBarry Smith +   snes - the SNES context
535fde5950dSBarry Smith -   viewer - the PetscViewer object (ignored)
5363a7fca6bSBarry Smith 
5373a7fca6bSBarry Smith    Level: intermediate
5383a7fca6bSBarry Smith 
539db781477SPatrick Sanan .seealso: `SNESMonitorSet()`, `SNESMonitorSolution()`, `SNESMonitorDefault()`, `SNESMonitorRatio()`
5403a7fca6bSBarry Smith @*/
5419371c9d4SSatish Balay PetscErrorCode SNESMonitorRatioSetUp(SNES snes, PetscViewerAndFormat *vf) {
54287828ca2SBarry Smith   PetscReal *history;
5433a7fca6bSBarry Smith 
5443a7fca6bSBarry Smith   PetscFunctionBegin;
5459566063dSJacob Faibussowitsch   PetscCall(SNESGetConvergenceHistory(snes, &history, NULL, NULL));
546*48a46eb9SPierre Jolivet   if (!history) PetscCall(SNESSetConvergenceHistory(snes, NULL, NULL, 100, PETSC_TRUE));
5473a7fca6bSBarry Smith   PetscFunctionReturn(0);
5483a7fca6bSBarry Smith }
5493a7fca6bSBarry Smith 
550e7e93795SLois Curfman McInnes /* ---------------------------------------------------------------- */
551be1f7002SBarry Smith /*
552a6570f20SBarry Smith      Default (short) SNES Monitor, same as SNESMonitorDefault() except
553be1f7002SBarry Smith   it prints fewer digits of the residual as the residual gets smaller.
554be1f7002SBarry Smith   This is because the later digits are meaningless and are often
555be1f7002SBarry Smith   different on different machines; by using this routine different
556be1f7002SBarry Smith   machines will usually generate the same output.
557dec21524SBarry Smith 
558dec21524SBarry Smith   Deprecated: Intentionally has no manual page
559be1f7002SBarry Smith */
5609371c9d4SSatish Balay PetscErrorCode SNESMonitorDefaultShort(SNES snes, PetscInt its, PetscReal fgnorm, PetscViewerAndFormat *vf) {
561d43b4f6eSBarry Smith   PetscViewer viewer = vf->viewer;
562d132466eSBarry Smith 
5633a40ed3dSBarry Smith   PetscFunctionBegin;
5644d4332d5SBarry Smith   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 4);
5659566063dSJacob Faibussowitsch   PetscCall(PetscViewerPushFormat(viewer, vf->format));
5669566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIIAddTab(viewer, ((PetscObject)snes)->tablevel));
5678f240d10SBarry Smith   if (fgnorm > 1.e-9) {
56863a3b9bcSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer, "%3" PetscInt_FMT " SNES Function norm %g \n", its, (double)fgnorm));
5693a40ed3dSBarry Smith   } else if (fgnorm > 1.e-11) {
57063a3b9bcSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer, "%3" PetscInt_FMT " SNES Function norm %5.3e \n", its, (double)fgnorm));
5713a40ed3dSBarry Smith   } else {
57263a3b9bcSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer, "%3" PetscInt_FMT " SNES Function norm < 1.e-11\n", its));
573a34d58ebSBarry Smith   }
5749566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIISubtractTab(viewer, ((PetscObject)snes)->tablevel));
5759566063dSJacob Faibussowitsch   PetscCall(PetscViewerPopFormat(viewer));
5763a40ed3dSBarry Smith   PetscFunctionReturn(0);
577e7e93795SLois Curfman McInnes }
5782db13446SMatthew G. Knepley 
5792db13446SMatthew G. Knepley /*@C
5802db13446SMatthew G. Knepley   SNESMonitorDefaultField - Monitors progress of the SNES solvers, separated into fields.
5812db13446SMatthew G. Knepley 
5822db13446SMatthew G. Knepley   Collective on SNES
5832db13446SMatthew G. Knepley 
5842db13446SMatthew G. Knepley   Input Parameters:
5852db13446SMatthew G. Knepley + snes   - the SNES context
5862db13446SMatthew G. Knepley . its    - iteration number
5872db13446SMatthew G. Knepley . fgnorm - 2-norm of residual
5882db13446SMatthew G. Knepley - ctx    - the PetscViewer
5892db13446SMatthew G. Knepley 
5902db13446SMatthew G. Knepley   Notes:
5913a61192cSBarry Smith   This routine uses the DM attached to the residual vector to define the fields.
5923a61192cSBarry Smith 
5933a61192cSBarry Smith   This is not called directly by users, rather one calls `SNESMonitorSet()`, with this function as an argument, to cause the monitor
5943a61192cSBarry Smith   to be used during the SNES solve.
5952db13446SMatthew G. Knepley 
5962db13446SMatthew G. Knepley   Level: intermediate
5972db13446SMatthew G. Knepley 
598db781477SPatrick Sanan .seealso: `SNESMonitorSet()`, `SNESMonitorSolution()`, `SNESMonitorDefault()`
5992db13446SMatthew G. Knepley @*/
6009371c9d4SSatish Balay PetscErrorCode SNESMonitorDefaultField(SNES snes, PetscInt its, PetscReal fgnorm, PetscViewerAndFormat *vf) {
601d43b4f6eSBarry Smith   PetscViewer viewer = vf->viewer;
6022db13446SMatthew G. Knepley   Vec         r;
6032db13446SMatthew G. Knepley   DM          dm;
6042db13446SMatthew G. Knepley   PetscReal   res[256];
6052db13446SMatthew G. Knepley   PetscInt    tablevel;
6062db13446SMatthew G. Knepley 
6072db13446SMatthew G. Knepley   PetscFunctionBegin;
6084d4332d5SBarry Smith   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 4);
6099566063dSJacob Faibussowitsch   PetscCall(SNESGetFunction(snes, &r, NULL, NULL));
6109566063dSJacob Faibussowitsch   PetscCall(VecGetDM(r, &dm));
6119566063dSJacob Faibussowitsch   if (!dm) PetscCall(SNESMonitorDefault(snes, its, fgnorm, vf));
6122db13446SMatthew G. Knepley   else {
6132db13446SMatthew G. Knepley     PetscSection s, gs;
6142db13446SMatthew G. Knepley     PetscInt     Nf, f;
6152db13446SMatthew G. Knepley 
6169566063dSJacob Faibussowitsch     PetscCall(DMGetLocalSection(dm, &s));
6179566063dSJacob Faibussowitsch     PetscCall(DMGetGlobalSection(dm, &gs));
6189566063dSJacob Faibussowitsch     if (!s || !gs) PetscCall(SNESMonitorDefault(snes, its, fgnorm, vf));
6199566063dSJacob Faibussowitsch     PetscCall(PetscSectionGetNumFields(s, &Nf));
62063a3b9bcSJacob Faibussowitsch     PetscCheck(Nf <= 256, PetscObjectComm((PetscObject)snes), PETSC_ERR_SUP, "Do not support %" PetscInt_FMT " fields > 256", Nf);
6219566063dSJacob Faibussowitsch     PetscCall(PetscSectionVecNorm(s, gs, r, NORM_2, res));
6229566063dSJacob Faibussowitsch     PetscCall(PetscObjectGetTabLevel((PetscObject)snes, &tablevel));
6239566063dSJacob Faibussowitsch     PetscCall(PetscViewerPushFormat(viewer, vf->format));
6249566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIAddTab(viewer, tablevel));
62563a3b9bcSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer, "%3" PetscInt_FMT " SNES Function norm %14.12e [", its, (double)fgnorm));
6262db13446SMatthew G. Knepley     for (f = 0; f < Nf; ++f) {
6279566063dSJacob Faibussowitsch       if (f) PetscCall(PetscViewerASCIIPrintf(viewer, ", "));
62863a3b9bcSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(viewer, "%14.12e", (double)res[f]));
6292db13446SMatthew G. Knepley     }
6309566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer, "] \n"));
6319566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIISubtractTab(viewer, tablevel));
6329566063dSJacob Faibussowitsch     PetscCall(PetscViewerPopFormat(viewer));
6332db13446SMatthew G. Knepley   }
6342db13446SMatthew G. Knepley   PetscFunctionReturn(0);
6352db13446SMatthew G. Knepley }
636e7e93795SLois Curfman McInnes /* ---------------------------------------------------------------- */
6374b828684SBarry Smith /*@C
638c34cbdceSBarry Smith    SNESConvergedDefault - Default onvergence test of the solvers for
639c34cbdceSBarry Smith    systems of nonlinear equations.
640e7e93795SLois Curfman McInnes 
641c7afd0dbSLois Curfman McInnes    Collective on SNES
642c7afd0dbSLois Curfman McInnes 
643e7e93795SLois Curfman McInnes    Input Parameters:
644c7afd0dbSLois Curfman McInnes +  snes - the SNES context
64506ee9f85SBarry Smith .  it - the iteration (0 indicates before any Newton steps)
646e7e93795SLois Curfman McInnes .  xnorm - 2-norm of current iterate
647c60f73f4SPeter Brune .  snorm - 2-norm of current step
6487f3332b4SBarry Smith .  fnorm - 2-norm of function at current iterate
649c7afd0dbSLois Curfman McInnes -  dummy - unused context
650e7e93795SLois Curfman McInnes 
651184914b5SBarry Smith    Output Parameter:
652184914b5SBarry Smith .   reason  - one of
65370441072SBarry Smith $  SNES_CONVERGED_FNORM_ABS       - (fnorm < abstol),
654c60f73f4SPeter Brune $  SNES_CONVERGED_SNORM_RELATIVE  - (snorm < stol*xnorm),
655184914b5SBarry Smith $  SNES_CONVERGED_FNORM_RELATIVE  - (fnorm < rtol*fnorm0),
656184914b5SBarry Smith $  SNES_DIVERGED_FUNCTION_COUNT   - (nfct > maxf),
657184914b5SBarry Smith $  SNES_DIVERGED_FNORM_NAN        - (fnorm == NaN),
658184914b5SBarry Smith $  SNES_CONVERGED_ITERATING       - (otherwise),
659c34cbdceSBarry Smith $  SNES_DIVERGED_DTOL             - (fnorm > divtol*snes->fnorm0)
660e7e93795SLois Curfman McInnes 
661e7e93795SLois Curfman McInnes    where
662c34cbdceSBarry Smith +    maxf - maximum number of function evaluations,  set with SNESSetTolerances()
663c7afd0dbSLois Curfman McInnes .    nfct - number of function evaluations,
664c34cbdceSBarry Smith .    abstol - absolute function norm tolerance, set with SNESSetTolerances()
665c34cbdceSBarry Smith .    rtol - relative function norm tolerance, set with SNESSetTolerances()
666c34cbdceSBarry Smith .    divtol - divergence tolerance, set with SNESSetDivergenceTolerance()
667c34cbdceSBarry Smith -    fnorm0 - 2-norm of the function at the initial solution (initial guess; zeroth iteration)
668c34cbdceSBarry Smith 
669c34cbdceSBarry Smith   Options Database Keys:
670f362779dSJed Brown +  -snes_convergence_test default - see SNESSetFromOptions()
671f362779dSJed Brown .  -snes_stol - convergence tolerance in terms of the norm  of the change in the solution between steps
672c34cbdceSBarry Smith .  -snes_atol <abstol> - absolute tolerance of residual norm
673c34cbdceSBarry Smith .  -snes_rtol <rtol> - relative decrease in tolerance norm from the initial 2-norm of the solution
674c34cbdceSBarry Smith .  -snes_divergence_tolerance <divtol> - if the residual goes above divtol*rnorm0, exit with divergence
675c34cbdceSBarry Smith .  -snes_max_funcs <max_funcs> - maximum number of function evaluations
676c34cbdceSBarry Smith .  -snes_max_fail <max_fail> - maximum number of line search failures allowed before stopping, default is none
677c34cbdceSBarry Smith -  -snes_max_linear_solve_fail - number of linear solver failures before SNESSolve() stops
678fee21e36SBarry Smith 
67936851e7fSLois Curfman McInnes    Level: intermediate
68036851e7fSLois Curfman McInnes 
681db781477SPatrick Sanan .seealso: `SNESSetConvergenceTest()`, `SNESConvergedSkip()`, `SNESSetTolerances()`, `SNESSetDivergenceTolerance()`
682e7e93795SLois Curfman McInnes @*/
6839371c9d4SSatish Balay PetscErrorCode SNESConvergedDefault(SNES snes, PetscInt it, PetscReal xnorm, PetscReal snorm, PetscReal fnorm, SNESConvergedReason *reason, void *dummy) {
6843a40ed3dSBarry Smith   PetscFunctionBegin;
6850700a824SBarry Smith   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
6863f149594SLisandro Dalcin   PetscValidPointer(reason, 6);
6873f149594SLisandro Dalcin 
68806ee9f85SBarry Smith   *reason = SNES_CONVERGED_ITERATING;
68906ee9f85SBarry Smith 
69006ee9f85SBarry Smith   if (!it) {
69106ee9f85SBarry Smith     /* set parameter for default relative tolerance convergence test */
69206ee9f85SBarry Smith     snes->ttol   = fnorm * snes->rtol;
693e37c518bSBarry Smith     snes->rnorm0 = fnorm;
69406ee9f85SBarry Smith   }
6958146f6ebSBarry Smith   if (PetscIsInfOrNanReal(fnorm)) {
6969566063dSJacob Faibussowitsch     PetscCall(PetscInfo(snes, "Failed to converged, function norm is NaN\n"));
697184914b5SBarry Smith     *reason = SNES_DIVERGED_FNORM_NAN;
698be5caee7SBarry Smith   } else if (fnorm < snes->abstol && (it || !snes->forceiteration)) {
6999566063dSJacob Faibussowitsch     PetscCall(PetscInfo(snes, "Converged due to function norm %14.12e < %14.12e\n", (double)fnorm, (double)snes->abstol));
700184914b5SBarry Smith     *reason = SNES_CONVERGED_FNORM_ABS;
701e71169deSBarry Smith   } else if (snes->nfuncs >= snes->max_funcs && snes->max_funcs >= 0) {
70263a3b9bcSJacob Faibussowitsch     PetscCall(PetscInfo(snes, "Exceeded maximum number of function evaluations: %" PetscInt_FMT " > %" PetscInt_FMT "\n", snes->nfuncs, snes->max_funcs));
703184914b5SBarry Smith     *reason = SNES_DIVERGED_FUNCTION_COUNT;
70406ee9f85SBarry Smith   }
70506ee9f85SBarry Smith 
70606ee9f85SBarry Smith   if (it && !*reason) {
70706ee9f85SBarry Smith     if (fnorm <= snes->ttol) {
7089566063dSJacob Faibussowitsch       PetscCall(PetscInfo(snes, "Converged due to function norm %14.12e < %14.12e (relative tolerance)\n", (double)fnorm, (double)snes->ttol));
70906ee9f85SBarry Smith       *reason = SNES_CONVERGED_FNORM_RELATIVE;
710c60f73f4SPeter Brune     } else if (snorm < snes->stol * xnorm) {
7119566063dSJacob Faibussowitsch       PetscCall(PetscInfo(snes, "Converged due to small update length: %14.12e < %14.12e * %14.12e\n", (double)snorm, (double)snes->stol, (double)xnorm));
712c60f73f4SPeter Brune       *reason = SNES_CONVERGED_SNORM_RELATIVE;
713e4d06f11SPatrick Farrell     } else if (snes->divtol > 0 && (fnorm > snes->divtol * snes->rnorm0)) {
7149566063dSJacob Faibussowitsch       PetscCall(PetscInfo(snes, "Diverged due to increase in function norm: %14.12e > %14.12e * %14.12e\n", (double)fnorm, (double)snes->divtol, (double)snes->rnorm0));
715e37c518bSBarry Smith       *reason = SNES_DIVERGED_DTOL;
71606ee9f85SBarry Smith     }
717e7e93795SLois Curfman McInnes   }
7183a40ed3dSBarry Smith   PetscFunctionReturn(0);
719e7e93795SLois Curfman McInnes }
7203f149594SLisandro Dalcin 
7213f149594SLisandro Dalcin /*@C
722e2a6519dSDmitry Karpeev    SNESConvergedSkip - Convergence test for SNES that NEVER returns as
7233f149594SLisandro Dalcin    converged, UNLESS the maximum number of iteration have been reached.
7243f149594SLisandro Dalcin 
7253f9fe445SBarry Smith    Logically Collective on SNES
7263f149594SLisandro Dalcin 
7273f149594SLisandro Dalcin    Input Parameters:
7283f149594SLisandro Dalcin +  snes - the SNES context
7293f149594SLisandro Dalcin .  it - the iteration (0 indicates before any Newton steps)
7303f149594SLisandro Dalcin .  xnorm - 2-norm of current iterate
731c60f73f4SPeter Brune .  snorm - 2-norm of current step
7323f149594SLisandro Dalcin .  fnorm - 2-norm of function at current iterate
7333f149594SLisandro Dalcin -  dummy - unused context
7343f149594SLisandro Dalcin 
7353f149594SLisandro Dalcin    Output Parameter:
73685385478SLisandro Dalcin .   reason  - SNES_CONVERGED_ITERATING, SNES_CONVERGED_ITS, or SNES_DIVERGED_FNORM_NAN
7373f149594SLisandro Dalcin 
7383f149594SLisandro Dalcin    Notes:
7393f149594SLisandro Dalcin    Convergence is then declared after a fixed number of iterations have been used.
7403f149594SLisandro Dalcin 
741f362779dSJed Brown    Options Database Keys:
742f362779dSJed Brown .  -snes_convergence_test default - see SNESSetFromOptions()
743f362779dSJed Brown 
7443f149594SLisandro Dalcin    Level: advanced
7453f149594SLisandro Dalcin 
746db781477SPatrick Sanan .seealso: `SNESConvergedDefault()`, `SNESSetConvergenceTest()`
7473f149594SLisandro Dalcin @*/
7489371c9d4SSatish Balay PetscErrorCode SNESConvergedSkip(SNES snes, PetscInt it, PetscReal xnorm, PetscReal snorm, PetscReal fnorm, SNESConvergedReason *reason, void *dummy) {
7493f149594SLisandro Dalcin   PetscFunctionBegin;
7500700a824SBarry Smith   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
7513f149594SLisandro Dalcin   PetscValidPointer(reason, 6);
7523f149594SLisandro Dalcin 
7533f149594SLisandro Dalcin   *reason = SNES_CONVERGED_ITERATING;
7543f149594SLisandro Dalcin 
7553f149594SLisandro Dalcin   if (fnorm != fnorm) {
7569566063dSJacob Faibussowitsch     PetscCall(PetscInfo(snes, "Failed to converged, function norm is NaN\n"));
7573f149594SLisandro Dalcin     *reason = SNES_DIVERGED_FNORM_NAN;
7583f149594SLisandro Dalcin   } else if (it == snes->max_its) {
7593f149594SLisandro Dalcin     *reason = SNES_CONVERGED_ITS;
7603f149594SLisandro Dalcin   }
7613f149594SLisandro Dalcin   PetscFunctionReturn(0);
7623f149594SLisandro Dalcin }
7633f149594SLisandro Dalcin 
7648d359177SBarry Smith /*@C
765fa0ddf94SBarry Smith   SNESSetWorkVecs - Gets a number of work vectors.
76658c9b817SLisandro Dalcin 
76758c9b817SLisandro Dalcin   Input Parameters:
768a2b725a8SWilliam Gropp + snes  - the SNES context
769a2b725a8SWilliam Gropp - nw - number of work vectors to allocate
77058c9b817SLisandro Dalcin 
77158c9b817SLisandro Dalcin   Level: developer
772fa0ddf94SBarry Smith 
77398acb6afSMatthew G Knepley @*/
7749371c9d4SSatish Balay PetscErrorCode SNESSetWorkVecs(SNES snes, PetscInt nw) {
775c5ed8070SMatthew G. Knepley   DM  dm;
776c5ed8070SMatthew G. Knepley   Vec v;
77758c9b817SLisandro Dalcin 
77858c9b817SLisandro Dalcin   PetscFunctionBegin;
7799566063dSJacob Faibussowitsch   if (snes->work) PetscCall(VecDestroyVecs(snes->nwork, &snes->work));
78058c9b817SLisandro Dalcin   snes->nwork = nw;
781f5af7f23SKarl Rupp 
7829566063dSJacob Faibussowitsch   PetscCall(SNESGetDM(snes, &dm));
7839566063dSJacob Faibussowitsch   PetscCall(DMGetGlobalVector(dm, &v));
7849566063dSJacob Faibussowitsch   PetscCall(VecDuplicateVecs(v, snes->nwork, &snes->work));
7859566063dSJacob Faibussowitsch   PetscCall(DMRestoreGlobalVector(dm, &v));
7869566063dSJacob Faibussowitsch   PetscCall(PetscLogObjectParents(snes, nw, snes->work));
78758c9b817SLisandro Dalcin   PetscFunctionReturn(0);
78858c9b817SLisandro Dalcin }
789