xref: /petsc/src/snes/interface/snesut.c (revision c2e3fba1fe1cda7e6350bbca19c4ed35ce95940a)
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 
2236851e7fSLois Curfman McInnes    Level: intermediate
233f1db9ecSBarry Smith 
24db781477SPatrick Sanan .seealso: `SNESMonitorSet()`, `SNESMonitorDefault()`, `VecView()`
253f1db9ecSBarry Smith @*/
26d43b4f6eSBarry Smith PetscErrorCode  SNESMonitorSolution(SNES snes,PetscInt its,PetscReal fgnorm,PetscViewerAndFormat *vf)
273f1db9ecSBarry Smith {
283f1db9ecSBarry Smith   Vec            x;
29d43b4f6eSBarry Smith   PetscViewer    viewer = vf->viewer;
303f1db9ecSBarry Smith 
313f1db9ecSBarry Smith   PetscFunctionBegin;
324d4332d5SBarry Smith   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,4);
339566063dSJacob Faibussowitsch   PetscCall(SNESGetSolution(snes,&x));
349566063dSJacob Faibussowitsch   PetscCall(PetscViewerPushFormat(viewer,vf->format));
359566063dSJacob Faibussowitsch   PetscCall(VecView(x,viewer));
369566063dSJacob Faibussowitsch   PetscCall(PetscViewerPopFormat(viewer));
373f1db9ecSBarry Smith   PetscFunctionReturn(0);
383f1db9ecSBarry Smith }
393f1db9ecSBarry Smith 
405ed2d596SBarry Smith /*@C
41a6570f20SBarry Smith    SNESMonitorResidual - Monitors progress of the SNES solvers by calling
425ed2d596SBarry Smith    VecView() for the residual at each iteration.
435ed2d596SBarry Smith 
445ed2d596SBarry Smith    Collective on SNES
455ed2d596SBarry Smith 
465ed2d596SBarry Smith    Input Parameters:
475ed2d596SBarry Smith +  snes - the SNES context
485ed2d596SBarry Smith .  its - iteration number
494b27c08aSLois Curfman McInnes .  fgnorm - 2-norm of residual
50f55353a2SBarry Smith -  dummy -  a viewer
515ed2d596SBarry Smith 
52ee32d87aSMatthew G. Knepley    Options Database Keys:
53ee32d87aSMatthew G. Knepley .  -snes_monitor_residual [ascii binary draw][:filename][:viewer format] - plots residual (not its norm) at each iteration
54ee32d87aSMatthew G. Knepley 
555ed2d596SBarry Smith    Level: intermediate
565ed2d596SBarry Smith 
57db781477SPatrick Sanan .seealso: `SNESMonitorSet()`, `SNESMonitorDefault()`, `VecView()`
585ed2d596SBarry Smith @*/
59d43b4f6eSBarry Smith PetscErrorCode  SNESMonitorResidual(SNES snes,PetscInt its,PetscReal fgnorm,PetscViewerAndFormat *vf)
605ed2d596SBarry Smith {
615ed2d596SBarry Smith   Vec            x;
62d43b4f6eSBarry Smith   PetscViewer    viewer = vf->viewer;
635ed2d596SBarry Smith 
645ed2d596SBarry Smith   PetscFunctionBegin;
654d4332d5SBarry Smith   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,4);
669566063dSJacob Faibussowitsch   PetscCall(SNESGetFunction(snes,&x,NULL,NULL));
679566063dSJacob Faibussowitsch   PetscCall(PetscViewerPushFormat(viewer,vf->format));
689566063dSJacob Faibussowitsch   PetscCall(VecView(x,viewer));
699566063dSJacob Faibussowitsch   PetscCall(PetscViewerPopFormat(viewer));
705ed2d596SBarry Smith   PetscFunctionReturn(0);
715ed2d596SBarry Smith }
725ed2d596SBarry Smith 
73d132466eSBarry Smith /*@C
74a6570f20SBarry Smith    SNESMonitorSolutionUpdate - Monitors progress of the SNES solvers by calling
75d132466eSBarry Smith    VecView() for the UPDATE to the solution at each iteration.
76d132466eSBarry Smith 
77d132466eSBarry Smith    Collective on SNES
78d132466eSBarry Smith 
79d132466eSBarry Smith    Input Parameters:
80d132466eSBarry Smith +  snes - the SNES context
81d132466eSBarry Smith .  its - iteration number
824b27c08aSLois Curfman McInnes .  fgnorm - 2-norm of residual
83f55353a2SBarry Smith -  dummy - a viewer
84d132466eSBarry Smith 
85ee32d87aSMatthew G. Knepley    Options Database Keys:
86ee32d87aSMatthew G. Knepley .  -snes_monitor_solution_update [ascii binary draw][:filename][:viewer format] - plots update to solution at each iteration
87ee32d87aSMatthew G. Knepley 
88d132466eSBarry Smith    Level: intermediate
89d132466eSBarry Smith 
90db781477SPatrick Sanan .seealso: `SNESMonitorSet()`, `SNESMonitorDefault()`, `VecView()`
91d132466eSBarry Smith @*/
92d43b4f6eSBarry Smith PetscErrorCode  SNESMonitorSolutionUpdate(SNES snes,PetscInt its,PetscReal fgnorm,PetscViewerAndFormat *vf)
93d132466eSBarry Smith {
94d132466eSBarry Smith   Vec            x;
95d43b4f6eSBarry Smith   PetscViewer    viewer = vf->viewer;
96d132466eSBarry Smith 
97d132466eSBarry Smith   PetscFunctionBegin;
984d4332d5SBarry Smith   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,4);
999566063dSJacob Faibussowitsch   PetscCall(SNESGetSolutionUpdate(snes,&x));
1009566063dSJacob Faibussowitsch   PetscCall(PetscViewerPushFormat(viewer,vf->format));
1019566063dSJacob Faibussowitsch   PetscCall(VecView(x,viewer));
1029566063dSJacob Faibussowitsch   PetscCall(PetscViewerPopFormat(viewer));
103d132466eSBarry Smith   PetscFunctionReturn(0);
104d132466eSBarry Smith }
105d132466eSBarry Smith 
106798534f6SMatthew G. Knepley #include <petscdraw.h>
107a5c2985bSBarry Smith 
108798534f6SMatthew G. Knepley /*@C
109798534f6SMatthew G. Knepley   KSPMonitorSNESResidual - Prints the SNES residual norm, as well as the linear residual norm, at each iteration of an iterative solver.
110798534f6SMatthew G. Knepley 
111798534f6SMatthew G. Knepley   Collective on ksp
112a5c2985bSBarry Smith 
113a5c2985bSBarry Smith   Input Parameters:
114a5c2985bSBarry Smith + ksp   - iterative context
115a5c2985bSBarry Smith . n     - iteration number
116a5c2985bSBarry Smith . rnorm - 2-norm (preconditioned) residual value (may be estimated).
117798534f6SMatthew G. Knepley - vf    - The viewer context
118798534f6SMatthew G. Knepley 
119798534f6SMatthew G. Knepley   Options Database Key:
120798534f6SMatthew G. Knepley . -snes_monitor_ksp - Activates KSPMonitorSNESResidual()
121a5c2985bSBarry Smith 
122a5c2985bSBarry Smith   Level: intermediate
123a5c2985bSBarry Smith 
124*c2e3fba1SPatrick Sanan .seealso: `KSPMonitorSet()`, `KSPMonitorResidual()`, `KSPMonitorTrueResidualMaxNorm()`
125a5c2985bSBarry Smith @*/
126798534f6SMatthew G. Knepley PetscErrorCode KSPMonitorSNESResidual(KSP ksp, PetscInt n, PetscReal rnorm, PetscViewerAndFormat *vf)
127a5c2985bSBarry Smith {
128798534f6SMatthew G. Knepley   PetscViewer       viewer = vf->viewer;
129798534f6SMatthew G. Knepley   PetscViewerFormat format = vf->format;
130798534f6SMatthew G. Knepley   SNES              snes   = (SNES) vf->data;
131a5c2985bSBarry Smith   Vec               snes_solution, work1, work2;
132a5c2985bSBarry Smith   PetscReal         snorm;
133798534f6SMatthew G. Knepley   PetscInt          tablevel;
134798534f6SMatthew G. Knepley   const char       *prefix;
135a5c2985bSBarry Smith 
136a5c2985bSBarry Smith   PetscFunctionBegin;
137798534f6SMatthew G. Knepley   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 4);
1389566063dSJacob Faibussowitsch   PetscCall(SNESGetSolution(snes, &snes_solution));
1399566063dSJacob Faibussowitsch   PetscCall(VecDuplicate(snes_solution, &work1));
1409566063dSJacob Faibussowitsch   PetscCall(VecDuplicate(snes_solution, &work2));
1419566063dSJacob Faibussowitsch   PetscCall(KSPBuildSolution(ksp, work1, NULL));
1429566063dSJacob Faibussowitsch   PetscCall(VecAYPX(work1, -1.0, snes_solution));
1439566063dSJacob Faibussowitsch   PetscCall(SNESComputeFunction(snes, work1, work2));
1449566063dSJacob Faibussowitsch   PetscCall(VecNorm(work2, NORM_2, &snorm));
1459566063dSJacob Faibussowitsch   PetscCall(VecDestroy(&work1));
1469566063dSJacob Faibussowitsch   PetscCall(VecDestroy(&work2));
147a5c2985bSBarry Smith 
1489566063dSJacob Faibussowitsch   PetscCall(PetscObjectGetTabLevel((PetscObject) ksp, &tablevel));
1499566063dSJacob Faibussowitsch   PetscCall(PetscObjectGetOptionsPrefix((PetscObject) ksp, &prefix));
1509566063dSJacob Faibussowitsch   PetscCall(PetscViewerPushFormat(viewer, format));
1519566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIIAddTab(viewer, tablevel));
1529566063dSJacob Faibussowitsch   if (n == 0 && prefix) PetscCall(PetscViewerASCIIPrintf(viewer, "  Residual norms for %s solve.\n", prefix));
15363a3b9bcSJacob Faibussowitsch   PetscCall(PetscViewerASCIIPrintf(viewer, "%3" PetscInt_FMT " SNES Residual norm %5.3e KSP Residual norm %5.3e \n", n, (double) snorm, (double) rnorm));
1549566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIISubtractTab(viewer, tablevel));
1559566063dSJacob Faibussowitsch   PetscCall(PetscViewerPopFormat(viewer));
156a5c2985bSBarry Smith   PetscFunctionReturn(0);
157a5c2985bSBarry Smith }
158a5c2985bSBarry Smith 
159e5f7ee39SBarry Smith /*@C
160798534f6SMatthew G. Knepley   KSPMonitorSNESResidualDrawLG - Plots the linear SNES residual norm at each iteration of an iterative solver.
161e5f7ee39SBarry Smith 
162798534f6SMatthew G. Knepley   Collective on ksp
163e5f7ee39SBarry Smith 
164e5f7ee39SBarry Smith   Input Parameters:
165798534f6SMatthew G. Knepley + ksp   - iterative context
166798534f6SMatthew G. Knepley . n     - iteration number
167798534f6SMatthew G. Knepley . rnorm - 2-norm (preconditioned) residual value (may be estimated).
168798534f6SMatthew G. Knepley - vf    - The viewer context
169e5f7ee39SBarry Smith 
170e5f7ee39SBarry Smith   Options Database Key:
171798534f6SMatthew G. Knepley . -snes_monitor_ksp draw::draw_lg - Activates KSPMonitorSNESResidualDrawLG()
172e5f7ee39SBarry Smith 
173e5f7ee39SBarry Smith   Level: intermediate
174e5f7ee39SBarry Smith 
175db781477SPatrick Sanan .seealso: `KSPMonitorSet()`, `KSPMonitorTrueResidual()`
176e5f7ee39SBarry Smith @*/
177798534f6SMatthew G. Knepley PetscErrorCode KSPMonitorSNESResidualDrawLG(KSP ksp, PetscInt n, PetscReal rnorm, PetscViewerAndFormat *vf)
178e5f7ee39SBarry Smith {
179798534f6SMatthew G. Knepley   PetscViewer        viewer = vf->viewer;
180798534f6SMatthew G. Knepley   PetscViewerFormat  format = vf->format;
181798534f6SMatthew G. Knepley   PetscDrawLG        lg     = vf->lg;
182798534f6SMatthew G. Knepley   SNES               snes   = (SNES) vf->data;
183e5f7ee39SBarry Smith   Vec                snes_solution, work1, work2;
184798534f6SMatthew G. Knepley   PetscReal          snorm;
185798534f6SMatthew G. Knepley   KSPConvergedReason reason;
186798534f6SMatthew G. Knepley   PetscReal          x[2], y[2];
187e5f7ee39SBarry Smith 
188e5f7ee39SBarry Smith   PetscFunctionBegin;
189798534f6SMatthew G. Knepley   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 4);
190064a246eSJacob Faibussowitsch   PetscValidHeaderSpecific(lg, PETSC_DRAWLG_CLASSID, 4);
1919566063dSJacob Faibussowitsch   PetscCall(SNESGetSolution(snes, &snes_solution));
1929566063dSJacob Faibussowitsch   PetscCall(VecDuplicate(snes_solution, &work1));
1939566063dSJacob Faibussowitsch   PetscCall(VecDuplicate(snes_solution, &work2));
1949566063dSJacob Faibussowitsch   PetscCall(KSPBuildSolution(ksp, work1, NULL));
1959566063dSJacob Faibussowitsch   PetscCall(VecAYPX(work1, -1.0, snes_solution));
1969566063dSJacob Faibussowitsch   PetscCall(SNESComputeFunction(snes, work1, work2));
1979566063dSJacob Faibussowitsch   PetscCall(VecNorm(work2, NORM_2, &snorm));
1989566063dSJacob Faibussowitsch   PetscCall(VecDestroy(&work1));
1999566063dSJacob Faibussowitsch   PetscCall(VecDestroy(&work2));
200e5f7ee39SBarry Smith 
2019566063dSJacob Faibussowitsch   PetscCall(PetscViewerPushFormat(viewer, format));
2029566063dSJacob Faibussowitsch   if (!n) PetscCall(PetscDrawLGReset(lg));
203798534f6SMatthew G. Knepley   x[0] = (PetscReal) n;
204798534f6SMatthew G. Knepley   if (rnorm > 0.0) y[0] = PetscLog10Real(rnorm);
205798534f6SMatthew G. Knepley   else y[0] = -15.0;
206798534f6SMatthew G. Knepley   x[1] = (PetscReal) n;
207798534f6SMatthew G. Knepley   if (snorm > 0.0) y[1] = PetscLog10Real(snorm);
208798534f6SMatthew G. Knepley   else y[1] = -15.0;
2099566063dSJacob Faibussowitsch   PetscCall(PetscDrawLGAddPoint(lg, x, y));
2109566063dSJacob Faibussowitsch   PetscCall(KSPGetConvergedReason(ksp, &reason));
211798534f6SMatthew G. Knepley   if (n <= 20 || !(n % 5) || reason) {
2129566063dSJacob Faibussowitsch     PetscCall(PetscDrawLGDraw(lg));
2139566063dSJacob Faibussowitsch     PetscCall(PetscDrawLGSave(lg));
214e5f7ee39SBarry Smith   }
2159566063dSJacob Faibussowitsch   PetscCall(PetscViewerPopFormat(viewer));
216e5f7ee39SBarry Smith   PetscFunctionReturn(0);
217e5f7ee39SBarry Smith }
218e5f7ee39SBarry Smith 
219798534f6SMatthew G. Knepley /*@C
220798534f6SMatthew G. Knepley   KSPMonitorSNESResidualDrawLGCreate - Creates the plotter for the linear SNES residual.
221e5f7ee39SBarry Smith 
222798534f6SMatthew G. Knepley   Collective on ksp
223e5f7ee39SBarry Smith 
224798534f6SMatthew G. Knepley   Input Parameters:
225b693eab9SMatthew G. Knepley + viewer - The PetscViewer
226798534f6SMatthew G. Knepley . format - The viewer format
227798534f6SMatthew G. Knepley - ctx    - An optional user context
228798534f6SMatthew G. Knepley 
229798534f6SMatthew G. Knepley   Output Parameter:
230798534f6SMatthew G. Knepley . vf    - The viewer context
231e5f7ee39SBarry Smith 
232e5f7ee39SBarry Smith   Level: intermediate
233e5f7ee39SBarry Smith 
234db781477SPatrick Sanan .seealso: `KSPMonitorSet()`, `KSPMonitorTrueResidual()`
235e5f7ee39SBarry Smith @*/
236798534f6SMatthew G. Knepley PetscErrorCode KSPMonitorSNESResidualDrawLGCreate(PetscViewer viewer, PetscViewerFormat format, void *ctx, PetscViewerAndFormat **vf)
237e5f7ee39SBarry Smith {
238798534f6SMatthew G. Knepley   const char    *names[] = {"linear", "nonlinear"};
239e5f7ee39SBarry Smith 
240e5f7ee39SBarry Smith   PetscFunctionBegin;
2419566063dSJacob Faibussowitsch   PetscCall(PetscViewerAndFormatCreate(viewer, format, vf));
242798534f6SMatthew G. Knepley   (*vf)->data = ctx;
2439566063dSJacob Faibussowitsch   PetscCall(KSPMonitorLGCreate(PetscObjectComm((PetscObject) viewer), NULL, NULL, "Log Residual Norm", 2, names, PETSC_DECIDE, PETSC_DECIDE, 400, 300, &(*vf)->lg));
244e5f7ee39SBarry Smith   PetscFunctionReturn(0);
245e5f7ee39SBarry Smith }
246e5f7ee39SBarry Smith 
247fbcc4530SMatthew G. Knepley PetscErrorCode SNESMonitorDefaultSetUp(SNES snes, PetscViewerAndFormat *vf)
248fbcc4530SMatthew G. Knepley {
249fbcc4530SMatthew G. Knepley   PetscFunctionBegin;
250fbcc4530SMatthew G. Knepley   if (vf->format == PETSC_VIEWER_DRAW_LG) {
2519566063dSJacob Faibussowitsch     PetscCall(KSPMonitorLGCreate(PetscObjectComm((PetscObject) vf->viewer), NULL, NULL, "Log Residual Norm", 1, NULL, PETSC_DECIDE, PETSC_DECIDE, 400, 300, &vf->lg));
252fbcc4530SMatthew G. Knepley   }
253fbcc4530SMatthew G. Knepley   PetscFunctionReturn(0);
254fbcc4530SMatthew G. Knepley }
255fbcc4530SMatthew G. Knepley 
2564b828684SBarry Smith /*@C
257a6570f20SBarry Smith    SNESMonitorDefault - Monitors progress of the SNES solvers (default).
258e7e93795SLois Curfman McInnes 
259c7afd0dbSLois Curfman McInnes    Collective on SNES
260c7afd0dbSLois Curfman McInnes 
261e7e93795SLois Curfman McInnes    Input Parameters:
262c7afd0dbSLois Curfman McInnes +  snes - the SNES context
263e7e93795SLois Curfman McInnes .  its - iteration number
2644b27c08aSLois Curfman McInnes .  fgnorm - 2-norm of residual
265d43b4f6eSBarry Smith -  vf - viewer and format structure
266fee21e36SBarry Smith 
267e7e93795SLois Curfman McInnes    Notes:
2684b27c08aSLois Curfman McInnes    This routine prints the residual norm at each iteration.
269e7e93795SLois Curfman McInnes 
27036851e7fSLois Curfman McInnes    Level: intermediate
27136851e7fSLois Curfman McInnes 
272db781477SPatrick Sanan .seealso: `SNESMonitorSet()`, `SNESMonitorSolution()`
273e7e93795SLois Curfman McInnes @*/
274d43b4f6eSBarry Smith PetscErrorCode  SNESMonitorDefault(SNES snes,PetscInt its,PetscReal fgnorm,PetscViewerAndFormat *vf)
275e7e93795SLois Curfman McInnes {
276d43b4f6eSBarry Smith   PetscViewer       viewer = vf->viewer;
277798534f6SMatthew G. Knepley   PetscViewerFormat format = vf->format;
278798534f6SMatthew G. Knepley   PetscBool         isascii, isdraw;
279d132466eSBarry Smith 
2803a40ed3dSBarry Smith   PetscFunctionBegin;
2814d4332d5SBarry Smith   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,4);
2829566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject) viewer, PETSCVIEWERASCII, &isascii));
2839566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject) viewer, PETSCVIEWERDRAW,  &isdraw));
2849566063dSJacob Faibussowitsch   PetscCall(PetscViewerPushFormat(viewer,format));
285798534f6SMatthew G. Knepley   if (isascii) {
2869566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIAddTab(viewer,((PetscObject)snes)->tablevel));
28763a3b9bcSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer,"%3" PetscInt_FMT " SNES Function norm %14.12e \n",its,(double)fgnorm));
2889566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIISubtractTab(viewer,((PetscObject)snes)->tablevel));
289798534f6SMatthew G. Knepley   } else if (isdraw) {
290798534f6SMatthew G. Knepley     if (format == PETSC_VIEWER_DRAW_LG) {
291798534f6SMatthew G. Knepley       PetscDrawLG lg = (PetscDrawLG) vf->lg;
292798534f6SMatthew G. Knepley       PetscReal   x, y;
293798534f6SMatthew G. Knepley 
294798534f6SMatthew G. Knepley       PetscValidHeaderSpecific(lg,PETSC_DRAWLG_CLASSID,4);
2959566063dSJacob Faibussowitsch       if (!its) PetscCall(PetscDrawLGReset(lg));
296798534f6SMatthew G. Knepley       x = (PetscReal) its;
297798534f6SMatthew G. Knepley       if (fgnorm > 0.0) y = PetscLog10Real(fgnorm);
298798534f6SMatthew G. Knepley       else y = -15.0;
2999566063dSJacob Faibussowitsch       PetscCall(PetscDrawLGAddPoint(lg,&x,&y));
300798534f6SMatthew G. Knepley       if (its <= 20 || !(its % 5) || snes->reason) {
3019566063dSJacob Faibussowitsch         PetscCall(PetscDrawLGDraw(lg));
3029566063dSJacob Faibussowitsch         PetscCall(PetscDrawLGSave(lg));
303798534f6SMatthew G. Knepley       }
304798534f6SMatthew G. Knepley     }
305798534f6SMatthew G. Knepley   }
3069566063dSJacob Faibussowitsch   PetscCall(PetscViewerPopFormat(viewer));
3073a40ed3dSBarry Smith   PetscFunctionReturn(0);
308e7e93795SLois Curfman McInnes }
3093f1db9ecSBarry Smith 
3101f60017eSBarry Smith /*@C
3111f60017eSBarry Smith    SNESMonitorScaling - Monitors the largest value in each row of the Jacobian.
3121f60017eSBarry Smith 
3131f60017eSBarry Smith    Collective on SNES
3141f60017eSBarry Smith 
3151f60017eSBarry Smith    Input Parameters:
3161f60017eSBarry Smith +  snes - the SNES context
3171f60017eSBarry Smith .  its - iteration number
3181f60017eSBarry Smith .  fgnorm - 2-norm of residual
3191f60017eSBarry Smith -  vf - viewer and format structure
3201f60017eSBarry Smith 
3211f60017eSBarry Smith    Notes:
3221f60017eSBarry Smith    This routine prints the largest value in each row of the Jacobian
3231f60017eSBarry Smith 
3241f60017eSBarry Smith    Level: intermediate
3251f60017eSBarry Smith 
326db781477SPatrick Sanan .seealso: `SNESMonitorSet()`, `SNESMonitorSolution()`
3271f60017eSBarry Smith @*/
3281f60017eSBarry Smith PetscErrorCode  SNESMonitorScaling(SNES snes,PetscInt its,PetscReal fgnorm,PetscViewerAndFormat *vf)
3291f60017eSBarry Smith {
3301f60017eSBarry Smith   PetscViewer    viewer = vf->viewer;
3311f60017eSBarry Smith   KSP            ksp;
3321f60017eSBarry Smith   Mat            J;
3331f60017eSBarry Smith   Vec            v;
3341f60017eSBarry Smith 
3351f60017eSBarry Smith   PetscFunctionBegin;
3361f60017eSBarry Smith   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,4);
3379566063dSJacob Faibussowitsch   PetscCall(SNESGetKSP(snes,&ksp));
3389566063dSJacob Faibussowitsch   PetscCall(KSPGetOperators(ksp,&J,NULL));
3399566063dSJacob Faibussowitsch   PetscCall(MatCreateVecs(J,&v,NULL));
3409566063dSJacob Faibussowitsch   PetscCall(MatGetRowMaxAbs(J,v,NULL));
3419566063dSJacob Faibussowitsch   PetscCall(PetscViewerPushFormat(viewer,vf->format));
3429566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIIAddTab(viewer,((PetscObject)snes)->tablevel));
34363a3b9bcSJacob Faibussowitsch   PetscCall(PetscViewerASCIIPrintf(viewer,"SNES Jacobian maximum row entries\n"));
3449566063dSJacob Faibussowitsch   PetscCall(VecView(v,viewer));
3459566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIISubtractTab(viewer,((PetscObject)snes)->tablevel));
3469566063dSJacob Faibussowitsch   PetscCall(PetscViewerPopFormat(viewer));
3479566063dSJacob Faibussowitsch   PetscCall(VecDestroy(&v));
3481f60017eSBarry Smith   PetscFunctionReturn(0);
3491f60017eSBarry Smith }
3501f60017eSBarry Smith 
351d43b4f6eSBarry Smith PetscErrorCode SNESMonitorJacUpdateSpectrum(SNES snes,PetscInt it,PetscReal fnorm,PetscViewerAndFormat *vf)
352a80ad3e0SBarry Smith {
3532e7541e6SPeter Brune   Vec            X;
3542e7541e6SPeter Brune   Mat            J,dJ,dJdense;
355d1e9a80fSBarry Smith   PetscErrorCode (*func)(SNES,Vec,Mat,Mat,void*);
3562f96bde4SJose E. Roman   PetscInt       n;
35723fff9afSBarry Smith   PetscBLASInt   nb = 0,lwork;
3582e7541e6SPeter Brune   PetscReal      *eigr,*eigi;
3592e7541e6SPeter Brune   PetscScalar    *work;
3602e7541e6SPeter Brune   PetscScalar    *a;
3612e7541e6SPeter Brune 
3622e7541e6SPeter Brune   PetscFunctionBegin;
3632e7541e6SPeter Brune   if (it == 0) PetscFunctionReturn(0);
3642e7541e6SPeter Brune   /* create the difference between the current update and the current jacobian */
3659566063dSJacob Faibussowitsch   PetscCall(SNESGetSolution(snes,&X));
3669566063dSJacob Faibussowitsch   PetscCall(SNESGetJacobian(snes,NULL,&J,&func,NULL));
3679566063dSJacob Faibussowitsch   PetscCall(MatDuplicate(J,MAT_COPY_VALUES,&dJ));
3689566063dSJacob Faibussowitsch   PetscCall(SNESComputeJacobian(snes,X,dJ,dJ));
3699566063dSJacob Faibussowitsch   PetscCall(MatAXPY(dJ,-1.0,J,SAME_NONZERO_PATTERN));
370f5af7f23SKarl Rupp 
3712e7541e6SPeter Brune   /* compute the spectrum directly */
3729566063dSJacob Faibussowitsch   PetscCall(MatConvert(dJ,MATSEQDENSE,MAT_INITIAL_MATRIX,&dJdense));
3739566063dSJacob Faibussowitsch   PetscCall(MatGetSize(dJ,&n,NULL));
3749566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(n,&nb));
3752e7541e6SPeter Brune   lwork = 3*nb;
3769566063dSJacob Faibussowitsch   PetscCall(PetscMalloc1(n,&eigr));
3779566063dSJacob Faibussowitsch   PetscCall(PetscMalloc1(n,&eigi));
3789566063dSJacob Faibussowitsch   PetscCall(PetscMalloc1(lwork,&work));
3799566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArray(dJdense,&a));
3802e7541e6SPeter Brune #if !defined(PETSC_USE_COMPLEX)
3812e7541e6SPeter Brune   {
3822e7541e6SPeter Brune     PetscBLASInt lierr;
3832f96bde4SJose E. Roman     PetscInt     i;
3849566063dSJacob Faibussowitsch     PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF));
3858b83055fSJed Brown     PetscStackCallBLAS("LAPACKgeev",LAPACKgeev_("N","N",&nb,a,&nb,eigr,eigi,NULL,&nb,NULL,&nb,work,&lwork,&lierr));
38663a3b9bcSJacob Faibussowitsch     PetscCheck(!lierr,PETSC_COMM_SELF,PETSC_ERR_LIB,"geev() error %" PetscBLASInt_FMT,lierr);
3879566063dSJacob Faibussowitsch     PetscCall(PetscFPTrapPop());
38863a3b9bcSJacob Faibussowitsch     PetscCall(PetscPrintf(PetscObjectComm((PetscObject)snes),"Eigenvalues of J_%" PetscInt_FMT " - J_%" PetscInt_FMT ":\n",it,it-1));
3892e7541e6SPeter Brune     for (i=0;i<n;i++) {
39063a3b9bcSJacob Faibussowitsch       PetscCall(PetscPrintf(PetscObjectComm((PetscObject)snes),"%5" PetscInt_FMT ": %20.5g + %20.5gi\n",i,(double)eigr[i],(double)eigi[i]));
3912e7541e6SPeter Brune     }
3922f96bde4SJose E. Roman   }
3939566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArray(dJdense,&a));
3949566063dSJacob Faibussowitsch   PetscCall(MatDestroy(&dJ));
3959566063dSJacob Faibussowitsch   PetscCall(MatDestroy(&dJdense));
3969566063dSJacob Faibussowitsch   PetscCall(PetscFree(eigr));
3979566063dSJacob Faibussowitsch   PetscCall(PetscFree(eigi));
3989566063dSJacob Faibussowitsch   PetscCall(PetscFree(work));
3992e7541e6SPeter Brune   PetscFunctionReturn(0);
4002f96bde4SJose E. Roman #else
4012f96bde4SJose E. Roman   SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not coded for complex");
4022f96bde4SJose E. Roman #endif
4032e7541e6SPeter Brune }
4042e7541e6SPeter Brune 
4056ba87a44SLisandro Dalcin PETSC_INTERN PetscErrorCode  SNESMonitorRange_Private(SNES,PetscInt,PetscReal*);
4066ba87a44SLisandro Dalcin 
4077087cfbeSBarry Smith PetscErrorCode  SNESMonitorRange_Private(SNES snes,PetscInt it,PetscReal *per)
408b271bb04SBarry Smith {
409b271bb04SBarry Smith   Vec            resid;
410b271bb04SBarry Smith   PetscReal      rmax,pwork;
411b271bb04SBarry Smith   PetscInt       i,n,N;
412b271bb04SBarry Smith   PetscScalar    *r;
413b271bb04SBarry Smith 
414b271bb04SBarry Smith   PetscFunctionBegin;
4159566063dSJacob Faibussowitsch   PetscCall(SNESGetFunction(snes,&resid,NULL,NULL));
4169566063dSJacob Faibussowitsch   PetscCall(VecNorm(resid,NORM_INFINITY,&rmax));
4179566063dSJacob Faibussowitsch   PetscCall(VecGetLocalSize(resid,&n));
4189566063dSJacob Faibussowitsch   PetscCall(VecGetSize(resid,&N));
4199566063dSJacob Faibussowitsch   PetscCall(VecGetArray(resid,&r));
420b271bb04SBarry Smith   pwork = 0.0;
421b271bb04SBarry Smith   for (i=0; i<n; i++) {
422b271bb04SBarry Smith     pwork += (PetscAbsScalar(r[i]) > .20*rmax);
423b271bb04SBarry Smith   }
4241c2dc1cbSBarry Smith   PetscCall(MPIU_Allreduce(&pwork,per,1,MPIU_REAL,MPIU_SUM,PetscObjectComm((PetscObject)snes)));
4259566063dSJacob Faibussowitsch   PetscCall(VecRestoreArray(resid,&r));
426b271bb04SBarry Smith   *per = *per/N;
427b271bb04SBarry Smith   PetscFunctionReturn(0);
428b271bb04SBarry Smith }
429b271bb04SBarry Smith 
430b271bb04SBarry Smith /*@C
431b271bb04SBarry Smith    SNESMonitorRange - Prints the percentage of residual elements that are more then 10 percent of the maximum value.
432b271bb04SBarry Smith 
433b271bb04SBarry Smith    Collective on SNES
434b271bb04SBarry Smith 
435b271bb04SBarry Smith    Input Parameters:
436b271bb04SBarry Smith +  snes   - iterative context
437b271bb04SBarry Smith .  it    - iteration number
438b271bb04SBarry Smith .  rnorm - 2-norm (preconditioned) residual value (may be estimated).
439b271bb04SBarry Smith -  dummy - unused monitor context
440b271bb04SBarry Smith 
441b271bb04SBarry Smith    Options Database Key:
442b271bb04SBarry Smith .  -snes_monitor_range - Activates SNESMonitorRange()
443b271bb04SBarry Smith 
444b271bb04SBarry Smith    Level: intermediate
445b271bb04SBarry Smith 
446db781477SPatrick Sanan .seealso: `SNESMonitorSet()`, `SNESMonitorDefault()`, `SNESMonitorLGCreate()`
447b271bb04SBarry Smith @*/
448d43b4f6eSBarry Smith PetscErrorCode  SNESMonitorRange(SNES snes,PetscInt it,PetscReal rnorm,PetscViewerAndFormat *vf)
449b271bb04SBarry Smith {
450b271bb04SBarry Smith   PetscReal      perc,rel;
451d43b4f6eSBarry Smith   PetscViewer    viewer = vf->viewer;
452b271bb04SBarry Smith   /* should be in a MonitorRangeContext */
453b271bb04SBarry Smith   static PetscReal prev;
454b271bb04SBarry Smith 
455b271bb04SBarry Smith   PetscFunctionBegin;
4564d4332d5SBarry Smith   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,4);
457b271bb04SBarry Smith   if (!it) prev = rnorm;
4589566063dSJacob Faibussowitsch   PetscCall(SNESMonitorRange_Private(snes,it,&perc));
459b271bb04SBarry Smith 
460b271bb04SBarry Smith   rel  = (prev - rnorm)/prev;
461b271bb04SBarry Smith   prev = rnorm;
4629566063dSJacob Faibussowitsch   PetscCall(PetscViewerPushFormat(viewer,vf->format));
4639566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIIAddTab(viewer,((PetscObject)snes)->tablevel));
46463a3b9bcSJacob 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)));
4659566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIISubtractTab(viewer,((PetscObject)snes)->tablevel));
4669566063dSJacob Faibussowitsch   PetscCall(PetscViewerPopFormat(viewer));
467b271bb04SBarry Smith   PetscFunctionReturn(0);
468b271bb04SBarry Smith }
469b271bb04SBarry Smith 
4703a7fca6bSBarry Smith /*@C
471a6570f20SBarry Smith    SNESMonitorRatio - Monitors progress of the SNES solvers by printing the ratio
4724b27c08aSLois Curfman McInnes    of residual norm at each iteration to the previous.
4733a7fca6bSBarry Smith 
4743a7fca6bSBarry Smith    Collective on SNES
4753a7fca6bSBarry Smith 
4763a7fca6bSBarry Smith    Input Parameters:
4773a7fca6bSBarry Smith +  snes - the SNES context
4783a7fca6bSBarry Smith .  its - iteration number
4793a7fca6bSBarry Smith .  fgnorm - 2-norm of residual (or gradient)
480eabae89aSBarry Smith -  dummy -  context of monitor
4813a7fca6bSBarry Smith 
4823a7fca6bSBarry Smith    Level: intermediate
4833a7fca6bSBarry Smith 
48495452b02SPatrick Sanan    Notes:
48595452b02SPatrick Sanan     Insure that SNESMonitorRatio() is called when you set this monitor
486db781477SPatrick Sanan .seealso: `SNESMonitorSet()`, `SNESMonitorSolution()`, `SNESMonitorRatio()`
4873a7fca6bSBarry Smith @*/
488d43b4f6eSBarry Smith PetscErrorCode  SNESMonitorRatio(SNES snes,PetscInt its,PetscReal fgnorm,PetscViewerAndFormat *vf)
4893a7fca6bSBarry Smith {
49077431f27SBarry Smith   PetscInt                len;
49187828ca2SBarry Smith   PetscReal               *history;
492d43b4f6eSBarry Smith   PetscViewer             viewer = vf->viewer;
4933a7fca6bSBarry Smith 
4943a7fca6bSBarry Smith   PetscFunctionBegin;
4959566063dSJacob Faibussowitsch   PetscCall(SNESGetConvergenceHistory(snes,&history,NULL,&len));
4969566063dSJacob Faibussowitsch   PetscCall(PetscViewerPushFormat(viewer,vf->format));
4979566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIIAddTab(viewer,((PetscObject)snes)->tablevel));
498958c9bccSBarry Smith   if (!its || !history || its > len) {
49963a3b9bcSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer,"%3" PetscInt_FMT " SNES Function norm %14.12e \n",its,(double)fgnorm));
5003a7fca6bSBarry Smith   } else {
50187828ca2SBarry Smith     PetscReal ratio = fgnorm/history[its-1];
50263a3b9bcSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer,"%3" PetscInt_FMT " SNES Function norm %14.12e %14.12e \n",its,(double)fgnorm,(double)ratio));
5033a7fca6bSBarry Smith   }
5049566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIISubtractTab(viewer,((PetscObject)snes)->tablevel));
5059566063dSJacob Faibussowitsch   PetscCall(PetscViewerPopFormat(viewer));
5063a7fca6bSBarry Smith   PetscFunctionReturn(0);
5073a7fca6bSBarry Smith }
5083a7fca6bSBarry Smith 
5093a7fca6bSBarry Smith /*@C
510fde5950dSBarry Smith    SNESMonitorRatioSetUp - Insures the SNES object is saving its history since this monitor needs access to it
5113a7fca6bSBarry Smith 
5123a7fca6bSBarry Smith    Collective on SNES
5133a7fca6bSBarry Smith 
5143a7fca6bSBarry Smith    Input Parameters:
515eabae89aSBarry Smith +   snes - the SNES context
516fde5950dSBarry Smith -   viewer - the PetscViewer object (ignored)
5173a7fca6bSBarry Smith 
5183a7fca6bSBarry Smith    Level: intermediate
5193a7fca6bSBarry Smith 
520db781477SPatrick Sanan .seealso: `SNESMonitorSet()`, `SNESMonitorSolution()`, `SNESMonitorDefault()`, `SNESMonitorRatio()`
5213a7fca6bSBarry Smith @*/
522d43b4f6eSBarry Smith PetscErrorCode  SNESMonitorRatioSetUp(SNES snes,PetscViewerAndFormat *vf)
5233a7fca6bSBarry Smith {
52487828ca2SBarry Smith   PetscReal               *history;
5253a7fca6bSBarry Smith 
5263a7fca6bSBarry Smith   PetscFunctionBegin;
5279566063dSJacob Faibussowitsch   PetscCall(SNESGetConvergenceHistory(snes,&history,NULL,NULL));
5283a7fca6bSBarry Smith   if (!history) {
5299566063dSJacob Faibussowitsch     PetscCall(SNESSetConvergenceHistory(snes,NULL,NULL,100,PETSC_TRUE));
5303a7fca6bSBarry Smith   }
5313a7fca6bSBarry Smith   PetscFunctionReturn(0);
5323a7fca6bSBarry Smith }
5333a7fca6bSBarry Smith 
534e7e93795SLois Curfman McInnes /* ---------------------------------------------------------------- */
535be1f7002SBarry Smith /*
536a6570f20SBarry Smith      Default (short) SNES Monitor, same as SNESMonitorDefault() except
537be1f7002SBarry Smith   it prints fewer digits of the residual as the residual gets smaller.
538be1f7002SBarry Smith   This is because the later digits are meaningless and are often
539be1f7002SBarry Smith   different on different machines; by using this routine different
540be1f7002SBarry Smith   machines will usually generate the same output.
541dec21524SBarry Smith 
542dec21524SBarry Smith   Deprecated: Intentionally has no manual page
543be1f7002SBarry Smith */
544d43b4f6eSBarry Smith PetscErrorCode  SNESMonitorDefaultShort(SNES snes,PetscInt its,PetscReal fgnorm,PetscViewerAndFormat *vf)
545e7e93795SLois Curfman McInnes {
546d43b4f6eSBarry Smith   PetscViewer    viewer = vf->viewer;
547d132466eSBarry Smith 
5483a40ed3dSBarry Smith   PetscFunctionBegin;
5494d4332d5SBarry Smith   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,4);
5509566063dSJacob Faibussowitsch   PetscCall(PetscViewerPushFormat(viewer,vf->format));
5519566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIIAddTab(viewer,((PetscObject)snes)->tablevel));
5528f240d10SBarry Smith   if (fgnorm > 1.e-9) {
55363a3b9bcSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer,"%3" PetscInt_FMT " SNES Function norm %g \n",its,(double)fgnorm));
5543a40ed3dSBarry Smith   } else if (fgnorm > 1.e-11) {
55563a3b9bcSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer,"%3" PetscInt_FMT " SNES Function norm %5.3e \n",its,(double)fgnorm));
5563a40ed3dSBarry Smith   } else {
55763a3b9bcSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer,"%3" PetscInt_FMT " SNES Function norm < 1.e-11\n",its));
558a34d58ebSBarry Smith   }
5599566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIISubtractTab(viewer,((PetscObject)snes)->tablevel));
5609566063dSJacob Faibussowitsch   PetscCall(PetscViewerPopFormat(viewer));
5613a40ed3dSBarry Smith   PetscFunctionReturn(0);
562e7e93795SLois Curfman McInnes }
5632db13446SMatthew G. Knepley 
5642db13446SMatthew G. Knepley /*@C
5652db13446SMatthew G. Knepley   SNESMonitorDefaultField - Monitors progress of the SNES solvers, separated into fields.
5662db13446SMatthew G. Knepley 
5672db13446SMatthew G. Knepley   Collective on SNES
5682db13446SMatthew G. Knepley 
5692db13446SMatthew G. Knepley   Input Parameters:
5702db13446SMatthew G. Knepley + snes   - the SNES context
5712db13446SMatthew G. Knepley . its    - iteration number
5722db13446SMatthew G. Knepley . fgnorm - 2-norm of residual
5732db13446SMatthew G. Knepley - ctx    - the PetscViewer
5742db13446SMatthew G. Knepley 
5752db13446SMatthew G. Knepley   Notes:
5762db13446SMatthew G. Knepley   This routine uses the DM attached to the residual vector
5772db13446SMatthew G. Knepley 
5782db13446SMatthew G. Knepley   Level: intermediate
5792db13446SMatthew G. Knepley 
580db781477SPatrick Sanan .seealso: `SNESMonitorSet()`, `SNESMonitorSolution()`, `SNESMonitorDefault()`
5812db13446SMatthew G. Knepley @*/
582d43b4f6eSBarry Smith PetscErrorCode SNESMonitorDefaultField(SNES snes, PetscInt its, PetscReal fgnorm, PetscViewerAndFormat *vf)
5832db13446SMatthew G. Knepley {
584d43b4f6eSBarry Smith   PetscViewer    viewer = vf->viewer;
5852db13446SMatthew G. Knepley   Vec            r;
5862db13446SMatthew G. Knepley   DM             dm;
5872db13446SMatthew G. Knepley   PetscReal      res[256];
5882db13446SMatthew G. Knepley   PetscInt       tablevel;
5892db13446SMatthew G. Knepley 
5902db13446SMatthew G. Knepley   PetscFunctionBegin;
5914d4332d5SBarry Smith   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,4);
5929566063dSJacob Faibussowitsch   PetscCall(SNESGetFunction(snes, &r, NULL, NULL));
5939566063dSJacob Faibussowitsch   PetscCall(VecGetDM(r, &dm));
5949566063dSJacob Faibussowitsch   if (!dm) PetscCall(SNESMonitorDefault(snes, its, fgnorm, vf));
5952db13446SMatthew G. Knepley   else {
5962db13446SMatthew G. Knepley     PetscSection s, gs;
5972db13446SMatthew G. Knepley     PetscInt     Nf, f;
5982db13446SMatthew G. Knepley 
5999566063dSJacob Faibussowitsch     PetscCall(DMGetLocalSection(dm, &s));
6009566063dSJacob Faibussowitsch     PetscCall(DMGetGlobalSection(dm, &gs));
6019566063dSJacob Faibussowitsch     if (!s || !gs) PetscCall(SNESMonitorDefault(snes, its, fgnorm, vf));
6029566063dSJacob Faibussowitsch     PetscCall(PetscSectionGetNumFields(s, &Nf));
60363a3b9bcSJacob Faibussowitsch     PetscCheck(Nf <= 256,PetscObjectComm((PetscObject) snes), PETSC_ERR_SUP, "Do not support %" PetscInt_FMT " fields > 256", Nf);
6049566063dSJacob Faibussowitsch     PetscCall(PetscSectionVecNorm(s, gs, r, NORM_2, res));
6059566063dSJacob Faibussowitsch     PetscCall(PetscObjectGetTabLevel((PetscObject) snes, &tablevel));
6069566063dSJacob Faibussowitsch     PetscCall(PetscViewerPushFormat(viewer,vf->format));
6079566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIAddTab(viewer, tablevel));
60863a3b9bcSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer, "%3" PetscInt_FMT " SNES Function norm %14.12e [", its, (double) fgnorm));
6092db13446SMatthew G. Knepley     for (f = 0; f < Nf; ++f) {
6109566063dSJacob Faibussowitsch       if (f) PetscCall(PetscViewerASCIIPrintf(viewer, ", "));
61163a3b9bcSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(viewer, "%14.12e", (double)res[f]));
6122db13446SMatthew G. Knepley     }
6139566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer, "] \n"));
6149566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIISubtractTab(viewer, tablevel));
6159566063dSJacob Faibussowitsch     PetscCall(PetscViewerPopFormat(viewer));
6162db13446SMatthew G. Knepley   }
6172db13446SMatthew G. Knepley   PetscFunctionReturn(0);
6182db13446SMatthew G. Knepley }
619e7e93795SLois Curfman McInnes /* ---------------------------------------------------------------- */
6204b828684SBarry Smith /*@C
621c34cbdceSBarry Smith    SNESConvergedDefault - Default onvergence test of the solvers for
622c34cbdceSBarry Smith    systems of nonlinear equations.
623e7e93795SLois Curfman McInnes 
624c7afd0dbSLois Curfman McInnes    Collective on SNES
625c7afd0dbSLois Curfman McInnes 
626e7e93795SLois Curfman McInnes    Input Parameters:
627c7afd0dbSLois Curfman McInnes +  snes - the SNES context
62806ee9f85SBarry Smith .  it - the iteration (0 indicates before any Newton steps)
629e7e93795SLois Curfman McInnes .  xnorm - 2-norm of current iterate
630c60f73f4SPeter Brune .  snorm - 2-norm of current step
6317f3332b4SBarry Smith .  fnorm - 2-norm of function at current iterate
632c7afd0dbSLois Curfman McInnes -  dummy - unused context
633e7e93795SLois Curfman McInnes 
634184914b5SBarry Smith    Output Parameter:
635184914b5SBarry Smith .   reason  - one of
63670441072SBarry Smith $  SNES_CONVERGED_FNORM_ABS       - (fnorm < abstol),
637c60f73f4SPeter Brune $  SNES_CONVERGED_SNORM_RELATIVE  - (snorm < stol*xnorm),
638184914b5SBarry Smith $  SNES_CONVERGED_FNORM_RELATIVE  - (fnorm < rtol*fnorm0),
639184914b5SBarry Smith $  SNES_DIVERGED_FUNCTION_COUNT   - (nfct > maxf),
640184914b5SBarry Smith $  SNES_DIVERGED_FNORM_NAN        - (fnorm == NaN),
641184914b5SBarry Smith $  SNES_CONVERGED_ITERATING       - (otherwise),
642c34cbdceSBarry Smith $  SNES_DIVERGED_DTOL             - (fnorm > divtol*snes->fnorm0)
643e7e93795SLois Curfman McInnes 
644e7e93795SLois Curfman McInnes    where
645c34cbdceSBarry Smith +    maxf - maximum number of function evaluations,  set with SNESSetTolerances()
646c7afd0dbSLois Curfman McInnes .    nfct - number of function evaluations,
647c34cbdceSBarry Smith .    abstol - absolute function norm tolerance, set with SNESSetTolerances()
648c34cbdceSBarry Smith .    rtol - relative function norm tolerance, set with SNESSetTolerances()
649c34cbdceSBarry Smith .    divtol - divergence tolerance, set with SNESSetDivergenceTolerance()
650c34cbdceSBarry Smith -    fnorm0 - 2-norm of the function at the initial solution (initial guess; zeroth iteration)
651c34cbdceSBarry Smith 
652c34cbdceSBarry Smith   Options Database Keys:
6535c50d39aSSatish Balay +  -snes_stol - convergence tolerance in terms of the norm  of the change in the solution between steps
654c34cbdceSBarry Smith .  -snes_atol <abstol> - absolute tolerance of residual norm
655c34cbdceSBarry Smith .  -snes_rtol <rtol> - relative decrease in tolerance norm from the initial 2-norm of the solution
656c34cbdceSBarry Smith .  -snes_divergence_tolerance <divtol> - if the residual goes above divtol*rnorm0, exit with divergence
657c34cbdceSBarry Smith .  -snes_max_funcs <max_funcs> - maximum number of function evaluations
658c34cbdceSBarry Smith .  -snes_max_fail <max_fail> - maximum number of line search failures allowed before stopping, default is none
659c34cbdceSBarry Smith -  -snes_max_linear_solve_fail - number of linear solver failures before SNESSolve() stops
660fee21e36SBarry Smith 
66136851e7fSLois Curfman McInnes    Level: intermediate
66236851e7fSLois Curfman McInnes 
663db781477SPatrick Sanan .seealso: `SNESSetConvergenceTest()`, `SNESConvergedSkip()`, `SNESSetTolerances()`, `SNESSetDivergenceTolerance()`
664e7e93795SLois Curfman McInnes @*/
6658d359177SBarry Smith PetscErrorCode  SNESConvergedDefault(SNES snes,PetscInt it,PetscReal xnorm,PetscReal snorm,PetscReal fnorm,SNESConvergedReason *reason,void *dummy)
666e7e93795SLois Curfman McInnes {
6673a40ed3dSBarry Smith   PetscFunctionBegin;
6680700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
6693f149594SLisandro Dalcin   PetscValidPointer(reason,6);
6703f149594SLisandro Dalcin 
67106ee9f85SBarry Smith   *reason = SNES_CONVERGED_ITERATING;
67206ee9f85SBarry Smith 
67306ee9f85SBarry Smith   if (!it) {
67406ee9f85SBarry Smith     /* set parameter for default relative tolerance convergence test */
67506ee9f85SBarry Smith     snes->ttol   = fnorm*snes->rtol;
676e37c518bSBarry Smith     snes->rnorm0 = fnorm;
67706ee9f85SBarry Smith   }
6788146f6ebSBarry Smith   if (PetscIsInfOrNanReal(fnorm)) {
6799566063dSJacob Faibussowitsch     PetscCall(PetscInfo(snes,"Failed to converged, function norm is NaN\n"));
680184914b5SBarry Smith     *reason = SNES_DIVERGED_FNORM_NAN;
681be5caee7SBarry Smith   } else if (fnorm < snes->abstol && (it || !snes->forceiteration)) {
6829566063dSJacob Faibussowitsch     PetscCall(PetscInfo(snes,"Converged due to function norm %14.12e < %14.12e\n",(double)fnorm,(double)snes->abstol));
683184914b5SBarry Smith     *reason = SNES_CONVERGED_FNORM_ABS;
684e71169deSBarry Smith   } else if (snes->nfuncs >= snes->max_funcs && snes->max_funcs >= 0) {
68563a3b9bcSJacob Faibussowitsch     PetscCall(PetscInfo(snes,"Exceeded maximum number of function evaluations: %" PetscInt_FMT " > %" PetscInt_FMT "\n",snes->nfuncs,snes->max_funcs));
686184914b5SBarry Smith     *reason = SNES_DIVERGED_FUNCTION_COUNT;
68706ee9f85SBarry Smith   }
68806ee9f85SBarry Smith 
68906ee9f85SBarry Smith   if (it && !*reason) {
69006ee9f85SBarry Smith     if (fnorm <= snes->ttol) {
6919566063dSJacob Faibussowitsch       PetscCall(PetscInfo(snes,"Converged due to function norm %14.12e < %14.12e (relative tolerance)\n",(double)fnorm,(double)snes->ttol));
69206ee9f85SBarry Smith       *reason = SNES_CONVERGED_FNORM_RELATIVE;
693c60f73f4SPeter Brune     } else if (snorm < snes->stol*xnorm) {
6949566063dSJacob Faibussowitsch       PetscCall(PetscInfo(snes,"Converged due to small update length: %14.12e < %14.12e * %14.12e\n",(double)snorm,(double)snes->stol,(double)xnorm));
695c60f73f4SPeter Brune       *reason = SNES_CONVERGED_SNORM_RELATIVE;
696e4d06f11SPatrick Farrell     } else if (snes->divtol > 0 && (fnorm > snes->divtol*snes->rnorm0)) {
6979566063dSJacob 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));
698e37c518bSBarry Smith       *reason = SNES_DIVERGED_DTOL;
69906ee9f85SBarry Smith     }
700e37c518bSBarry Smith 
701e7e93795SLois Curfman McInnes   }
7023a40ed3dSBarry Smith   PetscFunctionReturn(0);
703e7e93795SLois Curfman McInnes }
7043f149594SLisandro Dalcin 
7053f149594SLisandro Dalcin /*@C
706e2a6519dSDmitry Karpeev    SNESConvergedSkip - Convergence test for SNES that NEVER returns as
7073f149594SLisandro Dalcin    converged, UNLESS the maximum number of iteration have been reached.
7083f149594SLisandro Dalcin 
7093f9fe445SBarry Smith    Logically Collective on SNES
7103f149594SLisandro Dalcin 
7113f149594SLisandro Dalcin    Input Parameters:
7123f149594SLisandro Dalcin +  snes - the SNES context
7133f149594SLisandro Dalcin .  it - the iteration (0 indicates before any Newton steps)
7143f149594SLisandro Dalcin .  xnorm - 2-norm of current iterate
715c60f73f4SPeter Brune .  snorm - 2-norm of current step
7163f149594SLisandro Dalcin .  fnorm - 2-norm of function at current iterate
7173f149594SLisandro Dalcin -  dummy - unused context
7183f149594SLisandro Dalcin 
7193f149594SLisandro Dalcin    Output Parameter:
72085385478SLisandro Dalcin .   reason  - SNES_CONVERGED_ITERATING, SNES_CONVERGED_ITS, or SNES_DIVERGED_FNORM_NAN
7213f149594SLisandro Dalcin 
7223f149594SLisandro Dalcin    Notes:
7233f149594SLisandro Dalcin    Convergence is then declared after a fixed number of iterations have been used.
7243f149594SLisandro Dalcin 
7253f149594SLisandro Dalcin    Level: advanced
7263f149594SLisandro Dalcin 
727db781477SPatrick Sanan .seealso: `SNESConvergedDefault()`, `SNESSetConvergenceTest()`
7283f149594SLisandro Dalcin @*/
729e2a6519dSDmitry Karpeev PetscErrorCode  SNESConvergedSkip(SNES snes,PetscInt it,PetscReal xnorm,PetscReal snorm,PetscReal fnorm,SNESConvergedReason *reason,void *dummy)
7303f149594SLisandro Dalcin {
7313f149594SLisandro Dalcin   PetscFunctionBegin;
7320700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
7333f149594SLisandro Dalcin   PetscValidPointer(reason,6);
7343f149594SLisandro Dalcin 
7353f149594SLisandro Dalcin   *reason = SNES_CONVERGED_ITERATING;
7363f149594SLisandro Dalcin 
7373f149594SLisandro Dalcin   if (fnorm != fnorm) {
7389566063dSJacob Faibussowitsch     PetscCall(PetscInfo(snes,"Failed to converged, function norm is NaN\n"));
7393f149594SLisandro Dalcin     *reason = SNES_DIVERGED_FNORM_NAN;
7403f149594SLisandro Dalcin   } else if (it == snes->max_its) {
7413f149594SLisandro Dalcin     *reason = SNES_CONVERGED_ITS;
7423f149594SLisandro Dalcin   }
7433f149594SLisandro Dalcin   PetscFunctionReturn(0);
7443f149594SLisandro Dalcin }
7453f149594SLisandro Dalcin 
7468d359177SBarry Smith /*@C
747fa0ddf94SBarry Smith   SNESSetWorkVecs - Gets a number of work vectors.
74858c9b817SLisandro Dalcin 
74958c9b817SLisandro Dalcin   Input Parameters:
750a2b725a8SWilliam Gropp + snes  - the SNES context
751a2b725a8SWilliam Gropp - nw - number of work vectors to allocate
75258c9b817SLisandro Dalcin 
75358c9b817SLisandro Dalcin   Level: developer
754fa0ddf94SBarry Smith 
75598acb6afSMatthew G Knepley @*/
756fa0ddf94SBarry Smith PetscErrorCode SNESSetWorkVecs(SNES snes,PetscInt nw)
75758c9b817SLisandro Dalcin {
758c5ed8070SMatthew G. Knepley   DM             dm;
759c5ed8070SMatthew G. Knepley   Vec            v;
76058c9b817SLisandro Dalcin 
76158c9b817SLisandro Dalcin   PetscFunctionBegin;
7629566063dSJacob Faibussowitsch   if (snes->work) PetscCall(VecDestroyVecs(snes->nwork,&snes->work));
76358c9b817SLisandro Dalcin   snes->nwork = nw;
764f5af7f23SKarl Rupp 
7659566063dSJacob Faibussowitsch   PetscCall(SNESGetDM(snes, &dm));
7669566063dSJacob Faibussowitsch   PetscCall(DMGetGlobalVector(dm, &v));
7679566063dSJacob Faibussowitsch   PetscCall(VecDuplicateVecs(v,snes->nwork,&snes->work));
7689566063dSJacob Faibussowitsch   PetscCall(DMRestoreGlobalVector(dm, &v));
7699566063dSJacob Faibussowitsch   PetscCall(PetscLogObjectParents(snes,nw,snes->work));
77058c9b817SLisandro Dalcin   PetscFunctionReturn(0);
77158c9b817SLisandro Dalcin }
772