xref: /petsc/src/snes/interface/snesut.c (revision 6ba87a44a064cbbd9ffa5c81465925d2cbaeb66a)
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;
334d4332d5SBarry 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;
664d4332d5SBarry 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;
994d4332d5SBarry 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:
1648b0b5a47SLisandro Dalcin +  comm - communicator context
1658b0b5a47SLisandro Dalcin .  host - the X display to open, or null for the local machine
166e5f7ee39SBarry Smith .  label - the title to put in the title bar
167e5f7ee39SBarry Smith .  x, y - the screen coordinates of the upper left coordinate of
168e5f7ee39SBarry Smith           the window
169e5f7ee39SBarry Smith -  m, n - the screen width and height in pixels
170e5f7ee39SBarry Smith 
171e5f7ee39SBarry Smith    Output Parameter:
172e5f7ee39SBarry Smith .  draw - the drawing context
173e5f7ee39SBarry Smith 
174e5f7ee39SBarry Smith    Options Database Key:
175e5f7ee39SBarry Smith .  -ksp_monitor_lg_residualnorm - Sets line graph monitor
176e5f7ee39SBarry Smith 
177e5f7ee39SBarry Smith    Notes:
178e5f7ee39SBarry Smith    Use KSPMonitorSNESLGResidualNormDestroy() to destroy this line graph; do not use PetscDrawLGDestroy().
179e5f7ee39SBarry Smith 
180e5f7ee39SBarry Smith    Level: intermediate
181e5f7ee39SBarry Smith 
182e5f7ee39SBarry Smith .keywords: KSP, monitor, line graph, residual, create
183e5f7ee39SBarry Smith 
184e5f7ee39SBarry Smith .seealso: KSPMonitorSNESLGResidualNormDestroy(), KSPMonitorSet(), KSPMonitorSNESLGTrueResidualCreate()
185e5f7ee39SBarry Smith @*/
1868b0b5a47SLisandro Dalcin PetscErrorCode  KSPMonitorSNESLGResidualNormCreate(MPI_Comm comm,const char host[],const char label[],int x,int y,int m,int n,PetscObject **objs)
187e5f7ee39SBarry Smith {
188e5f7ee39SBarry Smith   PetscDraw      draw;
189e5f7ee39SBarry Smith   PetscErrorCode ierr;
190e5f7ee39SBarry Smith   PetscDrawAxis  axis;
191c36cb520SLisandro Dalcin   PetscDrawLG    lg;
192e5f7ee39SBarry Smith   const char     *names[] = {"Linear residual","Nonlinear residual"};
193e5f7ee39SBarry Smith 
194e5f7ee39SBarry Smith   PetscFunctionBegin;
1958b0b5a47SLisandro Dalcin   ierr = PetscDrawCreate(comm,host,label,x,y,m,n,&draw);CHKERRQ(ierr);
196e5f7ee39SBarry Smith   ierr = PetscDrawSetFromOptions(draw);CHKERRQ(ierr);
197c36cb520SLisandro Dalcin   ierr = PetscDrawLGCreate(draw,2,&lg);CHKERRQ(ierr);
198c36cb520SLisandro Dalcin   ierr = PetscDrawLGSetLegend(lg,names);CHKERRQ(ierr);
199c36cb520SLisandro Dalcin   ierr = PetscDrawLGSetFromOptions(lg);CHKERRQ(ierr);
200c36cb520SLisandro Dalcin   ierr = PetscDrawLGGetAxis(lg,&axis);CHKERRQ(ierr);
201e5f7ee39SBarry Smith   ierr = PetscDrawAxisSetLabels(axis,"Convergence of Residual Norm","Iteration","Residual Norm");CHKERRQ(ierr);
202c36cb520SLisandro Dalcin   ierr = PetscDrawDestroy(&draw);CHKERRQ(ierr);
203e5f7ee39SBarry Smith 
204c36cb520SLisandro Dalcin   ierr = PetscMalloc1(2,objs);CHKERRQ(ierr);
205c36cb520SLisandro Dalcin   (*objs)[1] = (PetscObject)lg;
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 {
213c36cb520SLisandro Dalcin   SNES           snes = (SNES) objs[0];
214e5f7ee39SBarry Smith   PetscDrawLG    lg   = (PetscDrawLG) objs[1];
215e5f7ee39SBarry Smith   PetscErrorCode ierr;
216e5f7ee39SBarry Smith   PetscReal      y[2];
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);
2366934998bSLisandro Dalcin   if (n < 20 || !(n % 5) || snes->reason) {
237e5f7ee39SBarry Smith     ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr);
2386934998bSLisandro Dalcin     ierr = PetscDrawLGSave(lg);CHKERRQ(ierr);
239e5f7ee39SBarry Smith   }
240e5f7ee39SBarry Smith   PetscFunctionReturn(0);
241e5f7ee39SBarry Smith }
242e5f7ee39SBarry Smith 
243e5f7ee39SBarry Smith #undef __FUNCT__
244e5f7ee39SBarry Smith #define __FUNCT__ "KSPMonitorSNESLGResidualNormDestroy"
245e5f7ee39SBarry Smith /*@
246e5f7ee39SBarry Smith    KSPMonitorSNESLGResidualNormDestroy - Destroys a line graph context that was created
247e5f7ee39SBarry Smith    with KSPMonitorSNESLGResidualNormCreate().
248e5f7ee39SBarry Smith 
249e5f7ee39SBarry Smith    Collective on KSP
250e5f7ee39SBarry Smith 
251e5f7ee39SBarry Smith    Input Parameter:
252e5f7ee39SBarry Smith .  draw - the drawing context
253e5f7ee39SBarry Smith 
254e5f7ee39SBarry Smith    Level: intermediate
255e5f7ee39SBarry Smith 
256e5f7ee39SBarry Smith .keywords: KSP, monitor, line graph, destroy
257e5f7ee39SBarry Smith 
258e5f7ee39SBarry Smith .seealso: KSPMonitorSNESLGResidualNormCreate(), KSPMonitorSNESLGTrueResidualDestroy(), KSPMonitorSet()
259e5f7ee39SBarry Smith @*/
260e5f7ee39SBarry Smith PetscErrorCode  KSPMonitorSNESLGResidualNormDestroy(PetscObject **objs)
261e5f7ee39SBarry Smith {
262e5f7ee39SBarry Smith   PetscErrorCode ierr;
263c36cb520SLisandro Dalcin   PetscDrawLG    lg = (PetscDrawLG) (*objs)[1];
264e5f7ee39SBarry Smith 
265e5f7ee39SBarry Smith   PetscFunctionBegin;
266c36cb520SLisandro Dalcin   ierr = PetscDrawLGDestroy(&lg);CHKERRQ(ierr);
267e5f7ee39SBarry Smith   ierr = PetscFree(*objs);CHKERRQ(ierr);
268e5f7ee39SBarry Smith   PetscFunctionReturn(0);
269e5f7ee39SBarry Smith }
270e5f7ee39SBarry Smith 
271a5c2985bSBarry Smith #undef __FUNCT__
272a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorDefault"
2734b828684SBarry Smith /*@C
274a6570f20SBarry Smith    SNESMonitorDefault - Monitors progress of the SNES solvers (default).
275e7e93795SLois Curfman McInnes 
276c7afd0dbSLois Curfman McInnes    Collective on SNES
277c7afd0dbSLois Curfman McInnes 
278e7e93795SLois Curfman McInnes    Input Parameters:
279c7afd0dbSLois Curfman McInnes +  snes - the SNES context
280e7e93795SLois Curfman McInnes .  its - iteration number
2814b27c08aSLois Curfman McInnes .  fgnorm - 2-norm of residual
282c7afd0dbSLois Curfman McInnes -  dummy - unused context
283fee21e36SBarry Smith 
284e7e93795SLois Curfman McInnes    Notes:
2854b27c08aSLois Curfman McInnes    This routine prints the residual norm at each iteration.
286e7e93795SLois Curfman McInnes 
28736851e7fSLois Curfman McInnes    Level: intermediate
28836851e7fSLois Curfman McInnes 
289e7e93795SLois Curfman McInnes .keywords: SNES, nonlinear, default, monitor, norm
290e7e93795SLois Curfman McInnes 
291a6570f20SBarry Smith .seealso: SNESMonitorSet(), SNESMonitorSolution()
292e7e93795SLois Curfman McInnes @*/
2937087cfbeSBarry Smith PetscErrorCode  SNESMonitorDefault(SNES snes,PetscInt its,PetscReal fgnorm,void *dummy)
294e7e93795SLois Curfman McInnes {
295dfbe8321SBarry Smith   PetscErrorCode ierr;
2964d4332d5SBarry Smith   PetscViewer    viewer = (PetscViewer) dummy;
297d132466eSBarry Smith 
2983a40ed3dSBarry Smith   PetscFunctionBegin;
2994d4332d5SBarry Smith   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,4);
300649052a6SBarry Smith   ierr = PetscViewerASCIIAddTab(viewer,((PetscObject)snes)->tablevel);CHKERRQ(ierr);
301649052a6SBarry Smith   ierr = PetscViewerASCIIPrintf(viewer,"%3D SNES Function norm %14.12e \n",its,(double)fgnorm);CHKERRQ(ierr);
302649052a6SBarry Smith   ierr = PetscViewerASCIISubtractTab(viewer,((PetscObject)snes)->tablevel);CHKERRQ(ierr);
3033a40ed3dSBarry Smith   PetscFunctionReturn(0);
304e7e93795SLois Curfman McInnes }
3053f1db9ecSBarry Smith 
306b271bb04SBarry Smith #undef __FUNCT__
3072e7541e6SPeter Brune #define __FUNCT__ "SNESMonitorJacUpdateSpectrum"
308a80ad3e0SBarry Smith PetscErrorCode SNESMonitorJacUpdateSpectrum(SNES snes,PetscInt it,PetscReal fnorm,void *ctx)
309a80ad3e0SBarry Smith {
310196da8b6SPeter Brune #if defined(PETSC_MISSING_LAPACK_GEEV)
311ce94432eSBarry Smith   SETERRQ(PetscObjectComm((PetscObject)snes),PETSC_ERR_SUP,"GEEV - Lapack routine is unavailable\nNot able to provide eigen values.");
312196da8b6SPeter Brune #elif defined(PETSC_HAVE_ESSL)
313ce94432eSBarry Smith   SETERRQ(PetscObjectComm((PetscObject)snes),PETSC_ERR_SUP,"GEEV - No support for ESSL Lapack Routines");
314196da8b6SPeter Brune #else
3152e7541e6SPeter Brune   Vec            X;
3162e7541e6SPeter Brune   Mat            J,dJ,dJdense;
3172e7541e6SPeter Brune   PetscErrorCode ierr;
318d1e9a80fSBarry Smith   PetscErrorCode (*func)(SNES,Vec,Mat,Mat,void*);
3192e7541e6SPeter Brune   PetscInt       n,i;
3202e7541e6SPeter Brune   PetscBLASInt   nb,lwork;
3212e7541e6SPeter Brune   PetscReal      *eigr,*eigi;
3222e7541e6SPeter Brune   PetscScalar    *work;
3232e7541e6SPeter Brune   PetscScalar    *a;
3242e7541e6SPeter Brune 
3252e7541e6SPeter Brune   PetscFunctionBegin;
3262e7541e6SPeter Brune   if (it == 0) PetscFunctionReturn(0);
3272e7541e6SPeter Brune   /* create the difference between the current update and the current jacobian */
3282e7541e6SPeter Brune   ierr = SNESGetSolution(snes,&X);CHKERRQ(ierr);
329d1e9a80fSBarry Smith   ierr = SNESGetJacobian(snes,NULL,&J,&func,NULL);CHKERRQ(ierr);
3302e7541e6SPeter Brune   ierr = MatDuplicate(J,MAT_COPY_VALUES,&dJ);CHKERRQ(ierr);
331d1e9a80fSBarry Smith   ierr = SNESComputeJacobian(snes,X,dJ,dJ);CHKERRQ(ierr);
3322e7541e6SPeter Brune   ierr = MatAXPY(dJ,-1.0,J,SAME_NONZERO_PATTERN);CHKERRQ(ierr);
333f5af7f23SKarl Rupp 
3342e7541e6SPeter Brune   /* compute the spectrum directly */
3352e7541e6SPeter Brune   ierr  = MatConvert(dJ,MATSEQDENSE,MAT_INITIAL_MATRIX,&dJdense);CHKERRQ(ierr);
3360298fd71SBarry Smith   ierr  = MatGetSize(dJ,&n,NULL);CHKERRQ(ierr);
337c5df96a5SBarry Smith   ierr  = PetscBLASIntCast(n,&nb);CHKERRQ(ierr);
3382e7541e6SPeter Brune   lwork = 3*nb;
339785e854fSJed Brown   ierr  = PetscMalloc1(n,&eigr);CHKERRQ(ierr);
340785e854fSJed Brown   ierr  = PetscMalloc1(n,&eigi);CHKERRQ(ierr);
341785e854fSJed Brown   ierr  = PetscMalloc1(lwork,&work);CHKERRQ(ierr);
3428c778c55SBarry Smith   ierr  = MatDenseGetArray(dJdense,&a);CHKERRQ(ierr);
3432e7541e6SPeter Brune #if !defined(PETSC_USE_COMPLEX)
3442e7541e6SPeter Brune   {
3452e7541e6SPeter Brune     PetscBLASInt lierr;
3462e7541e6SPeter Brune     ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
3478b83055fSJed Brown     PetscStackCallBLAS("LAPACKgeev",LAPACKgeev_("N","N",&nb,a,&nb,eigr,eigi,NULL,&nb,NULL,&nb,work,&lwork,&lierr));
3482e7541e6SPeter Brune     if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"geev() error %d",lierr);
3492e7541e6SPeter Brune     ierr = PetscFPTrapPop();CHKERRQ(ierr);
3502e7541e6SPeter Brune   }
3512e7541e6SPeter Brune #else
3522e7541e6SPeter Brune   SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not coded for complex");
3532e7541e6SPeter Brune #endif
354fde5950dSBarry Smith   ierr = PetscPrintf(PetscObjectComm((PetscObject)snes),"Eigenvalues of J_%d - J_%d:\n",it,it-1);CHKERRQ(ierr);
3552e7541e6SPeter Brune   for (i=0;i<n;i++) {
356fde5950dSBarry Smith     ierr = PetscPrintf(PetscObjectComm((PetscObject)snes),"%5d: %20.5g + %20.5gi\n",i,(double)eigr[i],(double)eigi[i]);CHKERRQ(ierr);
3572e7541e6SPeter Brune   }
3588c778c55SBarry Smith   ierr = MatDenseRestoreArray(dJdense,&a);CHKERRQ(ierr);
3592e7541e6SPeter Brune   ierr = MatDestroy(&dJ);CHKERRQ(ierr);
3602e7541e6SPeter Brune   ierr = MatDestroy(&dJdense);CHKERRQ(ierr);
3612e7541e6SPeter Brune   ierr = PetscFree(eigr);CHKERRQ(ierr);
3622e7541e6SPeter Brune   ierr = PetscFree(eigi);CHKERRQ(ierr);
3632e7541e6SPeter Brune   ierr = PetscFree(work);CHKERRQ(ierr);
3642e7541e6SPeter Brune   PetscFunctionReturn(0);
365196da8b6SPeter Brune #endif
3662e7541e6SPeter Brune }
3672e7541e6SPeter Brune 
368*6ba87a44SLisandro Dalcin PETSC_INTERN PetscErrorCode  SNESMonitorRange_Private(SNES,PetscInt,PetscReal*);
369*6ba87a44SLisandro Dalcin 
3702e7541e6SPeter Brune #undef __FUNCT__
371b271bb04SBarry Smith #define __FUNCT__ "SNESMonitorRange_Private"
3727087cfbeSBarry Smith PetscErrorCode  SNESMonitorRange_Private(SNES snes,PetscInt it,PetscReal *per)
373b271bb04SBarry Smith {
374b271bb04SBarry Smith   PetscErrorCode ierr;
375b271bb04SBarry Smith   Vec            resid;
376b271bb04SBarry Smith   PetscReal      rmax,pwork;
377b271bb04SBarry Smith   PetscInt       i,n,N;
378b271bb04SBarry Smith   PetscScalar    *r;
379b271bb04SBarry Smith 
380b271bb04SBarry Smith   PetscFunctionBegin;
381b271bb04SBarry Smith   ierr  = SNESGetFunction(snes,&resid,0,0);CHKERRQ(ierr);
382b271bb04SBarry Smith   ierr  = VecNorm(resid,NORM_INFINITY,&rmax);CHKERRQ(ierr);
383b271bb04SBarry Smith   ierr  = VecGetLocalSize(resid,&n);CHKERRQ(ierr);
384b271bb04SBarry Smith   ierr  = VecGetSize(resid,&N);CHKERRQ(ierr);
385b271bb04SBarry Smith   ierr  = VecGetArray(resid,&r);CHKERRQ(ierr);
386b271bb04SBarry Smith   pwork = 0.0;
387b271bb04SBarry Smith   for (i=0; i<n; i++) {
388b271bb04SBarry Smith     pwork += (PetscAbsScalar(r[i]) > .20*rmax);
389b271bb04SBarry Smith   }
390b2566f29SBarry Smith   ierr = MPIU_Allreduce(&pwork,per,1,MPIU_REAL,MPIU_SUM,PetscObjectComm((PetscObject)snes));CHKERRQ(ierr);
391b271bb04SBarry Smith   ierr = VecRestoreArray(resid,&r);CHKERRQ(ierr);
392b271bb04SBarry Smith   *per = *per/N;
393b271bb04SBarry Smith   PetscFunctionReturn(0);
394b271bb04SBarry Smith }
395b271bb04SBarry Smith 
396b271bb04SBarry Smith #undef __FUNCT__
397b271bb04SBarry Smith #define __FUNCT__ "SNESMonitorRange"
398b271bb04SBarry Smith /*@C
399b271bb04SBarry Smith    SNESMonitorRange - Prints the percentage of residual elements that are more then 10 percent of the maximum value.
400b271bb04SBarry Smith 
401b271bb04SBarry Smith    Collective on SNES
402b271bb04SBarry Smith 
403b271bb04SBarry Smith    Input Parameters:
404b271bb04SBarry Smith +  snes   - iterative context
405b271bb04SBarry Smith .  it    - iteration number
406b271bb04SBarry Smith .  rnorm - 2-norm (preconditioned) residual value (may be estimated).
407b271bb04SBarry Smith -  dummy - unused monitor context
408b271bb04SBarry Smith 
409b271bb04SBarry Smith    Options Database Key:
410b271bb04SBarry Smith .  -snes_monitor_range - Activates SNESMonitorRange()
411b271bb04SBarry Smith 
412b271bb04SBarry Smith    Level: intermediate
413b271bb04SBarry Smith 
414b271bb04SBarry Smith .keywords: SNES, default, monitor, residual
415b271bb04SBarry Smith 
416b271bb04SBarry Smith .seealso: SNESMonitorSet(), SNESMonitorDefault(), SNESMonitorLGCreate()
417b271bb04SBarry Smith @*/
4187087cfbeSBarry Smith PetscErrorCode  SNESMonitorRange(SNES snes,PetscInt it,PetscReal rnorm,void *dummy)
419b271bb04SBarry Smith {
420b271bb04SBarry Smith   PetscErrorCode ierr;
421b271bb04SBarry Smith   PetscReal      perc,rel;
4224d4332d5SBarry Smith   PetscViewer    viewer = (PetscViewer) dummy;
423b271bb04SBarry Smith   /* should be in a MonitorRangeContext */
424b271bb04SBarry Smith   static PetscReal prev;
425b271bb04SBarry Smith 
426b271bb04SBarry Smith   PetscFunctionBegin;
4274d4332d5SBarry Smith   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,4);
428b271bb04SBarry Smith   if (!it) prev = rnorm;
429b271bb04SBarry Smith   ierr = SNESMonitorRange_Private(snes,it,&perc);CHKERRQ(ierr);
430b271bb04SBarry Smith 
431b271bb04SBarry Smith   rel  = (prev - rnorm)/prev;
432b271bb04SBarry Smith   prev = rnorm;
433649052a6SBarry Smith   ierr = PetscViewerASCIIAddTab(viewer,((PetscObject)snes)->tablevel);CHKERRQ(ierr);
4346712e2f1SBarry 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);
435649052a6SBarry Smith   ierr = PetscViewerASCIISubtractTab(viewer,((PetscObject)snes)->tablevel);CHKERRQ(ierr);
436b271bb04SBarry Smith   PetscFunctionReturn(0);
437b271bb04SBarry Smith }
438b271bb04SBarry Smith 
4393a7fca6bSBarry Smith #undef __FUNCT__
440a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorRatio"
4413a7fca6bSBarry Smith /*@C
442a6570f20SBarry Smith    SNESMonitorRatio - Monitors progress of the SNES solvers by printing the ratio
4434b27c08aSLois Curfman McInnes    of residual norm at each iteration to the previous.
4443a7fca6bSBarry Smith 
4453a7fca6bSBarry Smith    Collective on SNES
4463a7fca6bSBarry Smith 
4473a7fca6bSBarry Smith    Input Parameters:
4483a7fca6bSBarry Smith +  snes - the SNES context
4493a7fca6bSBarry Smith .  its - iteration number
4503a7fca6bSBarry Smith .  fgnorm - 2-norm of residual (or gradient)
451eabae89aSBarry Smith -  dummy -  context of monitor
4523a7fca6bSBarry Smith 
4533a7fca6bSBarry Smith    Level: intermediate
4543a7fca6bSBarry Smith 
455fde5950dSBarry Smith    Notes: Insure that SNESMonitorRatio() is called when you set this monitor
4563a7fca6bSBarry Smith .keywords: SNES, nonlinear, monitor, norm
4573a7fca6bSBarry Smith 
458fde5950dSBarry Smith .seealso: SNESMonitorSet(), SNESMonitorSolution(), SNESMonitorRatio()
4593a7fca6bSBarry Smith @*/
4607087cfbeSBarry Smith PetscErrorCode  SNESMonitorRatio(SNES snes,PetscInt its,PetscReal fgnorm,void *dummy)
4613a7fca6bSBarry Smith {
462dfbe8321SBarry Smith   PetscErrorCode          ierr;
46377431f27SBarry Smith   PetscInt                len;
46487828ca2SBarry Smith   PetscReal               *history;
465fde5950dSBarry Smith   PetscViewer             viewer = (PetscViewer) dummy;
4663a7fca6bSBarry Smith 
4673a7fca6bSBarry Smith   PetscFunctionBegin;
4680298fd71SBarry Smith   ierr = SNESGetConvergenceHistory(snes,&history,NULL,&len);CHKERRQ(ierr);
469fde5950dSBarry Smith   ierr = PetscViewerASCIIAddTab(viewer,((PetscObject)snes)->tablevel);CHKERRQ(ierr);
470958c9bccSBarry Smith   if (!its || !history || its > len) {
471fde5950dSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"%3D SNES Function norm %14.12e \n",its,(double)fgnorm);CHKERRQ(ierr);
4723a7fca6bSBarry Smith   } else {
47387828ca2SBarry Smith     PetscReal ratio = fgnorm/history[its-1];
474fde5950dSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"%3D SNES Function norm %14.12e %14.12e \n",its,(double)fgnorm,(double)ratio);CHKERRQ(ierr);
4753a7fca6bSBarry Smith   }
476fde5950dSBarry Smith   ierr = PetscViewerASCIISubtractTab(viewer,((PetscObject)snes)->tablevel);CHKERRQ(ierr);
4773a7fca6bSBarry Smith   PetscFunctionReturn(0);
4783a7fca6bSBarry Smith }
4793a7fca6bSBarry Smith 
4803a7fca6bSBarry Smith #undef __FUNCT__
481fde5950dSBarry Smith #define __FUNCT__ "SNESMonitorRatioSetUp"
4823a7fca6bSBarry Smith /*@C
483fde5950dSBarry Smith    SNESMonitorRatioSetUp - Insures the SNES object is saving its history since this monitor needs access to it
4843a7fca6bSBarry Smith 
4853a7fca6bSBarry Smith    Collective on SNES
4863a7fca6bSBarry Smith 
4873a7fca6bSBarry Smith    Input Parameters:
488eabae89aSBarry Smith +   snes - the SNES context
489fde5950dSBarry Smith -   viewer - the PetscViewer object (ignored)
4903a7fca6bSBarry Smith 
4913a7fca6bSBarry Smith    Level: intermediate
4923a7fca6bSBarry Smith 
4933a7fca6bSBarry Smith .keywords: SNES, nonlinear, monitor, norm
4943a7fca6bSBarry Smith 
495fde5950dSBarry Smith .seealso: SNESMonitorSet(), SNESMonitorSolution(), SNESMonitorDefault(), SNESMonitorRatio()
4963a7fca6bSBarry Smith @*/
497fde5950dSBarry Smith PetscErrorCode  SNESMonitorRatioSetUp(SNES snes,PetscViewer viewer)
4983a7fca6bSBarry Smith {
499dfbe8321SBarry Smith   PetscErrorCode          ierr;
50087828ca2SBarry Smith   PetscReal               *history;
5013a7fca6bSBarry Smith 
5023a7fca6bSBarry Smith   PetscFunctionBegin;
5030298fd71SBarry Smith   ierr = SNESGetConvergenceHistory(snes,&history,NULL,NULL);CHKERRQ(ierr);
5043a7fca6bSBarry Smith   if (!history) {
505fde5950dSBarry Smith     ierr = SNESSetConvergenceHistory(snes,NULL,NULL,100,PETSC_TRUE);CHKERRQ(ierr);
5063a7fca6bSBarry Smith   }
5073a7fca6bSBarry Smith   PetscFunctionReturn(0);
5083a7fca6bSBarry Smith }
5093a7fca6bSBarry Smith 
510e7e93795SLois Curfman McInnes /* ---------------------------------------------------------------- */
5114a2ae208SSatish Balay #undef __FUNCT__
512a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorDefaultShort"
513be1f7002SBarry Smith /*
514a6570f20SBarry Smith      Default (short) SNES Monitor, same as SNESMonitorDefault() except
515be1f7002SBarry Smith   it prints fewer digits of the residual as the residual gets smaller.
516be1f7002SBarry Smith   This is because the later digits are meaningless and are often
517be1f7002SBarry Smith   different on different machines; by using this routine different
518be1f7002SBarry Smith   machines will usually generate the same output.
519be1f7002SBarry Smith */
5207087cfbeSBarry Smith PetscErrorCode  SNESMonitorDefaultShort(SNES snes,PetscInt its,PetscReal fgnorm,void *dummy)
521e7e93795SLois Curfman McInnes {
522dfbe8321SBarry Smith   PetscErrorCode ierr;
5234d4332d5SBarry Smith   PetscViewer    viewer = (PetscViewer) dummy;
524d132466eSBarry Smith 
5253a40ed3dSBarry Smith   PetscFunctionBegin;
5264d4332d5SBarry Smith   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,4);
527649052a6SBarry Smith   ierr = PetscViewerASCIIAddTab(viewer,((PetscObject)snes)->tablevel);CHKERRQ(ierr);
5288f240d10SBarry Smith   if (fgnorm > 1.e-9) {
5298fa295daSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"%3D SNES Function norm %g \n",its,(double)fgnorm);CHKERRQ(ierr);
5303a40ed3dSBarry Smith   } else if (fgnorm > 1.e-11) {
5318fa295daSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"%3D SNES Function norm %5.3e \n",its,(double)fgnorm);CHKERRQ(ierr);
5323a40ed3dSBarry Smith   } else {
533649052a6SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"%3D SNES Function norm < 1.e-11\n",its);CHKERRQ(ierr);
534a34d58ebSBarry Smith   }
535649052a6SBarry Smith   ierr = PetscViewerASCIISubtractTab(viewer,((PetscObject)snes)->tablevel);CHKERRQ(ierr);
5363a40ed3dSBarry Smith   PetscFunctionReturn(0);
537e7e93795SLois Curfman McInnes }
5382db13446SMatthew G. Knepley 
5392db13446SMatthew G. Knepley #undef __FUNCT__
5402db13446SMatthew G. Knepley #define __FUNCT__ "SNESMonitorDefaultField"
5412db13446SMatthew G. Knepley /*@C
5422db13446SMatthew G. Knepley   SNESMonitorDefaultField - Monitors progress of the SNES solvers, separated into fields.
5432db13446SMatthew G. Knepley 
5442db13446SMatthew G. Knepley   Collective on SNES
5452db13446SMatthew G. Knepley 
5462db13446SMatthew G. Knepley   Input Parameters:
5472db13446SMatthew G. Knepley + snes   - the SNES context
5482db13446SMatthew G. Knepley . its    - iteration number
5492db13446SMatthew G. Knepley . fgnorm - 2-norm of residual
5502db13446SMatthew G. Knepley - ctx    - the PetscViewer
5512db13446SMatthew G. Knepley 
5522db13446SMatthew G. Knepley   Notes:
5532db13446SMatthew G. Knepley   This routine uses the DM attached to the residual vector
5542db13446SMatthew G. Knepley 
5552db13446SMatthew G. Knepley   Level: intermediate
5562db13446SMatthew G. Knepley 
5572db13446SMatthew G. Knepley .keywords: SNES, nonlinear, field, monitor, norm
5582db13446SMatthew G. Knepley .seealso: SNESMonitorSet(), SNESMonitorSolution(), SNESMonitorDefault(), SNESMonitorDefaultShort()
5592db13446SMatthew G. Knepley @*/
5602db13446SMatthew G. Knepley PetscErrorCode SNESMonitorDefaultField(SNES snes, PetscInt its, PetscReal fgnorm, void *ctx)
5612db13446SMatthew G. Knepley {
5624d4332d5SBarry Smith   PetscViewer    viewer = (PetscViewer) ctx;
5632db13446SMatthew G. Knepley   Vec            r;
5642db13446SMatthew G. Knepley   DM             dm;
5652db13446SMatthew G. Knepley   PetscReal      res[256];
5662db13446SMatthew G. Knepley   PetscInt       tablevel;
5672db13446SMatthew G. Knepley   PetscErrorCode ierr;
5682db13446SMatthew G. Knepley 
5692db13446SMatthew G. Knepley   PetscFunctionBegin;
5704d4332d5SBarry Smith   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,4);
5712db13446SMatthew G. Knepley   ierr = SNESGetFunction(snes, &r, NULL, NULL);CHKERRQ(ierr);
5722db13446SMatthew G. Knepley   ierr = VecGetDM(r, &dm);CHKERRQ(ierr);
5732db13446SMatthew G. Knepley   if (!dm) {ierr = SNESMonitorDefault(snes, its, fgnorm, ctx);CHKERRQ(ierr);}
5742db13446SMatthew G. Knepley   else {
5752db13446SMatthew G. Knepley     PetscSection s, gs;
5762db13446SMatthew G. Knepley     PetscInt     Nf, f;
5772db13446SMatthew G. Knepley 
5782db13446SMatthew G. Knepley     ierr = DMGetDefaultSection(dm, &s);CHKERRQ(ierr);
5792db13446SMatthew G. Knepley     ierr = DMGetDefaultGlobalSection(dm, &gs);CHKERRQ(ierr);
5802db13446SMatthew G. Knepley     if (!s || !gs) {ierr = SNESMonitorDefault(snes, its, fgnorm, ctx);CHKERRQ(ierr);}
5812db13446SMatthew G. Knepley     ierr = PetscSectionGetNumFields(s, &Nf);CHKERRQ(ierr);
5822db13446SMatthew G. Knepley     if (Nf > 256) SETERRQ1(PetscObjectComm((PetscObject) snes), PETSC_ERR_SUP, "Do not support %d fields > 256", Nf);
5832db13446SMatthew G. Knepley     ierr = PetscSectionVecNorm(s, gs, r, NORM_2, res);CHKERRQ(ierr);
5842db13446SMatthew G. Knepley     ierr = PetscObjectGetTabLevel((PetscObject) snes, &tablevel);CHKERRQ(ierr);
5852db13446SMatthew G. Knepley     ierr = PetscViewerASCIIAddTab(viewer, tablevel);CHKERRQ(ierr);
5862db13446SMatthew G. Knepley     ierr = PetscViewerASCIIPrintf(viewer, "%3D SNES Function norm %14.12e [", its, (double) fgnorm);CHKERRQ(ierr);
5872db13446SMatthew G. Knepley     for (f = 0; f < Nf; ++f) {
5882db13446SMatthew G. Knepley       if (f) {ierr = PetscViewerASCIIPrintf(viewer, ", ");CHKERRQ(ierr);}
5892db13446SMatthew G. Knepley       ierr = PetscViewerASCIIPrintf(viewer, "%14.12e", res[f]);CHKERRQ(ierr);
5902db13446SMatthew G. Knepley     }
5912db13446SMatthew G. Knepley     ierr = PetscViewerASCIIPrintf(viewer, "] \n");CHKERRQ(ierr);
5922db13446SMatthew G. Knepley     ierr = PetscViewerASCIISubtractTab(viewer, tablevel);CHKERRQ(ierr);
5932db13446SMatthew G. Knepley   }
5942db13446SMatthew G. Knepley   PetscFunctionReturn(0);
5952db13446SMatthew G. Knepley }
596e7e93795SLois Curfman McInnes /* ---------------------------------------------------------------- */
5974a2ae208SSatish Balay #undef __FUNCT__
5988d359177SBarry Smith #define __FUNCT__ "SNESConvergedDefault"
5994b828684SBarry Smith /*@C
6008d359177SBarry Smith    SNESConvergedDefault - Convergence test of the solvers for
601f525115eSLois Curfman McInnes    systems of nonlinear equations (default).
602e7e93795SLois Curfman McInnes 
603c7afd0dbSLois Curfman McInnes    Collective on SNES
604c7afd0dbSLois Curfman McInnes 
605e7e93795SLois Curfman McInnes    Input Parameters:
606c7afd0dbSLois Curfman McInnes +  snes - the SNES context
60706ee9f85SBarry Smith .  it - the iteration (0 indicates before any Newton steps)
608e7e93795SLois Curfman McInnes .  xnorm - 2-norm of current iterate
609c60f73f4SPeter Brune .  snorm - 2-norm of current step
6107f3332b4SBarry Smith .  fnorm - 2-norm of function at current iterate
611c7afd0dbSLois Curfman McInnes -  dummy - unused context
612e7e93795SLois Curfman McInnes 
613184914b5SBarry Smith    Output Parameter:
614184914b5SBarry Smith .   reason  - one of
61570441072SBarry Smith $  SNES_CONVERGED_FNORM_ABS       - (fnorm < abstol),
616c60f73f4SPeter Brune $  SNES_CONVERGED_SNORM_RELATIVE  - (snorm < stol*xnorm),
617184914b5SBarry Smith $  SNES_CONVERGED_FNORM_RELATIVE  - (fnorm < rtol*fnorm0),
618184914b5SBarry Smith $  SNES_DIVERGED_FUNCTION_COUNT   - (nfct > maxf),
619184914b5SBarry Smith $  SNES_DIVERGED_FNORM_NAN        - (fnorm == NaN),
620184914b5SBarry Smith $  SNES_CONVERGED_ITERATING       - (otherwise),
621e7e93795SLois Curfman McInnes 
622e7e93795SLois Curfman McInnes    where
623c7afd0dbSLois Curfman McInnes +    maxf - maximum number of function evaluations,
624c7afd0dbSLois Curfman McInnes             set with SNESSetTolerances()
625c7afd0dbSLois Curfman McInnes .    nfct - number of function evaluations,
62670441072SBarry Smith .    abstol - absolute function norm tolerance,
627c7afd0dbSLois Curfman McInnes             set with SNESSetTolerances()
628c7afd0dbSLois Curfman McInnes -    rtol - relative function norm tolerance, set with SNESSetTolerances()
629fee21e36SBarry Smith 
63036851e7fSLois Curfman McInnes    Level: intermediate
63136851e7fSLois Curfman McInnes 
632e7e93795SLois Curfman McInnes .keywords: SNES, nonlinear, default, converged, convergence
633e7e93795SLois Curfman McInnes 
63471f87433Sdalcinl .seealso: SNESSetConvergenceTest()
635e7e93795SLois Curfman McInnes @*/
6368d359177SBarry Smith PetscErrorCode  SNESConvergedDefault(SNES snes,PetscInt it,PetscReal xnorm,PetscReal snorm,PetscReal fnorm,SNESConvergedReason *reason,void *dummy)
637e7e93795SLois Curfman McInnes {
63863ba0a88SBarry Smith   PetscErrorCode ierr;
63963ba0a88SBarry Smith 
6403a40ed3dSBarry Smith   PetscFunctionBegin;
6410700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
6423f149594SLisandro Dalcin   PetscValidPointer(reason,6);
6433f149594SLisandro Dalcin 
64406ee9f85SBarry Smith   *reason = SNES_CONVERGED_ITERATING;
64506ee9f85SBarry Smith 
64606ee9f85SBarry Smith   if (!it) {
64706ee9f85SBarry Smith     /* set parameter for default relative tolerance convergence test */
64806ee9f85SBarry Smith     snes->ttol = fnorm*snes->rtol;
64906ee9f85SBarry Smith   }
6508146f6ebSBarry Smith   if (PetscIsInfOrNanReal(fnorm)) {
651ae15b995SBarry Smith     ierr    = PetscInfo(snes,"Failed to converged, function norm is NaN\n");CHKERRQ(ierr);
652184914b5SBarry Smith     *reason = SNES_DIVERGED_FNORM_NAN;
65370441072SBarry Smith   } else if (fnorm < snes->abstol) {
6548f1a2a5eSBarry Smith     ierr    = PetscInfo2(snes,"Converged due to function norm %14.12e < %14.12e\n",(double)fnorm,(double)snes->abstol);CHKERRQ(ierr);
655184914b5SBarry Smith     *reason = SNES_CONVERGED_FNORM_ABS;
65643e71028SBarry Smith   } else if (snes->nfuncs >= snes->max_funcs) {
657ae15b995SBarry Smith     ierr    = PetscInfo2(snes,"Exceeded maximum number of function evaluations: %D > %D\n",snes->nfuncs,snes->max_funcs);CHKERRQ(ierr);
658184914b5SBarry Smith     *reason = SNES_DIVERGED_FUNCTION_COUNT;
65906ee9f85SBarry Smith   }
66006ee9f85SBarry Smith 
66106ee9f85SBarry Smith   if (it && !*reason) {
66206ee9f85SBarry Smith     if (fnorm <= snes->ttol) {
6638f1a2a5eSBarry Smith       ierr    = PetscInfo2(snes,"Converged due to function norm %14.12e < %14.12e (relative tolerance)\n",(double)fnorm,(double)snes->ttol);CHKERRQ(ierr);
66406ee9f85SBarry Smith       *reason = SNES_CONVERGED_FNORM_RELATIVE;
665c60f73f4SPeter Brune     } else if (snorm < snes->stol*xnorm) {
666c60f73f4SPeter 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);
667c60f73f4SPeter Brune       *reason = SNES_CONVERGED_SNORM_RELATIVE;
66806ee9f85SBarry Smith     }
669e7e93795SLois Curfman McInnes   }
6703a40ed3dSBarry Smith   PetscFunctionReturn(0);
671e7e93795SLois Curfman McInnes }
6723f149594SLisandro Dalcin 
6733f149594SLisandro Dalcin #undef __FUNCT__
674e2a6519dSDmitry Karpeev #define __FUNCT__ "SNESConvergedSkip"
6753f149594SLisandro Dalcin /*@C
676e2a6519dSDmitry Karpeev    SNESConvergedSkip - Convergence test for SNES that NEVER returns as
6773f149594SLisandro Dalcin    converged, UNLESS the maximum number of iteration have been reached.
6783f149594SLisandro Dalcin 
6793f9fe445SBarry Smith    Logically Collective on SNES
6803f149594SLisandro Dalcin 
6813f149594SLisandro Dalcin    Input Parameters:
6823f149594SLisandro Dalcin +  snes - the SNES context
6833f149594SLisandro Dalcin .  it - the iteration (0 indicates before any Newton steps)
6843f149594SLisandro Dalcin .  xnorm - 2-norm of current iterate
685c60f73f4SPeter Brune .  snorm - 2-norm of current step
6863f149594SLisandro Dalcin .  fnorm - 2-norm of function at current iterate
6873f149594SLisandro Dalcin -  dummy - unused context
6883f149594SLisandro Dalcin 
6893f149594SLisandro Dalcin    Output Parameter:
69085385478SLisandro Dalcin .   reason  - SNES_CONVERGED_ITERATING, SNES_CONVERGED_ITS, or SNES_DIVERGED_FNORM_NAN
6913f149594SLisandro Dalcin 
6923f149594SLisandro Dalcin    Notes:
6933f149594SLisandro Dalcin    Convergence is then declared after a fixed number of iterations have been used.
6943f149594SLisandro Dalcin 
6953f149594SLisandro Dalcin    Level: advanced
6963f149594SLisandro Dalcin 
6973f149594SLisandro Dalcin .keywords: SNES, nonlinear, skip, converged, convergence
6983f149594SLisandro Dalcin 
6993f149594SLisandro Dalcin .seealso: SNESSetConvergenceTest()
7003f149594SLisandro Dalcin @*/
701e2a6519dSDmitry Karpeev PetscErrorCode  SNESConvergedSkip(SNES snes,PetscInt it,PetscReal xnorm,PetscReal snorm,PetscReal fnorm,SNESConvergedReason *reason,void *dummy)
7023f149594SLisandro Dalcin {
7033f149594SLisandro Dalcin   PetscErrorCode ierr;
7043f149594SLisandro Dalcin 
7053f149594SLisandro Dalcin   PetscFunctionBegin;
7060700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
7073f149594SLisandro Dalcin   PetscValidPointer(reason,6);
7083f149594SLisandro Dalcin 
7093f149594SLisandro Dalcin   *reason = SNES_CONVERGED_ITERATING;
7103f149594SLisandro Dalcin 
7113f149594SLisandro Dalcin   if (fnorm != fnorm) {
7123f149594SLisandro Dalcin     ierr    = PetscInfo(snes,"Failed to converged, function norm is NaN\n");CHKERRQ(ierr);
7133f149594SLisandro Dalcin     *reason = SNES_DIVERGED_FNORM_NAN;
7143f149594SLisandro Dalcin   } else if (it == snes->max_its) {
7153f149594SLisandro Dalcin     *reason = SNES_CONVERGED_ITS;
7163f149594SLisandro Dalcin   }
7173f149594SLisandro Dalcin   PetscFunctionReturn(0);
7183f149594SLisandro Dalcin }
7193f149594SLisandro Dalcin 
72058c9b817SLisandro Dalcin #undef __FUNCT__
721fa0ddf94SBarry Smith #define __FUNCT__ "SNESSetWorkVecs"
7228d359177SBarry Smith /*@C
723fa0ddf94SBarry Smith   SNESSetWorkVecs - Gets a number of work vectors.
72458c9b817SLisandro Dalcin 
72558c9b817SLisandro Dalcin   Input Parameters:
72658c9b817SLisandro Dalcin . snes  - the SNES context
72758c9b817SLisandro Dalcin . nw - number of work vectors to allocate
72858c9b817SLisandro Dalcin 
72958c9b817SLisandro Dalcin    Level: developer
73058c9b817SLisandro Dalcin 
731fa0ddf94SBarry Smith    Developers Note: This is PETSC_EXTERN because it may be used by user written plugin SNES implementations
732fa0ddf94SBarry Smith 
73398acb6afSMatthew G Knepley @*/
734fa0ddf94SBarry Smith PetscErrorCode SNESSetWorkVecs(SNES snes,PetscInt nw)
73558c9b817SLisandro Dalcin {
736c5ed8070SMatthew G. Knepley   DM             dm;
737c5ed8070SMatthew G. Knepley   Vec            v;
73858c9b817SLisandro Dalcin   PetscErrorCode ierr;
73958c9b817SLisandro Dalcin 
74058c9b817SLisandro Dalcin   PetscFunctionBegin;
74158c9b817SLisandro Dalcin   if (snes->work) {ierr = VecDestroyVecs(snes->nwork,&snes->work);CHKERRQ(ierr);}
74258c9b817SLisandro Dalcin   snes->nwork = nw;
743f5af7f23SKarl Rupp 
744c5ed8070SMatthew G. Knepley   ierr = SNESGetDM(snes, &dm);CHKERRQ(ierr);
745c5ed8070SMatthew G. Knepley   ierr = DMGetGlobalVector(dm, &v);CHKERRQ(ierr);
746c5ed8070SMatthew G. Knepley   ierr = VecDuplicateVecs(v,snes->nwork,&snes->work);CHKERRQ(ierr);
747c5ed8070SMatthew G. Knepley   ierr = DMRestoreGlobalVector(dm, &v);CHKERRQ(ierr);
74858c9b817SLisandro Dalcin   ierr = PetscLogObjectParents(snes,nw,snes->work);CHKERRQ(ierr);
74958c9b817SLisandro Dalcin   PetscFunctionReturn(0);
75058c9b817SLisandro Dalcin }
751