xref: /petsc/src/snes/interface/snesut.c (revision fbcc45307503607706fe8c0dbb79ed00a61f8bb8)
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 
24a6570f20SBarry Smith .seealso: SNESMonitorSet(), SNESMonitorDefault(), VecView()
253f1db9ecSBarry Smith @*/
26d43b4f6eSBarry Smith PetscErrorCode  SNESMonitorSolution(SNES snes,PetscInt its,PetscReal fgnorm,PetscViewerAndFormat *vf)
273f1db9ecSBarry Smith {
28dfbe8321SBarry Smith   PetscErrorCode ierr;
293f1db9ecSBarry Smith   Vec            x;
30d43b4f6eSBarry Smith   PetscViewer    viewer = vf->viewer;
313f1db9ecSBarry Smith 
323f1db9ecSBarry Smith   PetscFunctionBegin;
334d4332d5SBarry Smith   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,4);
343f1db9ecSBarry Smith   ierr = SNESGetSolution(snes,&x);CHKERRQ(ierr);
35d43b4f6eSBarry Smith   ierr = PetscViewerPushFormat(viewer,vf->format);CHKERRQ(ierr);
363f1db9ecSBarry Smith   ierr = VecView(x,viewer);CHKERRQ(ierr);
37d43b4f6eSBarry Smith   ierr = PetscViewerPopFormat(viewer);CHKERRQ(ierr);
383f1db9ecSBarry Smith   PetscFunctionReturn(0);
393f1db9ecSBarry Smith }
403f1db9ecSBarry Smith 
415ed2d596SBarry Smith /*@C
42a6570f20SBarry Smith    SNESMonitorResidual - Monitors progress of the SNES solvers by calling
435ed2d596SBarry Smith    VecView() for the residual at each iteration.
445ed2d596SBarry Smith 
455ed2d596SBarry Smith    Collective on SNES
465ed2d596SBarry Smith 
475ed2d596SBarry Smith    Input Parameters:
485ed2d596SBarry Smith +  snes - the SNES context
495ed2d596SBarry Smith .  its - iteration number
504b27c08aSLois Curfman McInnes .  fgnorm - 2-norm of residual
51f55353a2SBarry Smith -  dummy -  a viewer
525ed2d596SBarry Smith 
53ee32d87aSMatthew G. Knepley    Options Database Keys:
54ee32d87aSMatthew G. Knepley .  -snes_monitor_residual [ascii binary draw][:filename][:viewer format] - plots residual (not its norm) at each iteration
55ee32d87aSMatthew G. Knepley 
565ed2d596SBarry Smith    Level: intermediate
575ed2d596SBarry Smith 
58a6570f20SBarry Smith .seealso: SNESMonitorSet(), SNESMonitorDefault(), VecView()
595ed2d596SBarry Smith @*/
60d43b4f6eSBarry Smith PetscErrorCode  SNESMonitorResidual(SNES snes,PetscInt its,PetscReal fgnorm,PetscViewerAndFormat *vf)
615ed2d596SBarry Smith {
62dfbe8321SBarry Smith   PetscErrorCode ierr;
635ed2d596SBarry Smith   Vec            x;
64d43b4f6eSBarry Smith   PetscViewer    viewer = vf->viewer;
655ed2d596SBarry Smith 
665ed2d596SBarry Smith   PetscFunctionBegin;
674d4332d5SBarry Smith   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,4);
689e5d0892SLisandro Dalcin   ierr = SNESGetFunction(snes,&x,NULL,NULL);CHKERRQ(ierr);
69d43b4f6eSBarry Smith   ierr = PetscViewerPushFormat(viewer,vf->format);CHKERRQ(ierr);
705ed2d596SBarry Smith   ierr = VecView(x,viewer);CHKERRQ(ierr);
71d43b4f6eSBarry Smith   ierr = PetscViewerPopFormat(viewer);CHKERRQ(ierr);
725ed2d596SBarry Smith   PetscFunctionReturn(0);
735ed2d596SBarry Smith }
745ed2d596SBarry Smith 
75d132466eSBarry Smith /*@C
76a6570f20SBarry Smith    SNESMonitorSolutionUpdate - Monitors progress of the SNES solvers by calling
77d132466eSBarry Smith    VecView() for the UPDATE to the solution at each iteration.
78d132466eSBarry Smith 
79d132466eSBarry Smith    Collective on SNES
80d132466eSBarry Smith 
81d132466eSBarry Smith    Input Parameters:
82d132466eSBarry Smith +  snes - the SNES context
83d132466eSBarry Smith .  its - iteration number
844b27c08aSLois Curfman McInnes .  fgnorm - 2-norm of residual
85f55353a2SBarry Smith -  dummy - a viewer
86d132466eSBarry Smith 
87ee32d87aSMatthew G. Knepley    Options Database Keys:
88ee32d87aSMatthew G. Knepley .  -snes_monitor_solution_update [ascii binary draw][:filename][:viewer format] - plots update to solution at each iteration
89ee32d87aSMatthew G. Knepley 
90d132466eSBarry Smith    Level: intermediate
91d132466eSBarry Smith 
92a6570f20SBarry Smith .seealso: SNESMonitorSet(), SNESMonitorDefault(), VecView()
93d132466eSBarry Smith @*/
94d43b4f6eSBarry Smith PetscErrorCode  SNESMonitorSolutionUpdate(SNES snes,PetscInt its,PetscReal fgnorm,PetscViewerAndFormat *vf)
95d132466eSBarry Smith {
96dfbe8321SBarry Smith   PetscErrorCode ierr;
97d132466eSBarry Smith   Vec            x;
98d43b4f6eSBarry Smith   PetscViewer    viewer = vf->viewer;
99d132466eSBarry Smith 
100d132466eSBarry Smith   PetscFunctionBegin;
1014d4332d5SBarry Smith   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,4);
102d132466eSBarry Smith   ierr = SNESGetSolutionUpdate(snes,&x);CHKERRQ(ierr);
103d43b4f6eSBarry Smith   ierr = PetscViewerPushFormat(viewer,vf->format);CHKERRQ(ierr);
104d132466eSBarry Smith   ierr = VecView(x,viewer);CHKERRQ(ierr);
105d43b4f6eSBarry Smith   ierr = PetscViewerPopFormat(viewer);CHKERRQ(ierr);
106d132466eSBarry Smith   PetscFunctionReturn(0);
107d132466eSBarry Smith }
108d132466eSBarry Smith 
109798534f6SMatthew G. Knepley #include <petscdraw.h>
110a5c2985bSBarry Smith 
111798534f6SMatthew G. Knepley /*@C
112798534f6SMatthew G. Knepley   KSPMonitorSNESResidual - Prints the SNES residual norm, as well as the linear residual norm, at each iteration of an iterative solver.
113798534f6SMatthew G. Knepley 
114798534f6SMatthew G. Knepley   Collective on ksp
115a5c2985bSBarry Smith 
116a5c2985bSBarry Smith   Input Parameters:
117a5c2985bSBarry Smith + ksp   - iterative context
118a5c2985bSBarry Smith . n     - iteration number
119a5c2985bSBarry Smith . rnorm - 2-norm (preconditioned) residual value (may be estimated).
120798534f6SMatthew G. Knepley - vf    - The viewer context
121798534f6SMatthew G. Knepley 
122798534f6SMatthew G. Knepley   Options Database Key:
123798534f6SMatthew G. Knepley . -snes_monitor_ksp - Activates KSPMonitorSNESResidual()
124a5c2985bSBarry Smith 
125a5c2985bSBarry Smith   Level: intermediate
126a5c2985bSBarry Smith 
127798534f6SMatthew G. Knepley .seealso: KSPMonitorSet(), KSPMonitorResidual(),KSPMonitorTrueResidualMaxNorm()
128a5c2985bSBarry Smith @*/
129798534f6SMatthew G. Knepley PetscErrorCode KSPMonitorSNESResidual(KSP ksp, PetscInt n, PetscReal rnorm, PetscViewerAndFormat *vf)
130a5c2985bSBarry Smith {
131798534f6SMatthew G. Knepley   PetscViewer       viewer = vf->viewer;
132798534f6SMatthew G. Knepley   PetscViewerFormat format = vf->format;
133798534f6SMatthew G. Knepley   SNES              snes   = (SNES) vf->data;
134a5c2985bSBarry Smith   Vec               snes_solution, work1, work2;
135a5c2985bSBarry Smith   PetscReal         snorm;
136798534f6SMatthew G. Knepley   PetscInt          tablevel;
137798534f6SMatthew G. Knepley   const char       *prefix;
138798534f6SMatthew G. Knepley   PetscErrorCode    ierr;
139a5c2985bSBarry Smith 
140a5c2985bSBarry Smith   PetscFunctionBegin;
141798534f6SMatthew G. Knepley   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 4);
142a5c2985bSBarry Smith   ierr = SNESGetSolution(snes, &snes_solution);CHKERRQ(ierr);
143a5c2985bSBarry Smith   ierr = VecDuplicate(snes_solution, &work1);CHKERRQ(ierr);
144a5c2985bSBarry Smith   ierr = VecDuplicate(snes_solution, &work2);CHKERRQ(ierr);
145a5c2985bSBarry Smith   ierr = KSPBuildSolution(ksp, work1, NULL);CHKERRQ(ierr);
146a5c2985bSBarry Smith   ierr = VecAYPX(work1, -1.0, snes_solution);CHKERRQ(ierr);
147a5c2985bSBarry Smith   ierr = SNESComputeFunction(snes, work1, work2);CHKERRQ(ierr);
148a5c2985bSBarry Smith   ierr = VecNorm(work2, NORM_2, &snorm);CHKERRQ(ierr);
149a5c2985bSBarry Smith   ierr = VecDestroy(&work1);CHKERRQ(ierr);
150a5c2985bSBarry Smith   ierr = VecDestroy(&work2);CHKERRQ(ierr);
151a5c2985bSBarry Smith 
152798534f6SMatthew G. Knepley   ierr = PetscObjectGetTabLevel((PetscObject) ksp, &tablevel);CHKERRQ(ierr);
153798534f6SMatthew G. Knepley   ierr = PetscObjectGetOptionsPrefix((PetscObject) ksp, &prefix);CHKERRQ(ierr);
154798534f6SMatthew G. Knepley   ierr = PetscViewerPushFormat(viewer, format);CHKERRQ(ierr);
155798534f6SMatthew G. Knepley   ierr = PetscViewerASCIIAddTab(viewer, tablevel);CHKERRQ(ierr);
156798534f6SMatthew G. Knepley   if (n == 0 && prefix) {ierr = PetscViewerASCIIPrintf(viewer, "  Residual norms for %s solve.\n", prefix);CHKERRQ(ierr);}
157a5c2985bSBarry Smith   ierr = PetscViewerASCIIPrintf(viewer, "%3D SNES Residual norm %5.3e KSP Residual norm %5.3e \n", n, (double) snorm, (double) rnorm);CHKERRQ(ierr);
158798534f6SMatthew G. Knepley   ierr = PetscViewerASCIISubtractTab(viewer, tablevel);CHKERRQ(ierr);
159798534f6SMatthew G. Knepley   ierr = PetscViewerPopFormat(viewer);CHKERRQ(ierr);
160a5c2985bSBarry Smith   PetscFunctionReturn(0);
161a5c2985bSBarry Smith }
162a5c2985bSBarry Smith 
163e5f7ee39SBarry Smith /*@C
164798534f6SMatthew G. Knepley   KSPMonitorSNESResidualDrawLG - Plots the linear SNES residual norm at each iteration of an iterative solver.
165e5f7ee39SBarry Smith 
166798534f6SMatthew G. Knepley   Collective on ksp
167e5f7ee39SBarry Smith 
168e5f7ee39SBarry Smith   Input Parameters:
169798534f6SMatthew G. Knepley + ksp   - iterative context
170798534f6SMatthew G. Knepley . n     - iteration number
171798534f6SMatthew G. Knepley . rnorm - 2-norm (preconditioned) residual value (may be estimated).
172798534f6SMatthew G. Knepley - vf    - The viewer context
173e5f7ee39SBarry Smith 
174e5f7ee39SBarry Smith   Options Database Key:
175798534f6SMatthew G. Knepley . -snes_monitor_ksp draw::draw_lg - Activates KSPMonitorSNESResidualDrawLG()
176e5f7ee39SBarry Smith 
177e5f7ee39SBarry Smith   Level: intermediate
178e5f7ee39SBarry Smith 
179798534f6SMatthew G. Knepley .seealso: KSPMonitorSet(), KSPMonitorTrueResidual()
180e5f7ee39SBarry Smith @*/
181798534f6SMatthew G. Knepley PetscErrorCode KSPMonitorSNESResidualDrawLG(KSP ksp, PetscInt n, PetscReal rnorm, PetscViewerAndFormat *vf)
182e5f7ee39SBarry Smith {
183798534f6SMatthew G. Knepley   PetscViewer        viewer = vf->viewer;
184798534f6SMatthew G. Knepley   PetscViewerFormat  format = vf->format;
185798534f6SMatthew G. Knepley   PetscDrawLG        lg     = vf->lg;
186798534f6SMatthew G. Knepley   SNES               snes   = (SNES) vf->data;
187e5f7ee39SBarry Smith   Vec                snes_solution, work1, work2;
188798534f6SMatthew G. Knepley   PetscReal          snorm;
189798534f6SMatthew G. Knepley   KSPConvergedReason reason;
190798534f6SMatthew G. Knepley   PetscReal          x[2], y[2];
191798534f6SMatthew G. Knepley   PetscErrorCode     ierr;
192e5f7ee39SBarry Smith 
193e5f7ee39SBarry Smith   PetscFunctionBegin;
194798534f6SMatthew G. Knepley   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 4);
195064a246eSJacob Faibussowitsch   PetscValidHeaderSpecific(lg, PETSC_DRAWLG_CLASSID, 4);
196e5f7ee39SBarry Smith   ierr = SNESGetSolution(snes, &snes_solution);CHKERRQ(ierr);
197e5f7ee39SBarry Smith   ierr = VecDuplicate(snes_solution, &work1);CHKERRQ(ierr);
198e5f7ee39SBarry Smith   ierr = VecDuplicate(snes_solution, &work2);CHKERRQ(ierr);
199e5f7ee39SBarry Smith   ierr = KSPBuildSolution(ksp, work1, NULL);CHKERRQ(ierr);
200e5f7ee39SBarry Smith   ierr = VecAYPX(work1, -1.0, snes_solution);CHKERRQ(ierr);
201e5f7ee39SBarry Smith   ierr = SNESComputeFunction(snes, work1, work2);CHKERRQ(ierr);
202798534f6SMatthew G. Knepley   ierr = VecNorm(work2, NORM_2, &snorm);CHKERRQ(ierr);
203e5f7ee39SBarry Smith   ierr = VecDestroy(&work1);CHKERRQ(ierr);
204e5f7ee39SBarry Smith   ierr = VecDestroy(&work2);CHKERRQ(ierr);
205e5f7ee39SBarry Smith 
206798534f6SMatthew G. Knepley   ierr = PetscViewerPushFormat(viewer, format);CHKERRQ(ierr);
207798534f6SMatthew G. Knepley   if (!n) {ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);}
208798534f6SMatthew G. Knepley   x[0] = (PetscReal) n;
209798534f6SMatthew G. Knepley   if (rnorm > 0.0) y[0] = PetscLog10Real(rnorm);
210798534f6SMatthew G. Knepley   else y[0] = -15.0;
211798534f6SMatthew G. Knepley   x[1] = (PetscReal) n;
212798534f6SMatthew G. Knepley   if (snorm > 0.0) y[1] = PetscLog10Real(snorm);
213798534f6SMatthew G. Knepley   else y[1] = -15.0;
214798534f6SMatthew G. Knepley   ierr = PetscDrawLGAddPoint(lg, x, y);CHKERRQ(ierr);
215798534f6SMatthew G. Knepley   ierr = KSPGetConvergedReason(ksp, &reason);CHKERRQ(ierr);
216798534f6SMatthew G. Knepley   if (n <= 20 || !(n % 5) || reason) {
217e5f7ee39SBarry Smith     ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr);
2186934998bSLisandro Dalcin     ierr = PetscDrawLGSave(lg);CHKERRQ(ierr);
219e5f7ee39SBarry Smith   }
220798534f6SMatthew G. Knepley   ierr = PetscViewerPopFormat(viewer);CHKERRQ(ierr);
221e5f7ee39SBarry Smith   PetscFunctionReturn(0);
222e5f7ee39SBarry Smith }
223e5f7ee39SBarry Smith 
224798534f6SMatthew G. Knepley /*@C
225798534f6SMatthew G. Knepley   KSPMonitorSNESResidualDrawLGCreate - Creates the plotter for the linear SNES residual.
226e5f7ee39SBarry Smith 
227798534f6SMatthew G. Knepley   Collective on ksp
228e5f7ee39SBarry Smith 
229798534f6SMatthew G. Knepley   Input Parameters:
230b693eab9SMatthew G. Knepley + viewer - The PetscViewer
231798534f6SMatthew G. Knepley . format - The viewer format
232798534f6SMatthew G. Knepley - ctx    - An optional user context
233798534f6SMatthew G. Knepley 
234798534f6SMatthew G. Knepley   Output Parameter:
235798534f6SMatthew G. Knepley . vf    - The viewer context
236e5f7ee39SBarry Smith 
237e5f7ee39SBarry Smith   Level: intermediate
238e5f7ee39SBarry Smith 
239798534f6SMatthew G. Knepley .seealso: KSPMonitorSet(), KSPMonitorTrueResidual()
240e5f7ee39SBarry Smith @*/
241798534f6SMatthew G. Knepley PetscErrorCode KSPMonitorSNESResidualDrawLGCreate(PetscViewer viewer, PetscViewerFormat format, void *ctx, PetscViewerAndFormat **vf)
242e5f7ee39SBarry Smith {
243798534f6SMatthew G. Knepley   const char    *names[] = {"linear", "nonlinear"};
244e5f7ee39SBarry Smith   PetscErrorCode ierr;
245e5f7ee39SBarry Smith 
246e5f7ee39SBarry Smith   PetscFunctionBegin;
247798534f6SMatthew G. Knepley   ierr = PetscViewerAndFormatCreate(viewer, format, vf);CHKERRQ(ierr);
248798534f6SMatthew G. Knepley   (*vf)->data = ctx;
249798534f6SMatthew G. Knepley   ierr = KSPMonitorLGCreate(PetscObjectComm((PetscObject) viewer), NULL, NULL, "Log Residual Norm", 2, names, PETSC_DECIDE, PETSC_DECIDE, 400, 300, &(*vf)->lg);CHKERRQ(ierr);
250e5f7ee39SBarry Smith   PetscFunctionReturn(0);
251e5f7ee39SBarry Smith }
252e5f7ee39SBarry Smith 
253*fbcc4530SMatthew G. Knepley PetscErrorCode SNESMonitorDefaultSetUp(SNES snes, PetscViewerAndFormat *vf)
254*fbcc4530SMatthew G. Knepley {
255*fbcc4530SMatthew G. Knepley   PetscErrorCode ierr;
256*fbcc4530SMatthew G. Knepley 
257*fbcc4530SMatthew G. Knepley   PetscFunctionBegin;
258*fbcc4530SMatthew G. Knepley   if (vf->format == PETSC_VIEWER_DRAW_LG) {
259*fbcc4530SMatthew G. Knepley     ierr = KSPMonitorLGCreate(PetscObjectComm((PetscObject) vf->viewer), NULL, NULL, "Log Residual Norm", 1, NULL, PETSC_DECIDE, PETSC_DECIDE, 400, 300, &vf->lg);CHKERRQ(ierr);
260*fbcc4530SMatthew G. Knepley   }
261*fbcc4530SMatthew G. Knepley   PetscFunctionReturn(0);
262*fbcc4530SMatthew G. Knepley }
263*fbcc4530SMatthew G. Knepley 
2644b828684SBarry Smith /*@C
265a6570f20SBarry Smith    SNESMonitorDefault - Monitors progress of the SNES solvers (default).
266e7e93795SLois Curfman McInnes 
267c7afd0dbSLois Curfman McInnes    Collective on SNES
268c7afd0dbSLois Curfman McInnes 
269e7e93795SLois Curfman McInnes    Input Parameters:
270c7afd0dbSLois Curfman McInnes +  snes - the SNES context
271e7e93795SLois Curfman McInnes .  its - iteration number
2724b27c08aSLois Curfman McInnes .  fgnorm - 2-norm of residual
273d43b4f6eSBarry Smith -  vf - viewer and format structure
274fee21e36SBarry Smith 
275e7e93795SLois Curfman McInnes    Notes:
2764b27c08aSLois Curfman McInnes    This routine prints the residual norm at each iteration.
277e7e93795SLois Curfman McInnes 
27836851e7fSLois Curfman McInnes    Level: intermediate
27936851e7fSLois Curfman McInnes 
280a6570f20SBarry Smith .seealso: SNESMonitorSet(), SNESMonitorSolution()
281e7e93795SLois Curfman McInnes @*/
282d43b4f6eSBarry Smith PetscErrorCode  SNESMonitorDefault(SNES snes,PetscInt its,PetscReal fgnorm,PetscViewerAndFormat *vf)
283e7e93795SLois Curfman McInnes {
284d43b4f6eSBarry Smith   PetscViewer       viewer = vf->viewer;
285798534f6SMatthew G. Knepley   PetscViewerFormat format = vf->format;
286798534f6SMatthew G. Knepley   PetscBool         isascii, isdraw;
287798534f6SMatthew G. Knepley   PetscErrorCode    ierr;
288d132466eSBarry Smith 
2893a40ed3dSBarry Smith   PetscFunctionBegin;
2904d4332d5SBarry Smith   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,4);
291798534f6SMatthew G. Knepley   ierr = PetscObjectTypeCompare((PetscObject) viewer, PETSCVIEWERASCII, &isascii);CHKERRQ(ierr);
292798534f6SMatthew G. Knepley   ierr = PetscObjectTypeCompare((PetscObject) viewer, PETSCVIEWERDRAW,  &isdraw);CHKERRQ(ierr);
293798534f6SMatthew G. Knepley   ierr = PetscViewerPushFormat(viewer,format);CHKERRQ(ierr);
294798534f6SMatthew G. Knepley   if (isascii) {
295649052a6SBarry Smith     ierr = PetscViewerASCIIAddTab(viewer,((PetscObject)snes)->tablevel);CHKERRQ(ierr);
296649052a6SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"%3D SNES Function norm %14.12e \n",its,(double)fgnorm);CHKERRQ(ierr);
297649052a6SBarry Smith     ierr = PetscViewerASCIISubtractTab(viewer,((PetscObject)snes)->tablevel);CHKERRQ(ierr);
298798534f6SMatthew G. Knepley   } else if (isdraw) {
299798534f6SMatthew G. Knepley     if (format == PETSC_VIEWER_DRAW_LG) {
300798534f6SMatthew G. Knepley       PetscDrawLG lg = (PetscDrawLG) vf->lg;
301798534f6SMatthew G. Knepley       PetscReal   x, y;
302798534f6SMatthew G. Knepley 
303798534f6SMatthew G. Knepley       PetscValidHeaderSpecific(lg,PETSC_DRAWLG_CLASSID,4);
304798534f6SMatthew G. Knepley       if (!its) {ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);}
305798534f6SMatthew G. Knepley       x = (PetscReal) its;
306798534f6SMatthew G. Knepley       if (fgnorm > 0.0) y = PetscLog10Real(fgnorm);
307798534f6SMatthew G. Knepley       else y = -15.0;
308798534f6SMatthew G. Knepley       ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr);
309798534f6SMatthew G. Knepley       if (its <= 20 || !(its % 5) || snes->reason) {
310798534f6SMatthew G. Knepley         ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr);
311798534f6SMatthew G. Knepley         ierr = PetscDrawLGSave(lg);CHKERRQ(ierr);
312798534f6SMatthew G. Knepley       }
313798534f6SMatthew G. Knepley     }
314798534f6SMatthew G. Knepley   }
315d43b4f6eSBarry Smith   ierr = PetscViewerPopFormat(viewer);CHKERRQ(ierr);
3163a40ed3dSBarry Smith   PetscFunctionReturn(0);
317e7e93795SLois Curfman McInnes }
3183f1db9ecSBarry Smith 
3191f60017eSBarry Smith /*@C
3201f60017eSBarry Smith    SNESMonitorScaling - Monitors the largest value in each row of the Jacobian.
3211f60017eSBarry Smith 
3221f60017eSBarry Smith    Collective on SNES
3231f60017eSBarry Smith 
3241f60017eSBarry Smith    Input Parameters:
3251f60017eSBarry Smith +  snes - the SNES context
3261f60017eSBarry Smith .  its - iteration number
3271f60017eSBarry Smith .  fgnorm - 2-norm of residual
3281f60017eSBarry Smith -  vf - viewer and format structure
3291f60017eSBarry Smith 
3301f60017eSBarry Smith    Notes:
3311f60017eSBarry Smith    This routine prints the largest value in each row of the Jacobian
3321f60017eSBarry Smith 
3331f60017eSBarry Smith    Level: intermediate
3341f60017eSBarry Smith 
3351f60017eSBarry Smith .seealso: SNESMonitorSet(), SNESMonitorSolution()
3361f60017eSBarry Smith @*/
3371f60017eSBarry Smith PetscErrorCode  SNESMonitorScaling(SNES snes,PetscInt its,PetscReal fgnorm,PetscViewerAndFormat *vf)
3381f60017eSBarry Smith {
3391f60017eSBarry Smith   PetscErrorCode ierr;
3401f60017eSBarry Smith   PetscViewer    viewer = vf->viewer;
3411f60017eSBarry Smith   KSP            ksp;
3421f60017eSBarry Smith   Mat            J;
3431f60017eSBarry Smith   Vec            v;
3441f60017eSBarry Smith 
3451f60017eSBarry Smith   PetscFunctionBegin;
3461f60017eSBarry Smith   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,4);
3471f60017eSBarry Smith   ierr = SNESGetKSP(snes,&ksp);CHKERRQ(ierr);
3481f60017eSBarry Smith   ierr = KSPGetOperators(ksp,&J,NULL);CHKERRQ(ierr);
3491f60017eSBarry Smith   ierr = MatCreateVecs(J,&v,NULL);CHKERRQ(ierr);
3501f60017eSBarry Smith   ierr = MatGetRowMaxAbs(J,v,NULL);CHKERRQ(ierr);
3511f60017eSBarry Smith   ierr = PetscViewerPushFormat(viewer,vf->format);CHKERRQ(ierr);
3521f60017eSBarry Smith   ierr = PetscViewerASCIIAddTab(viewer,((PetscObject)snes)->tablevel);CHKERRQ(ierr);
3531f60017eSBarry Smith   ierr = PetscViewerASCIIPrintf(viewer,"%3D SNES Jacobian maximum row entries \n");CHKERRQ(ierr);
3541f60017eSBarry Smith   ierr = VecView(v,viewer);CHKERRQ(ierr);
3551f60017eSBarry Smith   ierr = PetscViewerASCIISubtractTab(viewer,((PetscObject)snes)->tablevel);CHKERRQ(ierr);
3561f60017eSBarry Smith   ierr = PetscViewerPopFormat(viewer);CHKERRQ(ierr);
3571f60017eSBarry Smith   ierr = VecDestroy(&v);CHKERRQ(ierr);
3581f60017eSBarry Smith   PetscFunctionReturn(0);
3591f60017eSBarry Smith }
3601f60017eSBarry Smith 
361d43b4f6eSBarry Smith PetscErrorCode SNESMonitorJacUpdateSpectrum(SNES snes,PetscInt it,PetscReal fnorm,PetscViewerAndFormat *vf)
362a80ad3e0SBarry Smith {
3632e7541e6SPeter Brune   Vec            X;
3642e7541e6SPeter Brune   Mat            J,dJ,dJdense;
3652e7541e6SPeter Brune   PetscErrorCode ierr;
366d1e9a80fSBarry Smith   PetscErrorCode (*func)(SNES,Vec,Mat,Mat,void*);
3672f96bde4SJose E. Roman   PetscInt       n;
36823fff9afSBarry Smith   PetscBLASInt   nb = 0,lwork;
3692e7541e6SPeter Brune   PetscReal      *eigr,*eigi;
3702e7541e6SPeter Brune   PetscScalar    *work;
3712e7541e6SPeter Brune   PetscScalar    *a;
3722e7541e6SPeter Brune 
3732e7541e6SPeter Brune   PetscFunctionBegin;
3742e7541e6SPeter Brune   if (it == 0) PetscFunctionReturn(0);
3752e7541e6SPeter Brune   /* create the difference between the current update and the current jacobian */
3762e7541e6SPeter Brune   ierr = SNESGetSolution(snes,&X);CHKERRQ(ierr);
377d1e9a80fSBarry Smith   ierr = SNESGetJacobian(snes,NULL,&J,&func,NULL);CHKERRQ(ierr);
3782e7541e6SPeter Brune   ierr = MatDuplicate(J,MAT_COPY_VALUES,&dJ);CHKERRQ(ierr);
379d1e9a80fSBarry Smith   ierr = SNESComputeJacobian(snes,X,dJ,dJ);CHKERRQ(ierr);
3802e7541e6SPeter Brune   ierr = MatAXPY(dJ,-1.0,J,SAME_NONZERO_PATTERN);CHKERRQ(ierr);
381f5af7f23SKarl Rupp 
3822e7541e6SPeter Brune   /* compute the spectrum directly */
3832e7541e6SPeter Brune   ierr  = MatConvert(dJ,MATSEQDENSE,MAT_INITIAL_MATRIX,&dJdense);CHKERRQ(ierr);
3840298fd71SBarry Smith   ierr  = MatGetSize(dJ,&n,NULL);CHKERRQ(ierr);
385c5df96a5SBarry Smith   ierr  = PetscBLASIntCast(n,&nb);CHKERRQ(ierr);
3862e7541e6SPeter Brune   lwork = 3*nb;
387785e854fSJed Brown   ierr  = PetscMalloc1(n,&eigr);CHKERRQ(ierr);
388785e854fSJed Brown   ierr  = PetscMalloc1(n,&eigi);CHKERRQ(ierr);
389785e854fSJed Brown   ierr  = PetscMalloc1(lwork,&work);CHKERRQ(ierr);
3908c778c55SBarry Smith   ierr  = MatDenseGetArray(dJdense,&a);CHKERRQ(ierr);
3912e7541e6SPeter Brune #if !defined(PETSC_USE_COMPLEX)
3922e7541e6SPeter Brune   {
3932e7541e6SPeter Brune     PetscBLASInt lierr;
3942f96bde4SJose E. Roman     PetscInt     i;
3952e7541e6SPeter Brune     ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
3968b83055fSJed Brown     PetscStackCallBLAS("LAPACKgeev",LAPACKgeev_("N","N",&nb,a,&nb,eigr,eigi,NULL,&nb,NULL,&nb,work,&lwork,&lierr));
3972e7541e6SPeter Brune     if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"geev() error %d",lierr);
3982e7541e6SPeter Brune     ierr = PetscFPTrapPop();CHKERRQ(ierr);
399fde5950dSBarry Smith     ierr = PetscPrintf(PetscObjectComm((PetscObject)snes),"Eigenvalues of J_%d - J_%d:\n",it,it-1);CHKERRQ(ierr);
4002e7541e6SPeter Brune     for (i=0;i<n;i++) {
401fde5950dSBarry Smith       ierr = PetscPrintf(PetscObjectComm((PetscObject)snes),"%5d: %20.5g + %20.5gi\n",i,(double)eigr[i],(double)eigi[i]);CHKERRQ(ierr);
4022e7541e6SPeter Brune     }
4032f96bde4SJose E. Roman   }
4048c778c55SBarry Smith   ierr = MatDenseRestoreArray(dJdense,&a);CHKERRQ(ierr);
4052e7541e6SPeter Brune   ierr = MatDestroy(&dJ);CHKERRQ(ierr);
4062e7541e6SPeter Brune   ierr = MatDestroy(&dJdense);CHKERRQ(ierr);
4072e7541e6SPeter Brune   ierr = PetscFree(eigr);CHKERRQ(ierr);
4082e7541e6SPeter Brune   ierr = PetscFree(eigi);CHKERRQ(ierr);
4092e7541e6SPeter Brune   ierr = PetscFree(work);CHKERRQ(ierr);
4102e7541e6SPeter Brune   PetscFunctionReturn(0);
4112f96bde4SJose E. Roman #else
4122f96bde4SJose E. Roman   SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not coded for complex");
4132f96bde4SJose E. Roman #endif
4142e7541e6SPeter Brune }
4152e7541e6SPeter Brune 
4166ba87a44SLisandro Dalcin PETSC_INTERN PetscErrorCode  SNESMonitorRange_Private(SNES,PetscInt,PetscReal*);
4176ba87a44SLisandro Dalcin 
4187087cfbeSBarry Smith PetscErrorCode  SNESMonitorRange_Private(SNES snes,PetscInt it,PetscReal *per)
419b271bb04SBarry Smith {
420b271bb04SBarry Smith   PetscErrorCode ierr;
421b271bb04SBarry Smith   Vec            resid;
422b271bb04SBarry Smith   PetscReal      rmax,pwork;
423b271bb04SBarry Smith   PetscInt       i,n,N;
424b271bb04SBarry Smith   PetscScalar    *r;
425b271bb04SBarry Smith 
426b271bb04SBarry Smith   PetscFunctionBegin;
4279e5d0892SLisandro Dalcin   ierr  = SNESGetFunction(snes,&resid,NULL,NULL);CHKERRQ(ierr);
428b271bb04SBarry Smith   ierr  = VecNorm(resid,NORM_INFINITY,&rmax);CHKERRQ(ierr);
429b271bb04SBarry Smith   ierr  = VecGetLocalSize(resid,&n);CHKERRQ(ierr);
430b271bb04SBarry Smith   ierr  = VecGetSize(resid,&N);CHKERRQ(ierr);
431b271bb04SBarry Smith   ierr  = VecGetArray(resid,&r);CHKERRQ(ierr);
432b271bb04SBarry Smith   pwork = 0.0;
433b271bb04SBarry Smith   for (i=0; i<n; i++) {
434b271bb04SBarry Smith     pwork += (PetscAbsScalar(r[i]) > .20*rmax);
435b271bb04SBarry Smith   }
436820f2d46SBarry Smith   ierr = MPIU_Allreduce(&pwork,per,1,MPIU_REAL,MPIU_SUM,PetscObjectComm((PetscObject)snes));CHKERRMPI(ierr);
437b271bb04SBarry Smith   ierr = VecRestoreArray(resid,&r);CHKERRQ(ierr);
438b271bb04SBarry Smith   *per = *per/N;
439b271bb04SBarry Smith   PetscFunctionReturn(0);
440b271bb04SBarry Smith }
441b271bb04SBarry Smith 
442b271bb04SBarry Smith /*@C
443b271bb04SBarry Smith    SNESMonitorRange - Prints the percentage of residual elements that are more then 10 percent of the maximum value.
444b271bb04SBarry Smith 
445b271bb04SBarry Smith    Collective on SNES
446b271bb04SBarry Smith 
447b271bb04SBarry Smith    Input Parameters:
448b271bb04SBarry Smith +  snes   - iterative context
449b271bb04SBarry Smith .  it    - iteration number
450b271bb04SBarry Smith .  rnorm - 2-norm (preconditioned) residual value (may be estimated).
451b271bb04SBarry Smith -  dummy - unused monitor context
452b271bb04SBarry Smith 
453b271bb04SBarry Smith    Options Database Key:
454b271bb04SBarry Smith .  -snes_monitor_range - Activates SNESMonitorRange()
455b271bb04SBarry Smith 
456b271bb04SBarry Smith    Level: intermediate
457b271bb04SBarry Smith 
458b271bb04SBarry Smith .seealso: SNESMonitorSet(), SNESMonitorDefault(), SNESMonitorLGCreate()
459b271bb04SBarry Smith @*/
460d43b4f6eSBarry Smith PetscErrorCode  SNESMonitorRange(SNES snes,PetscInt it,PetscReal rnorm,PetscViewerAndFormat *vf)
461b271bb04SBarry Smith {
462b271bb04SBarry Smith   PetscErrorCode ierr;
463b271bb04SBarry Smith   PetscReal      perc,rel;
464d43b4f6eSBarry Smith   PetscViewer    viewer = vf->viewer;
465b271bb04SBarry Smith   /* should be in a MonitorRangeContext */
466b271bb04SBarry Smith   static PetscReal prev;
467b271bb04SBarry Smith 
468b271bb04SBarry Smith   PetscFunctionBegin;
4694d4332d5SBarry Smith   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,4);
470b271bb04SBarry Smith   if (!it) prev = rnorm;
471b271bb04SBarry Smith   ierr = SNESMonitorRange_Private(snes,it,&perc);CHKERRQ(ierr);
472b271bb04SBarry Smith 
473b271bb04SBarry Smith   rel  = (prev - rnorm)/prev;
474b271bb04SBarry Smith   prev = rnorm;
475d43b4f6eSBarry Smith   ierr = PetscViewerPushFormat(viewer,vf->format);CHKERRQ(ierr);
476649052a6SBarry Smith   ierr = PetscViewerASCIIAddTab(viewer,((PetscObject)snes)->tablevel);CHKERRQ(ierr);
4776712e2f1SBarry Smith   ierr = PetscViewerASCIIPrintf(viewer,"%3D SNES preconditioned resid norm %14.12e Percent values above 20 percent of maximum %5.2f relative decrease %5.2e ratio %5.2e \n",it,(double)rnorm,(double)(100.0*perc),(double)rel,(double)(rel/perc));CHKERRQ(ierr);
478649052a6SBarry Smith   ierr = PetscViewerASCIISubtractTab(viewer,((PetscObject)snes)->tablevel);CHKERRQ(ierr);
479d43b4f6eSBarry Smith   ierr = PetscViewerPopFormat(viewer);CHKERRQ(ierr);
480b271bb04SBarry Smith   PetscFunctionReturn(0);
481b271bb04SBarry Smith }
482b271bb04SBarry Smith 
4833a7fca6bSBarry Smith /*@C
484a6570f20SBarry Smith    SNESMonitorRatio - Monitors progress of the SNES solvers by printing the ratio
4854b27c08aSLois Curfman McInnes    of residual norm at each iteration to the previous.
4863a7fca6bSBarry Smith 
4873a7fca6bSBarry Smith    Collective on SNES
4883a7fca6bSBarry Smith 
4893a7fca6bSBarry Smith    Input Parameters:
4903a7fca6bSBarry Smith +  snes - the SNES context
4913a7fca6bSBarry Smith .  its - iteration number
4923a7fca6bSBarry Smith .  fgnorm - 2-norm of residual (or gradient)
493eabae89aSBarry Smith -  dummy -  context of monitor
4943a7fca6bSBarry Smith 
4953a7fca6bSBarry Smith    Level: intermediate
4963a7fca6bSBarry Smith 
49795452b02SPatrick Sanan    Notes:
49895452b02SPatrick Sanan     Insure that SNESMonitorRatio() is called when you set this monitor
499fde5950dSBarry Smith .seealso: SNESMonitorSet(), SNESMonitorSolution(), SNESMonitorRatio()
5003a7fca6bSBarry Smith @*/
501d43b4f6eSBarry Smith PetscErrorCode  SNESMonitorRatio(SNES snes,PetscInt its,PetscReal fgnorm,PetscViewerAndFormat *vf)
5023a7fca6bSBarry Smith {
503dfbe8321SBarry Smith   PetscErrorCode          ierr;
50477431f27SBarry Smith   PetscInt                len;
50587828ca2SBarry Smith   PetscReal               *history;
506d43b4f6eSBarry Smith   PetscViewer             viewer = vf->viewer;
5073a7fca6bSBarry Smith 
5083a7fca6bSBarry Smith   PetscFunctionBegin;
5090298fd71SBarry Smith   ierr = SNESGetConvergenceHistory(snes,&history,NULL,&len);CHKERRQ(ierr);
510d43b4f6eSBarry Smith   ierr = PetscViewerPushFormat(viewer,vf->format);CHKERRQ(ierr);
511fde5950dSBarry Smith   ierr = PetscViewerASCIIAddTab(viewer,((PetscObject)snes)->tablevel);CHKERRQ(ierr);
512958c9bccSBarry Smith   if (!its || !history || its > len) {
513fde5950dSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"%3D SNES Function norm %14.12e \n",its,(double)fgnorm);CHKERRQ(ierr);
5143a7fca6bSBarry Smith   } else {
51587828ca2SBarry Smith     PetscReal ratio = fgnorm/history[its-1];
516fde5950dSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"%3D SNES Function norm %14.12e %14.12e \n",its,(double)fgnorm,(double)ratio);CHKERRQ(ierr);
5173a7fca6bSBarry Smith   }
518fde5950dSBarry Smith   ierr = PetscViewerASCIISubtractTab(viewer,((PetscObject)snes)->tablevel);CHKERRQ(ierr);
519d43b4f6eSBarry Smith   ierr = PetscViewerPopFormat(viewer);CHKERRQ(ierr);
5203a7fca6bSBarry Smith   PetscFunctionReturn(0);
5213a7fca6bSBarry Smith }
5223a7fca6bSBarry Smith 
5233a7fca6bSBarry Smith /*@C
524fde5950dSBarry Smith    SNESMonitorRatioSetUp - Insures the SNES object is saving its history since this monitor needs access to it
5253a7fca6bSBarry Smith 
5263a7fca6bSBarry Smith    Collective on SNES
5273a7fca6bSBarry Smith 
5283a7fca6bSBarry Smith    Input Parameters:
529eabae89aSBarry Smith +   snes - the SNES context
530fde5950dSBarry Smith -   viewer - the PetscViewer object (ignored)
5313a7fca6bSBarry Smith 
5323a7fca6bSBarry Smith    Level: intermediate
5333a7fca6bSBarry Smith 
534fde5950dSBarry Smith .seealso: SNESMonitorSet(), SNESMonitorSolution(), SNESMonitorDefault(), SNESMonitorRatio()
5353a7fca6bSBarry Smith @*/
536d43b4f6eSBarry Smith PetscErrorCode  SNESMonitorRatioSetUp(SNES snes,PetscViewerAndFormat *vf)
5373a7fca6bSBarry Smith {
538dfbe8321SBarry Smith   PetscErrorCode          ierr;
53987828ca2SBarry Smith   PetscReal               *history;
5403a7fca6bSBarry Smith 
5413a7fca6bSBarry Smith   PetscFunctionBegin;
5420298fd71SBarry Smith   ierr = SNESGetConvergenceHistory(snes,&history,NULL,NULL);CHKERRQ(ierr);
5433a7fca6bSBarry Smith   if (!history) {
544fde5950dSBarry Smith     ierr = SNESSetConvergenceHistory(snes,NULL,NULL,100,PETSC_TRUE);CHKERRQ(ierr);
5453a7fca6bSBarry Smith   }
5463a7fca6bSBarry Smith   PetscFunctionReturn(0);
5473a7fca6bSBarry Smith }
5483a7fca6bSBarry Smith 
549e7e93795SLois Curfman McInnes /* ---------------------------------------------------------------- */
550be1f7002SBarry Smith /*
551a6570f20SBarry Smith      Default (short) SNES Monitor, same as SNESMonitorDefault() except
552be1f7002SBarry Smith   it prints fewer digits of the residual as the residual gets smaller.
553be1f7002SBarry Smith   This is because the later digits are meaningless and are often
554be1f7002SBarry Smith   different on different machines; by using this routine different
555be1f7002SBarry Smith   machines will usually generate the same output.
556dec21524SBarry Smith 
557dec21524SBarry Smith   Deprecated: Intentionally has no manual page
558be1f7002SBarry Smith */
559d43b4f6eSBarry Smith PetscErrorCode  SNESMonitorDefaultShort(SNES snes,PetscInt its,PetscReal fgnorm,PetscViewerAndFormat *vf)
560e7e93795SLois Curfman McInnes {
561dfbe8321SBarry Smith   PetscErrorCode ierr;
562d43b4f6eSBarry Smith   PetscViewer    viewer = vf->viewer;
563d132466eSBarry Smith 
5643a40ed3dSBarry Smith   PetscFunctionBegin;
5654d4332d5SBarry Smith   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,4);
566d43b4f6eSBarry Smith   ierr = PetscViewerPushFormat(viewer,vf->format);CHKERRQ(ierr);
567649052a6SBarry Smith   ierr = PetscViewerASCIIAddTab(viewer,((PetscObject)snes)->tablevel);CHKERRQ(ierr);
5688f240d10SBarry Smith   if (fgnorm > 1.e-9) {
5698fa295daSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"%3D SNES Function norm %g \n",its,(double)fgnorm);CHKERRQ(ierr);
5703a40ed3dSBarry Smith   } else if (fgnorm > 1.e-11) {
5718fa295daSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"%3D SNES Function norm %5.3e \n",its,(double)fgnorm);CHKERRQ(ierr);
5723a40ed3dSBarry Smith   } else {
573649052a6SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"%3D SNES Function norm < 1.e-11\n",its);CHKERRQ(ierr);
574a34d58ebSBarry Smith   }
575649052a6SBarry Smith   ierr = PetscViewerASCIISubtractTab(viewer,((PetscObject)snes)->tablevel);CHKERRQ(ierr);
576d43b4f6eSBarry Smith   ierr = PetscViewerPopFormat(viewer);CHKERRQ(ierr);
5773a40ed3dSBarry Smith   PetscFunctionReturn(0);
578e7e93795SLois Curfman McInnes }
5792db13446SMatthew G. Knepley 
5802db13446SMatthew G. Knepley /*@C
5812db13446SMatthew G. Knepley   SNESMonitorDefaultField - Monitors progress of the SNES solvers, separated into fields.
5822db13446SMatthew G. Knepley 
5832db13446SMatthew G. Knepley   Collective on SNES
5842db13446SMatthew G. Knepley 
5852db13446SMatthew G. Knepley   Input Parameters:
5862db13446SMatthew G. Knepley + snes   - the SNES context
5872db13446SMatthew G. Knepley . its    - iteration number
5882db13446SMatthew G. Knepley . fgnorm - 2-norm of residual
5892db13446SMatthew G. Knepley - ctx    - the PetscViewer
5902db13446SMatthew G. Knepley 
5912db13446SMatthew G. Knepley   Notes:
5922db13446SMatthew G. Knepley   This routine uses the DM attached to the residual vector
5932db13446SMatthew G. Knepley 
5942db13446SMatthew G. Knepley   Level: intermediate
5952db13446SMatthew G. Knepley 
596dec21524SBarry Smith .seealso: SNESMonitorSet(), SNESMonitorSolution(), SNESMonitorDefault()
5972db13446SMatthew G. Knepley @*/
598d43b4f6eSBarry Smith PetscErrorCode SNESMonitorDefaultField(SNES snes, PetscInt its, PetscReal fgnorm, PetscViewerAndFormat *vf)
5992db13446SMatthew G. Knepley {
600d43b4f6eSBarry Smith   PetscViewer    viewer = vf->viewer;
6012db13446SMatthew G. Knepley   Vec            r;
6022db13446SMatthew G. Knepley   DM             dm;
6032db13446SMatthew G. Knepley   PetscReal      res[256];
6042db13446SMatthew G. Knepley   PetscInt       tablevel;
6052db13446SMatthew G. Knepley   PetscErrorCode ierr;
6062db13446SMatthew G. Knepley 
6072db13446SMatthew G. Knepley   PetscFunctionBegin;
6084d4332d5SBarry Smith   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,4);
6092db13446SMatthew G. Knepley   ierr = SNESGetFunction(snes, &r, NULL, NULL);CHKERRQ(ierr);
6102db13446SMatthew G. Knepley   ierr = VecGetDM(r, &dm);CHKERRQ(ierr);
611d43b4f6eSBarry Smith   if (!dm) {ierr = SNESMonitorDefault(snes, its, fgnorm, vf);CHKERRQ(ierr);}
6122db13446SMatthew G. Knepley   else {
6132db13446SMatthew G. Knepley     PetscSection s, gs;
6142db13446SMatthew G. Knepley     PetscInt     Nf, f;
6152db13446SMatthew G. Knepley 
61692fd8e1eSJed Brown     ierr = DMGetLocalSection(dm, &s);CHKERRQ(ierr);
617e87a4003SBarry Smith     ierr = DMGetGlobalSection(dm, &gs);CHKERRQ(ierr);
618d43b4f6eSBarry Smith     if (!s || !gs) {ierr = SNESMonitorDefault(snes, its, fgnorm, vf);CHKERRQ(ierr);}
6192db13446SMatthew G. Knepley     ierr = PetscSectionGetNumFields(s, &Nf);CHKERRQ(ierr);
6202db13446SMatthew G. Knepley     if (Nf > 256) SETERRQ1(PetscObjectComm((PetscObject) snes), PETSC_ERR_SUP, "Do not support %d fields > 256", Nf);
6212db13446SMatthew G. Knepley     ierr = PetscSectionVecNorm(s, gs, r, NORM_2, res);CHKERRQ(ierr);
6222db13446SMatthew G. Knepley     ierr = PetscObjectGetTabLevel((PetscObject) snes, &tablevel);CHKERRQ(ierr);
623d43b4f6eSBarry Smith     ierr = PetscViewerPushFormat(viewer,vf->format);CHKERRQ(ierr);
6242db13446SMatthew G. Knepley     ierr = PetscViewerASCIIAddTab(viewer, tablevel);CHKERRQ(ierr);
6252db13446SMatthew G. Knepley     ierr = PetscViewerASCIIPrintf(viewer, "%3D SNES Function norm %14.12e [", its, (double) fgnorm);CHKERRQ(ierr);
6262db13446SMatthew G. Knepley     for (f = 0; f < Nf; ++f) {
6272db13446SMatthew G. Knepley       if (f) {ierr = PetscViewerASCIIPrintf(viewer, ", ");CHKERRQ(ierr);}
6282db13446SMatthew G. Knepley       ierr = PetscViewerASCIIPrintf(viewer, "%14.12e", res[f]);CHKERRQ(ierr);
6292db13446SMatthew G. Knepley     }
6302db13446SMatthew G. Knepley     ierr = PetscViewerASCIIPrintf(viewer, "] \n");CHKERRQ(ierr);
6312db13446SMatthew G. Knepley     ierr = PetscViewerASCIISubtractTab(viewer, tablevel);CHKERRQ(ierr);
632d43b4f6eSBarry Smith     ierr = PetscViewerPopFormat(viewer);CHKERRQ(ierr);
6332db13446SMatthew G. Knepley   }
6342db13446SMatthew G. Knepley   PetscFunctionReturn(0);
6352db13446SMatthew G. Knepley }
636e7e93795SLois Curfman McInnes /* ---------------------------------------------------------------- */
6374b828684SBarry Smith /*@C
638c34cbdceSBarry Smith    SNESConvergedDefault - Default onvergence test of the solvers for
639c34cbdceSBarry Smith    systems of nonlinear equations.
640e7e93795SLois Curfman McInnes 
641c7afd0dbSLois Curfman McInnes    Collective on SNES
642c7afd0dbSLois Curfman McInnes 
643e7e93795SLois Curfman McInnes    Input Parameters:
644c7afd0dbSLois Curfman McInnes +  snes - the SNES context
64506ee9f85SBarry Smith .  it - the iteration (0 indicates before any Newton steps)
646e7e93795SLois Curfman McInnes .  xnorm - 2-norm of current iterate
647c60f73f4SPeter Brune .  snorm - 2-norm of current step
6487f3332b4SBarry Smith .  fnorm - 2-norm of function at current iterate
649c7afd0dbSLois Curfman McInnes -  dummy - unused context
650e7e93795SLois Curfman McInnes 
651184914b5SBarry Smith    Output Parameter:
652184914b5SBarry Smith .   reason  - one of
65370441072SBarry Smith $  SNES_CONVERGED_FNORM_ABS       - (fnorm < abstol),
654c60f73f4SPeter Brune $  SNES_CONVERGED_SNORM_RELATIVE  - (snorm < stol*xnorm),
655184914b5SBarry Smith $  SNES_CONVERGED_FNORM_RELATIVE  - (fnorm < rtol*fnorm0),
656184914b5SBarry Smith $  SNES_DIVERGED_FUNCTION_COUNT   - (nfct > maxf),
657184914b5SBarry Smith $  SNES_DIVERGED_FNORM_NAN        - (fnorm == NaN),
658184914b5SBarry Smith $  SNES_CONVERGED_ITERATING       - (otherwise),
659c34cbdceSBarry Smith $  SNES_DIVERGED_DTOL             - (fnorm > divtol*snes->fnorm0)
660e7e93795SLois Curfman McInnes 
661e7e93795SLois Curfman McInnes    where
662c34cbdceSBarry Smith +    maxf - maximum number of function evaluations,  set with SNESSetTolerances()
663c7afd0dbSLois Curfman McInnes .    nfct - number of function evaluations,
664c34cbdceSBarry Smith .    abstol - absolute function norm tolerance, set with SNESSetTolerances()
665c34cbdceSBarry Smith .    rtol - relative function norm tolerance, set with SNESSetTolerances()
666c34cbdceSBarry Smith .    divtol - divergence tolerance, set with SNESSetDivergenceTolerance()
667c34cbdceSBarry Smith -    fnorm0 - 2-norm of the function at the initial solution (initial guess; zeroth iteration)
668c34cbdceSBarry Smith 
669c34cbdceSBarry Smith   Options Database Keys:
6705c50d39aSSatish Balay +  -snes_stol - convergence tolerance in terms of the norm  of the change in the solution between steps
671c34cbdceSBarry Smith .  -snes_atol <abstol> - absolute tolerance of residual norm
672c34cbdceSBarry Smith .  -snes_rtol <rtol> - relative decrease in tolerance norm from the initial 2-norm of the solution
673c34cbdceSBarry Smith .  -snes_divergence_tolerance <divtol> - if the residual goes above divtol*rnorm0, exit with divergence
674c34cbdceSBarry Smith .  -snes_max_funcs <max_funcs> - maximum number of function evaluations
675c34cbdceSBarry Smith .  -snes_max_fail <max_fail> - maximum number of line search failures allowed before stopping, default is none
676c34cbdceSBarry Smith -  -snes_max_linear_solve_fail - number of linear solver failures before SNESSolve() stops
677fee21e36SBarry Smith 
67836851e7fSLois Curfman McInnes    Level: intermediate
67936851e7fSLois Curfman McInnes 
680649ef022SMatthew Knepley .seealso: SNESSetConvergenceTest(), SNESConvergedSkip(), SNESSetTolerances(), SNESSetDivergenceTolerance()
681e7e93795SLois Curfman McInnes @*/
6828d359177SBarry Smith PetscErrorCode  SNESConvergedDefault(SNES snes,PetscInt it,PetscReal xnorm,PetscReal snorm,PetscReal fnorm,SNESConvergedReason *reason,void *dummy)
683e7e93795SLois Curfman McInnes {
68463ba0a88SBarry Smith   PetscErrorCode ierr;
68563ba0a88SBarry Smith 
6863a40ed3dSBarry Smith   PetscFunctionBegin;
6870700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
6883f149594SLisandro Dalcin   PetscValidPointer(reason,6);
6893f149594SLisandro Dalcin 
69006ee9f85SBarry Smith   *reason = SNES_CONVERGED_ITERATING;
69106ee9f85SBarry Smith 
69206ee9f85SBarry Smith   if (!it) {
69306ee9f85SBarry Smith     /* set parameter for default relative tolerance convergence test */
69406ee9f85SBarry Smith     snes->ttol   = fnorm*snes->rtol;
695e37c518bSBarry Smith     snes->rnorm0 = fnorm;
69606ee9f85SBarry Smith   }
6978146f6ebSBarry Smith   if (PetscIsInfOrNanReal(fnorm)) {
698ae15b995SBarry Smith     ierr    = PetscInfo(snes,"Failed to converged, function norm is NaN\n");CHKERRQ(ierr);
699184914b5SBarry Smith     *reason = SNES_DIVERGED_FNORM_NAN;
700be5caee7SBarry Smith   } else if (fnorm < snes->abstol && (it || !snes->forceiteration)) {
7018f1a2a5eSBarry Smith     ierr    = PetscInfo2(snes,"Converged due to function norm %14.12e < %14.12e\n",(double)fnorm,(double)snes->abstol);CHKERRQ(ierr);
702184914b5SBarry Smith     *reason = SNES_CONVERGED_FNORM_ABS;
703e71169deSBarry Smith   } else if (snes->nfuncs >= snes->max_funcs && snes->max_funcs >= 0) {
704ae15b995SBarry Smith     ierr    = PetscInfo2(snes,"Exceeded maximum number of function evaluations: %D > %D\n",snes->nfuncs,snes->max_funcs);CHKERRQ(ierr);
705184914b5SBarry Smith     *reason = SNES_DIVERGED_FUNCTION_COUNT;
70606ee9f85SBarry Smith   }
70706ee9f85SBarry Smith 
70806ee9f85SBarry Smith   if (it && !*reason) {
70906ee9f85SBarry Smith     if (fnorm <= snes->ttol) {
7108f1a2a5eSBarry Smith       ierr    = PetscInfo2(snes,"Converged due to function norm %14.12e < %14.12e (relative tolerance)\n",(double)fnorm,(double)snes->ttol);CHKERRQ(ierr);
71106ee9f85SBarry Smith       *reason = SNES_CONVERGED_FNORM_RELATIVE;
712c60f73f4SPeter Brune     } else if (snorm < snes->stol*xnorm) {
713c60f73f4SPeter Brune       ierr    = PetscInfo3(snes,"Converged due to small update length: %14.12e < %14.12e * %14.12e\n",(double)snorm,(double)snes->stol,(double)xnorm);CHKERRQ(ierr);
714c60f73f4SPeter Brune       *reason = SNES_CONVERGED_SNORM_RELATIVE;
715e4d06f11SPatrick Farrell     } else if (snes->divtol > 0 && (fnorm > snes->divtol*snes->rnorm0)) {
716e37c518bSBarry Smith       ierr    = PetscInfo3(snes,"Diverged due to increase in function norm: %14.12e > %14.12e * %14.12e\n",(double)fnorm,(double)snes->divtol,(double)snes->rnorm0);CHKERRQ(ierr);
717e37c518bSBarry Smith       *reason = SNES_DIVERGED_DTOL;
71806ee9f85SBarry Smith     }
719e37c518bSBarry Smith 
720e7e93795SLois Curfman McInnes   }
7213a40ed3dSBarry Smith   PetscFunctionReturn(0);
722e7e93795SLois Curfman McInnes }
7233f149594SLisandro Dalcin 
7243f149594SLisandro Dalcin /*@C
725e2a6519dSDmitry Karpeev    SNESConvergedSkip - Convergence test for SNES that NEVER returns as
7263f149594SLisandro Dalcin    converged, UNLESS the maximum number of iteration have been reached.
7273f149594SLisandro Dalcin 
7283f9fe445SBarry Smith    Logically Collective on SNES
7293f149594SLisandro Dalcin 
7303f149594SLisandro Dalcin    Input Parameters:
7313f149594SLisandro Dalcin +  snes - the SNES context
7323f149594SLisandro Dalcin .  it - the iteration (0 indicates before any Newton steps)
7333f149594SLisandro Dalcin .  xnorm - 2-norm of current iterate
734c60f73f4SPeter Brune .  snorm - 2-norm of current step
7353f149594SLisandro Dalcin .  fnorm - 2-norm of function at current iterate
7363f149594SLisandro Dalcin -  dummy - unused context
7373f149594SLisandro Dalcin 
7383f149594SLisandro Dalcin    Output Parameter:
73985385478SLisandro Dalcin .   reason  - SNES_CONVERGED_ITERATING, SNES_CONVERGED_ITS, or SNES_DIVERGED_FNORM_NAN
7403f149594SLisandro Dalcin 
7413f149594SLisandro Dalcin    Notes:
7423f149594SLisandro Dalcin    Convergence is then declared after a fixed number of iterations have been used.
7433f149594SLisandro Dalcin 
7443f149594SLisandro Dalcin    Level: advanced
7453f149594SLisandro Dalcin 
746649ef022SMatthew Knepley .seealso: SNESConvergedDefault(), SNESSetConvergenceTest()
7473f149594SLisandro Dalcin @*/
748e2a6519dSDmitry Karpeev PetscErrorCode  SNESConvergedSkip(SNES snes,PetscInt it,PetscReal xnorm,PetscReal snorm,PetscReal fnorm,SNESConvergedReason *reason,void *dummy)
7493f149594SLisandro Dalcin {
7503f149594SLisandro Dalcin   PetscErrorCode ierr;
7513f149594SLisandro Dalcin 
7523f149594SLisandro Dalcin   PetscFunctionBegin;
7530700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
7543f149594SLisandro Dalcin   PetscValidPointer(reason,6);
7553f149594SLisandro Dalcin 
7563f149594SLisandro Dalcin   *reason = SNES_CONVERGED_ITERATING;
7573f149594SLisandro Dalcin 
7583f149594SLisandro Dalcin   if (fnorm != fnorm) {
7593f149594SLisandro Dalcin     ierr    = PetscInfo(snes,"Failed to converged, function norm is NaN\n");CHKERRQ(ierr);
7603f149594SLisandro Dalcin     *reason = SNES_DIVERGED_FNORM_NAN;
7613f149594SLisandro Dalcin   } else if (it == snes->max_its) {
7623f149594SLisandro Dalcin     *reason = SNES_CONVERGED_ITS;
7633f149594SLisandro Dalcin   }
7643f149594SLisandro Dalcin   PetscFunctionReturn(0);
7653f149594SLisandro Dalcin }
7663f149594SLisandro Dalcin 
7678d359177SBarry Smith /*@C
768fa0ddf94SBarry Smith   SNESSetWorkVecs - Gets a number of work vectors.
76958c9b817SLisandro Dalcin 
77058c9b817SLisandro Dalcin   Input Parameters:
771a2b725a8SWilliam Gropp + snes  - the SNES context
772a2b725a8SWilliam Gropp - nw - number of work vectors to allocate
77358c9b817SLisandro Dalcin 
77458c9b817SLisandro Dalcin   Level: developer
775fa0ddf94SBarry Smith 
77698acb6afSMatthew G Knepley @*/
777fa0ddf94SBarry Smith PetscErrorCode SNESSetWorkVecs(SNES snes,PetscInt nw)
77858c9b817SLisandro Dalcin {
779c5ed8070SMatthew G. Knepley   DM             dm;
780c5ed8070SMatthew G. Knepley   Vec            v;
78158c9b817SLisandro Dalcin   PetscErrorCode ierr;
78258c9b817SLisandro Dalcin 
78358c9b817SLisandro Dalcin   PetscFunctionBegin;
78458c9b817SLisandro Dalcin   if (snes->work) {ierr = VecDestroyVecs(snes->nwork,&snes->work);CHKERRQ(ierr);}
78558c9b817SLisandro Dalcin   snes->nwork = nw;
786f5af7f23SKarl Rupp 
787c5ed8070SMatthew G. Knepley   ierr = SNESGetDM(snes, &dm);CHKERRQ(ierr);
788c5ed8070SMatthew G. Knepley   ierr = DMGetGlobalVector(dm, &v);CHKERRQ(ierr);
789c5ed8070SMatthew G. Knepley   ierr = VecDuplicateVecs(v,snes->nwork,&snes->work);CHKERRQ(ierr);
790c5ed8070SMatthew G. Knepley   ierr = DMRestoreGlobalVector(dm, &v);CHKERRQ(ierr);
79158c9b817SLisandro Dalcin   ierr = PetscLogObjectParents(snes,nw,snes->work);CHKERRQ(ierr);
79258c9b817SLisandro Dalcin   PetscFunctionReturn(0);
79358c9b817SLisandro Dalcin }
794