xref: /petsc/src/snes/interface/snesut.c (revision 92fd8e1efe7fa9ec717935596822d4c66b82412a)
1e7e93795SLois Curfman McInnes 
2af0996ceSBarry Smith #include <petsc/private/snesimpl.h>       /*I   "petsc/private/snesimpl.h"   I*/
3636fd056SMatthew G. Knepley #include <petscdm.h>
42e7541e6SPeter Brune #include <petscblaslapack.h>
5e7e93795SLois Curfman McInnes 
63f1db9ecSBarry Smith /*@C
7a6570f20SBarry Smith    SNESMonitorSolution - Monitors progress of the SNES solvers by calling
836851e7fSLois Curfman McInnes    VecView() for the approximate solution at each iteration.
93f1db9ecSBarry Smith 
103f1db9ecSBarry Smith    Collective on SNES
113f1db9ecSBarry Smith 
123f1db9ecSBarry Smith    Input Parameters:
133f1db9ecSBarry Smith +  snes - the SNES context
143f1db9ecSBarry Smith .  its - iteration number
154b27c08aSLois Curfman McInnes .  fgnorm - 2-norm of residual
16f55353a2SBarry Smith -  dummy -  a viewer
173f1db9ecSBarry Smith 
18ee32d87aSMatthew G. Knepley    Options Database Keys:
19ee32d87aSMatthew G. Knepley .  -snes_monitor_solution [ascii binary draw][:filename][:viewer format] - plots solution at each iteration
20ee32d87aSMatthew G. Knepley 
2136851e7fSLois Curfman McInnes    Level: intermediate
223f1db9ecSBarry Smith 
23a6570f20SBarry Smith .seealso: SNESMonitorSet(), SNESMonitorDefault(), VecView()
243f1db9ecSBarry Smith @*/
25d43b4f6eSBarry Smith PetscErrorCode  SNESMonitorSolution(SNES snes,PetscInt its,PetscReal fgnorm,PetscViewerAndFormat *vf)
263f1db9ecSBarry Smith {
27dfbe8321SBarry Smith   PetscErrorCode ierr;
283f1db9ecSBarry Smith   Vec            x;
29d43b4f6eSBarry Smith   PetscViewer    viewer = vf->viewer;
303f1db9ecSBarry Smith 
313f1db9ecSBarry Smith   PetscFunctionBegin;
324d4332d5SBarry Smith   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,4);
333f1db9ecSBarry Smith   ierr = SNESGetSolution(snes,&x);CHKERRQ(ierr);
34d43b4f6eSBarry Smith   ierr = PetscViewerPushFormat(viewer,vf->format);CHKERRQ(ierr);
353f1db9ecSBarry Smith   ierr = VecView(x,viewer);CHKERRQ(ierr);
36d43b4f6eSBarry Smith   ierr = PetscViewerPopFormat(viewer);CHKERRQ(ierr);
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 
57a6570f20SBarry Smith .seealso: SNESMonitorSet(), SNESMonitorDefault(), VecView()
585ed2d596SBarry Smith @*/
59d43b4f6eSBarry Smith PetscErrorCode  SNESMonitorResidual(SNES snes,PetscInt its,PetscReal fgnorm,PetscViewerAndFormat *vf)
605ed2d596SBarry Smith {
61dfbe8321SBarry Smith   PetscErrorCode ierr;
625ed2d596SBarry Smith   Vec            x;
63d43b4f6eSBarry Smith   PetscViewer    viewer = vf->viewer;
645ed2d596SBarry Smith 
655ed2d596SBarry Smith   PetscFunctionBegin;
664d4332d5SBarry Smith   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,4);
675ed2d596SBarry Smith   ierr = SNESGetFunction(snes,&x,0,0);CHKERRQ(ierr);
68d43b4f6eSBarry Smith   ierr = PetscViewerPushFormat(viewer,vf->format);CHKERRQ(ierr);
695ed2d596SBarry Smith   ierr = VecView(x,viewer);CHKERRQ(ierr);
70d43b4f6eSBarry Smith   ierr = PetscViewerPopFormat(viewer);CHKERRQ(ierr);
715ed2d596SBarry Smith   PetscFunctionReturn(0);
725ed2d596SBarry Smith }
735ed2d596SBarry Smith 
74d132466eSBarry Smith /*@C
75a6570f20SBarry Smith    SNESMonitorSolutionUpdate - Monitors progress of the SNES solvers by calling
76d132466eSBarry Smith    VecView() for the UPDATE to the solution at each iteration.
77d132466eSBarry Smith 
78d132466eSBarry Smith    Collective on SNES
79d132466eSBarry Smith 
80d132466eSBarry Smith    Input Parameters:
81d132466eSBarry Smith +  snes - the SNES context
82d132466eSBarry Smith .  its - iteration number
834b27c08aSLois Curfman McInnes .  fgnorm - 2-norm of residual
84f55353a2SBarry Smith -  dummy - a viewer
85d132466eSBarry Smith 
86ee32d87aSMatthew G. Knepley    Options Database Keys:
87ee32d87aSMatthew G. Knepley .  -snes_monitor_solution_update [ascii binary draw][:filename][:viewer format] - plots update to solution at each iteration
88ee32d87aSMatthew G. Knepley 
89d132466eSBarry Smith    Level: intermediate
90d132466eSBarry Smith 
91a6570f20SBarry Smith .seealso: SNESMonitorSet(), SNESMonitorDefault(), VecView()
92d132466eSBarry Smith @*/
93d43b4f6eSBarry Smith PetscErrorCode  SNESMonitorSolutionUpdate(SNES snes,PetscInt its,PetscReal fgnorm,PetscViewerAndFormat *vf)
94d132466eSBarry Smith {
95dfbe8321SBarry Smith   PetscErrorCode ierr;
96d132466eSBarry Smith   Vec            x;
97d43b4f6eSBarry Smith   PetscViewer    viewer = vf->viewer;
98d132466eSBarry Smith 
99d132466eSBarry Smith   PetscFunctionBegin;
1004d4332d5SBarry Smith   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,4);
101d132466eSBarry Smith   ierr = SNESGetSolutionUpdate(snes,&x);CHKERRQ(ierr);
102d43b4f6eSBarry Smith   ierr = PetscViewerPushFormat(viewer,vf->format);CHKERRQ(ierr);
103d132466eSBarry Smith   ierr = VecView(x,viewer);CHKERRQ(ierr);
104d43b4f6eSBarry Smith   ierr = PetscViewerPopFormat(viewer);CHKERRQ(ierr);
105d132466eSBarry Smith   PetscFunctionReturn(0);
106d132466eSBarry Smith }
107d132466eSBarry Smith 
108a5c2985bSBarry Smith /*@C
109a5c2985bSBarry Smith    KSPMonitorSNES - Print the residual norm of the nonlinear function at each iteration of the linear iterative solver.
110a5c2985bSBarry Smith 
111a5c2985bSBarry Smith    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).
117a5c2985bSBarry Smith -  dummy - unused monitor context
118a5c2985bSBarry Smith 
119a5c2985bSBarry Smith    Level: intermediate
120a5c2985bSBarry Smith 
121a5c2985bSBarry Smith .seealso: KSPMonitorSet(), KSPMonitorTrueResidualNorm(), KSPMonitorLGResidualNormCreate()
122a5c2985bSBarry Smith @*/
123a5c2985bSBarry Smith PetscErrorCode  KSPMonitorSNES(KSP ksp,PetscInt n,PetscReal rnorm,void *dummy)
124a5c2985bSBarry Smith {
125a5c2985bSBarry Smith   PetscErrorCode ierr;
126a5c2985bSBarry Smith   PetscViewer    viewer;
127a5c2985bSBarry Smith   SNES           snes = (SNES) dummy;
128a5c2985bSBarry Smith   Vec            snes_solution,work1,work2;
129a5c2985bSBarry Smith   PetscReal      snorm;
130a5c2985bSBarry Smith 
131a5c2985bSBarry Smith   PetscFunctionBegin;
132a5c2985bSBarry Smith   ierr = SNESGetSolution(snes,&snes_solution);CHKERRQ(ierr);
133a5c2985bSBarry Smith   ierr = VecDuplicate(snes_solution,&work1);CHKERRQ(ierr);
134a5c2985bSBarry Smith   ierr = VecDuplicate(snes_solution,&work2);CHKERRQ(ierr);
135a5c2985bSBarry Smith   ierr = KSPBuildSolution(ksp,work1,NULL);CHKERRQ(ierr);
136a5c2985bSBarry Smith   ierr = VecAYPX(work1,-1.0,snes_solution);CHKERRQ(ierr);
137a5c2985bSBarry Smith   ierr = SNESComputeFunction(snes,work1,work2);CHKERRQ(ierr);
138a5c2985bSBarry Smith   ierr = VecNorm(work2,NORM_2,&snorm);CHKERRQ(ierr);
139a5c2985bSBarry Smith   ierr = VecDestroy(&work1);CHKERRQ(ierr);
140a5c2985bSBarry Smith   ierr = VecDestroy(&work2);CHKERRQ(ierr);
141a5c2985bSBarry Smith 
142a5c2985bSBarry Smith   ierr = PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)ksp),&viewer);CHKERRQ(ierr);
143a5c2985bSBarry Smith   ierr = PetscViewerASCIIAddTab(viewer,((PetscObject)ksp)->tablevel);CHKERRQ(ierr);
144a5c2985bSBarry Smith   if (n == 0 && ((PetscObject)ksp)->prefix) {
145a5c2985bSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  Residual norms for %s solve.\n",((PetscObject)ksp)->prefix);CHKERRQ(ierr);
146a5c2985bSBarry Smith   }
147a5c2985bSBarry Smith   ierr = PetscViewerASCIIPrintf(viewer,"%3D SNES Residual norm %5.3e KSP Residual norm %5.3e \n",n,(double)snorm,(double)rnorm);CHKERRQ(ierr);
148a5c2985bSBarry Smith   ierr = PetscViewerASCIISubtractTab(viewer,((PetscObject)ksp)->tablevel);CHKERRQ(ierr);
149a5c2985bSBarry Smith   PetscFunctionReturn(0);
150a5c2985bSBarry Smith }
151a5c2985bSBarry Smith 
152e5f7ee39SBarry Smith #include <petscdraw.h>
153e5f7ee39SBarry Smith 
154e5f7ee39SBarry Smith /*@C
155e5f7ee39SBarry Smith    KSPMonitorSNESLGResidualNormCreate - Creates a line graph context for use with
156e5f7ee39SBarry Smith    KSP to monitor convergence of preconditioned residual norms.
157e5f7ee39SBarry Smith 
158e5f7ee39SBarry Smith    Collective on KSP
159e5f7ee39SBarry Smith 
160e5f7ee39SBarry Smith    Input Parameters:
1618b0b5a47SLisandro Dalcin +  comm - communicator context
1628b0b5a47SLisandro Dalcin .  host - the X display to open, or null for the local machine
163e5f7ee39SBarry Smith .  label - the title to put in the title bar
164e5f7ee39SBarry Smith .  x, y - the screen coordinates of the upper left coordinate of
165e5f7ee39SBarry Smith           the window
166e5f7ee39SBarry Smith -  m, n - the screen width and height in pixels
167e5f7ee39SBarry Smith 
168e5f7ee39SBarry Smith    Output Parameter:
169e5f7ee39SBarry Smith .  draw - the drawing context
170e5f7ee39SBarry Smith 
171e5f7ee39SBarry Smith    Options Database Key:
172e5f7ee39SBarry Smith .  -ksp_monitor_lg_residualnorm - Sets line graph monitor
173e5f7ee39SBarry Smith 
174e5f7ee39SBarry Smith    Notes:
175e5f7ee39SBarry Smith    Use KSPMonitorSNESLGResidualNormDestroy() to destroy this line graph; do not use PetscDrawLGDestroy().
176e5f7ee39SBarry Smith 
177e5f7ee39SBarry Smith    Level: intermediate
178e5f7ee39SBarry Smith 
179e5f7ee39SBarry Smith .seealso: KSPMonitorSNESLGResidualNormDestroy(), KSPMonitorSet(), KSPMonitorSNESLGTrueResidualCreate()
180e5f7ee39SBarry Smith @*/
1818b0b5a47SLisandro Dalcin PetscErrorCode  KSPMonitorSNESLGResidualNormCreate(MPI_Comm comm,const char host[],const char label[],int x,int y,int m,int n,PetscObject **objs)
182e5f7ee39SBarry Smith {
183e5f7ee39SBarry Smith   PetscDraw      draw;
184e5f7ee39SBarry Smith   PetscErrorCode ierr;
185e5f7ee39SBarry Smith   PetscDrawAxis  axis;
186c36cb520SLisandro Dalcin   PetscDrawLG    lg;
187e5f7ee39SBarry Smith   const char     *names[] = {"Linear residual","Nonlinear residual"};
188e5f7ee39SBarry Smith 
189e5f7ee39SBarry Smith   PetscFunctionBegin;
1908b0b5a47SLisandro Dalcin   ierr = PetscDrawCreate(comm,host,label,x,y,m,n,&draw);CHKERRQ(ierr);
191e5f7ee39SBarry Smith   ierr = PetscDrawSetFromOptions(draw);CHKERRQ(ierr);
192c36cb520SLisandro Dalcin   ierr = PetscDrawLGCreate(draw,2,&lg);CHKERRQ(ierr);
193c36cb520SLisandro Dalcin   ierr = PetscDrawLGSetLegend(lg,names);CHKERRQ(ierr);
194c36cb520SLisandro Dalcin   ierr = PetscDrawLGSetFromOptions(lg);CHKERRQ(ierr);
195c36cb520SLisandro Dalcin   ierr = PetscDrawLGGetAxis(lg,&axis);CHKERRQ(ierr);
196e5f7ee39SBarry Smith   ierr = PetscDrawAxisSetLabels(axis,"Convergence of Residual Norm","Iteration","Residual Norm");CHKERRQ(ierr);
197c36cb520SLisandro Dalcin   ierr = PetscDrawDestroy(&draw);CHKERRQ(ierr);
198e5f7ee39SBarry Smith 
199c36cb520SLisandro Dalcin   ierr = PetscMalloc1(2,objs);CHKERRQ(ierr);
200c36cb520SLisandro Dalcin   (*objs)[1] = (PetscObject)lg;
201e5f7ee39SBarry Smith   PetscFunctionReturn(0);
202e5f7ee39SBarry Smith }
203e5f7ee39SBarry Smith 
204e5f7ee39SBarry Smith PetscErrorCode  KSPMonitorSNESLGResidualNorm(KSP ksp,PetscInt n,PetscReal rnorm,PetscObject *objs)
205e5f7ee39SBarry Smith {
206c36cb520SLisandro Dalcin   SNES           snes = (SNES) objs[0];
207e5f7ee39SBarry Smith   PetscDrawLG    lg   = (PetscDrawLG) objs[1];
208e5f7ee39SBarry Smith   PetscErrorCode ierr;
209e5f7ee39SBarry Smith   PetscReal      y[2];
210e5f7ee39SBarry Smith   Vec            snes_solution,work1,work2;
211e5f7ee39SBarry Smith 
212e5f7ee39SBarry Smith   PetscFunctionBegin;
213e5f7ee39SBarry Smith   if (rnorm > 0.0) y[0] = PetscLog10Real(rnorm);
214e5f7ee39SBarry Smith   else y[0] = -15.0;
215e5f7ee39SBarry Smith 
216e5f7ee39SBarry Smith   ierr = SNESGetSolution(snes,&snes_solution);CHKERRQ(ierr);
217e5f7ee39SBarry Smith   ierr = VecDuplicate(snes_solution,&work1);CHKERRQ(ierr);
218e5f7ee39SBarry Smith   ierr = VecDuplicate(snes_solution,&work2);CHKERRQ(ierr);
219e5f7ee39SBarry Smith   ierr = KSPBuildSolution(ksp,work1,NULL);CHKERRQ(ierr);
220e5f7ee39SBarry Smith   ierr = VecAYPX(work1,-1.0,snes_solution);CHKERRQ(ierr);
221e5f7ee39SBarry Smith   ierr = SNESComputeFunction(snes,work1,work2);CHKERRQ(ierr);
222e5f7ee39SBarry Smith   ierr = VecNorm(work2,NORM_2,y+1);CHKERRQ(ierr);
223e5f7ee39SBarry Smith   if (y[1] > 0.0) y[1] = PetscLog10Real(y[1]);
224e5f7ee39SBarry Smith   else y[1] = -15.0;
225e5f7ee39SBarry Smith   ierr = VecDestroy(&work1);CHKERRQ(ierr);
226e5f7ee39SBarry Smith   ierr = VecDestroy(&work2);CHKERRQ(ierr);
227e5f7ee39SBarry Smith 
228e5f7ee39SBarry Smith   ierr = PetscDrawLGAddPoint(lg,NULL,y);CHKERRQ(ierr);
2296934998bSLisandro Dalcin   if (n < 20 || !(n % 5) || snes->reason) {
230e5f7ee39SBarry Smith     ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr);
2316934998bSLisandro Dalcin     ierr = PetscDrawLGSave(lg);CHKERRQ(ierr);
232e5f7ee39SBarry Smith   }
233e5f7ee39SBarry Smith   PetscFunctionReturn(0);
234e5f7ee39SBarry Smith }
235e5f7ee39SBarry Smith 
236e5f7ee39SBarry Smith /*@
237e5f7ee39SBarry Smith    KSPMonitorSNESLGResidualNormDestroy - Destroys a line graph context that was created
238e5f7ee39SBarry Smith    with KSPMonitorSNESLGResidualNormCreate().
239e5f7ee39SBarry Smith 
240e5f7ee39SBarry Smith    Collective on KSP
241e5f7ee39SBarry Smith 
242e5f7ee39SBarry Smith    Input Parameter:
243e5f7ee39SBarry Smith .  draw - the drawing context
244e5f7ee39SBarry Smith 
245e5f7ee39SBarry Smith    Level: intermediate
246e5f7ee39SBarry Smith 
247e5f7ee39SBarry Smith .seealso: KSPMonitorSNESLGResidualNormCreate(), KSPMonitorSNESLGTrueResidualDestroy(), KSPMonitorSet()
248e5f7ee39SBarry Smith @*/
249e5f7ee39SBarry Smith PetscErrorCode  KSPMonitorSNESLGResidualNormDestroy(PetscObject **objs)
250e5f7ee39SBarry Smith {
251e5f7ee39SBarry Smith   PetscErrorCode ierr;
252c36cb520SLisandro Dalcin   PetscDrawLG    lg = (PetscDrawLG) (*objs)[1];
253e5f7ee39SBarry Smith 
254e5f7ee39SBarry Smith   PetscFunctionBegin;
255c36cb520SLisandro Dalcin   ierr = PetscDrawLGDestroy(&lg);CHKERRQ(ierr);
256e5f7ee39SBarry Smith   ierr = PetscFree(*objs);CHKERRQ(ierr);
257e5f7ee39SBarry Smith   PetscFunctionReturn(0);
258e5f7ee39SBarry Smith }
259e5f7ee39SBarry Smith 
2604b828684SBarry Smith /*@C
261a6570f20SBarry Smith    SNESMonitorDefault - Monitors progress of the SNES solvers (default).
262e7e93795SLois Curfman McInnes 
263c7afd0dbSLois Curfman McInnes    Collective on SNES
264c7afd0dbSLois Curfman McInnes 
265e7e93795SLois Curfman McInnes    Input Parameters:
266c7afd0dbSLois Curfman McInnes +  snes - the SNES context
267e7e93795SLois Curfman McInnes .  its - iteration number
2684b27c08aSLois Curfman McInnes .  fgnorm - 2-norm of residual
269d43b4f6eSBarry Smith -  vf - viewer and format structure
270fee21e36SBarry Smith 
271e7e93795SLois Curfman McInnes    Notes:
2724b27c08aSLois Curfman McInnes    This routine prints the residual norm at each iteration.
273e7e93795SLois Curfman McInnes 
27436851e7fSLois Curfman McInnes    Level: intermediate
27536851e7fSLois Curfman McInnes 
276a6570f20SBarry Smith .seealso: SNESMonitorSet(), SNESMonitorSolution()
277e7e93795SLois Curfman McInnes @*/
278d43b4f6eSBarry Smith PetscErrorCode  SNESMonitorDefault(SNES snes,PetscInt its,PetscReal fgnorm,PetscViewerAndFormat *vf)
279e7e93795SLois Curfman McInnes {
280dfbe8321SBarry Smith   PetscErrorCode ierr;
281d43b4f6eSBarry Smith   PetscViewer    viewer = vf->viewer;
282d132466eSBarry Smith 
2833a40ed3dSBarry Smith   PetscFunctionBegin;
2844d4332d5SBarry Smith   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,4);
285d43b4f6eSBarry Smith   ierr = PetscViewerPushFormat(viewer,vf->format);CHKERRQ(ierr);
286649052a6SBarry Smith   ierr = PetscViewerASCIIAddTab(viewer,((PetscObject)snes)->tablevel);CHKERRQ(ierr);
287649052a6SBarry Smith   ierr = PetscViewerASCIIPrintf(viewer,"%3D SNES Function norm %14.12e \n",its,(double)fgnorm);CHKERRQ(ierr);
288649052a6SBarry Smith   ierr = PetscViewerASCIISubtractTab(viewer,((PetscObject)snes)->tablevel);CHKERRQ(ierr);
289d43b4f6eSBarry Smith   ierr = PetscViewerPopFormat(viewer);CHKERRQ(ierr) ;
2903a40ed3dSBarry Smith   PetscFunctionReturn(0);
291e7e93795SLois Curfman McInnes }
2923f1db9ecSBarry Smith 
2931f60017eSBarry Smith /*@C
2941f60017eSBarry Smith    SNESMonitorScaling - Monitors the largest value in each row of the Jacobian.
2951f60017eSBarry Smith 
2961f60017eSBarry Smith    Collective on SNES
2971f60017eSBarry Smith 
2981f60017eSBarry Smith    Input Parameters:
2991f60017eSBarry Smith +  snes - the SNES context
3001f60017eSBarry Smith .  its - iteration number
3011f60017eSBarry Smith .  fgnorm - 2-norm of residual
3021f60017eSBarry Smith -  vf - viewer and format structure
3031f60017eSBarry Smith 
3041f60017eSBarry Smith    Notes:
3051f60017eSBarry Smith    This routine prints the largest value in each row of the Jacobian
3061f60017eSBarry Smith 
3071f60017eSBarry Smith    Level: intermediate
3081f60017eSBarry Smith 
3091f60017eSBarry Smith .seealso: SNESMonitorSet(), SNESMonitorSolution()
3101f60017eSBarry Smith @*/
3111f60017eSBarry Smith PetscErrorCode  SNESMonitorScaling(SNES snes,PetscInt its,PetscReal fgnorm,PetscViewerAndFormat *vf)
3121f60017eSBarry Smith {
3131f60017eSBarry Smith   PetscErrorCode ierr;
3141f60017eSBarry Smith   PetscViewer    viewer = vf->viewer;
3151f60017eSBarry Smith   KSP            ksp;
3161f60017eSBarry Smith   Mat            J;
3171f60017eSBarry Smith   Vec            v;
3181f60017eSBarry Smith 
3191f60017eSBarry Smith   PetscFunctionBegin;
3201f60017eSBarry Smith   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,4);
3211f60017eSBarry Smith   ierr = SNESGetKSP(snes,&ksp);CHKERRQ(ierr);
3221f60017eSBarry Smith   ierr = KSPGetOperators(ksp,&J,NULL);CHKERRQ(ierr);
3231f60017eSBarry Smith   ierr = MatCreateVecs(J,&v,NULL);CHKERRQ(ierr);
3241f60017eSBarry Smith   ierr = MatGetRowMaxAbs(J,v,NULL);CHKERRQ(ierr);
3251f60017eSBarry Smith   ierr = PetscViewerPushFormat(viewer,vf->format);CHKERRQ(ierr);
3261f60017eSBarry Smith   ierr = PetscViewerASCIIAddTab(viewer,((PetscObject)snes)->tablevel);CHKERRQ(ierr);
3271f60017eSBarry Smith   ierr = PetscViewerASCIIPrintf(viewer,"%3D SNES Jacobian maximum row entries \n");CHKERRQ(ierr);
3281f60017eSBarry Smith   ierr = VecView(v,viewer);CHKERRQ(ierr);
3291f60017eSBarry Smith   ierr = PetscViewerASCIISubtractTab(viewer,((PetscObject)snes)->tablevel);CHKERRQ(ierr);
3301f60017eSBarry Smith   ierr = PetscViewerPopFormat(viewer);CHKERRQ(ierr) ;
3311f60017eSBarry Smith   ierr = VecDestroy(&v);CHKERRQ(ierr);
3321f60017eSBarry Smith   PetscFunctionReturn(0);
3331f60017eSBarry Smith }
3341f60017eSBarry Smith 
335d43b4f6eSBarry Smith PetscErrorCode SNESMonitorJacUpdateSpectrum(SNES snes,PetscInt it,PetscReal fnorm,PetscViewerAndFormat *vf)
336a80ad3e0SBarry Smith {
337196da8b6SPeter Brune #if defined(PETSC_MISSING_LAPACK_GEEV)
338ce94432eSBarry Smith   SETERRQ(PetscObjectComm((PetscObject)snes),PETSC_ERR_SUP,"GEEV - Lapack routine is unavailable\nNot able to provide eigen values.");
339196da8b6SPeter Brune #elif defined(PETSC_HAVE_ESSL)
340ce94432eSBarry Smith   SETERRQ(PetscObjectComm((PetscObject)snes),PETSC_ERR_SUP,"GEEV - No support for ESSL Lapack Routines");
341196da8b6SPeter Brune #else
3422e7541e6SPeter Brune   Vec            X;
3432e7541e6SPeter Brune   Mat            J,dJ,dJdense;
3442e7541e6SPeter Brune   PetscErrorCode ierr;
345d1e9a80fSBarry Smith   PetscErrorCode (*func)(SNES,Vec,Mat,Mat,void*);
3462e7541e6SPeter Brune   PetscInt       n,i;
3472e7541e6SPeter Brune   PetscBLASInt   nb,lwork;
3482e7541e6SPeter Brune   PetscReal      *eigr,*eigi;
3492e7541e6SPeter Brune   PetscScalar    *work;
3502e7541e6SPeter Brune   PetscScalar    *a;
3512e7541e6SPeter Brune 
3522e7541e6SPeter Brune   PetscFunctionBegin;
3532e7541e6SPeter Brune   if (it == 0) PetscFunctionReturn(0);
3542e7541e6SPeter Brune   /* create the difference between the current update and the current jacobian */
3552e7541e6SPeter Brune   ierr = SNESGetSolution(snes,&X);CHKERRQ(ierr);
356d1e9a80fSBarry Smith   ierr = SNESGetJacobian(snes,NULL,&J,&func,NULL);CHKERRQ(ierr);
3572e7541e6SPeter Brune   ierr = MatDuplicate(J,MAT_COPY_VALUES,&dJ);CHKERRQ(ierr);
358d1e9a80fSBarry Smith   ierr = SNESComputeJacobian(snes,X,dJ,dJ);CHKERRQ(ierr);
3592e7541e6SPeter Brune   ierr = MatAXPY(dJ,-1.0,J,SAME_NONZERO_PATTERN);CHKERRQ(ierr);
360f5af7f23SKarl Rupp 
3612e7541e6SPeter Brune   /* compute the spectrum directly */
3622e7541e6SPeter Brune   ierr  = MatConvert(dJ,MATSEQDENSE,MAT_INITIAL_MATRIX,&dJdense);CHKERRQ(ierr);
3630298fd71SBarry Smith   ierr  = MatGetSize(dJ,&n,NULL);CHKERRQ(ierr);
364c5df96a5SBarry Smith   ierr  = PetscBLASIntCast(n,&nb);CHKERRQ(ierr);
3652e7541e6SPeter Brune   lwork = 3*nb;
366785e854fSJed Brown   ierr  = PetscMalloc1(n,&eigr);CHKERRQ(ierr);
367785e854fSJed Brown   ierr  = PetscMalloc1(n,&eigi);CHKERRQ(ierr);
368785e854fSJed Brown   ierr  = PetscMalloc1(lwork,&work);CHKERRQ(ierr);
3698c778c55SBarry Smith   ierr  = MatDenseGetArray(dJdense,&a);CHKERRQ(ierr);
3702e7541e6SPeter Brune #if !defined(PETSC_USE_COMPLEX)
3712e7541e6SPeter Brune   {
3722e7541e6SPeter Brune     PetscBLASInt lierr;
3732e7541e6SPeter Brune     ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
3748b83055fSJed Brown     PetscStackCallBLAS("LAPACKgeev",LAPACKgeev_("N","N",&nb,a,&nb,eigr,eigi,NULL,&nb,NULL,&nb,work,&lwork,&lierr));
3752e7541e6SPeter Brune     if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"geev() error %d",lierr);
3762e7541e6SPeter Brune     ierr = PetscFPTrapPop();CHKERRQ(ierr);
3772e7541e6SPeter Brune   }
3782e7541e6SPeter Brune #else
3792e7541e6SPeter Brune   SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not coded for complex");
3802e7541e6SPeter Brune #endif
381fde5950dSBarry Smith   ierr = PetscPrintf(PetscObjectComm((PetscObject)snes),"Eigenvalues of J_%d - J_%d:\n",it,it-1);CHKERRQ(ierr);
3822e7541e6SPeter Brune   for (i=0;i<n;i++) {
383fde5950dSBarry Smith     ierr = PetscPrintf(PetscObjectComm((PetscObject)snes),"%5d: %20.5g + %20.5gi\n",i,(double)eigr[i],(double)eigi[i]);CHKERRQ(ierr);
3842e7541e6SPeter Brune   }
3858c778c55SBarry Smith   ierr = MatDenseRestoreArray(dJdense,&a);CHKERRQ(ierr);
3862e7541e6SPeter Brune   ierr = MatDestroy(&dJ);CHKERRQ(ierr);
3872e7541e6SPeter Brune   ierr = MatDestroy(&dJdense);CHKERRQ(ierr);
3882e7541e6SPeter Brune   ierr = PetscFree(eigr);CHKERRQ(ierr);
3892e7541e6SPeter Brune   ierr = PetscFree(eigi);CHKERRQ(ierr);
3902e7541e6SPeter Brune   ierr = PetscFree(work);CHKERRQ(ierr);
3912e7541e6SPeter Brune   PetscFunctionReturn(0);
392196da8b6SPeter Brune #endif
3932e7541e6SPeter Brune }
3942e7541e6SPeter Brune 
3956ba87a44SLisandro Dalcin PETSC_INTERN PetscErrorCode  SNESMonitorRange_Private(SNES,PetscInt,PetscReal*);
3966ba87a44SLisandro Dalcin 
3977087cfbeSBarry Smith PetscErrorCode  SNESMonitorRange_Private(SNES snes,PetscInt it,PetscReal *per)
398b271bb04SBarry Smith {
399b271bb04SBarry Smith   PetscErrorCode ierr;
400b271bb04SBarry Smith   Vec            resid;
401b271bb04SBarry Smith   PetscReal      rmax,pwork;
402b271bb04SBarry Smith   PetscInt       i,n,N;
403b271bb04SBarry Smith   PetscScalar    *r;
404b271bb04SBarry Smith 
405b271bb04SBarry Smith   PetscFunctionBegin;
406b271bb04SBarry Smith   ierr  = SNESGetFunction(snes,&resid,0,0);CHKERRQ(ierr);
407b271bb04SBarry Smith   ierr  = VecNorm(resid,NORM_INFINITY,&rmax);CHKERRQ(ierr);
408b271bb04SBarry Smith   ierr  = VecGetLocalSize(resid,&n);CHKERRQ(ierr);
409b271bb04SBarry Smith   ierr  = VecGetSize(resid,&N);CHKERRQ(ierr);
410b271bb04SBarry Smith   ierr  = VecGetArray(resid,&r);CHKERRQ(ierr);
411b271bb04SBarry Smith   pwork = 0.0;
412b271bb04SBarry Smith   for (i=0; i<n; i++) {
413b271bb04SBarry Smith     pwork += (PetscAbsScalar(r[i]) > .20*rmax);
414b271bb04SBarry Smith   }
415b2566f29SBarry Smith   ierr = MPIU_Allreduce(&pwork,per,1,MPIU_REAL,MPIU_SUM,PetscObjectComm((PetscObject)snes));CHKERRQ(ierr);
416b271bb04SBarry Smith   ierr = VecRestoreArray(resid,&r);CHKERRQ(ierr);
417b271bb04SBarry Smith   *per = *per/N;
418b271bb04SBarry Smith   PetscFunctionReturn(0);
419b271bb04SBarry Smith }
420b271bb04SBarry Smith 
421b271bb04SBarry Smith /*@C
422b271bb04SBarry Smith    SNESMonitorRange - Prints the percentage of residual elements that are more then 10 percent of the maximum value.
423b271bb04SBarry Smith 
424b271bb04SBarry Smith    Collective on SNES
425b271bb04SBarry Smith 
426b271bb04SBarry Smith    Input Parameters:
427b271bb04SBarry Smith +  snes   - iterative context
428b271bb04SBarry Smith .  it    - iteration number
429b271bb04SBarry Smith .  rnorm - 2-norm (preconditioned) residual value (may be estimated).
430b271bb04SBarry Smith -  dummy - unused monitor context
431b271bb04SBarry Smith 
432b271bb04SBarry Smith    Options Database Key:
433b271bb04SBarry Smith .  -snes_monitor_range - Activates SNESMonitorRange()
434b271bb04SBarry Smith 
435b271bb04SBarry Smith    Level: intermediate
436b271bb04SBarry Smith 
437b271bb04SBarry Smith .seealso: SNESMonitorSet(), SNESMonitorDefault(), SNESMonitorLGCreate()
438b271bb04SBarry Smith @*/
439d43b4f6eSBarry Smith PetscErrorCode  SNESMonitorRange(SNES snes,PetscInt it,PetscReal rnorm,PetscViewerAndFormat *vf)
440b271bb04SBarry Smith {
441b271bb04SBarry Smith   PetscErrorCode ierr;
442b271bb04SBarry Smith   PetscReal      perc,rel;
443d43b4f6eSBarry Smith   PetscViewer    viewer = vf->viewer;
444b271bb04SBarry Smith   /* should be in a MonitorRangeContext */
445b271bb04SBarry Smith   static PetscReal prev;
446b271bb04SBarry Smith 
447b271bb04SBarry Smith   PetscFunctionBegin;
4484d4332d5SBarry Smith   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,4);
449b271bb04SBarry Smith   if (!it) prev = rnorm;
450b271bb04SBarry Smith   ierr = SNESMonitorRange_Private(snes,it,&perc);CHKERRQ(ierr);
451b271bb04SBarry Smith 
452b271bb04SBarry Smith   rel  = (prev - rnorm)/prev;
453b271bb04SBarry Smith   prev = rnorm;
454d43b4f6eSBarry Smith   ierr = PetscViewerPushFormat(viewer,vf->format);CHKERRQ(ierr);
455649052a6SBarry Smith   ierr = PetscViewerASCIIAddTab(viewer,((PetscObject)snes)->tablevel);CHKERRQ(ierr);
4566712e2f1SBarry 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);
457649052a6SBarry Smith   ierr = PetscViewerASCIISubtractTab(viewer,((PetscObject)snes)->tablevel);CHKERRQ(ierr);
458d43b4f6eSBarry Smith   ierr = PetscViewerPopFormat(viewer);CHKERRQ(ierr);
459b271bb04SBarry Smith   PetscFunctionReturn(0);
460b271bb04SBarry Smith }
461b271bb04SBarry Smith 
4623a7fca6bSBarry Smith /*@C
463a6570f20SBarry Smith    SNESMonitorRatio - Monitors progress of the SNES solvers by printing the ratio
4644b27c08aSLois Curfman McInnes    of residual norm at each iteration to the previous.
4653a7fca6bSBarry Smith 
4663a7fca6bSBarry Smith    Collective on SNES
4673a7fca6bSBarry Smith 
4683a7fca6bSBarry Smith    Input Parameters:
4693a7fca6bSBarry Smith +  snes - the SNES context
4703a7fca6bSBarry Smith .  its - iteration number
4713a7fca6bSBarry Smith .  fgnorm - 2-norm of residual (or gradient)
472eabae89aSBarry Smith -  dummy -  context of monitor
4733a7fca6bSBarry Smith 
4743a7fca6bSBarry Smith    Level: intermediate
4753a7fca6bSBarry Smith 
47695452b02SPatrick Sanan    Notes:
47795452b02SPatrick Sanan     Insure that SNESMonitorRatio() is called when you set this monitor
478fde5950dSBarry Smith .seealso: SNESMonitorSet(), SNESMonitorSolution(), SNESMonitorRatio()
4793a7fca6bSBarry Smith @*/
480d43b4f6eSBarry Smith PetscErrorCode  SNESMonitorRatio(SNES snes,PetscInt its,PetscReal fgnorm,PetscViewerAndFormat *vf)
4813a7fca6bSBarry Smith {
482dfbe8321SBarry Smith   PetscErrorCode          ierr;
48377431f27SBarry Smith   PetscInt                len;
48487828ca2SBarry Smith   PetscReal               *history;
485d43b4f6eSBarry Smith   PetscViewer             viewer = vf->viewer;
4863a7fca6bSBarry Smith 
4873a7fca6bSBarry Smith   PetscFunctionBegin;
4880298fd71SBarry Smith   ierr = SNESGetConvergenceHistory(snes,&history,NULL,&len);CHKERRQ(ierr);
489d43b4f6eSBarry Smith   ierr = PetscViewerPushFormat(viewer,vf->format);CHKERRQ(ierr);
490fde5950dSBarry Smith   ierr = PetscViewerASCIIAddTab(viewer,((PetscObject)snes)->tablevel);CHKERRQ(ierr);
491958c9bccSBarry Smith   if (!its || !history || its > len) {
492fde5950dSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"%3D SNES Function norm %14.12e \n",its,(double)fgnorm);CHKERRQ(ierr);
4933a7fca6bSBarry Smith   } else {
49487828ca2SBarry Smith     PetscReal ratio = fgnorm/history[its-1];
495fde5950dSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"%3D SNES Function norm %14.12e %14.12e \n",its,(double)fgnorm,(double)ratio);CHKERRQ(ierr);
4963a7fca6bSBarry Smith   }
497fde5950dSBarry Smith   ierr = PetscViewerASCIISubtractTab(viewer,((PetscObject)snes)->tablevel);CHKERRQ(ierr);
498d43b4f6eSBarry Smith   ierr = PetscViewerPopFormat(viewer);CHKERRQ(ierr);
4993a7fca6bSBarry Smith   PetscFunctionReturn(0);
5003a7fca6bSBarry Smith }
5013a7fca6bSBarry Smith 
5023a7fca6bSBarry Smith /*@C
503fde5950dSBarry Smith    SNESMonitorRatioSetUp - Insures the SNES object is saving its history since this monitor needs access to it
5043a7fca6bSBarry Smith 
5053a7fca6bSBarry Smith    Collective on SNES
5063a7fca6bSBarry Smith 
5073a7fca6bSBarry Smith    Input Parameters:
508eabae89aSBarry Smith +   snes - the SNES context
509fde5950dSBarry Smith -   viewer - the PetscViewer object (ignored)
5103a7fca6bSBarry Smith 
5113a7fca6bSBarry Smith    Level: intermediate
5123a7fca6bSBarry Smith 
513fde5950dSBarry Smith .seealso: SNESMonitorSet(), SNESMonitorSolution(), SNESMonitorDefault(), SNESMonitorRatio()
5143a7fca6bSBarry Smith @*/
515d43b4f6eSBarry Smith PetscErrorCode  SNESMonitorRatioSetUp(SNES snes,PetscViewerAndFormat *vf)
5163a7fca6bSBarry Smith {
517dfbe8321SBarry Smith   PetscErrorCode          ierr;
51887828ca2SBarry Smith   PetscReal               *history;
5193a7fca6bSBarry Smith 
5203a7fca6bSBarry Smith   PetscFunctionBegin;
5210298fd71SBarry Smith   ierr = SNESGetConvergenceHistory(snes,&history,NULL,NULL);CHKERRQ(ierr);
5223a7fca6bSBarry Smith   if (!history) {
523fde5950dSBarry Smith     ierr = SNESSetConvergenceHistory(snes,NULL,NULL,100,PETSC_TRUE);CHKERRQ(ierr);
5243a7fca6bSBarry Smith   }
5253a7fca6bSBarry Smith   PetscFunctionReturn(0);
5263a7fca6bSBarry Smith }
5273a7fca6bSBarry Smith 
528e7e93795SLois Curfman McInnes /* ---------------------------------------------------------------- */
529be1f7002SBarry Smith /*
530a6570f20SBarry Smith      Default (short) SNES Monitor, same as SNESMonitorDefault() except
531be1f7002SBarry Smith   it prints fewer digits of the residual as the residual gets smaller.
532be1f7002SBarry Smith   This is because the later digits are meaningless and are often
533be1f7002SBarry Smith   different on different machines; by using this routine different
534be1f7002SBarry Smith   machines will usually generate the same output.
535dec21524SBarry Smith 
536dec21524SBarry Smith   Deprecated: Intentionally has no manual page
537be1f7002SBarry Smith */
538d43b4f6eSBarry Smith PetscErrorCode  SNESMonitorDefaultShort(SNES snes,PetscInt its,PetscReal fgnorm,PetscViewerAndFormat *vf)
539e7e93795SLois Curfman McInnes {
540dfbe8321SBarry Smith   PetscErrorCode ierr;
541d43b4f6eSBarry Smith   PetscViewer    viewer = vf->viewer;
542d132466eSBarry Smith 
5433a40ed3dSBarry Smith   PetscFunctionBegin;
5444d4332d5SBarry Smith   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,4);
545d43b4f6eSBarry Smith   ierr = PetscViewerPushFormat(viewer,vf->format);CHKERRQ(ierr);
546649052a6SBarry Smith   ierr = PetscViewerASCIIAddTab(viewer,((PetscObject)snes)->tablevel);CHKERRQ(ierr);
5478f240d10SBarry Smith   if (fgnorm > 1.e-9) {
5488fa295daSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"%3D SNES Function norm %g \n",its,(double)fgnorm);CHKERRQ(ierr);
5493a40ed3dSBarry Smith   } else if (fgnorm > 1.e-11) {
5508fa295daSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"%3D SNES Function norm %5.3e \n",its,(double)fgnorm);CHKERRQ(ierr);
5513a40ed3dSBarry Smith   } else {
552649052a6SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"%3D SNES Function norm < 1.e-11\n",its);CHKERRQ(ierr);
553a34d58ebSBarry Smith   }
554649052a6SBarry Smith   ierr = PetscViewerASCIISubtractTab(viewer,((PetscObject)snes)->tablevel);CHKERRQ(ierr);
555d43b4f6eSBarry Smith   ierr = PetscViewerPopFormat(viewer);CHKERRQ(ierr);
5563a40ed3dSBarry Smith   PetscFunctionReturn(0);
557e7e93795SLois Curfman McInnes }
5582db13446SMatthew G. Knepley 
5592db13446SMatthew G. Knepley /*@C
5602db13446SMatthew G. Knepley   SNESMonitorDefaultField - Monitors progress of the SNES solvers, separated into fields.
5612db13446SMatthew G. Knepley 
5622db13446SMatthew G. Knepley   Collective on SNES
5632db13446SMatthew G. Knepley 
5642db13446SMatthew G. Knepley   Input Parameters:
5652db13446SMatthew G. Knepley + snes   - the SNES context
5662db13446SMatthew G. Knepley . its    - iteration number
5672db13446SMatthew G. Knepley . fgnorm - 2-norm of residual
5682db13446SMatthew G. Knepley - ctx    - the PetscViewer
5692db13446SMatthew G. Knepley 
5702db13446SMatthew G. Knepley   Notes:
5712db13446SMatthew G. Knepley   This routine uses the DM attached to the residual vector
5722db13446SMatthew G. Knepley 
5732db13446SMatthew G. Knepley   Level: intermediate
5742db13446SMatthew G. Knepley 
575dec21524SBarry Smith .seealso: SNESMonitorSet(), SNESMonitorSolution(), SNESMonitorDefault()
5762db13446SMatthew G. Knepley @*/
577d43b4f6eSBarry Smith PetscErrorCode SNESMonitorDefaultField(SNES snes, PetscInt its, PetscReal fgnorm, PetscViewerAndFormat *vf)
5782db13446SMatthew G. Knepley {
579d43b4f6eSBarry Smith   PetscViewer    viewer = vf->viewer;
5802db13446SMatthew G. Knepley   Vec            r;
5812db13446SMatthew G. Knepley   DM             dm;
5822db13446SMatthew G. Knepley   PetscReal      res[256];
5832db13446SMatthew G. Knepley   PetscInt       tablevel;
5842db13446SMatthew G. Knepley   PetscErrorCode ierr;
5852db13446SMatthew G. Knepley 
5862db13446SMatthew G. Knepley   PetscFunctionBegin;
5874d4332d5SBarry Smith   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,4);
5882db13446SMatthew G. Knepley   ierr = SNESGetFunction(snes, &r, NULL, NULL);CHKERRQ(ierr);
5892db13446SMatthew G. Knepley   ierr = VecGetDM(r, &dm);CHKERRQ(ierr);
590d43b4f6eSBarry Smith   if (!dm) {ierr = SNESMonitorDefault(snes, its, fgnorm, vf);CHKERRQ(ierr);}
5912db13446SMatthew G. Knepley   else {
5922db13446SMatthew G. Knepley     PetscSection s, gs;
5932db13446SMatthew G. Knepley     PetscInt     Nf, f;
5942db13446SMatthew G. Knepley 
595*92fd8e1eSJed Brown     ierr = DMGetLocalSection(dm, &s);CHKERRQ(ierr);
596e87a4003SBarry Smith     ierr = DMGetGlobalSection(dm, &gs);CHKERRQ(ierr);
597d43b4f6eSBarry Smith     if (!s || !gs) {ierr = SNESMonitorDefault(snes, its, fgnorm, vf);CHKERRQ(ierr);}
5982db13446SMatthew G. Knepley     ierr = PetscSectionGetNumFields(s, &Nf);CHKERRQ(ierr);
5992db13446SMatthew G. Knepley     if (Nf > 256) SETERRQ1(PetscObjectComm((PetscObject) snes), PETSC_ERR_SUP, "Do not support %d fields > 256", Nf);
6002db13446SMatthew G. Knepley     ierr = PetscSectionVecNorm(s, gs, r, NORM_2, res);CHKERRQ(ierr);
6012db13446SMatthew G. Knepley     ierr = PetscObjectGetTabLevel((PetscObject) snes, &tablevel);CHKERRQ(ierr);
602d43b4f6eSBarry Smith     ierr = PetscViewerPushFormat(viewer,vf->format);CHKERRQ(ierr);
6032db13446SMatthew G. Knepley     ierr = PetscViewerASCIIAddTab(viewer, tablevel);CHKERRQ(ierr);
6042db13446SMatthew G. Knepley     ierr = PetscViewerASCIIPrintf(viewer, "%3D SNES Function norm %14.12e [", its, (double) fgnorm);CHKERRQ(ierr);
6052db13446SMatthew G. Knepley     for (f = 0; f < Nf; ++f) {
6062db13446SMatthew G. Knepley       if (f) {ierr = PetscViewerASCIIPrintf(viewer, ", ");CHKERRQ(ierr);}
6072db13446SMatthew G. Knepley       ierr = PetscViewerASCIIPrintf(viewer, "%14.12e", res[f]);CHKERRQ(ierr);
6082db13446SMatthew G. Knepley     }
6092db13446SMatthew G. Knepley     ierr = PetscViewerASCIIPrintf(viewer, "] \n");CHKERRQ(ierr);
6102db13446SMatthew G. Knepley     ierr = PetscViewerASCIISubtractTab(viewer, tablevel);CHKERRQ(ierr);
611d43b4f6eSBarry Smith     ierr = PetscViewerPopFormat(viewer);CHKERRQ(ierr);
6122db13446SMatthew G. Knepley   }
6132db13446SMatthew G. Knepley   PetscFunctionReturn(0);
6142db13446SMatthew G. Knepley }
615e7e93795SLois Curfman McInnes /* ---------------------------------------------------------------- */
6164b828684SBarry Smith /*@C
6178d359177SBarry Smith    SNESConvergedDefault - Convergence test of the solvers for
618f525115eSLois Curfman McInnes    systems of nonlinear equations (default).
619e7e93795SLois Curfman McInnes 
620c7afd0dbSLois Curfman McInnes    Collective on SNES
621c7afd0dbSLois Curfman McInnes 
622e7e93795SLois Curfman McInnes    Input Parameters:
623c7afd0dbSLois Curfman McInnes +  snes - the SNES context
62406ee9f85SBarry Smith .  it - the iteration (0 indicates before any Newton steps)
625e7e93795SLois Curfman McInnes .  xnorm - 2-norm of current iterate
626c60f73f4SPeter Brune .  snorm - 2-norm of current step
6277f3332b4SBarry Smith .  fnorm - 2-norm of function at current iterate
628c7afd0dbSLois Curfman McInnes -  dummy - unused context
629e7e93795SLois Curfman McInnes 
630184914b5SBarry Smith    Output Parameter:
631184914b5SBarry Smith .   reason  - one of
63270441072SBarry Smith $  SNES_CONVERGED_FNORM_ABS       - (fnorm < abstol),
633c60f73f4SPeter Brune $  SNES_CONVERGED_SNORM_RELATIVE  - (snorm < stol*xnorm),
634184914b5SBarry Smith $  SNES_CONVERGED_FNORM_RELATIVE  - (fnorm < rtol*fnorm0),
635184914b5SBarry Smith $  SNES_DIVERGED_FUNCTION_COUNT   - (nfct > maxf),
636184914b5SBarry Smith $  SNES_DIVERGED_FNORM_NAN        - (fnorm == NaN),
637184914b5SBarry Smith $  SNES_CONVERGED_ITERATING       - (otherwise),
638e7e93795SLois Curfman McInnes 
639e7e93795SLois Curfman McInnes    where
640c7afd0dbSLois Curfman McInnes +    maxf - maximum number of function evaluations,
641c7afd0dbSLois Curfman McInnes             set with SNESSetTolerances()
642c7afd0dbSLois Curfman McInnes .    nfct - number of function evaluations,
64370441072SBarry Smith .    abstol - absolute function norm tolerance,
644c7afd0dbSLois Curfman McInnes             set with SNESSetTolerances()
645c7afd0dbSLois Curfman McInnes -    rtol - relative function norm tolerance, set with SNESSetTolerances()
646fee21e36SBarry Smith 
64736851e7fSLois Curfman McInnes    Level: intermediate
64836851e7fSLois Curfman McInnes 
64971f87433Sdalcinl .seealso: SNESSetConvergenceTest()
650e7e93795SLois Curfman McInnes @*/
6518d359177SBarry Smith PetscErrorCode  SNESConvergedDefault(SNES snes,PetscInt it,PetscReal xnorm,PetscReal snorm,PetscReal fnorm,SNESConvergedReason *reason,void *dummy)
652e7e93795SLois Curfman McInnes {
65363ba0a88SBarry Smith   PetscErrorCode ierr;
65463ba0a88SBarry Smith 
6553a40ed3dSBarry Smith   PetscFunctionBegin;
6560700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
6573f149594SLisandro Dalcin   PetscValidPointer(reason,6);
6583f149594SLisandro Dalcin 
65906ee9f85SBarry Smith   *reason = SNES_CONVERGED_ITERATING;
66006ee9f85SBarry Smith 
66106ee9f85SBarry Smith   if (!it) {
66206ee9f85SBarry Smith     /* set parameter for default relative tolerance convergence test */
66306ee9f85SBarry Smith     snes->ttol   = fnorm*snes->rtol;
664e37c518bSBarry Smith     snes->rnorm0 = fnorm;
66506ee9f85SBarry Smith   }
6668146f6ebSBarry Smith   if (PetscIsInfOrNanReal(fnorm)) {
667ae15b995SBarry Smith     ierr    = PetscInfo(snes,"Failed to converged, function norm is NaN\n");CHKERRQ(ierr);
668184914b5SBarry Smith     *reason = SNES_DIVERGED_FNORM_NAN;
669be5caee7SBarry Smith   } else if (fnorm < snes->abstol && (it || !snes->forceiteration)) {
6708f1a2a5eSBarry Smith     ierr    = PetscInfo2(snes,"Converged due to function norm %14.12e < %14.12e\n",(double)fnorm,(double)snes->abstol);CHKERRQ(ierr);
671184914b5SBarry Smith     *reason = SNES_CONVERGED_FNORM_ABS;
672e71169deSBarry Smith   } else if (snes->nfuncs >= snes->max_funcs && snes->max_funcs >= 0) {
673ae15b995SBarry Smith     ierr    = PetscInfo2(snes,"Exceeded maximum number of function evaluations: %D > %D\n",snes->nfuncs,snes->max_funcs);CHKERRQ(ierr);
674184914b5SBarry Smith     *reason = SNES_DIVERGED_FUNCTION_COUNT;
67506ee9f85SBarry Smith   }
67606ee9f85SBarry Smith 
67706ee9f85SBarry Smith   if (it && !*reason) {
67806ee9f85SBarry Smith     if (fnorm <= snes->ttol) {
6798f1a2a5eSBarry Smith       ierr    = PetscInfo2(snes,"Converged due to function norm %14.12e < %14.12e (relative tolerance)\n",(double)fnorm,(double)snes->ttol);CHKERRQ(ierr);
68006ee9f85SBarry Smith       *reason = SNES_CONVERGED_FNORM_RELATIVE;
681c60f73f4SPeter Brune     } else if (snorm < snes->stol*xnorm) {
682c60f73f4SPeter 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);
683c60f73f4SPeter Brune       *reason = SNES_CONVERGED_SNORM_RELATIVE;
684e4d06f11SPatrick Farrell     } else if (snes->divtol > 0 && (fnorm > snes->divtol*snes->rnorm0)) {
685e37c518bSBarry 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);
686e37c518bSBarry Smith       *reason = SNES_DIVERGED_DTOL;
68706ee9f85SBarry Smith     }
688e37c518bSBarry Smith 
689e7e93795SLois Curfman McInnes   }
6903a40ed3dSBarry Smith   PetscFunctionReturn(0);
691e7e93795SLois Curfman McInnes }
6923f149594SLisandro Dalcin 
6933f149594SLisandro Dalcin /*@C
694e2a6519dSDmitry Karpeev    SNESConvergedSkip - Convergence test for SNES that NEVER returns as
6953f149594SLisandro Dalcin    converged, UNLESS the maximum number of iteration have been reached.
6963f149594SLisandro Dalcin 
6973f9fe445SBarry Smith    Logically Collective on SNES
6983f149594SLisandro Dalcin 
6993f149594SLisandro Dalcin    Input Parameters:
7003f149594SLisandro Dalcin +  snes - the SNES context
7013f149594SLisandro Dalcin .  it - the iteration (0 indicates before any Newton steps)
7023f149594SLisandro Dalcin .  xnorm - 2-norm of current iterate
703c60f73f4SPeter Brune .  snorm - 2-norm of current step
7043f149594SLisandro Dalcin .  fnorm - 2-norm of function at current iterate
7053f149594SLisandro Dalcin -  dummy - unused context
7063f149594SLisandro Dalcin 
7073f149594SLisandro Dalcin    Output Parameter:
70885385478SLisandro Dalcin .   reason  - SNES_CONVERGED_ITERATING, SNES_CONVERGED_ITS, or SNES_DIVERGED_FNORM_NAN
7093f149594SLisandro Dalcin 
7103f149594SLisandro Dalcin    Notes:
7113f149594SLisandro Dalcin    Convergence is then declared after a fixed number of iterations have been used.
7123f149594SLisandro Dalcin 
7133f149594SLisandro Dalcin    Level: advanced
7143f149594SLisandro Dalcin 
7153f149594SLisandro Dalcin .seealso: SNESSetConvergenceTest()
7163f149594SLisandro Dalcin @*/
717e2a6519dSDmitry Karpeev PetscErrorCode  SNESConvergedSkip(SNES snes,PetscInt it,PetscReal xnorm,PetscReal snorm,PetscReal fnorm,SNESConvergedReason *reason,void *dummy)
7183f149594SLisandro Dalcin {
7193f149594SLisandro Dalcin   PetscErrorCode ierr;
7203f149594SLisandro Dalcin 
7213f149594SLisandro Dalcin   PetscFunctionBegin;
7220700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
7233f149594SLisandro Dalcin   PetscValidPointer(reason,6);
7243f149594SLisandro Dalcin 
7253f149594SLisandro Dalcin   *reason = SNES_CONVERGED_ITERATING;
7263f149594SLisandro Dalcin 
7273f149594SLisandro Dalcin   if (fnorm != fnorm) {
7283f149594SLisandro Dalcin     ierr    = PetscInfo(snes,"Failed to converged, function norm is NaN\n");CHKERRQ(ierr);
7293f149594SLisandro Dalcin     *reason = SNES_DIVERGED_FNORM_NAN;
7303f149594SLisandro Dalcin   } else if (it == snes->max_its) {
7313f149594SLisandro Dalcin     *reason = SNES_CONVERGED_ITS;
7323f149594SLisandro Dalcin   }
7333f149594SLisandro Dalcin   PetscFunctionReturn(0);
7343f149594SLisandro Dalcin }
7353f149594SLisandro Dalcin 
7368d359177SBarry Smith /*@C
737fa0ddf94SBarry Smith   SNESSetWorkVecs - Gets a number of work vectors.
73858c9b817SLisandro Dalcin 
73958c9b817SLisandro Dalcin   Input Parameters:
740a2b725a8SWilliam Gropp + snes  - the SNES context
741a2b725a8SWilliam Gropp - nw - number of work vectors to allocate
74258c9b817SLisandro Dalcin 
74358c9b817SLisandro Dalcin   Level: developer
744fa0ddf94SBarry Smith 
74598acb6afSMatthew G Knepley @*/
746fa0ddf94SBarry Smith PetscErrorCode SNESSetWorkVecs(SNES snes,PetscInt nw)
74758c9b817SLisandro Dalcin {
748c5ed8070SMatthew G. Knepley   DM             dm;
749c5ed8070SMatthew G. Knepley   Vec            v;
75058c9b817SLisandro Dalcin   PetscErrorCode ierr;
75158c9b817SLisandro Dalcin 
75258c9b817SLisandro Dalcin   PetscFunctionBegin;
75358c9b817SLisandro Dalcin   if (snes->work) {ierr = VecDestroyVecs(snes->nwork,&snes->work);CHKERRQ(ierr);}
75458c9b817SLisandro Dalcin   snes->nwork = nw;
755f5af7f23SKarl Rupp 
756c5ed8070SMatthew G. Knepley   ierr = SNESGetDM(snes, &dm);CHKERRQ(ierr);
757c5ed8070SMatthew G. Knepley   ierr = DMGetGlobalVector(dm, &v);CHKERRQ(ierr);
758c5ed8070SMatthew G. Knepley   ierr = VecDuplicateVecs(v,snes->nwork,&snes->work);CHKERRQ(ierr);
759c5ed8070SMatthew G. Knepley   ierr = DMRestoreGlobalVector(dm, &v);CHKERRQ(ierr);
76058c9b817SLisandro Dalcin   ierr = PetscLogObjectParents(snes,nw,snes->work);CHKERRQ(ierr);
76158c9b817SLisandro Dalcin   PetscFunctionReturn(0);
76258c9b817SLisandro Dalcin }
763