xref: /petsc/src/snes/interface/snesut.c (revision 4d4332d57c8811c24bef4f82b0e35fedeab7f62b)
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 
64a2ae208SSatish Balay #undef __FUNCT__
7a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorSolution"
83f1db9ecSBarry Smith /*@C
9a6570f20SBarry Smith    SNESMonitorSolution - Monitors progress of the SNES solvers by calling
1036851e7fSLois Curfman McInnes    VecView() for the approximate solution at each iteration.
113f1db9ecSBarry Smith 
123f1db9ecSBarry Smith    Collective on SNES
133f1db9ecSBarry Smith 
143f1db9ecSBarry Smith    Input Parameters:
153f1db9ecSBarry Smith +  snes - the SNES context
163f1db9ecSBarry Smith .  its - iteration number
174b27c08aSLois Curfman McInnes .  fgnorm - 2-norm of residual
18f55353a2SBarry Smith -  dummy -  a viewer
193f1db9ecSBarry Smith 
2036851e7fSLois Curfman McInnes    Level: intermediate
213f1db9ecSBarry Smith 
2236851e7fSLois Curfman McInnes .keywords: SNES, nonlinear, vector, monitor, view
233f1db9ecSBarry Smith 
24a6570f20SBarry Smith .seealso: SNESMonitorSet(), SNESMonitorDefault(), VecView()
253f1db9ecSBarry Smith @*/
267087cfbeSBarry Smith PetscErrorCode  SNESMonitorSolution(SNES snes,PetscInt its,PetscReal fgnorm,void *dummy)
273f1db9ecSBarry Smith {
28dfbe8321SBarry Smith   PetscErrorCode ierr;
293f1db9ecSBarry Smith   Vec            x;
30b0a32e0cSBarry Smith   PetscViewer    viewer = (PetscViewer) dummy;
313f1db9ecSBarry Smith 
323f1db9ecSBarry Smith   PetscFunctionBegin;
33*4d4332d5SBarry Smith   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,4);
343f1db9ecSBarry Smith   ierr = SNESGetSolution(snes,&x);CHKERRQ(ierr);
353f1db9ecSBarry Smith   ierr = VecView(x,viewer);CHKERRQ(ierr);
363f1db9ecSBarry Smith   PetscFunctionReturn(0);
373f1db9ecSBarry Smith }
383f1db9ecSBarry Smith 
394a2ae208SSatish Balay #undef __FUNCT__
40a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorResidual"
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 
535ed2d596SBarry Smith    Level: intermediate
545ed2d596SBarry Smith 
555ed2d596SBarry Smith .keywords: SNES, nonlinear, vector, monitor, view
565ed2d596SBarry Smith 
57a6570f20SBarry Smith .seealso: SNESMonitorSet(), SNESMonitorDefault(), VecView()
585ed2d596SBarry Smith @*/
597087cfbeSBarry Smith PetscErrorCode  SNESMonitorResidual(SNES snes,PetscInt its,PetscReal fgnorm,void *dummy)
605ed2d596SBarry Smith {
61dfbe8321SBarry Smith   PetscErrorCode ierr;
625ed2d596SBarry Smith   Vec            x;
635ed2d596SBarry Smith   PetscViewer    viewer = (PetscViewer) dummy;
645ed2d596SBarry Smith 
655ed2d596SBarry Smith   PetscFunctionBegin;
66*4d4332d5SBarry Smith   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,4);
675ed2d596SBarry Smith   ierr = SNESGetFunction(snes,&x,0,0);CHKERRQ(ierr);
685ed2d596SBarry Smith   ierr = VecView(x,viewer);CHKERRQ(ierr);
695ed2d596SBarry Smith   PetscFunctionReturn(0);
705ed2d596SBarry Smith }
715ed2d596SBarry Smith 
725ed2d596SBarry Smith #undef __FUNCT__
73a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorSolutionUpdate"
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 
86d132466eSBarry Smith    Level: intermediate
87d132466eSBarry Smith 
88d132466eSBarry Smith .keywords: SNES, nonlinear, vector, monitor, view
89d132466eSBarry Smith 
90a6570f20SBarry Smith .seealso: SNESMonitorSet(), SNESMonitorDefault(), VecView()
91d132466eSBarry Smith @*/
927087cfbeSBarry Smith PetscErrorCode  SNESMonitorSolutionUpdate(SNES snes,PetscInt its,PetscReal fgnorm,void *dummy)
93d132466eSBarry Smith {
94dfbe8321SBarry Smith   PetscErrorCode ierr;
95d132466eSBarry Smith   Vec            x;
96b0a32e0cSBarry Smith   PetscViewer    viewer = (PetscViewer) dummy;
97d132466eSBarry Smith 
98d132466eSBarry Smith   PetscFunctionBegin;
99*4d4332d5SBarry Smith   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,4);
100d132466eSBarry Smith   ierr = SNESGetSolutionUpdate(snes,&x);CHKERRQ(ierr);
101d132466eSBarry Smith   ierr = VecView(x,viewer);CHKERRQ(ierr);
102d132466eSBarry Smith   PetscFunctionReturn(0);
103d132466eSBarry Smith }
104d132466eSBarry Smith 
1054a2ae208SSatish Balay #undef __FUNCT__
106a5c2985bSBarry Smith #define __FUNCT__ "KSPMonitorSNES"
107a5c2985bSBarry Smith /*@C
108a5c2985bSBarry Smith    KSPMonitorSNES - Print the residual norm of the nonlinear function at each iteration of the linear iterative solver.
109a5c2985bSBarry Smith 
110a5c2985bSBarry Smith    Collective on KSP
111a5c2985bSBarry Smith 
112a5c2985bSBarry Smith    Input Parameters:
113a5c2985bSBarry Smith +  ksp   - iterative context
114a5c2985bSBarry Smith .  n     - iteration number
115a5c2985bSBarry Smith .  rnorm - 2-norm (preconditioned) residual value (may be estimated).
116a5c2985bSBarry Smith -  dummy - unused monitor context
117a5c2985bSBarry Smith 
118a5c2985bSBarry Smith    Level: intermediate
119a5c2985bSBarry Smith 
120a5c2985bSBarry Smith .keywords: KSP, default, monitor, residual
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 #undef __FUNCT__
156e5f7ee39SBarry Smith #define __FUNCT__ "KSPMonitorSNESLGResidualNormCreate"
157e5f7ee39SBarry Smith /*@C
158e5f7ee39SBarry Smith    KSPMonitorSNESLGResidualNormCreate - Creates a line graph context for use with
159e5f7ee39SBarry Smith    KSP to monitor convergence of preconditioned residual norms.
160e5f7ee39SBarry Smith 
161e5f7ee39SBarry Smith    Collective on KSP
162e5f7ee39SBarry Smith 
163e5f7ee39SBarry Smith    Input Parameters:
164e5f7ee39SBarry Smith +  host - the X display to open, or null for the local machine
165e5f7ee39SBarry Smith .  label - the title to put in the title bar
166e5f7ee39SBarry Smith .  x, y - the screen coordinates of the upper left coordinate of
167e5f7ee39SBarry Smith           the window
168e5f7ee39SBarry Smith -  m, n - the screen width and height in pixels
169e5f7ee39SBarry Smith 
170e5f7ee39SBarry Smith    Output Parameter:
171e5f7ee39SBarry Smith .  draw - the drawing context
172e5f7ee39SBarry Smith 
173e5f7ee39SBarry Smith    Options Database Key:
174e5f7ee39SBarry Smith .  -ksp_monitor_lg_residualnorm - Sets line graph monitor
175e5f7ee39SBarry Smith 
176e5f7ee39SBarry Smith    Notes:
177e5f7ee39SBarry Smith    Use KSPMonitorSNESLGResidualNormDestroy() to destroy this line graph; do not use PetscDrawLGDestroy().
178e5f7ee39SBarry Smith 
179e5f7ee39SBarry Smith    Level: intermediate
180e5f7ee39SBarry Smith 
181e5f7ee39SBarry Smith .keywords: KSP, monitor, line graph, residual, create
182e5f7ee39SBarry Smith 
183e5f7ee39SBarry Smith .seealso: KSPMonitorSNESLGResidualNormDestroy(), KSPMonitorSet(), KSPMonitorSNESLGTrueResidualCreate()
184e5f7ee39SBarry Smith @*/
185e5f7ee39SBarry Smith PetscErrorCode  KSPMonitorSNESLGResidualNormCreate(const char host[],const char label[],int x,int y,int m,int n,PetscObject **objs)
186e5f7ee39SBarry Smith {
187e5f7ee39SBarry Smith   PetscDraw      draw;
188e5f7ee39SBarry Smith   PetscErrorCode ierr;
189e5f7ee39SBarry Smith   PetscDrawAxis  axis;
190e5f7ee39SBarry Smith   PetscDrawLG    drawlg;
191e5f7ee39SBarry Smith   const char     *names[] = {"Linear residual","Nonlinear residual"};
192e5f7ee39SBarry Smith 
193e5f7ee39SBarry Smith   PetscFunctionBegin;
194e5f7ee39SBarry Smith   ierr = PetscDrawCreate(PETSC_COMM_SELF,host,label,x,y,m,n,&draw);CHKERRQ(ierr);
195e5f7ee39SBarry Smith   ierr = PetscDrawSetFromOptions(draw);CHKERRQ(ierr);
196e5f7ee39SBarry Smith   ierr = PetscDrawLGCreate(draw,2,&drawlg);CHKERRQ(ierr);
197957f8de3SLisandro Dalcin   ierr = PetscDrawLGSetFromOptions(drawlg);CHKERRQ(ierr);
198e5f7ee39SBarry Smith   ierr = PetscDrawLGGetAxis(drawlg,&axis);CHKERRQ(ierr);
199e5f7ee39SBarry Smith   ierr = PetscDrawAxisSetLabels(axis,"Convergence of Residual Norm","Iteration","Residual Norm");CHKERRQ(ierr);
200e5f7ee39SBarry Smith   ierr = PetscDrawLGSetLegend(drawlg,names);CHKERRQ(ierr);
201e5f7ee39SBarry Smith   ierr = PetscLogObjectParent((PetscObject)drawlg,(PetscObject)draw);CHKERRQ(ierr);
202e5f7ee39SBarry Smith 
203435c5a64SBarry Smith   ierr = PetscMalloc1(3,objs);CHKERRQ(ierr);
204e5f7ee39SBarry Smith   (*objs)[1] = (PetscObject)drawlg;
205435c5a64SBarry Smith   (*objs)[2] = (PetscObject)draw;
206e5f7ee39SBarry Smith   PetscFunctionReturn(0);
207e5f7ee39SBarry Smith }
208e5f7ee39SBarry Smith 
209e5f7ee39SBarry Smith #undef __FUNCT__
210e5f7ee39SBarry Smith #define __FUNCT__ "KSPMonitorSNESLGResidualNorm"
211e5f7ee39SBarry Smith PetscErrorCode  KSPMonitorSNESLGResidualNorm(KSP ksp,PetscInt n,PetscReal rnorm,PetscObject *objs)
212e5f7ee39SBarry Smith {
213e5f7ee39SBarry Smith   PetscDrawLG    lg = (PetscDrawLG) objs[1];
214e5f7ee39SBarry Smith   PetscErrorCode ierr;
215e5f7ee39SBarry Smith   PetscReal      y[2];
216e5f7ee39SBarry Smith   SNES           snes = (SNES) objs[0];
217e5f7ee39SBarry Smith   Vec            snes_solution,work1,work2;
218e5f7ee39SBarry Smith 
219e5f7ee39SBarry Smith   PetscFunctionBegin;
220e5f7ee39SBarry Smith   if (rnorm > 0.0) y[0] = PetscLog10Real(rnorm);
221e5f7ee39SBarry Smith   else y[0] = -15.0;
222e5f7ee39SBarry Smith 
223e5f7ee39SBarry Smith   ierr = SNESGetSolution(snes,&snes_solution);CHKERRQ(ierr);
224e5f7ee39SBarry Smith   ierr = VecDuplicate(snes_solution,&work1);CHKERRQ(ierr);
225e5f7ee39SBarry Smith   ierr = VecDuplicate(snes_solution,&work2);CHKERRQ(ierr);
226e5f7ee39SBarry Smith   ierr = KSPBuildSolution(ksp,work1,NULL);CHKERRQ(ierr);
227e5f7ee39SBarry Smith   ierr = VecAYPX(work1,-1.0,snes_solution);CHKERRQ(ierr);
228e5f7ee39SBarry Smith   ierr = SNESComputeFunction(snes,work1,work2);CHKERRQ(ierr);
229e5f7ee39SBarry Smith   ierr = VecNorm(work2,NORM_2,y+1);CHKERRQ(ierr);
230e5f7ee39SBarry Smith   if (y[1] > 0.0) y[1] = PetscLog10Real(y[1]);
231e5f7ee39SBarry Smith   else y[1] = -15.0;
232e5f7ee39SBarry Smith   ierr = VecDestroy(&work1);CHKERRQ(ierr);
233e5f7ee39SBarry Smith   ierr = VecDestroy(&work2);CHKERRQ(ierr);
234e5f7ee39SBarry Smith 
235e5f7ee39SBarry Smith   ierr = PetscDrawLGAddPoint(lg,NULL,y);CHKERRQ(ierr);
236e5f7ee39SBarry Smith   if (n < 20 || !(n % 5)) {
237e5f7ee39SBarry Smith     ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr);
238e5f7ee39SBarry Smith   }
239e5f7ee39SBarry Smith   PetscFunctionReturn(0);
240e5f7ee39SBarry Smith }
241e5f7ee39SBarry Smith 
242e5f7ee39SBarry Smith #undef __FUNCT__
243e5f7ee39SBarry Smith #define __FUNCT__ "KSPMonitorSNESLGResidualNormDestroy"
244e5f7ee39SBarry Smith /*@
245e5f7ee39SBarry Smith    KSPMonitorSNESLGResidualNormDestroy - Destroys a line graph context that was created
246e5f7ee39SBarry Smith    with KSPMonitorSNESLGResidualNormCreate().
247e5f7ee39SBarry Smith 
248e5f7ee39SBarry Smith    Collective on KSP
249e5f7ee39SBarry Smith 
250e5f7ee39SBarry Smith    Input Parameter:
251e5f7ee39SBarry Smith .  draw - the drawing context
252e5f7ee39SBarry Smith 
253e5f7ee39SBarry Smith    Level: intermediate
254e5f7ee39SBarry Smith 
255e5f7ee39SBarry Smith .keywords: KSP, monitor, line graph, destroy
256e5f7ee39SBarry Smith 
257e5f7ee39SBarry Smith .seealso: KSPMonitorSNESLGResidualNormCreate(), KSPMonitorSNESLGTrueResidualDestroy(), KSPMonitorSet()
258e5f7ee39SBarry Smith @*/
259e5f7ee39SBarry Smith PetscErrorCode  KSPMonitorSNESLGResidualNormDestroy(PetscObject **objs)
260e5f7ee39SBarry Smith {
261e5f7ee39SBarry Smith   PetscErrorCode ierr;
262e5f7ee39SBarry Smith   PetscDrawLG    drawlg = (PetscDrawLG) (*objs)[1];
263435c5a64SBarry Smith   PetscDraw      draw = (PetscDraw) (*objs)[2];
264e5f7ee39SBarry Smith 
265e5f7ee39SBarry Smith   PetscFunctionBegin;
266e5f7ee39SBarry Smith   ierr = PetscDrawDestroy(&draw);CHKERRQ(ierr);
267e5f7ee39SBarry Smith   ierr = PetscDrawLGDestroy(&drawlg);CHKERRQ(ierr);
268e5f7ee39SBarry Smith   ierr = PetscFree(*objs);CHKERRQ(ierr);
269e5f7ee39SBarry Smith   PetscFunctionReturn(0);
270e5f7ee39SBarry Smith }
271e5f7ee39SBarry Smith 
272a5c2985bSBarry Smith #undef __FUNCT__
273a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorDefault"
2744b828684SBarry Smith /*@C
275a6570f20SBarry Smith    SNESMonitorDefault - Monitors progress of the SNES solvers (default).
276e7e93795SLois Curfman McInnes 
277c7afd0dbSLois Curfman McInnes    Collective on SNES
278c7afd0dbSLois Curfman McInnes 
279e7e93795SLois Curfman McInnes    Input Parameters:
280c7afd0dbSLois Curfman McInnes +  snes - the SNES context
281e7e93795SLois Curfman McInnes .  its - iteration number
2824b27c08aSLois Curfman McInnes .  fgnorm - 2-norm of residual
283c7afd0dbSLois Curfman McInnes -  dummy - unused context
284fee21e36SBarry Smith 
285e7e93795SLois Curfman McInnes    Notes:
2864b27c08aSLois Curfman McInnes    This routine prints the residual norm at each iteration.
287e7e93795SLois Curfman McInnes 
28836851e7fSLois Curfman McInnes    Level: intermediate
28936851e7fSLois Curfman McInnes 
290e7e93795SLois Curfman McInnes .keywords: SNES, nonlinear, default, monitor, norm
291e7e93795SLois Curfman McInnes 
292a6570f20SBarry Smith .seealso: SNESMonitorSet(), SNESMonitorSolution()
293e7e93795SLois Curfman McInnes @*/
2947087cfbeSBarry Smith PetscErrorCode  SNESMonitorDefault(SNES snes,PetscInt its,PetscReal fgnorm,void *dummy)
295e7e93795SLois Curfman McInnes {
296dfbe8321SBarry Smith   PetscErrorCode ierr;
297*4d4332d5SBarry Smith   PetscViewer    viewer = (PetscViewer) dummy;
298d132466eSBarry Smith 
2993a40ed3dSBarry Smith   PetscFunctionBegin;
300*4d4332d5SBarry Smith   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,4);
301649052a6SBarry Smith   ierr = PetscViewerASCIIAddTab(viewer,((PetscObject)snes)->tablevel);CHKERRQ(ierr);
302649052a6SBarry Smith   ierr = PetscViewerASCIIPrintf(viewer,"%3D SNES Function norm %14.12e \n",its,(double)fgnorm);CHKERRQ(ierr);
303649052a6SBarry Smith   ierr = PetscViewerASCIISubtractTab(viewer,((PetscObject)snes)->tablevel);CHKERRQ(ierr);
3043a40ed3dSBarry Smith   PetscFunctionReturn(0);
305e7e93795SLois Curfman McInnes }
3063f1db9ecSBarry Smith 
307b271bb04SBarry Smith #undef __FUNCT__
3082e7541e6SPeter Brune #define __FUNCT__ "SNESMonitorJacUpdateSpectrum"
309a80ad3e0SBarry Smith PetscErrorCode SNESMonitorJacUpdateSpectrum(SNES snes,PetscInt it,PetscReal fnorm,void *ctx)
310a80ad3e0SBarry Smith {
311196da8b6SPeter Brune #if defined(PETSC_MISSING_LAPACK_GEEV)
312ce94432eSBarry Smith   SETERRQ(PetscObjectComm((PetscObject)snes),PETSC_ERR_SUP,"GEEV - Lapack routine is unavailable\nNot able to provide eigen values.");
313196da8b6SPeter Brune #elif defined(PETSC_HAVE_ESSL)
314ce94432eSBarry Smith   SETERRQ(PetscObjectComm((PetscObject)snes),PETSC_ERR_SUP,"GEEV - No support for ESSL Lapack Routines");
315196da8b6SPeter Brune #else
3162e7541e6SPeter Brune   Vec            X;
3172e7541e6SPeter Brune   Mat            J,dJ,dJdense;
3182e7541e6SPeter Brune   PetscErrorCode ierr;
319d1e9a80fSBarry Smith   PetscErrorCode (*func)(SNES,Vec,Mat,Mat,void*);
3202e7541e6SPeter Brune   PetscInt       n,i;
3212e7541e6SPeter Brune   PetscBLASInt   nb,lwork;
3222e7541e6SPeter Brune   PetscReal      *eigr,*eigi;
3232e7541e6SPeter Brune   PetscScalar    *work;
3242e7541e6SPeter Brune   PetscScalar    *a;
3252e7541e6SPeter Brune 
3262e7541e6SPeter Brune   PetscFunctionBegin;
3272e7541e6SPeter Brune   if (it == 0) PetscFunctionReturn(0);
3282e7541e6SPeter Brune   /* create the difference between the current update and the current jacobian */
3292e7541e6SPeter Brune   ierr = SNESGetSolution(snes,&X);CHKERRQ(ierr);
330d1e9a80fSBarry Smith   ierr = SNESGetJacobian(snes,NULL,&J,&func,NULL);CHKERRQ(ierr);
3312e7541e6SPeter Brune   ierr = MatDuplicate(J,MAT_COPY_VALUES,&dJ);CHKERRQ(ierr);
332d1e9a80fSBarry Smith   ierr = SNESComputeJacobian(snes,X,dJ,dJ);CHKERRQ(ierr);
3332e7541e6SPeter Brune   ierr = MatAXPY(dJ,-1.0,J,SAME_NONZERO_PATTERN);CHKERRQ(ierr);
334f5af7f23SKarl Rupp 
3352e7541e6SPeter Brune   /* compute the spectrum directly */
3362e7541e6SPeter Brune   ierr  = MatConvert(dJ,MATSEQDENSE,MAT_INITIAL_MATRIX,&dJdense);CHKERRQ(ierr);
3370298fd71SBarry Smith   ierr  = MatGetSize(dJ,&n,NULL);CHKERRQ(ierr);
338c5df96a5SBarry Smith   ierr  = PetscBLASIntCast(n,&nb);CHKERRQ(ierr);
3392e7541e6SPeter Brune   lwork = 3*nb;
340785e854fSJed Brown   ierr  = PetscMalloc1(n,&eigr);CHKERRQ(ierr);
341785e854fSJed Brown   ierr  = PetscMalloc1(n,&eigi);CHKERRQ(ierr);
342785e854fSJed Brown   ierr  = PetscMalloc1(lwork,&work);CHKERRQ(ierr);
3438c778c55SBarry Smith   ierr  = MatDenseGetArray(dJdense,&a);CHKERRQ(ierr);
3442e7541e6SPeter Brune #if !defined(PETSC_USE_COMPLEX)
3452e7541e6SPeter Brune   {
3462e7541e6SPeter Brune     PetscBLASInt lierr;
3472e7541e6SPeter Brune     ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
3488b83055fSJed Brown     PetscStackCallBLAS("LAPACKgeev",LAPACKgeev_("N","N",&nb,a,&nb,eigr,eigi,NULL,&nb,NULL,&nb,work,&lwork,&lierr));
3492e7541e6SPeter Brune     if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"geev() error %d",lierr);
3502e7541e6SPeter Brune     ierr = PetscFPTrapPop();CHKERRQ(ierr);
3512e7541e6SPeter Brune   }
3522e7541e6SPeter Brune #else
3532e7541e6SPeter Brune   SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not coded for complex");
3542e7541e6SPeter Brune #endif
355ce94432eSBarry Smith   PetscPrintf(PetscObjectComm((PetscObject)snes),"Eigenvalues of J_%d - J_%d:\n",it,it-1);CHKERRQ(ierr);
3562e7541e6SPeter Brune   for (i=0;i<n;i++) {
3578fa295daSBarry Smith     PetscPrintf(PetscObjectComm((PetscObject)snes),"%5d: %20.5g + %20.5gi\n",i,(double)eigr[i],(double)eigi[i]);CHKERRQ(ierr);
3582e7541e6SPeter Brune   }
3598c778c55SBarry Smith   ierr = MatDenseRestoreArray(dJdense,&a);CHKERRQ(ierr);
3602e7541e6SPeter Brune   ierr = MatDestroy(&dJ);CHKERRQ(ierr);
3612e7541e6SPeter Brune   ierr = MatDestroy(&dJdense);CHKERRQ(ierr);
3622e7541e6SPeter Brune   ierr = PetscFree(eigr);CHKERRQ(ierr);
3632e7541e6SPeter Brune   ierr = PetscFree(eigi);CHKERRQ(ierr);
3642e7541e6SPeter Brune   ierr = PetscFree(work);CHKERRQ(ierr);
3652e7541e6SPeter Brune   PetscFunctionReturn(0);
366196da8b6SPeter Brune #endif
3672e7541e6SPeter Brune }
3682e7541e6SPeter Brune 
3692e7541e6SPeter Brune #undef __FUNCT__
370b271bb04SBarry Smith #define __FUNCT__ "SNESMonitorRange_Private"
3717087cfbeSBarry Smith PetscErrorCode  SNESMonitorRange_Private(SNES snes,PetscInt it,PetscReal *per)
372b271bb04SBarry Smith {
373b271bb04SBarry Smith   PetscErrorCode ierr;
374b271bb04SBarry Smith   Vec            resid;
375b271bb04SBarry Smith   PetscReal      rmax,pwork;
376b271bb04SBarry Smith   PetscInt       i,n,N;
377b271bb04SBarry Smith   PetscScalar    *r;
378b271bb04SBarry Smith 
379b271bb04SBarry Smith   PetscFunctionBegin;
380b271bb04SBarry Smith   ierr  = SNESGetFunction(snes,&resid,0,0);CHKERRQ(ierr);
381b271bb04SBarry Smith   ierr  = VecNorm(resid,NORM_INFINITY,&rmax);CHKERRQ(ierr);
382b271bb04SBarry Smith   ierr  = VecGetLocalSize(resid,&n);CHKERRQ(ierr);
383b271bb04SBarry Smith   ierr  = VecGetSize(resid,&N);CHKERRQ(ierr);
384b271bb04SBarry Smith   ierr  = VecGetArray(resid,&r);CHKERRQ(ierr);
385b271bb04SBarry Smith   pwork = 0.0;
386b271bb04SBarry Smith   for (i=0; i<n; i++) {
387b271bb04SBarry Smith     pwork += (PetscAbsScalar(r[i]) > .20*rmax);
388b271bb04SBarry Smith   }
389ce94432eSBarry Smith   ierr = MPI_Allreduce(&pwork,per,1,MPIU_REAL,MPIU_SUM,PetscObjectComm((PetscObject)snes));CHKERRQ(ierr);
390b271bb04SBarry Smith   ierr = VecRestoreArray(resid,&r);CHKERRQ(ierr);
391b271bb04SBarry Smith   *per = *per/N;
392b271bb04SBarry Smith   PetscFunctionReturn(0);
393b271bb04SBarry Smith }
394b271bb04SBarry Smith 
395b271bb04SBarry Smith #undef __FUNCT__
396b271bb04SBarry Smith #define __FUNCT__ "SNESMonitorRange"
397b271bb04SBarry Smith /*@C
398b271bb04SBarry Smith    SNESMonitorRange - Prints the percentage of residual elements that are more then 10 percent of the maximum value.
399b271bb04SBarry Smith 
400b271bb04SBarry Smith    Collective on SNES
401b271bb04SBarry Smith 
402b271bb04SBarry Smith    Input Parameters:
403b271bb04SBarry Smith +  snes   - iterative context
404b271bb04SBarry Smith .  it    - iteration number
405b271bb04SBarry Smith .  rnorm - 2-norm (preconditioned) residual value (may be estimated).
406b271bb04SBarry Smith -  dummy - unused monitor context
407b271bb04SBarry Smith 
408b271bb04SBarry Smith    Options Database Key:
409b271bb04SBarry Smith .  -snes_monitor_range - Activates SNESMonitorRange()
410b271bb04SBarry Smith 
411b271bb04SBarry Smith    Level: intermediate
412b271bb04SBarry Smith 
413b271bb04SBarry Smith .keywords: SNES, default, monitor, residual
414b271bb04SBarry Smith 
415b271bb04SBarry Smith .seealso: SNESMonitorSet(), SNESMonitorDefault(), SNESMonitorLGCreate()
416b271bb04SBarry Smith @*/
4177087cfbeSBarry Smith PetscErrorCode  SNESMonitorRange(SNES snes,PetscInt it,PetscReal rnorm,void *dummy)
418b271bb04SBarry Smith {
419b271bb04SBarry Smith   PetscErrorCode ierr;
420b271bb04SBarry Smith   PetscReal      perc,rel;
421*4d4332d5SBarry Smith   PetscViewer    viewer = (PetscViewer) dummy;
422b271bb04SBarry Smith   /* should be in a MonitorRangeContext */
423b271bb04SBarry Smith   static PetscReal prev;
424b271bb04SBarry Smith 
425b271bb04SBarry Smith   PetscFunctionBegin;
426*4d4332d5SBarry Smith   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,4);
427b271bb04SBarry Smith   if (!it) prev = rnorm;
428b271bb04SBarry Smith   ierr = SNESMonitorRange_Private(snes,it,&perc);CHKERRQ(ierr);
429b271bb04SBarry Smith 
430b271bb04SBarry Smith   rel  = (prev - rnorm)/prev;
431b271bb04SBarry Smith   prev = rnorm;
432649052a6SBarry Smith   ierr = PetscViewerASCIIAddTab(viewer,((PetscObject)snes)->tablevel);CHKERRQ(ierr);
4336712e2f1SBarry 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);
434649052a6SBarry Smith   ierr = PetscViewerASCIISubtractTab(viewer,((PetscObject)snes)->tablevel);CHKERRQ(ierr);
435b271bb04SBarry Smith   PetscFunctionReturn(0);
436b271bb04SBarry Smith }
437b271bb04SBarry Smith 
438eabae89aSBarry Smith typedef struct {
439649052a6SBarry Smith   PetscViewer viewer;
440eabae89aSBarry Smith   PetscReal   *history;
441a6570f20SBarry Smith } SNESMonitorRatioContext;
442eabae89aSBarry Smith 
4433a7fca6bSBarry Smith #undef __FUNCT__
444a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorRatio"
4453a7fca6bSBarry Smith /*@C
446a6570f20SBarry Smith    SNESMonitorRatio - Monitors progress of the SNES solvers by printing the ratio
4474b27c08aSLois Curfman McInnes    of residual norm at each iteration to the previous.
4483a7fca6bSBarry Smith 
4493a7fca6bSBarry Smith    Collective on SNES
4503a7fca6bSBarry Smith 
4513a7fca6bSBarry Smith    Input Parameters:
4523a7fca6bSBarry Smith +  snes - the SNES context
4533a7fca6bSBarry Smith .  its - iteration number
4543a7fca6bSBarry Smith .  fgnorm - 2-norm of residual (or gradient)
455eabae89aSBarry Smith -  dummy -  context of monitor
4563a7fca6bSBarry Smith 
4573a7fca6bSBarry Smith    Level: intermediate
4583a7fca6bSBarry Smith 
4593a7fca6bSBarry Smith .keywords: SNES, nonlinear, monitor, norm
4603a7fca6bSBarry Smith 
461a6570f20SBarry Smith .seealso: SNESMonitorSet(), SNESMonitorSolution()
4623a7fca6bSBarry Smith @*/
4637087cfbeSBarry Smith PetscErrorCode  SNESMonitorRatio(SNES snes,PetscInt its,PetscReal fgnorm,void *dummy)
4643a7fca6bSBarry Smith {
465dfbe8321SBarry Smith   PetscErrorCode          ierr;
46677431f27SBarry Smith   PetscInt                len;
46787828ca2SBarry Smith   PetscReal               *history;
468a6570f20SBarry Smith   SNESMonitorRatioContext *ctx = (SNESMonitorRatioContext*)dummy;
4693a7fca6bSBarry Smith 
4703a7fca6bSBarry Smith   PetscFunctionBegin;
4710298fd71SBarry Smith   ierr = SNESGetConvergenceHistory(snes,&history,NULL,&len);CHKERRQ(ierr);
472649052a6SBarry Smith   ierr = PetscViewerASCIIAddTab(ctx->viewer,((PetscObject)snes)->tablevel);CHKERRQ(ierr);
473958c9bccSBarry Smith   if (!its || !history || its > len) {
474649052a6SBarry Smith     ierr = PetscViewerASCIIPrintf(ctx->viewer,"%3D SNES Function norm %14.12e \n",its,(double)fgnorm);CHKERRQ(ierr);
4753a7fca6bSBarry Smith   } else {
47687828ca2SBarry Smith     PetscReal ratio = fgnorm/history[its-1];
4778f1a2a5eSBarry Smith     ierr = PetscViewerASCIIPrintf(ctx->viewer,"%3D SNES Function norm %14.12e %14.12e \n",its,(double)fgnorm,(double)ratio);CHKERRQ(ierr);
4783a7fca6bSBarry Smith   }
479649052a6SBarry Smith   ierr = PetscViewerASCIISubtractTab(ctx->viewer,((PetscObject)snes)->tablevel);CHKERRQ(ierr);
4803a7fca6bSBarry Smith   PetscFunctionReturn(0);
4813a7fca6bSBarry Smith }
4823a7fca6bSBarry Smith 
4833a7fca6bSBarry Smith /*
4843a7fca6bSBarry Smith    If the we set the history monitor space then we must destroy it
4853a7fca6bSBarry Smith */
4863a7fca6bSBarry Smith #undef __FUNCT__
487a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorRatioDestroy"
488c2efdce3SBarry Smith PetscErrorCode SNESMonitorRatioDestroy(void **ct)
4893a7fca6bSBarry Smith {
490dfbe8321SBarry Smith   PetscErrorCode          ierr;
491c2efdce3SBarry Smith   SNESMonitorRatioContext *ctx = *(SNESMonitorRatioContext**)ct;
4923a7fca6bSBarry Smith 
4933a7fca6bSBarry Smith   PetscFunctionBegin;
49405b42c5fSBarry Smith   ierr = PetscFree(ctx->history);CHKERRQ(ierr);
495649052a6SBarry Smith   ierr = PetscViewerDestroy(&ctx->viewer);CHKERRQ(ierr);
496eabae89aSBarry Smith   ierr = PetscFree(ctx);CHKERRQ(ierr);
4973a7fca6bSBarry Smith   PetscFunctionReturn(0);
4983a7fca6bSBarry Smith }
4993a7fca6bSBarry Smith 
5003a7fca6bSBarry Smith #undef __FUNCT__
501a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorSetRatio"
5023a7fca6bSBarry Smith /*@C
503a6570f20SBarry Smith    SNESMonitorSetRatio - Sets SNES to use a monitor that prints the
5044b27c08aSLois Curfman McInnes    ratio of the function norm at each iteration.
5053a7fca6bSBarry Smith 
5063a7fca6bSBarry Smith    Collective on SNES
5073a7fca6bSBarry Smith 
5083a7fca6bSBarry Smith    Input Parameters:
509eabae89aSBarry Smith +   snes - the SNES context
510eabae89aSBarry Smith -   viewer - ASCII viewer to print output
5113a7fca6bSBarry Smith 
5123a7fca6bSBarry Smith    Level: intermediate
5133a7fca6bSBarry Smith 
5143a7fca6bSBarry Smith .keywords: SNES, nonlinear, monitor, norm
5153a7fca6bSBarry Smith 
516a6570f20SBarry Smith .seealso: SNESMonitorSet(), SNESMonitorSolution(), SNESMonitorDefault()
5173a7fca6bSBarry Smith @*/
518649052a6SBarry Smith PetscErrorCode  SNESMonitorSetRatio(SNES snes,PetscViewer viewer)
5193a7fca6bSBarry Smith {
520dfbe8321SBarry Smith   PetscErrorCode          ierr;
521a6570f20SBarry Smith   SNESMonitorRatioContext *ctx;
52287828ca2SBarry Smith   PetscReal               *history;
5233a7fca6bSBarry Smith 
5243a7fca6bSBarry Smith   PetscFunctionBegin;
525b00a9115SJed Brown   ierr = PetscNewLog(snes,&ctx);CHKERRQ(ierr);
5260298fd71SBarry Smith   ierr = SNESGetConvergenceHistory(snes,&history,NULL,NULL);CHKERRQ(ierr);
5273a7fca6bSBarry Smith   if (!history) {
528785e854fSJed Brown     ierr = PetscMalloc1(100,&ctx->history);CHKERRQ(ierr);
529eabae89aSBarry Smith     ierr = SNESSetConvergenceHistory(snes,ctx->history,0,100,PETSC_TRUE);CHKERRQ(ierr);
5303a7fca6bSBarry Smith   }
531eabae89aSBarry Smith   ctx->viewer = viewer;
532f5af7f23SKarl Rupp 
533a6570f20SBarry Smith   ierr = SNESMonitorSet(snes,SNESMonitorRatio,ctx,SNESMonitorRatioDestroy);CHKERRQ(ierr);
5343a7fca6bSBarry Smith   PetscFunctionReturn(0);
5353a7fca6bSBarry Smith }
5363a7fca6bSBarry Smith 
537e7e93795SLois Curfman McInnes /* ---------------------------------------------------------------- */
5384a2ae208SSatish Balay #undef __FUNCT__
539a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorDefaultShort"
540be1f7002SBarry Smith /*
541a6570f20SBarry Smith      Default (short) SNES Monitor, same as SNESMonitorDefault() except
542be1f7002SBarry Smith   it prints fewer digits of the residual as the residual gets smaller.
543be1f7002SBarry Smith   This is because the later digits are meaningless and are often
544be1f7002SBarry Smith   different on different machines; by using this routine different
545be1f7002SBarry Smith   machines will usually generate the same output.
546be1f7002SBarry Smith */
5477087cfbeSBarry Smith PetscErrorCode  SNESMonitorDefaultShort(SNES snes,PetscInt its,PetscReal fgnorm,void *dummy)
548e7e93795SLois Curfman McInnes {
549dfbe8321SBarry Smith   PetscErrorCode ierr;
550*4d4332d5SBarry Smith   PetscViewer    viewer = (PetscViewer) dummy;
551d132466eSBarry Smith 
5523a40ed3dSBarry Smith   PetscFunctionBegin;
553*4d4332d5SBarry Smith   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,4);
554649052a6SBarry Smith   ierr = PetscViewerASCIIAddTab(viewer,((PetscObject)snes)->tablevel);CHKERRQ(ierr);
5558f240d10SBarry Smith   if (fgnorm > 1.e-9) {
5568fa295daSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"%3D SNES Function norm %g \n",its,(double)fgnorm);CHKERRQ(ierr);
5573a40ed3dSBarry Smith   } else if (fgnorm > 1.e-11) {
5588fa295daSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"%3D SNES Function norm %5.3e \n",its,(double)fgnorm);CHKERRQ(ierr);
5593a40ed3dSBarry Smith   } else {
560649052a6SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"%3D SNES Function norm < 1.e-11\n",its);CHKERRQ(ierr);
561a34d58ebSBarry Smith   }
562649052a6SBarry Smith   ierr = PetscViewerASCIISubtractTab(viewer,((PetscObject)snes)->tablevel);CHKERRQ(ierr);
5633a40ed3dSBarry Smith   PetscFunctionReturn(0);
564e7e93795SLois Curfman McInnes }
5652db13446SMatthew G. Knepley 
5662db13446SMatthew G. Knepley #undef __FUNCT__
5672db13446SMatthew G. Knepley #define __FUNCT__ "SNESMonitorDefaultField"
5682db13446SMatthew G. Knepley /*@C
5692db13446SMatthew G. Knepley   SNESMonitorDefaultField - Monitors progress of the SNES solvers, separated into fields.
5702db13446SMatthew G. Knepley 
5712db13446SMatthew G. Knepley   Collective on SNES
5722db13446SMatthew G. Knepley 
5732db13446SMatthew G. Knepley   Input Parameters:
5742db13446SMatthew G. Knepley + snes   - the SNES context
5752db13446SMatthew G. Knepley . its    - iteration number
5762db13446SMatthew G. Knepley . fgnorm - 2-norm of residual
5772db13446SMatthew G. Knepley - ctx    - the PetscViewer
5782db13446SMatthew G. Knepley 
5792db13446SMatthew G. Knepley   Notes:
5802db13446SMatthew G. Knepley   This routine uses the DM attached to the residual vector
5812db13446SMatthew G. Knepley 
5822db13446SMatthew G. Knepley   Level: intermediate
5832db13446SMatthew G. Knepley 
5842db13446SMatthew G. Knepley .keywords: SNES, nonlinear, field, monitor, norm
5852db13446SMatthew G. Knepley .seealso: SNESMonitorSet(), SNESMonitorSolution(), SNESMonitorDefault(), SNESMonitorDefaultShort()
5862db13446SMatthew G. Knepley @*/
5872db13446SMatthew G. Knepley PetscErrorCode SNESMonitorDefaultField(SNES snes, PetscInt its, PetscReal fgnorm, void *ctx)
5882db13446SMatthew G. Knepley {
589*4d4332d5SBarry Smith   PetscViewer    viewer = (PetscViewer) ctx;
5902db13446SMatthew G. Knepley   Vec            r;
5912db13446SMatthew G. Knepley   DM             dm;
5922db13446SMatthew G. Knepley   PetscReal      res[256];
5932db13446SMatthew G. Knepley   PetscInt       tablevel;
5942db13446SMatthew G. Knepley   PetscErrorCode ierr;
5952db13446SMatthew G. Knepley 
5962db13446SMatthew G. Knepley   PetscFunctionBegin;
597*4d4332d5SBarry Smith   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,4);
5982db13446SMatthew G. Knepley   ierr = SNESGetFunction(snes, &r, NULL, NULL);CHKERRQ(ierr);
5992db13446SMatthew G. Knepley   ierr = VecGetDM(r, &dm);CHKERRQ(ierr);
6002db13446SMatthew G. Knepley   if (!dm) {ierr = SNESMonitorDefault(snes, its, fgnorm, ctx);CHKERRQ(ierr);}
6012db13446SMatthew G. Knepley   else {
6022db13446SMatthew G. Knepley     PetscSection s, gs;
6032db13446SMatthew G. Knepley     PetscInt     Nf, f;
6042db13446SMatthew G. Knepley 
6052db13446SMatthew G. Knepley     ierr = DMGetDefaultSection(dm, &s);CHKERRQ(ierr);
6062db13446SMatthew G. Knepley     ierr = DMGetDefaultGlobalSection(dm, &gs);CHKERRQ(ierr);
6072db13446SMatthew G. Knepley     if (!s || !gs) {ierr = SNESMonitorDefault(snes, its, fgnorm, ctx);CHKERRQ(ierr);}
6082db13446SMatthew G. Knepley     ierr = PetscSectionGetNumFields(s, &Nf);CHKERRQ(ierr);
6092db13446SMatthew G. Knepley     if (Nf > 256) SETERRQ1(PetscObjectComm((PetscObject) snes), PETSC_ERR_SUP, "Do not support %d fields > 256", Nf);
6102db13446SMatthew G. Knepley     ierr = PetscSectionVecNorm(s, gs, r, NORM_2, res);CHKERRQ(ierr);
6112db13446SMatthew G. Knepley     ierr = PetscObjectGetTabLevel((PetscObject) snes, &tablevel);CHKERRQ(ierr);
6122db13446SMatthew G. Knepley     ierr = PetscViewerASCIIAddTab(viewer, tablevel);CHKERRQ(ierr);
6132db13446SMatthew G. Knepley     ierr = PetscViewerASCIIPrintf(viewer, "%3D SNES Function norm %14.12e [", its, (double) fgnorm);CHKERRQ(ierr);
6142db13446SMatthew G. Knepley     for (f = 0; f < Nf; ++f) {
6152db13446SMatthew G. Knepley       if (f) {ierr = PetscViewerASCIIPrintf(viewer, ", ");CHKERRQ(ierr);}
6162db13446SMatthew G. Knepley       ierr = PetscViewerASCIIPrintf(viewer, "%14.12e", res[f]);CHKERRQ(ierr);
6172db13446SMatthew G. Knepley     }
6182db13446SMatthew G. Knepley     ierr = PetscViewerASCIIPrintf(viewer, "] \n");CHKERRQ(ierr);
6192db13446SMatthew G. Knepley     ierr = PetscViewerASCIISubtractTab(viewer, tablevel);CHKERRQ(ierr);
6202db13446SMatthew G. Knepley   }
6212db13446SMatthew G. Knepley   PetscFunctionReturn(0);
6222db13446SMatthew G. Knepley }
623e7e93795SLois Curfman McInnes /* ---------------------------------------------------------------- */
6244a2ae208SSatish Balay #undef __FUNCT__
6258d359177SBarry Smith #define __FUNCT__ "SNESConvergedDefault"
6264b828684SBarry Smith /*@C
6278d359177SBarry Smith    SNESConvergedDefault - Convergence test of the solvers for
628f525115eSLois Curfman McInnes    systems of nonlinear equations (default).
629e7e93795SLois Curfman McInnes 
630c7afd0dbSLois Curfman McInnes    Collective on SNES
631c7afd0dbSLois Curfman McInnes 
632e7e93795SLois Curfman McInnes    Input Parameters:
633c7afd0dbSLois Curfman McInnes +  snes - the SNES context
63406ee9f85SBarry Smith .  it - the iteration (0 indicates before any Newton steps)
635e7e93795SLois Curfman McInnes .  xnorm - 2-norm of current iterate
636c60f73f4SPeter Brune .  snorm - 2-norm of current step
6377f3332b4SBarry Smith .  fnorm - 2-norm of function at current iterate
638c7afd0dbSLois Curfman McInnes -  dummy - unused context
639e7e93795SLois Curfman McInnes 
640184914b5SBarry Smith    Output Parameter:
641184914b5SBarry Smith .   reason  - one of
64270441072SBarry Smith $  SNES_CONVERGED_FNORM_ABS       - (fnorm < abstol),
643c60f73f4SPeter Brune $  SNES_CONVERGED_SNORM_RELATIVE  - (snorm < stol*xnorm),
644184914b5SBarry Smith $  SNES_CONVERGED_FNORM_RELATIVE  - (fnorm < rtol*fnorm0),
645184914b5SBarry Smith $  SNES_DIVERGED_FUNCTION_COUNT   - (nfct > maxf),
646184914b5SBarry Smith $  SNES_DIVERGED_FNORM_NAN        - (fnorm == NaN),
647184914b5SBarry Smith $  SNES_CONVERGED_ITERATING       - (otherwise),
648e7e93795SLois Curfman McInnes 
649e7e93795SLois Curfman McInnes    where
650c7afd0dbSLois Curfman McInnes +    maxf - maximum number of function evaluations,
651c7afd0dbSLois Curfman McInnes             set with SNESSetTolerances()
652c7afd0dbSLois Curfman McInnes .    nfct - number of function evaluations,
65370441072SBarry Smith .    abstol - absolute function norm tolerance,
654c7afd0dbSLois Curfman McInnes             set with SNESSetTolerances()
655c7afd0dbSLois Curfman McInnes -    rtol - relative function norm tolerance, set with SNESSetTolerances()
656fee21e36SBarry Smith 
65736851e7fSLois Curfman McInnes    Level: intermediate
65836851e7fSLois Curfman McInnes 
659e7e93795SLois Curfman McInnes .keywords: SNES, nonlinear, default, converged, convergence
660e7e93795SLois Curfman McInnes 
66171f87433Sdalcinl .seealso: SNESSetConvergenceTest()
662e7e93795SLois Curfman McInnes @*/
6638d359177SBarry Smith PetscErrorCode  SNESConvergedDefault(SNES snes,PetscInt it,PetscReal xnorm,PetscReal snorm,PetscReal fnorm,SNESConvergedReason *reason,void *dummy)
664e7e93795SLois Curfman McInnes {
66563ba0a88SBarry Smith   PetscErrorCode ierr;
66663ba0a88SBarry Smith 
6673a40ed3dSBarry Smith   PetscFunctionBegin;
6680700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
6693f149594SLisandro Dalcin   PetscValidPointer(reason,6);
6703f149594SLisandro Dalcin 
67106ee9f85SBarry Smith   *reason = SNES_CONVERGED_ITERATING;
67206ee9f85SBarry Smith 
67306ee9f85SBarry Smith   if (!it) {
67406ee9f85SBarry Smith     /* set parameter for default relative tolerance convergence test */
67506ee9f85SBarry Smith     snes->ttol = fnorm*snes->rtol;
67606ee9f85SBarry Smith   }
6778146f6ebSBarry Smith   if (PetscIsInfOrNanReal(fnorm)) {
678ae15b995SBarry Smith     ierr    = PetscInfo(snes,"Failed to converged, function norm is NaN\n");CHKERRQ(ierr);
679184914b5SBarry Smith     *reason = SNES_DIVERGED_FNORM_NAN;
68070441072SBarry Smith   } else if (fnorm < snes->abstol) {
6818f1a2a5eSBarry Smith     ierr    = PetscInfo2(snes,"Converged due to function norm %14.12e < %14.12e\n",(double)fnorm,(double)snes->abstol);CHKERRQ(ierr);
682184914b5SBarry Smith     *reason = SNES_CONVERGED_FNORM_ABS;
68343e71028SBarry Smith   } else if (snes->nfuncs >= snes->max_funcs) {
684ae15b995SBarry Smith     ierr    = PetscInfo2(snes,"Exceeded maximum number of function evaluations: %D > %D\n",snes->nfuncs,snes->max_funcs);CHKERRQ(ierr);
685184914b5SBarry Smith     *reason = SNES_DIVERGED_FUNCTION_COUNT;
68606ee9f85SBarry Smith   }
68706ee9f85SBarry Smith 
68806ee9f85SBarry Smith   if (it && !*reason) {
68906ee9f85SBarry Smith     if (fnorm <= snes->ttol) {
6908f1a2a5eSBarry Smith       ierr    = PetscInfo2(snes,"Converged due to function norm %14.12e < %14.12e (relative tolerance)\n",(double)fnorm,(double)snes->ttol);CHKERRQ(ierr);
69106ee9f85SBarry Smith       *reason = SNES_CONVERGED_FNORM_RELATIVE;
692c60f73f4SPeter Brune     } else if (snorm < snes->stol*xnorm) {
693c60f73f4SPeter 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);
694c60f73f4SPeter Brune       *reason = SNES_CONVERGED_SNORM_RELATIVE;
69506ee9f85SBarry Smith     }
696e7e93795SLois Curfman McInnes   }
6973a40ed3dSBarry Smith   PetscFunctionReturn(0);
698e7e93795SLois Curfman McInnes }
6993f149594SLisandro Dalcin 
7003f149594SLisandro Dalcin #undef __FUNCT__
701e2a6519dSDmitry Karpeev #define __FUNCT__ "SNESConvergedSkip"
7023f149594SLisandro Dalcin /*@C
703e2a6519dSDmitry Karpeev    SNESConvergedSkip - Convergence test for SNES that NEVER returns as
7043f149594SLisandro Dalcin    converged, UNLESS the maximum number of iteration have been reached.
7053f149594SLisandro Dalcin 
7063f9fe445SBarry Smith    Logically Collective on SNES
7073f149594SLisandro Dalcin 
7083f149594SLisandro Dalcin    Input Parameters:
7093f149594SLisandro Dalcin +  snes - the SNES context
7103f149594SLisandro Dalcin .  it - the iteration (0 indicates before any Newton steps)
7113f149594SLisandro Dalcin .  xnorm - 2-norm of current iterate
712c60f73f4SPeter Brune .  snorm - 2-norm of current step
7133f149594SLisandro Dalcin .  fnorm - 2-norm of function at current iterate
7143f149594SLisandro Dalcin -  dummy - unused context
7153f149594SLisandro Dalcin 
7163f149594SLisandro Dalcin    Output Parameter:
71785385478SLisandro Dalcin .   reason  - SNES_CONVERGED_ITERATING, SNES_CONVERGED_ITS, or SNES_DIVERGED_FNORM_NAN
7183f149594SLisandro Dalcin 
7193f149594SLisandro Dalcin    Notes:
7203f149594SLisandro Dalcin    Convergence is then declared after a fixed number of iterations have been used.
7213f149594SLisandro Dalcin 
7223f149594SLisandro Dalcin    Level: advanced
7233f149594SLisandro Dalcin 
7243f149594SLisandro Dalcin .keywords: SNES, nonlinear, skip, converged, convergence
7253f149594SLisandro Dalcin 
7263f149594SLisandro Dalcin .seealso: SNESSetConvergenceTest()
7273f149594SLisandro Dalcin @*/
728e2a6519dSDmitry Karpeev PetscErrorCode  SNESConvergedSkip(SNES snes,PetscInt it,PetscReal xnorm,PetscReal snorm,PetscReal fnorm,SNESConvergedReason *reason,void *dummy)
7293f149594SLisandro Dalcin {
7303f149594SLisandro Dalcin   PetscErrorCode ierr;
7313f149594SLisandro Dalcin 
7323f149594SLisandro Dalcin   PetscFunctionBegin;
7330700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
7343f149594SLisandro Dalcin   PetscValidPointer(reason,6);
7353f149594SLisandro Dalcin 
7363f149594SLisandro Dalcin   *reason = SNES_CONVERGED_ITERATING;
7373f149594SLisandro Dalcin 
7383f149594SLisandro Dalcin   if (fnorm != fnorm) {
7393f149594SLisandro Dalcin     ierr    = PetscInfo(snes,"Failed to converged, function norm is NaN\n");CHKERRQ(ierr);
7403f149594SLisandro Dalcin     *reason = SNES_DIVERGED_FNORM_NAN;
7413f149594SLisandro Dalcin   } else if (it == snes->max_its) {
7423f149594SLisandro Dalcin     *reason = SNES_CONVERGED_ITS;
7433f149594SLisandro Dalcin   }
7443f149594SLisandro Dalcin   PetscFunctionReturn(0);
7453f149594SLisandro Dalcin }
7463f149594SLisandro Dalcin 
74758c9b817SLisandro Dalcin #undef __FUNCT__
748fa0ddf94SBarry Smith #define __FUNCT__ "SNESSetWorkVecs"
7498d359177SBarry Smith /*@C
750fa0ddf94SBarry Smith   SNESSetWorkVecs - Gets a number of work vectors.
75158c9b817SLisandro Dalcin 
75258c9b817SLisandro Dalcin   Input Parameters:
75358c9b817SLisandro Dalcin . snes  - the SNES context
75458c9b817SLisandro Dalcin . nw - number of work vectors to allocate
75558c9b817SLisandro Dalcin 
75658c9b817SLisandro Dalcin    Level: developer
75758c9b817SLisandro Dalcin 
758fa0ddf94SBarry Smith    Developers Note: This is PETSC_EXTERN because it may be used by user written plugin SNES implementations
759fa0ddf94SBarry Smith 
76098acb6afSMatthew G Knepley @*/
761fa0ddf94SBarry Smith PetscErrorCode SNESSetWorkVecs(SNES snes,PetscInt nw)
76258c9b817SLisandro Dalcin {
763c5ed8070SMatthew G. Knepley   DM             dm;
764c5ed8070SMatthew G. Knepley   Vec            v;
76558c9b817SLisandro Dalcin   PetscErrorCode ierr;
76658c9b817SLisandro Dalcin 
76758c9b817SLisandro Dalcin   PetscFunctionBegin;
76858c9b817SLisandro Dalcin   if (snes->work) {ierr = VecDestroyVecs(snes->nwork,&snes->work);CHKERRQ(ierr);}
76958c9b817SLisandro Dalcin   snes->nwork = nw;
770f5af7f23SKarl Rupp 
771c5ed8070SMatthew G. Knepley   ierr = SNESGetDM(snes, &dm);CHKERRQ(ierr);
772c5ed8070SMatthew G. Knepley   ierr = DMGetGlobalVector(dm, &v);CHKERRQ(ierr);
773c5ed8070SMatthew G. Knepley   ierr = VecDuplicateVecs(v,snes->nwork,&snes->work);CHKERRQ(ierr);
774c5ed8070SMatthew G. Knepley   ierr = DMRestoreGlobalVector(dm, &v);CHKERRQ(ierr);
77558c9b817SLisandro Dalcin   ierr = PetscLogObjectParents(snes,nw,snes->work);CHKERRQ(ierr);
77658c9b817SLisandro Dalcin   PetscFunctionReturn(0);
77758c9b817SLisandro Dalcin }
778