xref: /petsc/src/snes/interface/snesut.c (revision ea844a1adba28e307898a6e94a1f422fd7d2db48)
1e7e93795SLois Curfman McInnes 
2af0996ceSBarry Smith #include <petsc/private/snesimpl.h>       /*I   "petsc/private/snesimpl.h"   I*/
3636fd056SMatthew G. Knepley #include <petscdm.h>
4*ea844a1aSMatthew 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);
685ed2d596SBarry Smith   ierr = SNESGetFunction(snes,&x,0,0);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 
109a5c2985bSBarry Smith /*@C
110a5c2985bSBarry Smith    KSPMonitorSNES - Print the residual norm of the nonlinear function at each iteration of the linear iterative solver.
111a5c2985bSBarry Smith 
112a5c2985bSBarry Smith    Collective on KSP
113a5c2985bSBarry Smith 
114a5c2985bSBarry Smith    Input Parameters:
115a5c2985bSBarry Smith +  ksp   - iterative context
116a5c2985bSBarry Smith .  n     - iteration number
117a5c2985bSBarry Smith .  rnorm - 2-norm (preconditioned) residual value (may be estimated).
118a5c2985bSBarry Smith -  dummy - unused monitor context
119a5c2985bSBarry Smith 
120a5c2985bSBarry Smith    Level: intermediate
121a5c2985bSBarry Smith 
122a5c2985bSBarry Smith .seealso: KSPMonitorSet(), KSPMonitorTrueResidualNorm(), KSPMonitorLGResidualNormCreate()
123a5c2985bSBarry Smith @*/
124a5c2985bSBarry Smith PetscErrorCode  KSPMonitorSNES(KSP ksp,PetscInt n,PetscReal rnorm,void *dummy)
125a5c2985bSBarry Smith {
126a5c2985bSBarry Smith   PetscErrorCode ierr;
127a5c2985bSBarry Smith   PetscViewer    viewer;
128a5c2985bSBarry Smith   SNES           snes = (SNES) dummy;
129a5c2985bSBarry Smith   Vec            snes_solution,work1,work2;
130a5c2985bSBarry Smith   PetscReal      snorm;
131a5c2985bSBarry Smith 
132a5c2985bSBarry Smith   PetscFunctionBegin;
133a5c2985bSBarry Smith   ierr = SNESGetSolution(snes,&snes_solution);CHKERRQ(ierr);
134a5c2985bSBarry Smith   ierr = VecDuplicate(snes_solution,&work1);CHKERRQ(ierr);
135a5c2985bSBarry Smith   ierr = VecDuplicate(snes_solution,&work2);CHKERRQ(ierr);
136a5c2985bSBarry Smith   ierr = KSPBuildSolution(ksp,work1,NULL);CHKERRQ(ierr);
137a5c2985bSBarry Smith   ierr = VecAYPX(work1,-1.0,snes_solution);CHKERRQ(ierr);
138a5c2985bSBarry Smith   ierr = SNESComputeFunction(snes,work1,work2);CHKERRQ(ierr);
139a5c2985bSBarry Smith   ierr = VecNorm(work2,NORM_2,&snorm);CHKERRQ(ierr);
140a5c2985bSBarry Smith   ierr = VecDestroy(&work1);CHKERRQ(ierr);
141a5c2985bSBarry Smith   ierr = VecDestroy(&work2);CHKERRQ(ierr);
142a5c2985bSBarry Smith 
143a5c2985bSBarry Smith   ierr = PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)ksp),&viewer);CHKERRQ(ierr);
144a5c2985bSBarry Smith   ierr = PetscViewerASCIIAddTab(viewer,((PetscObject)ksp)->tablevel);CHKERRQ(ierr);
145a5c2985bSBarry Smith   if (n == 0 && ((PetscObject)ksp)->prefix) {
146a5c2985bSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  Residual norms for %s solve.\n",((PetscObject)ksp)->prefix);CHKERRQ(ierr);
147a5c2985bSBarry Smith   }
148a5c2985bSBarry Smith   ierr = PetscViewerASCIIPrintf(viewer,"%3D SNES Residual norm %5.3e KSP Residual norm %5.3e \n",n,(double)snorm,(double)rnorm);CHKERRQ(ierr);
149a5c2985bSBarry Smith   ierr = PetscViewerASCIISubtractTab(viewer,((PetscObject)ksp)->tablevel);CHKERRQ(ierr);
150a5c2985bSBarry Smith   PetscFunctionReturn(0);
151a5c2985bSBarry Smith }
152a5c2985bSBarry Smith 
153e5f7ee39SBarry Smith #include <petscdraw.h>
154e5f7ee39SBarry Smith 
155e5f7ee39SBarry Smith /*@C
156e5f7ee39SBarry Smith    KSPMonitorSNESLGResidualNormCreate - Creates a line graph context for use with
157e5f7ee39SBarry Smith    KSP to monitor convergence of preconditioned residual norms.
158e5f7ee39SBarry Smith 
159e5f7ee39SBarry Smith    Collective on KSP
160e5f7ee39SBarry Smith 
161e5f7ee39SBarry Smith    Input Parameters:
1628b0b5a47SLisandro Dalcin +  comm - communicator context
1638b0b5a47SLisandro Dalcin .  host - the X display to open, or null for the local machine
164e5f7ee39SBarry Smith .  label - the title to put in the title bar
165e5f7ee39SBarry Smith .  x, y - the screen coordinates of the upper left coordinate of
166e5f7ee39SBarry Smith           the window
167e5f7ee39SBarry Smith -  m, n - the screen width and height in pixels
168e5f7ee39SBarry Smith 
169e5f7ee39SBarry Smith    Output Parameter:
170e5f7ee39SBarry Smith .  draw - the drawing context
171e5f7ee39SBarry Smith 
172e5f7ee39SBarry Smith    Options Database Key:
173e5f7ee39SBarry Smith .  -ksp_monitor_lg_residualnorm - Sets line graph monitor
174e5f7ee39SBarry Smith 
175e5f7ee39SBarry Smith    Notes:
176e5f7ee39SBarry Smith    Use KSPMonitorSNESLGResidualNormDestroy() to destroy this line graph; do not use PetscDrawLGDestroy().
177e5f7ee39SBarry Smith 
178e5f7ee39SBarry Smith    Level: intermediate
179e5f7ee39SBarry Smith 
180e5f7ee39SBarry Smith .seealso: KSPMonitorSNESLGResidualNormDestroy(), KSPMonitorSet(), KSPMonitorSNESLGTrueResidualCreate()
181e5f7ee39SBarry Smith @*/
1828b0b5a47SLisandro Dalcin PetscErrorCode  KSPMonitorSNESLGResidualNormCreate(MPI_Comm comm,const char host[],const char label[],int x,int y,int m,int n,PetscObject **objs)
183e5f7ee39SBarry Smith {
184e5f7ee39SBarry Smith   PetscDraw      draw;
185e5f7ee39SBarry Smith   PetscErrorCode ierr;
186e5f7ee39SBarry Smith   PetscDrawAxis  axis;
187c36cb520SLisandro Dalcin   PetscDrawLG    lg;
188e5f7ee39SBarry Smith   const char     *names[] = {"Linear residual","Nonlinear residual"};
189e5f7ee39SBarry Smith 
190e5f7ee39SBarry Smith   PetscFunctionBegin;
1918b0b5a47SLisandro Dalcin   ierr = PetscDrawCreate(comm,host,label,x,y,m,n,&draw);CHKERRQ(ierr);
192e5f7ee39SBarry Smith   ierr = PetscDrawSetFromOptions(draw);CHKERRQ(ierr);
193c36cb520SLisandro Dalcin   ierr = PetscDrawLGCreate(draw,2,&lg);CHKERRQ(ierr);
194c36cb520SLisandro Dalcin   ierr = PetscDrawLGSetLegend(lg,names);CHKERRQ(ierr);
195c36cb520SLisandro Dalcin   ierr = PetscDrawLGSetFromOptions(lg);CHKERRQ(ierr);
196c36cb520SLisandro Dalcin   ierr = PetscDrawLGGetAxis(lg,&axis);CHKERRQ(ierr);
197e5f7ee39SBarry Smith   ierr = PetscDrawAxisSetLabels(axis,"Convergence of Residual Norm","Iteration","Residual Norm");CHKERRQ(ierr);
198c36cb520SLisandro Dalcin   ierr = PetscDrawDestroy(&draw);CHKERRQ(ierr);
199e5f7ee39SBarry Smith 
200c36cb520SLisandro Dalcin   ierr = PetscMalloc1(2,objs);CHKERRQ(ierr);
201c36cb520SLisandro Dalcin   (*objs)[1] = (PetscObject)lg;
202e5f7ee39SBarry Smith   PetscFunctionReturn(0);
203e5f7ee39SBarry Smith }
204e5f7ee39SBarry Smith 
205e5f7ee39SBarry Smith PetscErrorCode  KSPMonitorSNESLGResidualNorm(KSP ksp,PetscInt n,PetscReal rnorm,PetscObject *objs)
206e5f7ee39SBarry Smith {
207c36cb520SLisandro Dalcin   SNES           snes = (SNES) objs[0];
208e5f7ee39SBarry Smith   PetscDrawLG    lg   = (PetscDrawLG) objs[1];
209e5f7ee39SBarry Smith   PetscErrorCode ierr;
210e5f7ee39SBarry Smith   PetscReal      y[2];
211e5f7ee39SBarry Smith   Vec            snes_solution,work1,work2;
212e5f7ee39SBarry Smith 
213e5f7ee39SBarry Smith   PetscFunctionBegin;
214e5f7ee39SBarry Smith   if (rnorm > 0.0) y[0] = PetscLog10Real(rnorm);
215e5f7ee39SBarry Smith   else y[0] = -15.0;
216e5f7ee39SBarry Smith 
217e5f7ee39SBarry Smith   ierr = SNESGetSolution(snes,&snes_solution);CHKERRQ(ierr);
218e5f7ee39SBarry Smith   ierr = VecDuplicate(snes_solution,&work1);CHKERRQ(ierr);
219e5f7ee39SBarry Smith   ierr = VecDuplicate(snes_solution,&work2);CHKERRQ(ierr);
220e5f7ee39SBarry Smith   ierr = KSPBuildSolution(ksp,work1,NULL);CHKERRQ(ierr);
221e5f7ee39SBarry Smith   ierr = VecAYPX(work1,-1.0,snes_solution);CHKERRQ(ierr);
222e5f7ee39SBarry Smith   ierr = SNESComputeFunction(snes,work1,work2);CHKERRQ(ierr);
223e5f7ee39SBarry Smith   ierr = VecNorm(work2,NORM_2,y+1);CHKERRQ(ierr);
224e5f7ee39SBarry Smith   if (y[1] > 0.0) y[1] = PetscLog10Real(y[1]);
225e5f7ee39SBarry Smith   else y[1] = -15.0;
226e5f7ee39SBarry Smith   ierr = VecDestroy(&work1);CHKERRQ(ierr);
227e5f7ee39SBarry Smith   ierr = VecDestroy(&work2);CHKERRQ(ierr);
228e5f7ee39SBarry Smith 
229e5f7ee39SBarry Smith   ierr = PetscDrawLGAddPoint(lg,NULL,y);CHKERRQ(ierr);
2306934998bSLisandro Dalcin   if (n < 20 || !(n % 5) || snes->reason) {
231e5f7ee39SBarry Smith     ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr);
2326934998bSLisandro Dalcin     ierr = PetscDrawLGSave(lg);CHKERRQ(ierr);
233e5f7ee39SBarry Smith   }
234e5f7ee39SBarry Smith   PetscFunctionReturn(0);
235e5f7ee39SBarry Smith }
236e5f7ee39SBarry Smith 
237e5f7ee39SBarry Smith /*@
238e5f7ee39SBarry Smith    KSPMonitorSNESLGResidualNormDestroy - Destroys a line graph context that was created
239e5f7ee39SBarry Smith    with KSPMonitorSNESLGResidualNormCreate().
240e5f7ee39SBarry Smith 
241e5f7ee39SBarry Smith    Collective on KSP
242e5f7ee39SBarry Smith 
243e5f7ee39SBarry Smith    Input Parameter:
244e5f7ee39SBarry Smith .  draw - the drawing context
245e5f7ee39SBarry Smith 
246e5f7ee39SBarry Smith    Level: intermediate
247e5f7ee39SBarry Smith 
248e5f7ee39SBarry Smith .seealso: KSPMonitorSNESLGResidualNormCreate(), KSPMonitorSNESLGTrueResidualDestroy(), KSPMonitorSet()
249e5f7ee39SBarry Smith @*/
250e5f7ee39SBarry Smith PetscErrorCode  KSPMonitorSNESLGResidualNormDestroy(PetscObject **objs)
251e5f7ee39SBarry Smith {
252e5f7ee39SBarry Smith   PetscErrorCode ierr;
253c36cb520SLisandro Dalcin   PetscDrawLG    lg = (PetscDrawLG) (*objs)[1];
254e5f7ee39SBarry Smith 
255e5f7ee39SBarry Smith   PetscFunctionBegin;
256c36cb520SLisandro Dalcin   ierr = PetscDrawLGDestroy(&lg);CHKERRQ(ierr);
257e5f7ee39SBarry Smith   ierr = PetscFree(*objs);CHKERRQ(ierr);
258e5f7ee39SBarry Smith   PetscFunctionReturn(0);
259e5f7ee39SBarry Smith }
260e5f7ee39SBarry Smith 
2614b828684SBarry Smith /*@C
262a6570f20SBarry Smith    SNESMonitorDefault - Monitors progress of the SNES solvers (default).
263e7e93795SLois Curfman McInnes 
264c7afd0dbSLois Curfman McInnes    Collective on SNES
265c7afd0dbSLois Curfman McInnes 
266e7e93795SLois Curfman McInnes    Input Parameters:
267c7afd0dbSLois Curfman McInnes +  snes - the SNES context
268e7e93795SLois Curfman McInnes .  its - iteration number
2694b27c08aSLois Curfman McInnes .  fgnorm - 2-norm of residual
270d43b4f6eSBarry Smith -  vf - viewer and format structure
271fee21e36SBarry Smith 
272e7e93795SLois Curfman McInnes    Notes:
2734b27c08aSLois Curfman McInnes    This routine prints the residual norm at each iteration.
274e7e93795SLois Curfman McInnes 
27536851e7fSLois Curfman McInnes    Level: intermediate
27636851e7fSLois Curfman McInnes 
277a6570f20SBarry Smith .seealso: SNESMonitorSet(), SNESMonitorSolution()
278e7e93795SLois Curfman McInnes @*/
279d43b4f6eSBarry Smith PetscErrorCode  SNESMonitorDefault(SNES snes,PetscInt its,PetscReal fgnorm,PetscViewerAndFormat *vf)
280e7e93795SLois Curfman McInnes {
281dfbe8321SBarry Smith   PetscErrorCode ierr;
282d43b4f6eSBarry Smith   PetscViewer    viewer = vf->viewer;
283d132466eSBarry Smith 
2843a40ed3dSBarry Smith   PetscFunctionBegin;
2854d4332d5SBarry Smith   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,4);
286d43b4f6eSBarry Smith   ierr = PetscViewerPushFormat(viewer,vf->format);CHKERRQ(ierr);
287649052a6SBarry Smith   ierr = PetscViewerASCIIAddTab(viewer,((PetscObject)snes)->tablevel);CHKERRQ(ierr);
288649052a6SBarry Smith   ierr = PetscViewerASCIIPrintf(viewer,"%3D SNES Function norm %14.12e \n",its,(double)fgnorm);CHKERRQ(ierr);
289649052a6SBarry Smith   ierr = PetscViewerASCIISubtractTab(viewer,((PetscObject)snes)->tablevel);CHKERRQ(ierr);
290d43b4f6eSBarry Smith   ierr = PetscViewerPopFormat(viewer);CHKERRQ(ierr) ;
2913a40ed3dSBarry Smith   PetscFunctionReturn(0);
292e7e93795SLois Curfman McInnes }
2933f1db9ecSBarry Smith 
2941f60017eSBarry Smith /*@C
2951f60017eSBarry Smith    SNESMonitorScaling - Monitors the largest value in each row of the Jacobian.
2961f60017eSBarry Smith 
2971f60017eSBarry Smith    Collective on SNES
2981f60017eSBarry Smith 
2991f60017eSBarry Smith    Input Parameters:
3001f60017eSBarry Smith +  snes - the SNES context
3011f60017eSBarry Smith .  its - iteration number
3021f60017eSBarry Smith .  fgnorm - 2-norm of residual
3031f60017eSBarry Smith -  vf - viewer and format structure
3041f60017eSBarry Smith 
3051f60017eSBarry Smith    Notes:
3061f60017eSBarry Smith    This routine prints the largest value in each row of the Jacobian
3071f60017eSBarry Smith 
3081f60017eSBarry Smith    Level: intermediate
3091f60017eSBarry Smith 
3101f60017eSBarry Smith .seealso: SNESMonitorSet(), SNESMonitorSolution()
3111f60017eSBarry Smith @*/
3121f60017eSBarry Smith PetscErrorCode  SNESMonitorScaling(SNES snes,PetscInt its,PetscReal fgnorm,PetscViewerAndFormat *vf)
3131f60017eSBarry Smith {
3141f60017eSBarry Smith   PetscErrorCode ierr;
3151f60017eSBarry Smith   PetscViewer    viewer = vf->viewer;
3161f60017eSBarry Smith   KSP            ksp;
3171f60017eSBarry Smith   Mat            J;
3181f60017eSBarry Smith   Vec            v;
3191f60017eSBarry Smith 
3201f60017eSBarry Smith   PetscFunctionBegin;
3211f60017eSBarry Smith   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,4);
3221f60017eSBarry Smith   ierr = SNESGetKSP(snes,&ksp);CHKERRQ(ierr);
3231f60017eSBarry Smith   ierr = KSPGetOperators(ksp,&J,NULL);CHKERRQ(ierr);
3241f60017eSBarry Smith   ierr = MatCreateVecs(J,&v,NULL);CHKERRQ(ierr);
3251f60017eSBarry Smith   ierr = MatGetRowMaxAbs(J,v,NULL);CHKERRQ(ierr);
3261f60017eSBarry Smith   ierr = PetscViewerPushFormat(viewer,vf->format);CHKERRQ(ierr);
3271f60017eSBarry Smith   ierr = PetscViewerASCIIAddTab(viewer,((PetscObject)snes)->tablevel);CHKERRQ(ierr);
3281f60017eSBarry Smith   ierr = PetscViewerASCIIPrintf(viewer,"%3D SNES Jacobian maximum row entries \n");CHKERRQ(ierr);
3291f60017eSBarry Smith   ierr = VecView(v,viewer);CHKERRQ(ierr);
3301f60017eSBarry Smith   ierr = PetscViewerASCIISubtractTab(viewer,((PetscObject)snes)->tablevel);CHKERRQ(ierr);
3311f60017eSBarry Smith   ierr = PetscViewerPopFormat(viewer);CHKERRQ(ierr) ;
3321f60017eSBarry Smith   ierr = VecDestroy(&v);CHKERRQ(ierr);
3331f60017eSBarry Smith   PetscFunctionReturn(0);
3341f60017eSBarry Smith }
3351f60017eSBarry Smith 
336d43b4f6eSBarry Smith PetscErrorCode SNESMonitorJacUpdateSpectrum(SNES snes,PetscInt it,PetscReal fnorm,PetscViewerAndFormat *vf)
337a80ad3e0SBarry Smith {
338196da8b6SPeter Brune #if defined(PETSC_MISSING_LAPACK_GEEV)
339ce94432eSBarry Smith   SETERRQ(PetscObjectComm((PetscObject)snes),PETSC_ERR_SUP,"GEEV - Lapack routine is unavailable\nNot able to provide eigen values.");
340196da8b6SPeter Brune #elif defined(PETSC_HAVE_ESSL)
341ce94432eSBarry Smith   SETERRQ(PetscObjectComm((PetscObject)snes),PETSC_ERR_SUP,"GEEV - No support for ESSL Lapack Routines");
342196da8b6SPeter Brune #else
3432e7541e6SPeter Brune   Vec            X;
3442e7541e6SPeter Brune   Mat            J,dJ,dJdense;
3452e7541e6SPeter Brune   PetscErrorCode ierr;
346d1e9a80fSBarry Smith   PetscErrorCode (*func)(SNES,Vec,Mat,Mat,void*);
3472e7541e6SPeter Brune   PetscInt       n,i;
3482e7541e6SPeter Brune   PetscBLASInt   nb,lwork;
3492e7541e6SPeter Brune   PetscReal      *eigr,*eigi;
3502e7541e6SPeter Brune   PetscScalar    *work;
3512e7541e6SPeter Brune   PetscScalar    *a;
3522e7541e6SPeter Brune 
3532e7541e6SPeter Brune   PetscFunctionBegin;
3542e7541e6SPeter Brune   if (it == 0) PetscFunctionReturn(0);
3552e7541e6SPeter Brune   /* create the difference between the current update and the current jacobian */
3562e7541e6SPeter Brune   ierr = SNESGetSolution(snes,&X);CHKERRQ(ierr);
357d1e9a80fSBarry Smith   ierr = SNESGetJacobian(snes,NULL,&J,&func,NULL);CHKERRQ(ierr);
3582e7541e6SPeter Brune   ierr = MatDuplicate(J,MAT_COPY_VALUES,&dJ);CHKERRQ(ierr);
359d1e9a80fSBarry Smith   ierr = SNESComputeJacobian(snes,X,dJ,dJ);CHKERRQ(ierr);
3602e7541e6SPeter Brune   ierr = MatAXPY(dJ,-1.0,J,SAME_NONZERO_PATTERN);CHKERRQ(ierr);
361f5af7f23SKarl Rupp 
3622e7541e6SPeter Brune   /* compute the spectrum directly */
3632e7541e6SPeter Brune   ierr  = MatConvert(dJ,MATSEQDENSE,MAT_INITIAL_MATRIX,&dJdense);CHKERRQ(ierr);
3640298fd71SBarry Smith   ierr  = MatGetSize(dJ,&n,NULL);CHKERRQ(ierr);
365c5df96a5SBarry Smith   ierr  = PetscBLASIntCast(n,&nb);CHKERRQ(ierr);
3662e7541e6SPeter Brune   lwork = 3*nb;
367785e854fSJed Brown   ierr  = PetscMalloc1(n,&eigr);CHKERRQ(ierr);
368785e854fSJed Brown   ierr  = PetscMalloc1(n,&eigi);CHKERRQ(ierr);
369785e854fSJed Brown   ierr  = PetscMalloc1(lwork,&work);CHKERRQ(ierr);
3708c778c55SBarry Smith   ierr  = MatDenseGetArray(dJdense,&a);CHKERRQ(ierr);
3712e7541e6SPeter Brune #if !defined(PETSC_USE_COMPLEX)
3722e7541e6SPeter Brune   {
3732e7541e6SPeter Brune     PetscBLASInt lierr;
3742e7541e6SPeter Brune     ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
3758b83055fSJed Brown     PetscStackCallBLAS("LAPACKgeev",LAPACKgeev_("N","N",&nb,a,&nb,eigr,eigi,NULL,&nb,NULL,&nb,work,&lwork,&lierr));
3762e7541e6SPeter Brune     if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"geev() error %d",lierr);
3772e7541e6SPeter Brune     ierr = PetscFPTrapPop();CHKERRQ(ierr);
3782e7541e6SPeter Brune   }
3792e7541e6SPeter Brune #else
3802e7541e6SPeter Brune   SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not coded for complex");
3812e7541e6SPeter Brune #endif
382fde5950dSBarry Smith   ierr = PetscPrintf(PetscObjectComm((PetscObject)snes),"Eigenvalues of J_%d - J_%d:\n",it,it-1);CHKERRQ(ierr);
3832e7541e6SPeter Brune   for (i=0;i<n;i++) {
384fde5950dSBarry Smith     ierr = PetscPrintf(PetscObjectComm((PetscObject)snes),"%5d: %20.5g + %20.5gi\n",i,(double)eigr[i],(double)eigi[i]);CHKERRQ(ierr);
3852e7541e6SPeter Brune   }
3868c778c55SBarry Smith   ierr = MatDenseRestoreArray(dJdense,&a);CHKERRQ(ierr);
3872e7541e6SPeter Brune   ierr = MatDestroy(&dJ);CHKERRQ(ierr);
3882e7541e6SPeter Brune   ierr = MatDestroy(&dJdense);CHKERRQ(ierr);
3892e7541e6SPeter Brune   ierr = PetscFree(eigr);CHKERRQ(ierr);
3902e7541e6SPeter Brune   ierr = PetscFree(eigi);CHKERRQ(ierr);
3912e7541e6SPeter Brune   ierr = PetscFree(work);CHKERRQ(ierr);
3922e7541e6SPeter Brune   PetscFunctionReturn(0);
393196da8b6SPeter Brune #endif
3942e7541e6SPeter Brune }
3952e7541e6SPeter Brune 
3966ba87a44SLisandro Dalcin PETSC_INTERN PetscErrorCode  SNESMonitorRange_Private(SNES,PetscInt,PetscReal*);
3976ba87a44SLisandro Dalcin 
3987087cfbeSBarry Smith PetscErrorCode  SNESMonitorRange_Private(SNES snes,PetscInt it,PetscReal *per)
399b271bb04SBarry Smith {
400b271bb04SBarry Smith   PetscErrorCode ierr;
401b271bb04SBarry Smith   Vec            resid;
402b271bb04SBarry Smith   PetscReal      rmax,pwork;
403b271bb04SBarry Smith   PetscInt       i,n,N;
404b271bb04SBarry Smith   PetscScalar    *r;
405b271bb04SBarry Smith 
406b271bb04SBarry Smith   PetscFunctionBegin;
407b271bb04SBarry Smith   ierr  = SNESGetFunction(snes,&resid,0,0);CHKERRQ(ierr);
408b271bb04SBarry Smith   ierr  = VecNorm(resid,NORM_INFINITY,&rmax);CHKERRQ(ierr);
409b271bb04SBarry Smith   ierr  = VecGetLocalSize(resid,&n);CHKERRQ(ierr);
410b271bb04SBarry Smith   ierr  = VecGetSize(resid,&N);CHKERRQ(ierr);
411b271bb04SBarry Smith   ierr  = VecGetArray(resid,&r);CHKERRQ(ierr);
412b271bb04SBarry Smith   pwork = 0.0;
413b271bb04SBarry Smith   for (i=0; i<n; i++) {
414b271bb04SBarry Smith     pwork += (PetscAbsScalar(r[i]) > .20*rmax);
415b271bb04SBarry Smith   }
416b2566f29SBarry Smith   ierr = MPIU_Allreduce(&pwork,per,1,MPIU_REAL,MPIU_SUM,PetscObjectComm((PetscObject)snes));CHKERRQ(ierr);
417b271bb04SBarry Smith   ierr = VecRestoreArray(resid,&r);CHKERRQ(ierr);
418b271bb04SBarry Smith   *per = *per/N;
419b271bb04SBarry Smith   PetscFunctionReturn(0);
420b271bb04SBarry Smith }
421b271bb04SBarry Smith 
422b271bb04SBarry Smith /*@C
423b271bb04SBarry Smith    SNESMonitorRange - Prints the percentage of residual elements that are more then 10 percent of the maximum value.
424b271bb04SBarry Smith 
425b271bb04SBarry Smith    Collective on SNES
426b271bb04SBarry Smith 
427b271bb04SBarry Smith    Input Parameters:
428b271bb04SBarry Smith +  snes   - iterative context
429b271bb04SBarry Smith .  it    - iteration number
430b271bb04SBarry Smith .  rnorm - 2-norm (preconditioned) residual value (may be estimated).
431b271bb04SBarry Smith -  dummy - unused monitor context
432b271bb04SBarry Smith 
433b271bb04SBarry Smith    Options Database Key:
434b271bb04SBarry Smith .  -snes_monitor_range - Activates SNESMonitorRange()
435b271bb04SBarry Smith 
436b271bb04SBarry Smith    Level: intermediate
437b271bb04SBarry Smith 
438b271bb04SBarry Smith .seealso: SNESMonitorSet(), SNESMonitorDefault(), SNESMonitorLGCreate()
439b271bb04SBarry Smith @*/
440d43b4f6eSBarry Smith PetscErrorCode  SNESMonitorRange(SNES snes,PetscInt it,PetscReal rnorm,PetscViewerAndFormat *vf)
441b271bb04SBarry Smith {
442b271bb04SBarry Smith   PetscErrorCode ierr;
443b271bb04SBarry Smith   PetscReal      perc,rel;
444d43b4f6eSBarry Smith   PetscViewer    viewer = vf->viewer;
445b271bb04SBarry Smith   /* should be in a MonitorRangeContext */
446b271bb04SBarry Smith   static PetscReal prev;
447b271bb04SBarry Smith 
448b271bb04SBarry Smith   PetscFunctionBegin;
4494d4332d5SBarry Smith   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,4);
450b271bb04SBarry Smith   if (!it) prev = rnorm;
451b271bb04SBarry Smith   ierr = SNESMonitorRange_Private(snes,it,&perc);CHKERRQ(ierr);
452b271bb04SBarry Smith 
453b271bb04SBarry Smith   rel  = (prev - rnorm)/prev;
454b271bb04SBarry Smith   prev = rnorm;
455d43b4f6eSBarry Smith   ierr = PetscViewerPushFormat(viewer,vf->format);CHKERRQ(ierr);
456649052a6SBarry Smith   ierr = PetscViewerASCIIAddTab(viewer,((PetscObject)snes)->tablevel);CHKERRQ(ierr);
4576712e2f1SBarry 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);
458649052a6SBarry Smith   ierr = PetscViewerASCIISubtractTab(viewer,((PetscObject)snes)->tablevel);CHKERRQ(ierr);
459d43b4f6eSBarry Smith   ierr = PetscViewerPopFormat(viewer);CHKERRQ(ierr);
460b271bb04SBarry Smith   PetscFunctionReturn(0);
461b271bb04SBarry Smith }
462b271bb04SBarry Smith 
4633a7fca6bSBarry Smith /*@C
464a6570f20SBarry Smith    SNESMonitorRatio - Monitors progress of the SNES solvers by printing the ratio
4654b27c08aSLois Curfman McInnes    of residual norm at each iteration to the previous.
4663a7fca6bSBarry Smith 
4673a7fca6bSBarry Smith    Collective on SNES
4683a7fca6bSBarry Smith 
4693a7fca6bSBarry Smith    Input Parameters:
4703a7fca6bSBarry Smith +  snes - the SNES context
4713a7fca6bSBarry Smith .  its - iteration number
4723a7fca6bSBarry Smith .  fgnorm - 2-norm of residual (or gradient)
473eabae89aSBarry Smith -  dummy -  context of monitor
4743a7fca6bSBarry Smith 
4753a7fca6bSBarry Smith    Level: intermediate
4763a7fca6bSBarry Smith 
47795452b02SPatrick Sanan    Notes:
47895452b02SPatrick Sanan     Insure that SNESMonitorRatio() is called when you set this monitor
479fde5950dSBarry Smith .seealso: SNESMonitorSet(), SNESMonitorSolution(), SNESMonitorRatio()
4803a7fca6bSBarry Smith @*/
481d43b4f6eSBarry Smith PetscErrorCode  SNESMonitorRatio(SNES snes,PetscInt its,PetscReal fgnorm,PetscViewerAndFormat *vf)
4823a7fca6bSBarry Smith {
483dfbe8321SBarry Smith   PetscErrorCode          ierr;
48477431f27SBarry Smith   PetscInt                len;
48587828ca2SBarry Smith   PetscReal               *history;
486d43b4f6eSBarry Smith   PetscViewer             viewer = vf->viewer;
4873a7fca6bSBarry Smith 
4883a7fca6bSBarry Smith   PetscFunctionBegin;
4890298fd71SBarry Smith   ierr = SNESGetConvergenceHistory(snes,&history,NULL,&len);CHKERRQ(ierr);
490d43b4f6eSBarry Smith   ierr = PetscViewerPushFormat(viewer,vf->format);CHKERRQ(ierr);
491fde5950dSBarry Smith   ierr = PetscViewerASCIIAddTab(viewer,((PetscObject)snes)->tablevel);CHKERRQ(ierr);
492958c9bccSBarry Smith   if (!its || !history || its > len) {
493fde5950dSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"%3D SNES Function norm %14.12e \n",its,(double)fgnorm);CHKERRQ(ierr);
4943a7fca6bSBarry Smith   } else {
49587828ca2SBarry Smith     PetscReal ratio = fgnorm/history[its-1];
496fde5950dSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"%3D SNES Function norm %14.12e %14.12e \n",its,(double)fgnorm,(double)ratio);CHKERRQ(ierr);
4973a7fca6bSBarry Smith   }
498fde5950dSBarry Smith   ierr = PetscViewerASCIISubtractTab(viewer,((PetscObject)snes)->tablevel);CHKERRQ(ierr);
499d43b4f6eSBarry Smith   ierr = PetscViewerPopFormat(viewer);CHKERRQ(ierr);
5003a7fca6bSBarry Smith   PetscFunctionReturn(0);
5013a7fca6bSBarry Smith }
5023a7fca6bSBarry Smith 
5033a7fca6bSBarry Smith /*@C
504fde5950dSBarry Smith    SNESMonitorRatioSetUp - Insures the SNES object is saving its history since this monitor needs access to it
5053a7fca6bSBarry Smith 
5063a7fca6bSBarry Smith    Collective on SNES
5073a7fca6bSBarry Smith 
5083a7fca6bSBarry Smith    Input Parameters:
509eabae89aSBarry Smith +   snes - the SNES context
510fde5950dSBarry Smith -   viewer - the PetscViewer object (ignored)
5113a7fca6bSBarry Smith 
5123a7fca6bSBarry Smith    Level: intermediate
5133a7fca6bSBarry Smith 
514fde5950dSBarry Smith .seealso: SNESMonitorSet(), SNESMonitorSolution(), SNESMonitorDefault(), SNESMonitorRatio()
5153a7fca6bSBarry Smith @*/
516d43b4f6eSBarry Smith PetscErrorCode  SNESMonitorRatioSetUp(SNES snes,PetscViewerAndFormat *vf)
5173a7fca6bSBarry Smith {
518dfbe8321SBarry Smith   PetscErrorCode          ierr;
51987828ca2SBarry Smith   PetscReal               *history;
5203a7fca6bSBarry Smith 
5213a7fca6bSBarry Smith   PetscFunctionBegin;
5220298fd71SBarry Smith   ierr = SNESGetConvergenceHistory(snes,&history,NULL,NULL);CHKERRQ(ierr);
5233a7fca6bSBarry Smith   if (!history) {
524fde5950dSBarry Smith     ierr = SNESSetConvergenceHistory(snes,NULL,NULL,100,PETSC_TRUE);CHKERRQ(ierr);
5253a7fca6bSBarry Smith   }
5263a7fca6bSBarry Smith   PetscFunctionReturn(0);
5273a7fca6bSBarry Smith }
5283a7fca6bSBarry Smith 
529e7e93795SLois Curfman McInnes /* ---------------------------------------------------------------- */
530be1f7002SBarry Smith /*
531a6570f20SBarry Smith      Default (short) SNES Monitor, same as SNESMonitorDefault() except
532be1f7002SBarry Smith   it prints fewer digits of the residual as the residual gets smaller.
533be1f7002SBarry Smith   This is because the later digits are meaningless and are often
534be1f7002SBarry Smith   different on different machines; by using this routine different
535be1f7002SBarry Smith   machines will usually generate the same output.
536dec21524SBarry Smith 
537dec21524SBarry Smith   Deprecated: Intentionally has no manual page
538be1f7002SBarry Smith */
539d43b4f6eSBarry Smith PetscErrorCode  SNESMonitorDefaultShort(SNES snes,PetscInt its,PetscReal fgnorm,PetscViewerAndFormat *vf)
540e7e93795SLois Curfman McInnes {
541dfbe8321SBarry Smith   PetscErrorCode ierr;
542d43b4f6eSBarry Smith   PetscViewer    viewer = vf->viewer;
543d132466eSBarry Smith 
5443a40ed3dSBarry Smith   PetscFunctionBegin;
5454d4332d5SBarry Smith   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,4);
546d43b4f6eSBarry Smith   ierr = PetscViewerPushFormat(viewer,vf->format);CHKERRQ(ierr);
547649052a6SBarry Smith   ierr = PetscViewerASCIIAddTab(viewer,((PetscObject)snes)->tablevel);CHKERRQ(ierr);
5488f240d10SBarry Smith   if (fgnorm > 1.e-9) {
5498fa295daSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"%3D SNES Function norm %g \n",its,(double)fgnorm);CHKERRQ(ierr);
5503a40ed3dSBarry Smith   } else if (fgnorm > 1.e-11) {
5518fa295daSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"%3D SNES Function norm %5.3e \n",its,(double)fgnorm);CHKERRQ(ierr);
5523a40ed3dSBarry Smith   } else {
553649052a6SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"%3D SNES Function norm < 1.e-11\n",its);CHKERRQ(ierr);
554a34d58ebSBarry Smith   }
555649052a6SBarry Smith   ierr = PetscViewerASCIISubtractTab(viewer,((PetscObject)snes)->tablevel);CHKERRQ(ierr);
556d43b4f6eSBarry Smith   ierr = PetscViewerPopFormat(viewer);CHKERRQ(ierr);
5573a40ed3dSBarry Smith   PetscFunctionReturn(0);
558e7e93795SLois Curfman McInnes }
5592db13446SMatthew G. Knepley 
5602db13446SMatthew G. Knepley /*@C
5612db13446SMatthew G. Knepley   SNESMonitorDefaultField - Monitors progress of the SNES solvers, separated into fields.
5622db13446SMatthew G. Knepley 
5632db13446SMatthew G. Knepley   Collective on SNES
5642db13446SMatthew G. Knepley 
5652db13446SMatthew G. Knepley   Input Parameters:
5662db13446SMatthew G. Knepley + snes   - the SNES context
5672db13446SMatthew G. Knepley . its    - iteration number
5682db13446SMatthew G. Knepley . fgnorm - 2-norm of residual
5692db13446SMatthew G. Knepley - ctx    - the PetscViewer
5702db13446SMatthew G. Knepley 
5712db13446SMatthew G. Knepley   Notes:
5722db13446SMatthew G. Knepley   This routine uses the DM attached to the residual vector
5732db13446SMatthew G. Knepley 
5742db13446SMatthew G. Knepley   Level: intermediate
5752db13446SMatthew G. Knepley 
576dec21524SBarry Smith .seealso: SNESMonitorSet(), SNESMonitorSolution(), SNESMonitorDefault()
5772db13446SMatthew G. Knepley @*/
578d43b4f6eSBarry Smith PetscErrorCode SNESMonitorDefaultField(SNES snes, PetscInt its, PetscReal fgnorm, PetscViewerAndFormat *vf)
5792db13446SMatthew G. Knepley {
580d43b4f6eSBarry Smith   PetscViewer    viewer = vf->viewer;
5812db13446SMatthew G. Knepley   Vec            r;
5822db13446SMatthew G. Knepley   DM             dm;
5832db13446SMatthew G. Knepley   PetscReal      res[256];
5842db13446SMatthew G. Knepley   PetscInt       tablevel;
5852db13446SMatthew G. Knepley   PetscErrorCode ierr;
5862db13446SMatthew G. Knepley 
5872db13446SMatthew G. Knepley   PetscFunctionBegin;
5884d4332d5SBarry Smith   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,4);
5892db13446SMatthew G. Knepley   ierr = SNESGetFunction(snes, &r, NULL, NULL);CHKERRQ(ierr);
5902db13446SMatthew G. Knepley   ierr = VecGetDM(r, &dm);CHKERRQ(ierr);
591d43b4f6eSBarry Smith   if (!dm) {ierr = SNESMonitorDefault(snes, its, fgnorm, vf);CHKERRQ(ierr);}
5922db13446SMatthew G. Knepley   else {
5932db13446SMatthew G. Knepley     PetscSection s, gs;
5942db13446SMatthew G. Knepley     PetscInt     Nf, f;
5952db13446SMatthew G. Knepley 
59692fd8e1eSJed Brown     ierr = DMGetLocalSection(dm, &s);CHKERRQ(ierr);
597e87a4003SBarry Smith     ierr = DMGetGlobalSection(dm, &gs);CHKERRQ(ierr);
598d43b4f6eSBarry Smith     if (!s || !gs) {ierr = SNESMonitorDefault(snes, its, fgnorm, vf);CHKERRQ(ierr);}
5992db13446SMatthew G. Knepley     ierr = PetscSectionGetNumFields(s, &Nf);CHKERRQ(ierr);
6002db13446SMatthew G. Knepley     if (Nf > 256) SETERRQ1(PetscObjectComm((PetscObject) snes), PETSC_ERR_SUP, "Do not support %d fields > 256", Nf);
6012db13446SMatthew G. Knepley     ierr = PetscSectionVecNorm(s, gs, r, NORM_2, res);CHKERRQ(ierr);
6022db13446SMatthew G. Knepley     ierr = PetscObjectGetTabLevel((PetscObject) snes, &tablevel);CHKERRQ(ierr);
603d43b4f6eSBarry Smith     ierr = PetscViewerPushFormat(viewer,vf->format);CHKERRQ(ierr);
6042db13446SMatthew G. Knepley     ierr = PetscViewerASCIIAddTab(viewer, tablevel);CHKERRQ(ierr);
6052db13446SMatthew G. Knepley     ierr = PetscViewerASCIIPrintf(viewer, "%3D SNES Function norm %14.12e [", its, (double) fgnorm);CHKERRQ(ierr);
6062db13446SMatthew G. Knepley     for (f = 0; f < Nf; ++f) {
6072db13446SMatthew G. Knepley       if (f) {ierr = PetscViewerASCIIPrintf(viewer, ", ");CHKERRQ(ierr);}
6082db13446SMatthew G. Knepley       ierr = PetscViewerASCIIPrintf(viewer, "%14.12e", res[f]);CHKERRQ(ierr);
6092db13446SMatthew G. Knepley     }
6102db13446SMatthew G. Knepley     ierr = PetscViewerASCIIPrintf(viewer, "] \n");CHKERRQ(ierr);
6112db13446SMatthew G. Knepley     ierr = PetscViewerASCIISubtractTab(viewer, tablevel);CHKERRQ(ierr);
612d43b4f6eSBarry Smith     ierr = PetscViewerPopFormat(viewer);CHKERRQ(ierr);
6132db13446SMatthew G. Knepley   }
6142db13446SMatthew G. Knepley   PetscFunctionReturn(0);
6152db13446SMatthew G. Knepley }
616e7e93795SLois Curfman McInnes /* ---------------------------------------------------------------- */
6174b828684SBarry Smith /*@C
6188d359177SBarry Smith    SNESConvergedDefault - Convergence test of the solvers for
619f525115eSLois Curfman McInnes    systems of nonlinear equations (default).
620e7e93795SLois Curfman McInnes 
621c7afd0dbSLois Curfman McInnes    Collective on SNES
622c7afd0dbSLois Curfman McInnes 
623e7e93795SLois Curfman McInnes    Input Parameters:
624c7afd0dbSLois Curfman McInnes +  snes - the SNES context
62506ee9f85SBarry Smith .  it - the iteration (0 indicates before any Newton steps)
626e7e93795SLois Curfman McInnes .  xnorm - 2-norm of current iterate
627c60f73f4SPeter Brune .  snorm - 2-norm of current step
6287f3332b4SBarry Smith .  fnorm - 2-norm of function at current iterate
629c7afd0dbSLois Curfman McInnes -  dummy - unused context
630e7e93795SLois Curfman McInnes 
631184914b5SBarry Smith    Output Parameter:
632184914b5SBarry Smith .   reason  - one of
63370441072SBarry Smith $  SNES_CONVERGED_FNORM_ABS       - (fnorm < abstol),
634c60f73f4SPeter Brune $  SNES_CONVERGED_SNORM_RELATIVE  - (snorm < stol*xnorm),
635184914b5SBarry Smith $  SNES_CONVERGED_FNORM_RELATIVE  - (fnorm < rtol*fnorm0),
636184914b5SBarry Smith $  SNES_DIVERGED_FUNCTION_COUNT   - (nfct > maxf),
637184914b5SBarry Smith $  SNES_DIVERGED_FNORM_NAN        - (fnorm == NaN),
638184914b5SBarry Smith $  SNES_CONVERGED_ITERATING       - (otherwise),
639e7e93795SLois Curfman McInnes 
640e7e93795SLois Curfman McInnes    where
641c7afd0dbSLois Curfman McInnes +    maxf - maximum number of function evaluations,
642c7afd0dbSLois Curfman McInnes             set with SNESSetTolerances()
643c7afd0dbSLois Curfman McInnes .    nfct - number of function evaluations,
64470441072SBarry Smith .    abstol - absolute function norm tolerance,
645c7afd0dbSLois Curfman McInnes             set with SNESSetTolerances()
646c7afd0dbSLois Curfman McInnes -    rtol - relative function norm tolerance, set with SNESSetTolerances()
647fee21e36SBarry Smith 
64836851e7fSLois Curfman McInnes    Level: intermediate
64936851e7fSLois Curfman McInnes 
65071f87433Sdalcinl .seealso: SNESSetConvergenceTest()
651e7e93795SLois Curfman McInnes @*/
6528d359177SBarry Smith PetscErrorCode  SNESConvergedDefault(SNES snes,PetscInt it,PetscReal xnorm,PetscReal snorm,PetscReal fnorm,SNESConvergedReason *reason,void *dummy)
653e7e93795SLois Curfman McInnes {
65463ba0a88SBarry Smith   PetscErrorCode ierr;
65563ba0a88SBarry Smith 
6563a40ed3dSBarry Smith   PetscFunctionBegin;
6570700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
6583f149594SLisandro Dalcin   PetscValidPointer(reason,6);
6593f149594SLisandro Dalcin 
66006ee9f85SBarry Smith   *reason = SNES_CONVERGED_ITERATING;
66106ee9f85SBarry Smith 
66206ee9f85SBarry Smith   if (!it) {
66306ee9f85SBarry Smith     /* set parameter for default relative tolerance convergence test */
66406ee9f85SBarry Smith     snes->ttol   = fnorm*snes->rtol;
665e37c518bSBarry Smith     snes->rnorm0 = fnorm;
66606ee9f85SBarry Smith   }
6678146f6ebSBarry Smith   if (PetscIsInfOrNanReal(fnorm)) {
668ae15b995SBarry Smith     ierr    = PetscInfo(snes,"Failed to converged, function norm is NaN\n");CHKERRQ(ierr);
669184914b5SBarry Smith     *reason = SNES_DIVERGED_FNORM_NAN;
670be5caee7SBarry Smith   } else if (fnorm < snes->abstol && (it || !snes->forceiteration)) {
6718f1a2a5eSBarry Smith     ierr    = PetscInfo2(snes,"Converged due to function norm %14.12e < %14.12e\n",(double)fnorm,(double)snes->abstol);CHKERRQ(ierr);
672184914b5SBarry Smith     *reason = SNES_CONVERGED_FNORM_ABS;
673e71169deSBarry Smith   } else if (snes->nfuncs >= snes->max_funcs && snes->max_funcs >= 0) {
674ae15b995SBarry Smith     ierr    = PetscInfo2(snes,"Exceeded maximum number of function evaluations: %D > %D\n",snes->nfuncs,snes->max_funcs);CHKERRQ(ierr);
675184914b5SBarry Smith     *reason = SNES_DIVERGED_FUNCTION_COUNT;
67606ee9f85SBarry Smith   }
67706ee9f85SBarry Smith 
67806ee9f85SBarry Smith   if (it && !*reason) {
67906ee9f85SBarry Smith     if (fnorm <= snes->ttol) {
6808f1a2a5eSBarry Smith       ierr    = PetscInfo2(snes,"Converged due to function norm %14.12e < %14.12e (relative tolerance)\n",(double)fnorm,(double)snes->ttol);CHKERRQ(ierr);
68106ee9f85SBarry Smith       *reason = SNES_CONVERGED_FNORM_RELATIVE;
682c60f73f4SPeter Brune     } else if (snorm < snes->stol*xnorm) {
683c60f73f4SPeter 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);
684c60f73f4SPeter Brune       *reason = SNES_CONVERGED_SNORM_RELATIVE;
685e4d06f11SPatrick Farrell     } else if (snes->divtol > 0 && (fnorm > snes->divtol*snes->rnorm0)) {
686e37c518bSBarry 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);
687e37c518bSBarry Smith       *reason = SNES_DIVERGED_DTOL;
68806ee9f85SBarry Smith     }
689e37c518bSBarry Smith 
690e7e93795SLois Curfman McInnes   }
6913a40ed3dSBarry Smith   PetscFunctionReturn(0);
692e7e93795SLois Curfman McInnes }
6933f149594SLisandro Dalcin 
6943f149594SLisandro Dalcin /*@C
695e2a6519dSDmitry Karpeev    SNESConvergedSkip - Convergence test for SNES that NEVER returns as
6963f149594SLisandro Dalcin    converged, UNLESS the maximum number of iteration have been reached.
6973f149594SLisandro Dalcin 
6983f9fe445SBarry Smith    Logically Collective on SNES
6993f149594SLisandro Dalcin 
7003f149594SLisandro Dalcin    Input Parameters:
7013f149594SLisandro Dalcin +  snes - the SNES context
7023f149594SLisandro Dalcin .  it - the iteration (0 indicates before any Newton steps)
7033f149594SLisandro Dalcin .  xnorm - 2-norm of current iterate
704c60f73f4SPeter Brune .  snorm - 2-norm of current step
7053f149594SLisandro Dalcin .  fnorm - 2-norm of function at current iterate
7063f149594SLisandro Dalcin -  dummy - unused context
7073f149594SLisandro Dalcin 
7083f149594SLisandro Dalcin    Output Parameter:
70985385478SLisandro Dalcin .   reason  - SNES_CONVERGED_ITERATING, SNES_CONVERGED_ITS, or SNES_DIVERGED_FNORM_NAN
7103f149594SLisandro Dalcin 
7113f149594SLisandro Dalcin    Notes:
7123f149594SLisandro Dalcin    Convergence is then declared after a fixed number of iterations have been used.
7133f149594SLisandro Dalcin 
7143f149594SLisandro Dalcin    Level: advanced
7153f149594SLisandro Dalcin 
7163f149594SLisandro Dalcin .seealso: SNESSetConvergenceTest()
7173f149594SLisandro Dalcin @*/
718e2a6519dSDmitry Karpeev PetscErrorCode  SNESConvergedSkip(SNES snes,PetscInt it,PetscReal xnorm,PetscReal snorm,PetscReal fnorm,SNESConvergedReason *reason,void *dummy)
7193f149594SLisandro Dalcin {
7203f149594SLisandro Dalcin   PetscErrorCode ierr;
7213f149594SLisandro Dalcin 
7223f149594SLisandro Dalcin   PetscFunctionBegin;
7230700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
7243f149594SLisandro Dalcin   PetscValidPointer(reason,6);
7253f149594SLisandro Dalcin 
7263f149594SLisandro Dalcin   *reason = SNES_CONVERGED_ITERATING;
7273f149594SLisandro Dalcin 
7283f149594SLisandro Dalcin   if (fnorm != fnorm) {
7293f149594SLisandro Dalcin     ierr    = PetscInfo(snes,"Failed to converged, function norm is NaN\n");CHKERRQ(ierr);
7303f149594SLisandro Dalcin     *reason = SNES_DIVERGED_FNORM_NAN;
7313f149594SLisandro Dalcin   } else if (it == snes->max_its) {
7323f149594SLisandro Dalcin     *reason = SNES_CONVERGED_ITS;
7333f149594SLisandro Dalcin   }
7343f149594SLisandro Dalcin   PetscFunctionReturn(0);
7353f149594SLisandro Dalcin }
7363f149594SLisandro Dalcin 
7378d359177SBarry Smith /*@C
738fa0ddf94SBarry Smith   SNESSetWorkVecs - Gets a number of work vectors.
73958c9b817SLisandro Dalcin 
74058c9b817SLisandro Dalcin   Input Parameters:
741a2b725a8SWilliam Gropp + snes  - the SNES context
742a2b725a8SWilliam Gropp - nw - number of work vectors to allocate
74358c9b817SLisandro Dalcin 
74458c9b817SLisandro Dalcin   Level: developer
745fa0ddf94SBarry Smith 
74698acb6afSMatthew G Knepley @*/
747fa0ddf94SBarry Smith PetscErrorCode SNESSetWorkVecs(SNES snes,PetscInt nw)
74858c9b817SLisandro Dalcin {
749c5ed8070SMatthew G. Knepley   DM             dm;
750c5ed8070SMatthew G. Knepley   Vec            v;
75158c9b817SLisandro Dalcin   PetscErrorCode ierr;
75258c9b817SLisandro Dalcin 
75358c9b817SLisandro Dalcin   PetscFunctionBegin;
75458c9b817SLisandro Dalcin   if (snes->work) {ierr = VecDestroyVecs(snes->nwork,&snes->work);CHKERRQ(ierr);}
75558c9b817SLisandro Dalcin   snes->nwork = nw;
756f5af7f23SKarl Rupp 
757c5ed8070SMatthew G. Knepley   ierr = SNESGetDM(snes, &dm);CHKERRQ(ierr);
758c5ed8070SMatthew G. Knepley   ierr = DMGetGlobalVector(dm, &v);CHKERRQ(ierr);
759c5ed8070SMatthew G. Knepley   ierr = VecDuplicateVecs(v,snes->nwork,&snes->work);CHKERRQ(ierr);
760c5ed8070SMatthew G. Knepley   ierr = DMRestoreGlobalVector(dm, &v);CHKERRQ(ierr);
76158c9b817SLisandro Dalcin   ierr = PetscLogObjectParents(snes,nw,snes->work);CHKERRQ(ierr);
76258c9b817SLisandro Dalcin   PetscFunctionReturn(0);
76358c9b817SLisandro Dalcin }
764