xref: /petsc/src/snes/interface/snesut.c (revision f55353a2a7c46e5e81f955495d9d64b6042b9555)
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
18*f55353a2SBarry 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;
333f1db9ecSBarry Smith   ierr = SNESGetSolution(snes,&x);CHKERRQ(ierr);
343f1db9ecSBarry Smith   ierr = VecView(x,viewer);CHKERRQ(ierr);
353f1db9ecSBarry Smith   PetscFunctionReturn(0);
363f1db9ecSBarry Smith }
373f1db9ecSBarry Smith 
384a2ae208SSatish Balay #undef __FUNCT__
39a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorResidual"
405ed2d596SBarry Smith /*@C
41a6570f20SBarry Smith    SNESMonitorResidual - Monitors progress of the SNES solvers by calling
425ed2d596SBarry Smith    VecView() for the residual at each iteration.
435ed2d596SBarry Smith 
445ed2d596SBarry Smith    Collective on SNES
455ed2d596SBarry Smith 
465ed2d596SBarry Smith    Input Parameters:
475ed2d596SBarry Smith +  snes - the SNES context
485ed2d596SBarry Smith .  its - iteration number
494b27c08aSLois Curfman McInnes .  fgnorm - 2-norm of residual
50*f55353a2SBarry Smith -  dummy -  a viewer
515ed2d596SBarry Smith 
525ed2d596SBarry Smith    Level: intermediate
535ed2d596SBarry Smith 
545ed2d596SBarry Smith .keywords: SNES, nonlinear, vector, monitor, view
555ed2d596SBarry Smith 
56a6570f20SBarry Smith .seealso: SNESMonitorSet(), SNESMonitorDefault(), VecView()
575ed2d596SBarry Smith @*/
587087cfbeSBarry Smith PetscErrorCode  SNESMonitorResidual(SNES snes,PetscInt its,PetscReal fgnorm,void *dummy)
595ed2d596SBarry Smith {
60dfbe8321SBarry Smith   PetscErrorCode ierr;
615ed2d596SBarry Smith   Vec            x;
625ed2d596SBarry Smith   PetscViewer    viewer = (PetscViewer) dummy;
635ed2d596SBarry Smith 
645ed2d596SBarry Smith   PetscFunctionBegin;
655ed2d596SBarry Smith   ierr = SNESGetFunction(snes,&x,0,0);CHKERRQ(ierr);
665ed2d596SBarry Smith   ierr = VecView(x,viewer);CHKERRQ(ierr);
675ed2d596SBarry Smith   PetscFunctionReturn(0);
685ed2d596SBarry Smith }
695ed2d596SBarry Smith 
705ed2d596SBarry Smith #undef __FUNCT__
71a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorSolutionUpdate"
72d132466eSBarry Smith /*@C
73a6570f20SBarry Smith    SNESMonitorSolutionUpdate - Monitors progress of the SNES solvers by calling
74d132466eSBarry Smith    VecView() for the UPDATE to the solution at each iteration.
75d132466eSBarry Smith 
76d132466eSBarry Smith    Collective on SNES
77d132466eSBarry Smith 
78d132466eSBarry Smith    Input Parameters:
79d132466eSBarry Smith +  snes - the SNES context
80d132466eSBarry Smith .  its - iteration number
814b27c08aSLois Curfman McInnes .  fgnorm - 2-norm of residual
82*f55353a2SBarry Smith -  dummy - a viewer
83d132466eSBarry Smith 
84d132466eSBarry Smith    Level: intermediate
85d132466eSBarry Smith 
86d132466eSBarry Smith .keywords: SNES, nonlinear, vector, monitor, view
87d132466eSBarry Smith 
88a6570f20SBarry Smith .seealso: SNESMonitorSet(), SNESMonitorDefault(), VecView()
89d132466eSBarry Smith @*/
907087cfbeSBarry Smith PetscErrorCode  SNESMonitorSolutionUpdate(SNES snes,PetscInt its,PetscReal fgnorm,void *dummy)
91d132466eSBarry Smith {
92dfbe8321SBarry Smith   PetscErrorCode ierr;
93d132466eSBarry Smith   Vec            x;
94b0a32e0cSBarry Smith   PetscViewer    viewer = (PetscViewer) dummy;
95d132466eSBarry Smith 
96d132466eSBarry Smith   PetscFunctionBegin;
97d132466eSBarry Smith   ierr = SNESGetSolutionUpdate(snes,&x);CHKERRQ(ierr);
98d132466eSBarry Smith   ierr = VecView(x,viewer);CHKERRQ(ierr);
99d132466eSBarry Smith   PetscFunctionReturn(0);
100d132466eSBarry Smith }
101d132466eSBarry Smith 
1024a2ae208SSatish Balay #undef __FUNCT__
103a5c2985bSBarry Smith #define __FUNCT__ "KSPMonitorSNES"
104a5c2985bSBarry Smith /*@C
105a5c2985bSBarry Smith    KSPMonitorSNES - Print the residual norm of the nonlinear function at each iteration of the linear iterative solver.
106a5c2985bSBarry Smith 
107a5c2985bSBarry Smith    Collective on KSP
108a5c2985bSBarry Smith 
109a5c2985bSBarry Smith    Input Parameters:
110a5c2985bSBarry Smith +  ksp   - iterative context
111a5c2985bSBarry Smith .  n     - iteration number
112a5c2985bSBarry Smith .  rnorm - 2-norm (preconditioned) residual value (may be estimated).
113a5c2985bSBarry Smith -  dummy - unused monitor context
114a5c2985bSBarry Smith 
115a5c2985bSBarry Smith    Level: intermediate
116a5c2985bSBarry Smith 
117a5c2985bSBarry Smith .keywords: KSP, default, monitor, residual
118a5c2985bSBarry Smith 
119a5c2985bSBarry Smith .seealso: KSPMonitorSet(), KSPMonitorTrueResidualNorm(), KSPMonitorLGResidualNormCreate()
120a5c2985bSBarry Smith @*/
121a5c2985bSBarry Smith PetscErrorCode  KSPMonitorSNES(KSP ksp,PetscInt n,PetscReal rnorm,void *dummy)
122a5c2985bSBarry Smith {
123a5c2985bSBarry Smith   PetscErrorCode ierr;
124a5c2985bSBarry Smith   PetscViewer    viewer;
125a5c2985bSBarry Smith   SNES           snes = (SNES) dummy;
126a5c2985bSBarry Smith   Vec            snes_solution,work1,work2;
127a5c2985bSBarry Smith   PetscReal      snorm;
128a5c2985bSBarry Smith 
129a5c2985bSBarry Smith   PetscFunctionBegin;
130a5c2985bSBarry Smith   ierr = SNESGetSolution(snes,&snes_solution);CHKERRQ(ierr);
131a5c2985bSBarry Smith   ierr = VecDuplicate(snes_solution,&work1);CHKERRQ(ierr);
132a5c2985bSBarry Smith   ierr = VecDuplicate(snes_solution,&work2);CHKERRQ(ierr);
133a5c2985bSBarry Smith   ierr = KSPBuildSolution(ksp,work1,NULL);CHKERRQ(ierr);
134a5c2985bSBarry Smith   ierr = VecAYPX(work1,-1.0,snes_solution);CHKERRQ(ierr);
135a5c2985bSBarry Smith   ierr = SNESComputeFunction(snes,work1,work2);CHKERRQ(ierr);
136a5c2985bSBarry Smith   ierr = VecNorm(work2,NORM_2,&snorm);CHKERRQ(ierr);
137a5c2985bSBarry Smith   ierr = VecDestroy(&work1);CHKERRQ(ierr);
138a5c2985bSBarry Smith   ierr = VecDestroy(&work2);CHKERRQ(ierr);
139a5c2985bSBarry Smith 
140a5c2985bSBarry Smith   ierr = PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)ksp),&viewer);CHKERRQ(ierr);
141a5c2985bSBarry Smith   ierr = PetscViewerASCIIAddTab(viewer,((PetscObject)ksp)->tablevel);CHKERRQ(ierr);
142a5c2985bSBarry Smith   if (n == 0 && ((PetscObject)ksp)->prefix) {
143a5c2985bSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  Residual norms for %s solve.\n",((PetscObject)ksp)->prefix);CHKERRQ(ierr);
144a5c2985bSBarry Smith   }
145a5c2985bSBarry Smith   ierr = PetscViewerASCIIPrintf(viewer,"%3D SNES Residual norm %5.3e KSP Residual norm %5.3e \n",n,(double)snorm,(double)rnorm);CHKERRQ(ierr);
146a5c2985bSBarry Smith   ierr = PetscViewerASCIISubtractTab(viewer,((PetscObject)ksp)->tablevel);CHKERRQ(ierr);
147a5c2985bSBarry Smith   PetscFunctionReturn(0);
148a5c2985bSBarry Smith }
149a5c2985bSBarry Smith 
150e5f7ee39SBarry Smith #include <petscdraw.h>
151e5f7ee39SBarry Smith 
152e5f7ee39SBarry Smith #undef __FUNCT__
153e5f7ee39SBarry Smith #define __FUNCT__ "KSPMonitorSNESLGResidualNormCreate"
154e5f7ee39SBarry Smith /*@C
155e5f7ee39SBarry Smith    KSPMonitorSNESLGResidualNormCreate - Creates a line graph context for use with
156e5f7ee39SBarry Smith    KSP to monitor convergence of preconditioned residual norms.
157e5f7ee39SBarry Smith 
158e5f7ee39SBarry Smith    Collective on KSP
159e5f7ee39SBarry Smith 
160e5f7ee39SBarry Smith    Input Parameters:
161e5f7ee39SBarry Smith +  host - the X display to open, or null for the local machine
162e5f7ee39SBarry Smith .  label - the title to put in the title bar
163e5f7ee39SBarry Smith .  x, y - the screen coordinates of the upper left coordinate of
164e5f7ee39SBarry Smith           the window
165e5f7ee39SBarry Smith -  m, n - the screen width and height in pixels
166e5f7ee39SBarry Smith 
167e5f7ee39SBarry Smith    Output Parameter:
168e5f7ee39SBarry Smith .  draw - the drawing context
169e5f7ee39SBarry Smith 
170e5f7ee39SBarry Smith    Options Database Key:
171e5f7ee39SBarry Smith .  -ksp_monitor_lg_residualnorm - Sets line graph monitor
172e5f7ee39SBarry Smith 
173e5f7ee39SBarry Smith    Notes:
174e5f7ee39SBarry Smith    Use KSPMonitorSNESLGResidualNormDestroy() to destroy this line graph; do not use PetscDrawLGDestroy().
175e5f7ee39SBarry Smith 
176e5f7ee39SBarry Smith    Level: intermediate
177e5f7ee39SBarry Smith 
178e5f7ee39SBarry Smith .keywords: KSP, monitor, line graph, residual, create
179e5f7ee39SBarry Smith 
180e5f7ee39SBarry Smith .seealso: KSPMonitorSNESLGResidualNormDestroy(), KSPMonitorSet(), KSPMonitorSNESLGTrueResidualCreate()
181e5f7ee39SBarry Smith @*/
182e5f7ee39SBarry Smith PetscErrorCode  KSPMonitorSNESLGResidualNormCreate(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;
187e5f7ee39SBarry Smith   PetscDrawLG    drawlg;
188e5f7ee39SBarry Smith   const char     *names[] = {"Linear residual","Nonlinear residual"};
189e5f7ee39SBarry Smith 
190e5f7ee39SBarry Smith   PetscFunctionBegin;
191e5f7ee39SBarry Smith   ierr = PetscDrawCreate(PETSC_COMM_SELF,host,label,x,y,m,n,&draw);CHKERRQ(ierr);
192e5f7ee39SBarry Smith   ierr = PetscDrawSetFromOptions(draw);CHKERRQ(ierr);
193e5f7ee39SBarry Smith   ierr = PetscDrawLGCreate(draw,2,&drawlg);CHKERRQ(ierr);
194957f8de3SLisandro Dalcin   ierr = PetscDrawLGSetFromOptions(drawlg);CHKERRQ(ierr);
195e5f7ee39SBarry Smith   ierr = PetscDrawLGGetAxis(drawlg,&axis);CHKERRQ(ierr);
196e5f7ee39SBarry Smith   ierr = PetscDrawAxisSetLabels(axis,"Convergence of Residual Norm","Iteration","Residual Norm");CHKERRQ(ierr);
197e5f7ee39SBarry Smith   ierr = PetscDrawLGSetLegend(drawlg,names);CHKERRQ(ierr);
198e5f7ee39SBarry Smith   ierr = PetscLogObjectParent((PetscObject)drawlg,(PetscObject)draw);CHKERRQ(ierr);
199e5f7ee39SBarry Smith 
200435c5a64SBarry Smith   ierr = PetscMalloc1(3,objs);CHKERRQ(ierr);
201e5f7ee39SBarry Smith   (*objs)[1] = (PetscObject)drawlg;
202435c5a64SBarry Smith   (*objs)[2] = (PetscObject)draw;
203e5f7ee39SBarry Smith   PetscFunctionReturn(0);
204e5f7ee39SBarry Smith }
205e5f7ee39SBarry Smith 
206e5f7ee39SBarry Smith #undef __FUNCT__
207e5f7ee39SBarry Smith #define __FUNCT__ "KSPMonitorSNESLGResidualNorm"
208e5f7ee39SBarry Smith PetscErrorCode  KSPMonitorSNESLGResidualNorm(KSP ksp,PetscInt n,PetscReal rnorm,PetscObject *objs)
209e5f7ee39SBarry Smith {
210e5f7ee39SBarry Smith   PetscDrawLG    lg = (PetscDrawLG) objs[1];
211e5f7ee39SBarry Smith   PetscErrorCode ierr;
212e5f7ee39SBarry Smith   PetscReal      y[2];
213e5f7ee39SBarry Smith   SNES           snes = (SNES) objs[0];
214e5f7ee39SBarry Smith   Vec            snes_solution,work1,work2;
215e5f7ee39SBarry Smith 
216e5f7ee39SBarry Smith   PetscFunctionBegin;
217e5f7ee39SBarry Smith   if (rnorm > 0.0) y[0] = PetscLog10Real(rnorm);
218e5f7ee39SBarry Smith   else y[0] = -15.0;
219e5f7ee39SBarry Smith 
220e5f7ee39SBarry Smith   ierr = SNESGetSolution(snes,&snes_solution);CHKERRQ(ierr);
221e5f7ee39SBarry Smith   ierr = VecDuplicate(snes_solution,&work1);CHKERRQ(ierr);
222e5f7ee39SBarry Smith   ierr = VecDuplicate(snes_solution,&work2);CHKERRQ(ierr);
223e5f7ee39SBarry Smith   ierr = KSPBuildSolution(ksp,work1,NULL);CHKERRQ(ierr);
224e5f7ee39SBarry Smith   ierr = VecAYPX(work1,-1.0,snes_solution);CHKERRQ(ierr);
225e5f7ee39SBarry Smith   ierr = SNESComputeFunction(snes,work1,work2);CHKERRQ(ierr);
226e5f7ee39SBarry Smith   ierr = VecNorm(work2,NORM_2,y+1);CHKERRQ(ierr);
227e5f7ee39SBarry Smith   if (y[1] > 0.0) y[1] = PetscLog10Real(y[1]);
228e5f7ee39SBarry Smith   else y[1] = -15.0;
229e5f7ee39SBarry Smith   ierr = VecDestroy(&work1);CHKERRQ(ierr);
230e5f7ee39SBarry Smith   ierr = VecDestroy(&work2);CHKERRQ(ierr);
231e5f7ee39SBarry Smith 
232e5f7ee39SBarry Smith   ierr = PetscDrawLGAddPoint(lg,NULL,y);CHKERRQ(ierr);
233e5f7ee39SBarry Smith   if (n < 20 || !(n % 5)) {
234e5f7ee39SBarry Smith     ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr);
235e5f7ee39SBarry Smith   }
236e5f7ee39SBarry Smith   PetscFunctionReturn(0);
237e5f7ee39SBarry Smith }
238e5f7ee39SBarry Smith 
239e5f7ee39SBarry Smith #undef __FUNCT__
240e5f7ee39SBarry Smith #define __FUNCT__ "KSPMonitorSNESLGResidualNormDestroy"
241e5f7ee39SBarry Smith /*@
242e5f7ee39SBarry Smith    KSPMonitorSNESLGResidualNormDestroy - Destroys a line graph context that was created
243e5f7ee39SBarry Smith    with KSPMonitorSNESLGResidualNormCreate().
244e5f7ee39SBarry Smith 
245e5f7ee39SBarry Smith    Collective on KSP
246e5f7ee39SBarry Smith 
247e5f7ee39SBarry Smith    Input Parameter:
248e5f7ee39SBarry Smith .  draw - the drawing context
249e5f7ee39SBarry Smith 
250e5f7ee39SBarry Smith    Level: intermediate
251e5f7ee39SBarry Smith 
252e5f7ee39SBarry Smith .keywords: KSP, monitor, line graph, destroy
253e5f7ee39SBarry Smith 
254e5f7ee39SBarry Smith .seealso: KSPMonitorSNESLGResidualNormCreate(), KSPMonitorSNESLGTrueResidualDestroy(), KSPMonitorSet()
255e5f7ee39SBarry Smith @*/
256e5f7ee39SBarry Smith PetscErrorCode  KSPMonitorSNESLGResidualNormDestroy(PetscObject **objs)
257e5f7ee39SBarry Smith {
258e5f7ee39SBarry Smith   PetscErrorCode ierr;
259e5f7ee39SBarry Smith   PetscDrawLG    drawlg = (PetscDrawLG) (*objs)[1];
260435c5a64SBarry Smith   PetscDraw      draw = (PetscDraw) (*objs)[2];
261e5f7ee39SBarry Smith 
262e5f7ee39SBarry Smith   PetscFunctionBegin;
263e5f7ee39SBarry Smith   ierr = PetscDrawDestroy(&draw);CHKERRQ(ierr);
264e5f7ee39SBarry Smith   ierr = PetscDrawLGDestroy(&drawlg);CHKERRQ(ierr);
265e5f7ee39SBarry Smith   ierr = PetscFree(*objs);CHKERRQ(ierr);
266e5f7ee39SBarry Smith   PetscFunctionReturn(0);
267e5f7ee39SBarry Smith }
268e5f7ee39SBarry Smith 
269a5c2985bSBarry Smith #undef __FUNCT__
270a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorDefault"
2714b828684SBarry Smith /*@C
272a6570f20SBarry Smith    SNESMonitorDefault - Monitors progress of the SNES solvers (default).
273e7e93795SLois Curfman McInnes 
274c7afd0dbSLois Curfman McInnes    Collective on SNES
275c7afd0dbSLois Curfman McInnes 
276e7e93795SLois Curfman McInnes    Input Parameters:
277c7afd0dbSLois Curfman McInnes +  snes - the SNES context
278e7e93795SLois Curfman McInnes .  its - iteration number
2794b27c08aSLois Curfman McInnes .  fgnorm - 2-norm of residual
280c7afd0dbSLois Curfman McInnes -  dummy - unused context
281fee21e36SBarry Smith 
282e7e93795SLois Curfman McInnes    Notes:
2834b27c08aSLois Curfman McInnes    This routine prints the residual norm at each iteration.
284e7e93795SLois Curfman McInnes 
28536851e7fSLois Curfman McInnes    Level: intermediate
28636851e7fSLois Curfman McInnes 
287e7e93795SLois Curfman McInnes .keywords: SNES, nonlinear, default, monitor, norm
288e7e93795SLois Curfman McInnes 
289a6570f20SBarry Smith .seealso: SNESMonitorSet(), SNESMonitorSolution()
290e7e93795SLois Curfman McInnes @*/
2917087cfbeSBarry Smith PetscErrorCode  SNESMonitorDefault(SNES snes,PetscInt its,PetscReal fgnorm,void *dummy)
292e7e93795SLois Curfman McInnes {
293dfbe8321SBarry Smith   PetscErrorCode ierr;
294ce94432eSBarry Smith   PetscViewer    viewer = dummy ? (PetscViewer) dummy : PETSC_VIEWER_STDOUT_(PetscObjectComm((PetscObject)snes));
295d132466eSBarry Smith 
2963a40ed3dSBarry Smith   PetscFunctionBegin;
297649052a6SBarry Smith   ierr = PetscViewerASCIIAddTab(viewer,((PetscObject)snes)->tablevel);CHKERRQ(ierr);
298649052a6SBarry Smith   ierr = PetscViewerASCIIPrintf(viewer,"%3D SNES Function norm %14.12e \n",its,(double)fgnorm);CHKERRQ(ierr);
299649052a6SBarry Smith   ierr = PetscViewerASCIISubtractTab(viewer,((PetscObject)snes)->tablevel);CHKERRQ(ierr);
3003a40ed3dSBarry Smith   PetscFunctionReturn(0);
301e7e93795SLois Curfman McInnes }
3023f1db9ecSBarry Smith 
303b271bb04SBarry Smith #undef __FUNCT__
3042e7541e6SPeter Brune #define __FUNCT__ "SNESMonitorJacUpdateSpectrum"
305a80ad3e0SBarry Smith PetscErrorCode SNESMonitorJacUpdateSpectrum(SNES snes,PetscInt it,PetscReal fnorm,void *ctx)
306a80ad3e0SBarry Smith {
307196da8b6SPeter Brune #if defined(PETSC_MISSING_LAPACK_GEEV)
308ce94432eSBarry Smith   SETERRQ(PetscObjectComm((PetscObject)snes),PETSC_ERR_SUP,"GEEV - Lapack routine is unavailable\nNot able to provide eigen values.");
309196da8b6SPeter Brune #elif defined(PETSC_HAVE_ESSL)
310ce94432eSBarry Smith   SETERRQ(PetscObjectComm((PetscObject)snes),PETSC_ERR_SUP,"GEEV - No support for ESSL Lapack Routines");
311196da8b6SPeter Brune #else
3122e7541e6SPeter Brune   Vec            X;
3132e7541e6SPeter Brune   Mat            J,dJ,dJdense;
3142e7541e6SPeter Brune   PetscErrorCode ierr;
315d1e9a80fSBarry Smith   PetscErrorCode (*func)(SNES,Vec,Mat,Mat,void*);
3162e7541e6SPeter Brune   PetscInt       n,i;
3172e7541e6SPeter Brune   PetscBLASInt   nb,lwork;
3182e7541e6SPeter Brune   PetscReal      *eigr,*eigi;
3192e7541e6SPeter Brune   PetscScalar    *work;
3202e7541e6SPeter Brune   PetscScalar    *a;
3212e7541e6SPeter Brune 
3222e7541e6SPeter Brune   PetscFunctionBegin;
3232e7541e6SPeter Brune   if (it == 0) PetscFunctionReturn(0);
3242e7541e6SPeter Brune   /* create the difference between the current update and the current jacobian */
3252e7541e6SPeter Brune   ierr = SNESGetSolution(snes,&X);CHKERRQ(ierr);
326d1e9a80fSBarry Smith   ierr = SNESGetJacobian(snes,NULL,&J,&func,NULL);CHKERRQ(ierr);
3272e7541e6SPeter Brune   ierr = MatDuplicate(J,MAT_COPY_VALUES,&dJ);CHKERRQ(ierr);
328d1e9a80fSBarry Smith   ierr = SNESComputeJacobian(snes,X,dJ,dJ);CHKERRQ(ierr);
3292e7541e6SPeter Brune   ierr = MatAXPY(dJ,-1.0,J,SAME_NONZERO_PATTERN);CHKERRQ(ierr);
330f5af7f23SKarl Rupp 
3312e7541e6SPeter Brune   /* compute the spectrum directly */
3322e7541e6SPeter Brune   ierr  = MatConvert(dJ,MATSEQDENSE,MAT_INITIAL_MATRIX,&dJdense);CHKERRQ(ierr);
3330298fd71SBarry Smith   ierr  = MatGetSize(dJ,&n,NULL);CHKERRQ(ierr);
334c5df96a5SBarry Smith   ierr  = PetscBLASIntCast(n,&nb);CHKERRQ(ierr);
3352e7541e6SPeter Brune   lwork = 3*nb;
336785e854fSJed Brown   ierr  = PetscMalloc1(n,&eigr);CHKERRQ(ierr);
337785e854fSJed Brown   ierr  = PetscMalloc1(n,&eigi);CHKERRQ(ierr);
338785e854fSJed Brown   ierr  = PetscMalloc1(lwork,&work);CHKERRQ(ierr);
3398c778c55SBarry Smith   ierr  = MatDenseGetArray(dJdense,&a);CHKERRQ(ierr);
3402e7541e6SPeter Brune #if !defined(PETSC_USE_COMPLEX)
3412e7541e6SPeter Brune   {
3422e7541e6SPeter Brune     PetscBLASInt lierr;
3432e7541e6SPeter Brune     ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
3448b83055fSJed Brown     PetscStackCallBLAS("LAPACKgeev",LAPACKgeev_("N","N",&nb,a,&nb,eigr,eigi,NULL,&nb,NULL,&nb,work,&lwork,&lierr));
3452e7541e6SPeter Brune     if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"geev() error %d",lierr);
3462e7541e6SPeter Brune     ierr = PetscFPTrapPop();CHKERRQ(ierr);
3472e7541e6SPeter Brune   }
3482e7541e6SPeter Brune #else
3492e7541e6SPeter Brune   SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not coded for complex");
3502e7541e6SPeter Brune #endif
351ce94432eSBarry Smith   PetscPrintf(PetscObjectComm((PetscObject)snes),"Eigenvalues of J_%d - J_%d:\n",it,it-1);CHKERRQ(ierr);
3522e7541e6SPeter Brune   for (i=0;i<n;i++) {
3538fa295daSBarry Smith     PetscPrintf(PetscObjectComm((PetscObject)snes),"%5d: %20.5g + %20.5gi\n",i,(double)eigr[i],(double)eigi[i]);CHKERRQ(ierr);
3542e7541e6SPeter Brune   }
3558c778c55SBarry Smith   ierr = MatDenseRestoreArray(dJdense,&a);CHKERRQ(ierr);
3562e7541e6SPeter Brune   ierr = MatDestroy(&dJ);CHKERRQ(ierr);
3572e7541e6SPeter Brune   ierr = MatDestroy(&dJdense);CHKERRQ(ierr);
3582e7541e6SPeter Brune   ierr = PetscFree(eigr);CHKERRQ(ierr);
3592e7541e6SPeter Brune   ierr = PetscFree(eigi);CHKERRQ(ierr);
3602e7541e6SPeter Brune   ierr = PetscFree(work);CHKERRQ(ierr);
3612e7541e6SPeter Brune   PetscFunctionReturn(0);
362196da8b6SPeter Brune #endif
3632e7541e6SPeter Brune }
3642e7541e6SPeter Brune 
3652e7541e6SPeter Brune #undef __FUNCT__
366b271bb04SBarry Smith #define __FUNCT__ "SNESMonitorRange_Private"
3677087cfbeSBarry Smith PetscErrorCode  SNESMonitorRange_Private(SNES snes,PetscInt it,PetscReal *per)
368b271bb04SBarry Smith {
369b271bb04SBarry Smith   PetscErrorCode ierr;
370b271bb04SBarry Smith   Vec            resid;
371b271bb04SBarry Smith   PetscReal      rmax,pwork;
372b271bb04SBarry Smith   PetscInt       i,n,N;
373b271bb04SBarry Smith   PetscScalar    *r;
374b271bb04SBarry Smith 
375b271bb04SBarry Smith   PetscFunctionBegin;
376b271bb04SBarry Smith   ierr  = SNESGetFunction(snes,&resid,0,0);CHKERRQ(ierr);
377b271bb04SBarry Smith   ierr  = VecNorm(resid,NORM_INFINITY,&rmax);CHKERRQ(ierr);
378b271bb04SBarry Smith   ierr  = VecGetLocalSize(resid,&n);CHKERRQ(ierr);
379b271bb04SBarry Smith   ierr  = VecGetSize(resid,&N);CHKERRQ(ierr);
380b271bb04SBarry Smith   ierr  = VecGetArray(resid,&r);CHKERRQ(ierr);
381b271bb04SBarry Smith   pwork = 0.0;
382b271bb04SBarry Smith   for (i=0; i<n; i++) {
383b271bb04SBarry Smith     pwork += (PetscAbsScalar(r[i]) > .20*rmax);
384b271bb04SBarry Smith   }
385ce94432eSBarry Smith   ierr = MPI_Allreduce(&pwork,per,1,MPIU_REAL,MPIU_SUM,PetscObjectComm((PetscObject)snes));CHKERRQ(ierr);
386b271bb04SBarry Smith   ierr = VecRestoreArray(resid,&r);CHKERRQ(ierr);
387b271bb04SBarry Smith   *per = *per/N;
388b271bb04SBarry Smith   PetscFunctionReturn(0);
389b271bb04SBarry Smith }
390b271bb04SBarry Smith 
391b271bb04SBarry Smith #undef __FUNCT__
392b271bb04SBarry Smith #define __FUNCT__ "SNESMonitorRange"
393b271bb04SBarry Smith /*@C
394b271bb04SBarry Smith    SNESMonitorRange - Prints the percentage of residual elements that are more then 10 percent of the maximum value.
395b271bb04SBarry Smith 
396b271bb04SBarry Smith    Collective on SNES
397b271bb04SBarry Smith 
398b271bb04SBarry Smith    Input Parameters:
399b271bb04SBarry Smith +  snes   - iterative context
400b271bb04SBarry Smith .  it    - iteration number
401b271bb04SBarry Smith .  rnorm - 2-norm (preconditioned) residual value (may be estimated).
402b271bb04SBarry Smith -  dummy - unused monitor context
403b271bb04SBarry Smith 
404b271bb04SBarry Smith    Options Database Key:
405b271bb04SBarry Smith .  -snes_monitor_range - Activates SNESMonitorRange()
406b271bb04SBarry Smith 
407b271bb04SBarry Smith    Level: intermediate
408b271bb04SBarry Smith 
409b271bb04SBarry Smith .keywords: SNES, default, monitor, residual
410b271bb04SBarry Smith 
411b271bb04SBarry Smith .seealso: SNESMonitorSet(), SNESMonitorDefault(), SNESMonitorLGCreate()
412b271bb04SBarry Smith @*/
4137087cfbeSBarry Smith PetscErrorCode  SNESMonitorRange(SNES snes,PetscInt it,PetscReal rnorm,void *dummy)
414b271bb04SBarry Smith {
415b271bb04SBarry Smith   PetscErrorCode ierr;
416b271bb04SBarry Smith   PetscReal      perc,rel;
417ce94432eSBarry Smith   PetscViewer    viewer = dummy ? (PetscViewer) dummy : PETSC_VIEWER_STDOUT_(PetscObjectComm((PetscObject)snes));
418b271bb04SBarry Smith   /* should be in a MonitorRangeContext */
419b271bb04SBarry Smith   static PetscReal prev;
420b271bb04SBarry Smith 
421b271bb04SBarry Smith   PetscFunctionBegin;
422b271bb04SBarry Smith   if (!it) prev = rnorm;
423b271bb04SBarry Smith   ierr = SNESMonitorRange_Private(snes,it,&perc);CHKERRQ(ierr);
424b271bb04SBarry Smith 
425b271bb04SBarry Smith   rel  = (prev - rnorm)/prev;
426b271bb04SBarry Smith   prev = rnorm;
427649052a6SBarry Smith   ierr = PetscViewerASCIIAddTab(viewer,((PetscObject)snes)->tablevel);CHKERRQ(ierr);
4286712e2f1SBarry 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);
429649052a6SBarry Smith   ierr = PetscViewerASCIISubtractTab(viewer,((PetscObject)snes)->tablevel);CHKERRQ(ierr);
430b271bb04SBarry Smith   PetscFunctionReturn(0);
431b271bb04SBarry Smith }
432b271bb04SBarry Smith 
433eabae89aSBarry Smith typedef struct {
434649052a6SBarry Smith   PetscViewer viewer;
435eabae89aSBarry Smith   PetscReal   *history;
436a6570f20SBarry Smith } SNESMonitorRatioContext;
437eabae89aSBarry Smith 
4383a7fca6bSBarry Smith #undef __FUNCT__
439a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorRatio"
4403a7fca6bSBarry Smith /*@C
441a6570f20SBarry Smith    SNESMonitorRatio - Monitors progress of the SNES solvers by printing the ratio
4424b27c08aSLois Curfman McInnes    of residual norm at each iteration to the previous.
4433a7fca6bSBarry Smith 
4443a7fca6bSBarry Smith    Collective on SNES
4453a7fca6bSBarry Smith 
4463a7fca6bSBarry Smith    Input Parameters:
4473a7fca6bSBarry Smith +  snes - the SNES context
4483a7fca6bSBarry Smith .  its - iteration number
4493a7fca6bSBarry Smith .  fgnorm - 2-norm of residual (or gradient)
450eabae89aSBarry Smith -  dummy -  context of monitor
4513a7fca6bSBarry Smith 
4523a7fca6bSBarry Smith    Level: intermediate
4533a7fca6bSBarry Smith 
4543a7fca6bSBarry Smith .keywords: SNES, nonlinear, monitor, norm
4553a7fca6bSBarry Smith 
456a6570f20SBarry Smith .seealso: SNESMonitorSet(), SNESMonitorSolution()
4573a7fca6bSBarry Smith @*/
4587087cfbeSBarry Smith PetscErrorCode  SNESMonitorRatio(SNES snes,PetscInt its,PetscReal fgnorm,void *dummy)
4593a7fca6bSBarry Smith {
460dfbe8321SBarry Smith   PetscErrorCode          ierr;
46177431f27SBarry Smith   PetscInt                len;
46287828ca2SBarry Smith   PetscReal               *history;
463a6570f20SBarry Smith   SNESMonitorRatioContext *ctx = (SNESMonitorRatioContext*)dummy;
4643a7fca6bSBarry Smith 
4653a7fca6bSBarry Smith   PetscFunctionBegin;
4660298fd71SBarry Smith   ierr = SNESGetConvergenceHistory(snes,&history,NULL,&len);CHKERRQ(ierr);
467649052a6SBarry Smith   ierr = PetscViewerASCIIAddTab(ctx->viewer,((PetscObject)snes)->tablevel);CHKERRQ(ierr);
468958c9bccSBarry Smith   if (!its || !history || its > len) {
469649052a6SBarry Smith     ierr = PetscViewerASCIIPrintf(ctx->viewer,"%3D SNES Function norm %14.12e \n",its,(double)fgnorm);CHKERRQ(ierr);
4703a7fca6bSBarry Smith   } else {
47187828ca2SBarry Smith     PetscReal ratio = fgnorm/history[its-1];
4728f1a2a5eSBarry Smith     ierr = PetscViewerASCIIPrintf(ctx->viewer,"%3D SNES Function norm %14.12e %14.12e \n",its,(double)fgnorm,(double)ratio);CHKERRQ(ierr);
4733a7fca6bSBarry Smith   }
474649052a6SBarry Smith   ierr = PetscViewerASCIISubtractTab(ctx->viewer,((PetscObject)snes)->tablevel);CHKERRQ(ierr);
4753a7fca6bSBarry Smith   PetscFunctionReturn(0);
4763a7fca6bSBarry Smith }
4773a7fca6bSBarry Smith 
4783a7fca6bSBarry Smith /*
4793a7fca6bSBarry Smith    If the we set the history monitor space then we must destroy it
4803a7fca6bSBarry Smith */
4813a7fca6bSBarry Smith #undef __FUNCT__
482a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorRatioDestroy"
483c2efdce3SBarry Smith PetscErrorCode SNESMonitorRatioDestroy(void **ct)
4843a7fca6bSBarry Smith {
485dfbe8321SBarry Smith   PetscErrorCode          ierr;
486c2efdce3SBarry Smith   SNESMonitorRatioContext *ctx = *(SNESMonitorRatioContext**)ct;
4873a7fca6bSBarry Smith 
4883a7fca6bSBarry Smith   PetscFunctionBegin;
48905b42c5fSBarry Smith   ierr = PetscFree(ctx->history);CHKERRQ(ierr);
490649052a6SBarry Smith   ierr = PetscViewerDestroy(&ctx->viewer);CHKERRQ(ierr);
491eabae89aSBarry Smith   ierr = PetscFree(ctx);CHKERRQ(ierr);
4923a7fca6bSBarry Smith   PetscFunctionReturn(0);
4933a7fca6bSBarry Smith }
4943a7fca6bSBarry Smith 
4953a7fca6bSBarry Smith #undef __FUNCT__
496a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorSetRatio"
4973a7fca6bSBarry Smith /*@C
498a6570f20SBarry Smith    SNESMonitorSetRatio - Sets SNES to use a monitor that prints the
4994b27c08aSLois Curfman McInnes    ratio of the function norm at each iteration.
5003a7fca6bSBarry Smith 
5013a7fca6bSBarry Smith    Collective on SNES
5023a7fca6bSBarry Smith 
5033a7fca6bSBarry Smith    Input Parameters:
504eabae89aSBarry Smith +   snes - the SNES context
505eabae89aSBarry Smith -   viewer - ASCII viewer to print output
5063a7fca6bSBarry Smith 
5073a7fca6bSBarry Smith    Level: intermediate
5083a7fca6bSBarry Smith 
5093a7fca6bSBarry Smith .keywords: SNES, nonlinear, monitor, norm
5103a7fca6bSBarry Smith 
511a6570f20SBarry Smith .seealso: SNESMonitorSet(), SNESMonitorSolution(), SNESMonitorDefault()
5123a7fca6bSBarry Smith @*/
513649052a6SBarry Smith PetscErrorCode  SNESMonitorSetRatio(SNES snes,PetscViewer viewer)
5143a7fca6bSBarry Smith {
515dfbe8321SBarry Smith   PetscErrorCode          ierr;
516a6570f20SBarry Smith   SNESMonitorRatioContext *ctx;
51787828ca2SBarry Smith   PetscReal               *history;
5183a7fca6bSBarry Smith 
5193a7fca6bSBarry Smith   PetscFunctionBegin;
520b00a9115SJed Brown   ierr = PetscNewLog(snes,&ctx);CHKERRQ(ierr);
5210298fd71SBarry Smith   ierr = SNESGetConvergenceHistory(snes,&history,NULL,NULL);CHKERRQ(ierr);
5223a7fca6bSBarry Smith   if (!history) {
523785e854fSJed Brown     ierr = PetscMalloc1(100,&ctx->history);CHKERRQ(ierr);
524eabae89aSBarry Smith     ierr = SNESSetConvergenceHistory(snes,ctx->history,0,100,PETSC_TRUE);CHKERRQ(ierr);
5253a7fca6bSBarry Smith   }
526eabae89aSBarry Smith   ctx->viewer = viewer;
527f5af7f23SKarl Rupp 
528a6570f20SBarry Smith   ierr = SNESMonitorSet(snes,SNESMonitorRatio,ctx,SNESMonitorRatioDestroy);CHKERRQ(ierr);
5293a7fca6bSBarry Smith   PetscFunctionReturn(0);
5303a7fca6bSBarry Smith }
5313a7fca6bSBarry Smith 
532e7e93795SLois Curfman McInnes /* ---------------------------------------------------------------- */
5334a2ae208SSatish Balay #undef __FUNCT__
534a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorDefaultShort"
535be1f7002SBarry Smith /*
536a6570f20SBarry Smith      Default (short) SNES Monitor, same as SNESMonitorDefault() except
537be1f7002SBarry Smith   it prints fewer digits of the residual as the residual gets smaller.
538be1f7002SBarry Smith   This is because the later digits are meaningless and are often
539be1f7002SBarry Smith   different on different machines; by using this routine different
540be1f7002SBarry Smith   machines will usually generate the same output.
541be1f7002SBarry Smith */
5427087cfbeSBarry Smith PetscErrorCode  SNESMonitorDefaultShort(SNES snes,PetscInt its,PetscReal fgnorm,void *dummy)
543e7e93795SLois Curfman McInnes {
544dfbe8321SBarry Smith   PetscErrorCode ierr;
545ce94432eSBarry Smith   PetscViewer    viewer = dummy ? (PetscViewer) dummy : PETSC_VIEWER_STDOUT_(PetscObjectComm((PetscObject)snes));
546d132466eSBarry Smith 
5473a40ed3dSBarry Smith   PetscFunctionBegin;
548649052a6SBarry Smith   ierr = PetscViewerASCIIAddTab(viewer,((PetscObject)snes)->tablevel);CHKERRQ(ierr);
5498f240d10SBarry Smith   if (fgnorm > 1.e-9) {
5508fa295daSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"%3D SNES Function norm %g \n",its,(double)fgnorm);CHKERRQ(ierr);
5513a40ed3dSBarry Smith   } else if (fgnorm > 1.e-11) {
5528fa295daSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"%3D SNES Function norm %5.3e \n",its,(double)fgnorm);CHKERRQ(ierr);
5533a40ed3dSBarry Smith   } else {
554649052a6SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"%3D SNES Function norm < 1.e-11\n",its);CHKERRQ(ierr);
555a34d58ebSBarry Smith   }
556649052a6SBarry Smith   ierr = PetscViewerASCIISubtractTab(viewer,((PetscObject)snes)->tablevel);CHKERRQ(ierr);
5573a40ed3dSBarry Smith   PetscFunctionReturn(0);
558e7e93795SLois Curfman McInnes }
5592db13446SMatthew G. Knepley 
5602db13446SMatthew G. Knepley #undef __FUNCT__
5612db13446SMatthew G. Knepley #define __FUNCT__ "SNESMonitorDefaultField"
5622db13446SMatthew G. Knepley /*@C
5632db13446SMatthew G. Knepley   SNESMonitorDefaultField - Monitors progress of the SNES solvers, separated into fields.
5642db13446SMatthew G. Knepley 
5652db13446SMatthew G. Knepley   Collective on SNES
5662db13446SMatthew G. Knepley 
5672db13446SMatthew G. Knepley   Input Parameters:
5682db13446SMatthew G. Knepley + snes   - the SNES context
5692db13446SMatthew G. Knepley . its    - iteration number
5702db13446SMatthew G. Knepley . fgnorm - 2-norm of residual
5712db13446SMatthew G. Knepley - ctx    - the PetscViewer
5722db13446SMatthew G. Knepley 
5732db13446SMatthew G. Knepley   Notes:
5742db13446SMatthew G. Knepley   This routine uses the DM attached to the residual vector
5752db13446SMatthew G. Knepley 
5762db13446SMatthew G. Knepley   Level: intermediate
5772db13446SMatthew G. Knepley 
5782db13446SMatthew G. Knepley .keywords: SNES, nonlinear, field, monitor, norm
5792db13446SMatthew G. Knepley .seealso: SNESMonitorSet(), SNESMonitorSolution(), SNESMonitorDefault(), SNESMonitorDefaultShort()
5802db13446SMatthew G. Knepley @*/
5812db13446SMatthew G. Knepley PetscErrorCode SNESMonitorDefaultField(SNES snes, PetscInt its, PetscReal fgnorm, void *ctx)
5822db13446SMatthew G. Knepley {
5832db13446SMatthew G. Knepley   PetscViewer    viewer = ctx ? (PetscViewer) ctx : PETSC_VIEWER_STDOUT_(PetscObjectComm((PetscObject) snes));
5842db13446SMatthew G. Knepley   Vec            r;
5852db13446SMatthew G. Knepley   DM             dm;
5862db13446SMatthew G. Knepley   PetscReal      res[256];
5872db13446SMatthew G. Knepley   PetscInt       tablevel;
5882db13446SMatthew G. Knepley   PetscErrorCode ierr;
5892db13446SMatthew G. Knepley 
5902db13446SMatthew G. Knepley   PetscFunctionBegin;
5912db13446SMatthew G. Knepley   ierr = SNESGetFunction(snes, &r, NULL, NULL);CHKERRQ(ierr);
5922db13446SMatthew G. Knepley   ierr = VecGetDM(r, &dm);CHKERRQ(ierr);
5932db13446SMatthew G. Knepley   if (!dm) {ierr = SNESMonitorDefault(snes, its, fgnorm, ctx);CHKERRQ(ierr);}
5942db13446SMatthew G. Knepley   else {
5952db13446SMatthew G. Knepley     PetscSection s, gs;
5962db13446SMatthew G. Knepley     PetscInt     Nf, f;
5972db13446SMatthew G. Knepley 
5982db13446SMatthew G. Knepley     ierr = DMGetDefaultSection(dm, &s);CHKERRQ(ierr);
5992db13446SMatthew G. Knepley     ierr = DMGetDefaultGlobalSection(dm, &gs);CHKERRQ(ierr);
6002db13446SMatthew G. Knepley     if (!s || !gs) {ierr = SNESMonitorDefault(snes, its, fgnorm, ctx);CHKERRQ(ierr);}
6012db13446SMatthew G. Knepley     ierr = PetscSectionGetNumFields(s, &Nf);CHKERRQ(ierr);
6022db13446SMatthew G. Knepley     if (Nf > 256) SETERRQ1(PetscObjectComm((PetscObject) snes), PETSC_ERR_SUP, "Do not support %d fields > 256", Nf);
6032db13446SMatthew G. Knepley     ierr = PetscSectionVecNorm(s, gs, r, NORM_2, res);CHKERRQ(ierr);
6042db13446SMatthew G. Knepley     ierr = PetscObjectGetTabLevel((PetscObject) snes, &tablevel);CHKERRQ(ierr);
6052db13446SMatthew G. Knepley     ierr = PetscViewerASCIIAddTab(viewer, tablevel);CHKERRQ(ierr);
6062db13446SMatthew G. Knepley     ierr = PetscViewerASCIIPrintf(viewer, "%3D SNES Function norm %14.12e [", its, (double) fgnorm);CHKERRQ(ierr);
6072db13446SMatthew G. Knepley     for (f = 0; f < Nf; ++f) {
6082db13446SMatthew G. Knepley       if (f) {ierr = PetscViewerASCIIPrintf(viewer, ", ");CHKERRQ(ierr);}
6092db13446SMatthew G. Knepley       ierr = PetscViewerASCIIPrintf(viewer, "%14.12e", res[f]);CHKERRQ(ierr);
6102db13446SMatthew G. Knepley     }
6112db13446SMatthew G. Knepley     ierr = PetscViewerASCIIPrintf(viewer, "] \n");CHKERRQ(ierr);
6122db13446SMatthew G. Knepley     ierr = PetscViewerASCIISubtractTab(viewer, tablevel);CHKERRQ(ierr);
6132db13446SMatthew G. Knepley   }
6142db13446SMatthew G. Knepley   PetscFunctionReturn(0);
6152db13446SMatthew G. Knepley }
616e7e93795SLois Curfman McInnes /* ---------------------------------------------------------------- */
6174a2ae208SSatish Balay #undef __FUNCT__
6188d359177SBarry Smith #define __FUNCT__ "SNESConvergedDefault"
6194b828684SBarry Smith /*@C
6208d359177SBarry Smith    SNESConvergedDefault - Convergence test of the solvers for
621f525115eSLois Curfman McInnes    systems of nonlinear equations (default).
622e7e93795SLois Curfman McInnes 
623c7afd0dbSLois Curfman McInnes    Collective on SNES
624c7afd0dbSLois Curfman McInnes 
625e7e93795SLois Curfman McInnes    Input Parameters:
626c7afd0dbSLois Curfman McInnes +  snes - the SNES context
62706ee9f85SBarry Smith .  it - the iteration (0 indicates before any Newton steps)
628e7e93795SLois Curfman McInnes .  xnorm - 2-norm of current iterate
629c60f73f4SPeter Brune .  snorm - 2-norm of current step
6307f3332b4SBarry Smith .  fnorm - 2-norm of function at current iterate
631c7afd0dbSLois Curfman McInnes -  dummy - unused context
632e7e93795SLois Curfman McInnes 
633184914b5SBarry Smith    Output Parameter:
634184914b5SBarry Smith .   reason  - one of
63570441072SBarry Smith $  SNES_CONVERGED_FNORM_ABS       - (fnorm < abstol),
636c60f73f4SPeter Brune $  SNES_CONVERGED_SNORM_RELATIVE  - (snorm < stol*xnorm),
637184914b5SBarry Smith $  SNES_CONVERGED_FNORM_RELATIVE  - (fnorm < rtol*fnorm0),
638184914b5SBarry Smith $  SNES_DIVERGED_FUNCTION_COUNT   - (nfct > maxf),
639184914b5SBarry Smith $  SNES_DIVERGED_FNORM_NAN        - (fnorm == NaN),
640184914b5SBarry Smith $  SNES_CONVERGED_ITERATING       - (otherwise),
641e7e93795SLois Curfman McInnes 
642e7e93795SLois Curfman McInnes    where
643c7afd0dbSLois Curfman McInnes +    maxf - maximum number of function evaluations,
644c7afd0dbSLois Curfman McInnes             set with SNESSetTolerances()
645c7afd0dbSLois Curfman McInnes .    nfct - number of function evaluations,
64670441072SBarry Smith .    abstol - absolute function norm tolerance,
647c7afd0dbSLois Curfman McInnes             set with SNESSetTolerances()
648c7afd0dbSLois Curfman McInnes -    rtol - relative function norm tolerance, set with SNESSetTolerances()
649fee21e36SBarry Smith 
65036851e7fSLois Curfman McInnes    Level: intermediate
65136851e7fSLois Curfman McInnes 
652e7e93795SLois Curfman McInnes .keywords: SNES, nonlinear, default, converged, convergence
653e7e93795SLois Curfman McInnes 
65471f87433Sdalcinl .seealso: SNESSetConvergenceTest()
655e7e93795SLois Curfman McInnes @*/
6568d359177SBarry Smith PetscErrorCode  SNESConvergedDefault(SNES snes,PetscInt it,PetscReal xnorm,PetscReal snorm,PetscReal fnorm,SNESConvergedReason *reason,void *dummy)
657e7e93795SLois Curfman McInnes {
65863ba0a88SBarry Smith   PetscErrorCode ierr;
65963ba0a88SBarry Smith 
6603a40ed3dSBarry Smith   PetscFunctionBegin;
6610700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
6623f149594SLisandro Dalcin   PetscValidPointer(reason,6);
6633f149594SLisandro Dalcin 
66406ee9f85SBarry Smith   *reason = SNES_CONVERGED_ITERATING;
66506ee9f85SBarry Smith 
66606ee9f85SBarry Smith   if (!it) {
66706ee9f85SBarry Smith     /* set parameter for default relative tolerance convergence test */
66806ee9f85SBarry Smith     snes->ttol = fnorm*snes->rtol;
66906ee9f85SBarry Smith   }
6708146f6ebSBarry Smith   if (PetscIsInfOrNanReal(fnorm)) {
671ae15b995SBarry Smith     ierr    = PetscInfo(snes,"Failed to converged, function norm is NaN\n");CHKERRQ(ierr);
672184914b5SBarry Smith     *reason = SNES_DIVERGED_FNORM_NAN;
67370441072SBarry Smith   } else if (fnorm < snes->abstol) {
6748f1a2a5eSBarry Smith     ierr    = PetscInfo2(snes,"Converged due to function norm %14.12e < %14.12e\n",(double)fnorm,(double)snes->abstol);CHKERRQ(ierr);
675184914b5SBarry Smith     *reason = SNES_CONVERGED_FNORM_ABS;
67643e71028SBarry Smith   } else if (snes->nfuncs >= snes->max_funcs) {
677ae15b995SBarry Smith     ierr    = PetscInfo2(snes,"Exceeded maximum number of function evaluations: %D > %D\n",snes->nfuncs,snes->max_funcs);CHKERRQ(ierr);
678184914b5SBarry Smith     *reason = SNES_DIVERGED_FUNCTION_COUNT;
67906ee9f85SBarry Smith   }
68006ee9f85SBarry Smith 
68106ee9f85SBarry Smith   if (it && !*reason) {
68206ee9f85SBarry Smith     if (fnorm <= snes->ttol) {
6838f1a2a5eSBarry Smith       ierr    = PetscInfo2(snes,"Converged due to function norm %14.12e < %14.12e (relative tolerance)\n",(double)fnorm,(double)snes->ttol);CHKERRQ(ierr);
68406ee9f85SBarry Smith       *reason = SNES_CONVERGED_FNORM_RELATIVE;
685c60f73f4SPeter Brune     } else if (snorm < snes->stol*xnorm) {
686c60f73f4SPeter 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);
687c60f73f4SPeter Brune       *reason = SNES_CONVERGED_SNORM_RELATIVE;
68806ee9f85SBarry Smith     }
689e7e93795SLois Curfman McInnes   }
6903a40ed3dSBarry Smith   PetscFunctionReturn(0);
691e7e93795SLois Curfman McInnes }
6923f149594SLisandro Dalcin 
6933f149594SLisandro Dalcin #undef __FUNCT__
694e2a6519dSDmitry Karpeev #define __FUNCT__ "SNESConvergedSkip"
6953f149594SLisandro Dalcin /*@C
696e2a6519dSDmitry Karpeev    SNESConvergedSkip - Convergence test for SNES that NEVER returns as
6973f149594SLisandro Dalcin    converged, UNLESS the maximum number of iteration have been reached.
6983f149594SLisandro Dalcin 
6993f9fe445SBarry Smith    Logically Collective on SNES
7003f149594SLisandro Dalcin 
7013f149594SLisandro Dalcin    Input Parameters:
7023f149594SLisandro Dalcin +  snes - the SNES context
7033f149594SLisandro Dalcin .  it - the iteration (0 indicates before any Newton steps)
7043f149594SLisandro Dalcin .  xnorm - 2-norm of current iterate
705c60f73f4SPeter Brune .  snorm - 2-norm of current step
7063f149594SLisandro Dalcin .  fnorm - 2-norm of function at current iterate
7073f149594SLisandro Dalcin -  dummy - unused context
7083f149594SLisandro Dalcin 
7093f149594SLisandro Dalcin    Output Parameter:
71085385478SLisandro Dalcin .   reason  - SNES_CONVERGED_ITERATING, SNES_CONVERGED_ITS, or SNES_DIVERGED_FNORM_NAN
7113f149594SLisandro Dalcin 
7123f149594SLisandro Dalcin    Notes:
7133f149594SLisandro Dalcin    Convergence is then declared after a fixed number of iterations have been used.
7143f149594SLisandro Dalcin 
7153f149594SLisandro Dalcin    Level: advanced
7163f149594SLisandro Dalcin 
7173f149594SLisandro Dalcin .keywords: SNES, nonlinear, skip, converged, convergence
7183f149594SLisandro Dalcin 
7193f149594SLisandro Dalcin .seealso: SNESSetConvergenceTest()
7203f149594SLisandro Dalcin @*/
721e2a6519dSDmitry Karpeev PetscErrorCode  SNESConvergedSkip(SNES snes,PetscInt it,PetscReal xnorm,PetscReal snorm,PetscReal fnorm,SNESConvergedReason *reason,void *dummy)
7223f149594SLisandro Dalcin {
7233f149594SLisandro Dalcin   PetscErrorCode ierr;
7243f149594SLisandro Dalcin 
7253f149594SLisandro Dalcin   PetscFunctionBegin;
7260700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
7273f149594SLisandro Dalcin   PetscValidPointer(reason,6);
7283f149594SLisandro Dalcin 
7293f149594SLisandro Dalcin   *reason = SNES_CONVERGED_ITERATING;
7303f149594SLisandro Dalcin 
7313f149594SLisandro Dalcin   if (fnorm != fnorm) {
7323f149594SLisandro Dalcin     ierr    = PetscInfo(snes,"Failed to converged, function norm is NaN\n");CHKERRQ(ierr);
7333f149594SLisandro Dalcin     *reason = SNES_DIVERGED_FNORM_NAN;
7343f149594SLisandro Dalcin   } else if (it == snes->max_its) {
7353f149594SLisandro Dalcin     *reason = SNES_CONVERGED_ITS;
7363f149594SLisandro Dalcin   }
7373f149594SLisandro Dalcin   PetscFunctionReturn(0);
7383f149594SLisandro Dalcin }
7393f149594SLisandro Dalcin 
74058c9b817SLisandro Dalcin #undef __FUNCT__
741fa0ddf94SBarry Smith #define __FUNCT__ "SNESSetWorkVecs"
7428d359177SBarry Smith /*@C
743fa0ddf94SBarry Smith   SNESSetWorkVecs - Gets a number of work vectors.
74458c9b817SLisandro Dalcin 
74558c9b817SLisandro Dalcin   Input Parameters:
74658c9b817SLisandro Dalcin . snes  - the SNES context
74758c9b817SLisandro Dalcin . nw - number of work vectors to allocate
74858c9b817SLisandro Dalcin 
74958c9b817SLisandro Dalcin    Level: developer
75058c9b817SLisandro Dalcin 
751fa0ddf94SBarry Smith    Developers Note: This is PETSC_EXTERN because it may be used by user written plugin SNES implementations
752fa0ddf94SBarry Smith 
75398acb6afSMatthew G Knepley @*/
754fa0ddf94SBarry Smith PetscErrorCode SNESSetWorkVecs(SNES snes,PetscInt nw)
75558c9b817SLisandro Dalcin {
756c5ed8070SMatthew G. Knepley   DM             dm;
757c5ed8070SMatthew G. Knepley   Vec            v;
75858c9b817SLisandro Dalcin   PetscErrorCode ierr;
75958c9b817SLisandro Dalcin 
76058c9b817SLisandro Dalcin   PetscFunctionBegin;
76158c9b817SLisandro Dalcin   if (snes->work) {ierr = VecDestroyVecs(snes->nwork,&snes->work);CHKERRQ(ierr);}
76258c9b817SLisandro Dalcin   snes->nwork = nw;
763f5af7f23SKarl Rupp 
764c5ed8070SMatthew G. Knepley   ierr = SNESGetDM(snes, &dm);CHKERRQ(ierr);
765c5ed8070SMatthew G. Knepley   ierr = DMGetGlobalVector(dm, &v);CHKERRQ(ierr);
766c5ed8070SMatthew G. Knepley   ierr = VecDuplicateVecs(v,snes->nwork,&snes->work);CHKERRQ(ierr);
767c5ed8070SMatthew G. Knepley   ierr = DMRestoreGlobalVector(dm, &v);CHKERRQ(ierr);
76858c9b817SLisandro Dalcin   ierr = PetscLogObjectParents(snes,nw,snes->work);CHKERRQ(ierr);
76958c9b817SLisandro Dalcin   PetscFunctionReturn(0);
77058c9b817SLisandro Dalcin }
771