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