xref: /petsc/src/snes/interface/snesut.c (revision 435c5a64420bae3860f5c77caee5c3af74fbed67)
1e7e93795SLois Curfman McInnes 
28d359177SBarry 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
180298fd71SBarry Smith -  dummy - either a viewer or NULL
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   if (!viewer) {
353f1db9ecSBarry Smith     MPI_Comm comm;
363f1db9ecSBarry Smith     ierr   = PetscObjectGetComm((PetscObject)snes,&comm);CHKERRQ(ierr);
37b0a32e0cSBarry Smith     viewer = PETSC_VIEWER_DRAW_(comm);
383f1db9ecSBarry Smith   }
393f1db9ecSBarry Smith   ierr = VecView(x,viewer);CHKERRQ(ierr);
403f1db9ecSBarry Smith   PetscFunctionReturn(0);
413f1db9ecSBarry Smith }
423f1db9ecSBarry Smith 
434a2ae208SSatish Balay #undef __FUNCT__
44a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorResidual"
455ed2d596SBarry Smith /*@C
46a6570f20SBarry Smith    SNESMonitorResidual - Monitors progress of the SNES solvers by calling
475ed2d596SBarry Smith    VecView() for the residual at each iteration.
485ed2d596SBarry Smith 
495ed2d596SBarry Smith    Collective on SNES
505ed2d596SBarry Smith 
515ed2d596SBarry Smith    Input Parameters:
525ed2d596SBarry Smith +  snes - the SNES context
535ed2d596SBarry Smith .  its - iteration number
544b27c08aSLois Curfman McInnes .  fgnorm - 2-norm of residual
550298fd71SBarry Smith -  dummy - either a viewer or NULL
565ed2d596SBarry Smith 
575ed2d596SBarry Smith    Level: intermediate
585ed2d596SBarry Smith 
595ed2d596SBarry Smith .keywords: SNES, nonlinear, vector, monitor, view
605ed2d596SBarry Smith 
61a6570f20SBarry Smith .seealso: SNESMonitorSet(), SNESMonitorDefault(), VecView()
625ed2d596SBarry Smith @*/
637087cfbeSBarry Smith PetscErrorCode  SNESMonitorResidual(SNES snes,PetscInt its,PetscReal fgnorm,void *dummy)
645ed2d596SBarry Smith {
65dfbe8321SBarry Smith   PetscErrorCode ierr;
665ed2d596SBarry Smith   Vec            x;
675ed2d596SBarry Smith   PetscViewer    viewer = (PetscViewer) dummy;
685ed2d596SBarry Smith 
695ed2d596SBarry Smith   PetscFunctionBegin;
705ed2d596SBarry Smith   ierr = SNESGetFunction(snes,&x,0,0);CHKERRQ(ierr);
715ed2d596SBarry Smith   if (!viewer) {
725ed2d596SBarry Smith     MPI_Comm comm;
735ed2d596SBarry Smith     ierr   = PetscObjectGetComm((PetscObject)snes,&comm);CHKERRQ(ierr);
745ed2d596SBarry Smith     viewer = PETSC_VIEWER_DRAW_(comm);
755ed2d596SBarry Smith   }
765ed2d596SBarry Smith   ierr = VecView(x,viewer);CHKERRQ(ierr);
775ed2d596SBarry Smith   PetscFunctionReturn(0);
785ed2d596SBarry Smith }
795ed2d596SBarry Smith 
805ed2d596SBarry Smith #undef __FUNCT__
81a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorSolutionUpdate"
82d132466eSBarry Smith /*@C
83a6570f20SBarry Smith    SNESMonitorSolutionUpdate - Monitors progress of the SNES solvers by calling
84d132466eSBarry Smith    VecView() for the UPDATE to the solution at each iteration.
85d132466eSBarry Smith 
86d132466eSBarry Smith    Collective on SNES
87d132466eSBarry Smith 
88d132466eSBarry Smith    Input Parameters:
89d132466eSBarry Smith +  snes - the SNES context
90d132466eSBarry Smith .  its - iteration number
914b27c08aSLois Curfman McInnes .  fgnorm - 2-norm of residual
920298fd71SBarry Smith -  dummy - either a viewer or NULL
93d132466eSBarry Smith 
94d132466eSBarry Smith    Level: intermediate
95d132466eSBarry Smith 
96d132466eSBarry Smith .keywords: SNES, nonlinear, vector, monitor, view
97d132466eSBarry Smith 
98a6570f20SBarry Smith .seealso: SNESMonitorSet(), SNESMonitorDefault(), VecView()
99d132466eSBarry Smith @*/
1007087cfbeSBarry Smith PetscErrorCode  SNESMonitorSolutionUpdate(SNES snes,PetscInt its,PetscReal fgnorm,void *dummy)
101d132466eSBarry Smith {
102dfbe8321SBarry Smith   PetscErrorCode ierr;
103d132466eSBarry Smith   Vec            x;
104b0a32e0cSBarry Smith   PetscViewer    viewer = (PetscViewer) dummy;
105d132466eSBarry Smith 
106d132466eSBarry Smith   PetscFunctionBegin;
107d132466eSBarry Smith   ierr = SNESGetSolutionUpdate(snes,&x);CHKERRQ(ierr);
108d132466eSBarry Smith   if (!viewer) {
109d132466eSBarry Smith     MPI_Comm comm;
110d132466eSBarry Smith     ierr   = PetscObjectGetComm((PetscObject)snes,&comm);CHKERRQ(ierr);
111b0a32e0cSBarry Smith     viewer = PETSC_VIEWER_DRAW_(comm);
112d132466eSBarry Smith   }
113d132466eSBarry Smith   ierr = VecView(x,viewer);CHKERRQ(ierr);
114d132466eSBarry Smith   PetscFunctionReturn(0);
115d132466eSBarry Smith }
116d132466eSBarry Smith 
1174a2ae208SSatish Balay #undef __FUNCT__
118a5c2985bSBarry Smith #define __FUNCT__ "KSPMonitorSNES"
119a5c2985bSBarry Smith /*@C
120a5c2985bSBarry Smith    KSPMonitorSNES - Print the residual norm of the nonlinear function at each iteration of the linear iterative solver.
121a5c2985bSBarry Smith 
122a5c2985bSBarry Smith    Collective on KSP
123a5c2985bSBarry Smith 
124a5c2985bSBarry Smith    Input Parameters:
125a5c2985bSBarry Smith +  ksp   - iterative context
126a5c2985bSBarry Smith .  n     - iteration number
127a5c2985bSBarry Smith .  rnorm - 2-norm (preconditioned) residual value (may be estimated).
128a5c2985bSBarry Smith -  dummy - unused monitor context
129a5c2985bSBarry Smith 
130a5c2985bSBarry Smith    Level: intermediate
131a5c2985bSBarry Smith 
132a5c2985bSBarry Smith .keywords: KSP, default, monitor, residual
133a5c2985bSBarry Smith 
134a5c2985bSBarry Smith .seealso: KSPMonitorSet(), KSPMonitorTrueResidualNorm(), KSPMonitorLGResidualNormCreate()
135a5c2985bSBarry Smith @*/
136a5c2985bSBarry Smith PetscErrorCode  KSPMonitorSNES(KSP ksp,PetscInt n,PetscReal rnorm,void *dummy)
137a5c2985bSBarry Smith {
138a5c2985bSBarry Smith   PetscErrorCode ierr;
139a5c2985bSBarry Smith   PetscViewer    viewer;
140a5c2985bSBarry Smith   SNES           snes = (SNES) dummy;
141a5c2985bSBarry Smith   Vec            snes_solution,work1,work2;
142a5c2985bSBarry Smith   PetscReal      snorm;
143a5c2985bSBarry Smith 
144a5c2985bSBarry Smith   PetscFunctionBegin;
145a5c2985bSBarry Smith   ierr = SNESGetSolution(snes,&snes_solution);CHKERRQ(ierr);
146a5c2985bSBarry Smith   ierr = VecDuplicate(snes_solution,&work1);CHKERRQ(ierr);
147a5c2985bSBarry Smith   ierr = VecDuplicate(snes_solution,&work2);CHKERRQ(ierr);
148a5c2985bSBarry Smith   ierr = KSPBuildSolution(ksp,work1,NULL);CHKERRQ(ierr);
149a5c2985bSBarry Smith   ierr = VecAYPX(work1,-1.0,snes_solution);CHKERRQ(ierr);
150a5c2985bSBarry Smith   ierr = SNESComputeFunction(snes,work1,work2);CHKERRQ(ierr);
151a5c2985bSBarry Smith   ierr = VecNorm(work2,NORM_2,&snorm);CHKERRQ(ierr);
152a5c2985bSBarry Smith   ierr = VecDestroy(&work1);CHKERRQ(ierr);
153a5c2985bSBarry Smith   ierr = VecDestroy(&work2);CHKERRQ(ierr);
154a5c2985bSBarry Smith 
155a5c2985bSBarry Smith   ierr = PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)ksp),&viewer);CHKERRQ(ierr);
156a5c2985bSBarry Smith   ierr = PetscViewerASCIIAddTab(viewer,((PetscObject)ksp)->tablevel);CHKERRQ(ierr);
157a5c2985bSBarry Smith   if (n == 0 && ((PetscObject)ksp)->prefix) {
158a5c2985bSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  Residual norms for %s solve.\n",((PetscObject)ksp)->prefix);CHKERRQ(ierr);
159a5c2985bSBarry Smith   }
160a5c2985bSBarry Smith   ierr = PetscViewerASCIIPrintf(viewer,"%3D SNES Residual norm %5.3e KSP Residual norm %5.3e \n",n,(double)snorm,(double)rnorm);CHKERRQ(ierr);
161a5c2985bSBarry Smith   ierr = PetscViewerASCIISubtractTab(viewer,((PetscObject)ksp)->tablevel);CHKERRQ(ierr);
162a5c2985bSBarry Smith   PetscFunctionReturn(0);
163a5c2985bSBarry Smith }
164a5c2985bSBarry Smith 
165e5f7ee39SBarry Smith #include <petscdraw.h>
166e5f7ee39SBarry Smith 
167e5f7ee39SBarry Smith #undef __FUNCT__
168e5f7ee39SBarry Smith #define __FUNCT__ "KSPMonitorSNESLGResidualNormCreate"
169e5f7ee39SBarry Smith /*@C
170e5f7ee39SBarry Smith    KSPMonitorSNESLGResidualNormCreate - Creates a line graph context for use with
171e5f7ee39SBarry Smith    KSP to monitor convergence of preconditioned residual norms.
172e5f7ee39SBarry Smith 
173e5f7ee39SBarry Smith    Collective on KSP
174e5f7ee39SBarry Smith 
175e5f7ee39SBarry Smith    Input Parameters:
176e5f7ee39SBarry Smith +  host - the X display to open, or null for the local machine
177e5f7ee39SBarry Smith .  label - the title to put in the title bar
178e5f7ee39SBarry Smith .  x, y - the screen coordinates of the upper left coordinate of
179e5f7ee39SBarry Smith           the window
180e5f7ee39SBarry Smith -  m, n - the screen width and height in pixels
181e5f7ee39SBarry Smith 
182e5f7ee39SBarry Smith    Output Parameter:
183e5f7ee39SBarry Smith .  draw - the drawing context
184e5f7ee39SBarry Smith 
185e5f7ee39SBarry Smith    Options Database Key:
186e5f7ee39SBarry Smith .  -ksp_monitor_lg_residualnorm - Sets line graph monitor
187e5f7ee39SBarry Smith 
188e5f7ee39SBarry Smith    Notes:
189e5f7ee39SBarry Smith    Use KSPMonitorSNESLGResidualNormDestroy() to destroy this line graph; do not use PetscDrawLGDestroy().
190e5f7ee39SBarry Smith 
191e5f7ee39SBarry Smith    Level: intermediate
192e5f7ee39SBarry Smith 
193e5f7ee39SBarry Smith .keywords: KSP, monitor, line graph, residual, create
194e5f7ee39SBarry Smith 
195e5f7ee39SBarry Smith .seealso: KSPMonitorSNESLGResidualNormDestroy(), KSPMonitorSet(), KSPMonitorSNESLGTrueResidualCreate()
196e5f7ee39SBarry Smith @*/
197e5f7ee39SBarry Smith PetscErrorCode  KSPMonitorSNESLGResidualNormCreate(const char host[],const char label[],int x,int y,int m,int n,PetscObject **objs)
198e5f7ee39SBarry Smith {
199e5f7ee39SBarry Smith   PetscDraw      draw;
200e5f7ee39SBarry Smith   PetscErrorCode ierr;
201e5f7ee39SBarry Smith   PetscDrawAxis  axis;
202e5f7ee39SBarry Smith   PetscDrawLG    drawlg;
203e5f7ee39SBarry Smith   const char     *names[] = {"Linear residual","Nonlinear residual"};
204e5f7ee39SBarry Smith 
205e5f7ee39SBarry Smith   PetscFunctionBegin;
206e5f7ee39SBarry Smith   ierr = PetscDrawCreate(PETSC_COMM_SELF,host,label,x,y,m,n,&draw);CHKERRQ(ierr);
207e5f7ee39SBarry Smith   ierr = PetscDrawSetFromOptions(draw);CHKERRQ(ierr);
208e5f7ee39SBarry Smith   ierr = PetscDrawLGCreate(draw,2,&drawlg);CHKERRQ(ierr);
209e5f7ee39SBarry Smith   ierr = PetscDrawLGGetAxis(drawlg,&axis);CHKERRQ(ierr);
210e5f7ee39SBarry Smith   ierr = PetscDrawAxisSetLabels(axis,"Convergence of Residual Norm","Iteration","Residual Norm");CHKERRQ(ierr);
211e5f7ee39SBarry Smith   ierr = PetscDrawLGSetLegend(drawlg,names);CHKERRQ(ierr);
212e5f7ee39SBarry Smith   ierr = PetscLogObjectParent((PetscObject)drawlg,(PetscObject)draw);CHKERRQ(ierr);
213e5f7ee39SBarry Smith 
214*435c5a64SBarry Smith   ierr = PetscMalloc1(3,objs);CHKERRQ(ierr);
215e5f7ee39SBarry Smith   (*objs)[1] = (PetscObject)drawlg;
216*435c5a64SBarry Smith   (*objs)[2] = (PetscObject)draw;
217e5f7ee39SBarry Smith   PetscFunctionReturn(0);
218e5f7ee39SBarry Smith }
219e5f7ee39SBarry Smith 
220e5f7ee39SBarry Smith #undef __FUNCT__
221e5f7ee39SBarry Smith #define __FUNCT__ "KSPMonitorSNESLGResidualNorm"
222e5f7ee39SBarry Smith PetscErrorCode  KSPMonitorSNESLGResidualNorm(KSP ksp,PetscInt n,PetscReal rnorm,PetscObject *objs)
223e5f7ee39SBarry Smith {
224e5f7ee39SBarry Smith   PetscDrawLG    lg = (PetscDrawLG) objs[1];
225e5f7ee39SBarry Smith   PetscErrorCode ierr;
226e5f7ee39SBarry Smith   PetscReal      y[2];
227e5f7ee39SBarry Smith   SNES           snes = (SNES) objs[0];
228e5f7ee39SBarry Smith   Vec            snes_solution,work1,work2;
229e5f7ee39SBarry Smith 
230e5f7ee39SBarry Smith   PetscFunctionBegin;
231e5f7ee39SBarry Smith   if (rnorm > 0.0) y[0] = PetscLog10Real(rnorm);
232e5f7ee39SBarry Smith   else y[0] = -15.0;
233e5f7ee39SBarry Smith 
234e5f7ee39SBarry Smith   ierr = SNESGetSolution(snes,&snes_solution);CHKERRQ(ierr);
235e5f7ee39SBarry Smith   ierr = VecDuplicate(snes_solution,&work1);CHKERRQ(ierr);
236e5f7ee39SBarry Smith   ierr = VecDuplicate(snes_solution,&work2);CHKERRQ(ierr);
237e5f7ee39SBarry Smith   ierr = KSPBuildSolution(ksp,work1,NULL);CHKERRQ(ierr);
238e5f7ee39SBarry Smith   ierr = VecAYPX(work1,-1.0,snes_solution);CHKERRQ(ierr);
239e5f7ee39SBarry Smith   ierr = SNESComputeFunction(snes,work1,work2);CHKERRQ(ierr);
240e5f7ee39SBarry Smith   ierr = VecNorm(work2,NORM_2,y+1);CHKERRQ(ierr);
241e5f7ee39SBarry Smith   if (y[1] > 0.0) y[1] = PetscLog10Real(y[1]);
242e5f7ee39SBarry Smith   else y[1] = -15.0;
243e5f7ee39SBarry Smith   ierr = VecDestroy(&work1);CHKERRQ(ierr);
244e5f7ee39SBarry Smith   ierr = VecDestroy(&work2);CHKERRQ(ierr);
245e5f7ee39SBarry Smith 
246e5f7ee39SBarry Smith   ierr = PetscDrawLGAddPoint(lg,NULL,y);CHKERRQ(ierr);
247e5f7ee39SBarry Smith   if (n < 20 || !(n % 5)) {
248e5f7ee39SBarry Smith     ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr);
249e5f7ee39SBarry Smith   }
250e5f7ee39SBarry Smith   PetscFunctionReturn(0);
251e5f7ee39SBarry Smith }
252e5f7ee39SBarry Smith 
253e5f7ee39SBarry Smith #undef __FUNCT__
254e5f7ee39SBarry Smith #define __FUNCT__ "KSPMonitorSNESLGResidualNormDestroy"
255e5f7ee39SBarry Smith /*@
256e5f7ee39SBarry Smith    KSPMonitorSNESLGResidualNormDestroy - Destroys a line graph context that was created
257e5f7ee39SBarry Smith    with KSPMonitorSNESLGResidualNormCreate().
258e5f7ee39SBarry Smith 
259e5f7ee39SBarry Smith    Collective on KSP
260e5f7ee39SBarry Smith 
261e5f7ee39SBarry Smith    Input Parameter:
262e5f7ee39SBarry Smith .  draw - the drawing context
263e5f7ee39SBarry Smith 
264e5f7ee39SBarry Smith    Level: intermediate
265e5f7ee39SBarry Smith 
266e5f7ee39SBarry Smith .keywords: KSP, monitor, line graph, destroy
267e5f7ee39SBarry Smith 
268e5f7ee39SBarry Smith .seealso: KSPMonitorSNESLGResidualNormCreate(), KSPMonitorSNESLGTrueResidualDestroy(), KSPMonitorSet()
269e5f7ee39SBarry Smith @*/
270e5f7ee39SBarry Smith PetscErrorCode  KSPMonitorSNESLGResidualNormDestroy(PetscObject **objs)
271e5f7ee39SBarry Smith {
272e5f7ee39SBarry Smith   PetscErrorCode ierr;
273e5f7ee39SBarry Smith   PetscDrawLG    drawlg = (PetscDrawLG) (*objs)[1];
274*435c5a64SBarry Smith   PetscDraw      draw = (PetscDraw) (*objs)[2];
275e5f7ee39SBarry Smith 
276e5f7ee39SBarry Smith   PetscFunctionBegin;
277e5f7ee39SBarry Smith   ierr = PetscDrawDestroy(&draw);CHKERRQ(ierr);
278e5f7ee39SBarry Smith   ierr = PetscDrawLGDestroy(&drawlg);CHKERRQ(ierr);
279e5f7ee39SBarry Smith   ierr = PetscFree(*objs);CHKERRQ(ierr);
280e5f7ee39SBarry Smith   PetscFunctionReturn(0);
281e5f7ee39SBarry Smith }
282e5f7ee39SBarry Smith 
283a5c2985bSBarry Smith #undef __FUNCT__
284a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorDefault"
2854b828684SBarry Smith /*@C
286a6570f20SBarry Smith    SNESMonitorDefault - Monitors progress of the SNES solvers (default).
287e7e93795SLois Curfman McInnes 
288c7afd0dbSLois Curfman McInnes    Collective on SNES
289c7afd0dbSLois Curfman McInnes 
290e7e93795SLois Curfman McInnes    Input Parameters:
291c7afd0dbSLois Curfman McInnes +  snes - the SNES context
292e7e93795SLois Curfman McInnes .  its - iteration number
2934b27c08aSLois Curfman McInnes .  fgnorm - 2-norm of residual
294c7afd0dbSLois Curfman McInnes -  dummy - unused context
295fee21e36SBarry Smith 
296e7e93795SLois Curfman McInnes    Notes:
2974b27c08aSLois Curfman McInnes    This routine prints the residual norm at each iteration.
298e7e93795SLois Curfman McInnes 
29936851e7fSLois Curfman McInnes    Level: intermediate
30036851e7fSLois Curfman McInnes 
301e7e93795SLois Curfman McInnes .keywords: SNES, nonlinear, default, monitor, norm
302e7e93795SLois Curfman McInnes 
303a6570f20SBarry Smith .seealso: SNESMonitorSet(), SNESMonitorSolution()
304e7e93795SLois Curfman McInnes @*/
3057087cfbeSBarry Smith PetscErrorCode  SNESMonitorDefault(SNES snes,PetscInt its,PetscReal fgnorm,void *dummy)
306e7e93795SLois Curfman McInnes {
307dfbe8321SBarry Smith   PetscErrorCode ierr;
308ce94432eSBarry Smith   PetscViewer    viewer = dummy ? (PetscViewer) dummy : PETSC_VIEWER_STDOUT_(PetscObjectComm((PetscObject)snes));
309d132466eSBarry Smith 
3103a40ed3dSBarry Smith   PetscFunctionBegin;
311649052a6SBarry Smith   ierr = PetscViewerASCIIAddTab(viewer,((PetscObject)snes)->tablevel);CHKERRQ(ierr);
312649052a6SBarry Smith   ierr = PetscViewerASCIIPrintf(viewer,"%3D SNES Function norm %14.12e \n",its,(double)fgnorm);CHKERRQ(ierr);
313649052a6SBarry Smith   ierr = PetscViewerASCIISubtractTab(viewer,((PetscObject)snes)->tablevel);CHKERRQ(ierr);
3143a40ed3dSBarry Smith   PetscFunctionReturn(0);
315e7e93795SLois Curfman McInnes }
3163f1db9ecSBarry Smith 
317b271bb04SBarry Smith #undef __FUNCT__
3182e7541e6SPeter Brune #define __FUNCT__ "SNESMonitorJacUpdateSpectrum"
319a80ad3e0SBarry Smith PetscErrorCode SNESMonitorJacUpdateSpectrum(SNES snes,PetscInt it,PetscReal fnorm,void *ctx)
320a80ad3e0SBarry Smith {
321196da8b6SPeter Brune #if defined(PETSC_MISSING_LAPACK_GEEV)
322ce94432eSBarry Smith   SETERRQ(PetscObjectComm((PetscObject)snes),PETSC_ERR_SUP,"GEEV - Lapack routine is unavailable\nNot able to provide eigen values.");
323196da8b6SPeter Brune #elif defined(PETSC_HAVE_ESSL)
324ce94432eSBarry Smith   SETERRQ(PetscObjectComm((PetscObject)snes),PETSC_ERR_SUP,"GEEV - No support for ESSL Lapack Routines");
325196da8b6SPeter Brune #else
3262e7541e6SPeter Brune   Vec            X;
3272e7541e6SPeter Brune   Mat            J,dJ,dJdense;
3282e7541e6SPeter Brune   PetscErrorCode ierr;
329d1e9a80fSBarry Smith   PetscErrorCode (*func)(SNES,Vec,Mat,Mat,void*);
3302e7541e6SPeter Brune   PetscInt       n,i;
3312e7541e6SPeter Brune   PetscBLASInt   nb,lwork;
3322e7541e6SPeter Brune   PetscReal      *eigr,*eigi;
3332e7541e6SPeter Brune   PetscScalar    *work;
3342e7541e6SPeter Brune   PetscScalar    *a;
3352e7541e6SPeter Brune 
3362e7541e6SPeter Brune   PetscFunctionBegin;
3372e7541e6SPeter Brune   if (it == 0) PetscFunctionReturn(0);
3382e7541e6SPeter Brune   /* create the difference between the current update and the current jacobian */
3392e7541e6SPeter Brune   ierr = SNESGetSolution(snes,&X);CHKERRQ(ierr);
340d1e9a80fSBarry Smith   ierr = SNESGetJacobian(snes,NULL,&J,&func,NULL);CHKERRQ(ierr);
3412e7541e6SPeter Brune   ierr = MatDuplicate(J,MAT_COPY_VALUES,&dJ);CHKERRQ(ierr);
342d1e9a80fSBarry Smith   ierr = SNESComputeJacobian(snes,X,dJ,dJ);CHKERRQ(ierr);
3432e7541e6SPeter Brune   ierr = MatAXPY(dJ,-1.0,J,SAME_NONZERO_PATTERN);CHKERRQ(ierr);
344f5af7f23SKarl Rupp 
3452e7541e6SPeter Brune   /* compute the spectrum directly */
3462e7541e6SPeter Brune   ierr  = MatConvert(dJ,MATSEQDENSE,MAT_INITIAL_MATRIX,&dJdense);CHKERRQ(ierr);
3470298fd71SBarry Smith   ierr  = MatGetSize(dJ,&n,NULL);CHKERRQ(ierr);
348c5df96a5SBarry Smith   ierr  = PetscBLASIntCast(n,&nb);CHKERRQ(ierr);
3492e7541e6SPeter Brune   lwork = 3*nb;
350785e854fSJed Brown   ierr  = PetscMalloc1(n,&eigr);CHKERRQ(ierr);
351785e854fSJed Brown   ierr  = PetscMalloc1(n,&eigi);CHKERRQ(ierr);
352785e854fSJed Brown   ierr  = PetscMalloc1(lwork,&work);CHKERRQ(ierr);
3538c778c55SBarry Smith   ierr  = MatDenseGetArray(dJdense,&a);CHKERRQ(ierr);
3542e7541e6SPeter Brune #if !defined(PETSC_USE_COMPLEX)
3552e7541e6SPeter Brune   {
3562e7541e6SPeter Brune     PetscBLASInt lierr;
3572e7541e6SPeter Brune     ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
3588b83055fSJed Brown     PetscStackCallBLAS("LAPACKgeev",LAPACKgeev_("N","N",&nb,a,&nb,eigr,eigi,NULL,&nb,NULL,&nb,work,&lwork,&lierr));
3592e7541e6SPeter Brune     if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"geev() error %d",lierr);
3602e7541e6SPeter Brune     ierr = PetscFPTrapPop();CHKERRQ(ierr);
3612e7541e6SPeter Brune   }
3622e7541e6SPeter Brune #else
3632e7541e6SPeter Brune   SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not coded for complex");
3642e7541e6SPeter Brune #endif
365ce94432eSBarry Smith   PetscPrintf(PetscObjectComm((PetscObject)snes),"Eigenvalues of J_%d - J_%d:\n",it,it-1);CHKERRQ(ierr);
3662e7541e6SPeter Brune   for (i=0;i<n;i++) {
3678fa295daSBarry Smith     PetscPrintf(PetscObjectComm((PetscObject)snes),"%5d: %20.5g + %20.5gi\n",i,(double)eigr[i],(double)eigi[i]);CHKERRQ(ierr);
3682e7541e6SPeter Brune   }
3698c778c55SBarry Smith   ierr = MatDenseRestoreArray(dJdense,&a);CHKERRQ(ierr);
3702e7541e6SPeter Brune   ierr = MatDestroy(&dJ);CHKERRQ(ierr);
3712e7541e6SPeter Brune   ierr = MatDestroy(&dJdense);CHKERRQ(ierr);
3722e7541e6SPeter Brune   ierr = PetscFree(eigr);CHKERRQ(ierr);
3732e7541e6SPeter Brune   ierr = PetscFree(eigi);CHKERRQ(ierr);
3742e7541e6SPeter Brune   ierr = PetscFree(work);CHKERRQ(ierr);
3752e7541e6SPeter Brune   PetscFunctionReturn(0);
376196da8b6SPeter Brune #endif
3772e7541e6SPeter Brune }
3782e7541e6SPeter Brune 
3792e7541e6SPeter Brune #undef __FUNCT__
380b271bb04SBarry Smith #define __FUNCT__ "SNESMonitorRange_Private"
3817087cfbeSBarry Smith PetscErrorCode  SNESMonitorRange_Private(SNES snes,PetscInt it,PetscReal *per)
382b271bb04SBarry Smith {
383b271bb04SBarry Smith   PetscErrorCode ierr;
384b271bb04SBarry Smith   Vec            resid;
385b271bb04SBarry Smith   PetscReal      rmax,pwork;
386b271bb04SBarry Smith   PetscInt       i,n,N;
387b271bb04SBarry Smith   PetscScalar    *r;
388b271bb04SBarry Smith 
389b271bb04SBarry Smith   PetscFunctionBegin;
390b271bb04SBarry Smith   ierr  = SNESGetFunction(snes,&resid,0,0);CHKERRQ(ierr);
391b271bb04SBarry Smith   ierr  = VecNorm(resid,NORM_INFINITY,&rmax);CHKERRQ(ierr);
392b271bb04SBarry Smith   ierr  = VecGetLocalSize(resid,&n);CHKERRQ(ierr);
393b271bb04SBarry Smith   ierr  = VecGetSize(resid,&N);CHKERRQ(ierr);
394b271bb04SBarry Smith   ierr  = VecGetArray(resid,&r);CHKERRQ(ierr);
395b271bb04SBarry Smith   pwork = 0.0;
396b271bb04SBarry Smith   for (i=0; i<n; i++) {
397b271bb04SBarry Smith     pwork += (PetscAbsScalar(r[i]) > .20*rmax);
398b271bb04SBarry Smith   }
399ce94432eSBarry Smith   ierr = MPI_Allreduce(&pwork,per,1,MPIU_REAL,MPIU_SUM,PetscObjectComm((PetscObject)snes));CHKERRQ(ierr);
400b271bb04SBarry Smith   ierr = VecRestoreArray(resid,&r);CHKERRQ(ierr);
401b271bb04SBarry Smith   *per = *per/N;
402b271bb04SBarry Smith   PetscFunctionReturn(0);
403b271bb04SBarry Smith }
404b271bb04SBarry Smith 
405b271bb04SBarry Smith #undef __FUNCT__
406b271bb04SBarry Smith #define __FUNCT__ "SNESMonitorRange"
407b271bb04SBarry Smith /*@C
408b271bb04SBarry Smith    SNESMonitorRange - Prints the percentage of residual elements that are more then 10 percent of the maximum value.
409b271bb04SBarry Smith 
410b271bb04SBarry Smith    Collective on SNES
411b271bb04SBarry Smith 
412b271bb04SBarry Smith    Input Parameters:
413b271bb04SBarry Smith +  snes   - iterative context
414b271bb04SBarry Smith .  it    - iteration number
415b271bb04SBarry Smith .  rnorm - 2-norm (preconditioned) residual value (may be estimated).
416b271bb04SBarry Smith -  dummy - unused monitor context
417b271bb04SBarry Smith 
418b271bb04SBarry Smith    Options Database Key:
419b271bb04SBarry Smith .  -snes_monitor_range - Activates SNESMonitorRange()
420b271bb04SBarry Smith 
421b271bb04SBarry Smith    Level: intermediate
422b271bb04SBarry Smith 
423b271bb04SBarry Smith .keywords: SNES, default, monitor, residual
424b271bb04SBarry Smith 
425b271bb04SBarry Smith .seealso: SNESMonitorSet(), SNESMonitorDefault(), SNESMonitorLGCreate()
426b271bb04SBarry Smith @*/
4277087cfbeSBarry Smith PetscErrorCode  SNESMonitorRange(SNES snes,PetscInt it,PetscReal rnorm,void *dummy)
428b271bb04SBarry Smith {
429b271bb04SBarry Smith   PetscErrorCode ierr;
430b271bb04SBarry Smith   PetscReal      perc,rel;
431ce94432eSBarry Smith   PetscViewer    viewer = dummy ? (PetscViewer) dummy : PETSC_VIEWER_STDOUT_(PetscObjectComm((PetscObject)snes));
432b271bb04SBarry Smith   /* should be in a MonitorRangeContext */
433b271bb04SBarry Smith   static PetscReal prev;
434b271bb04SBarry Smith 
435b271bb04SBarry Smith   PetscFunctionBegin;
436b271bb04SBarry Smith   if (!it) prev = rnorm;
437b271bb04SBarry Smith   ierr = SNESMonitorRange_Private(snes,it,&perc);CHKERRQ(ierr);
438b271bb04SBarry Smith 
439b271bb04SBarry Smith   rel  = (prev - rnorm)/prev;
440b271bb04SBarry Smith   prev = rnorm;
441649052a6SBarry Smith   ierr = PetscViewerASCIIAddTab(viewer,((PetscObject)snes)->tablevel);CHKERRQ(ierr);
4426712e2f1SBarry 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);
443649052a6SBarry Smith   ierr = PetscViewerASCIISubtractTab(viewer,((PetscObject)snes)->tablevel);CHKERRQ(ierr);
444b271bb04SBarry Smith   PetscFunctionReturn(0);
445b271bb04SBarry Smith }
446b271bb04SBarry Smith 
447eabae89aSBarry Smith typedef struct {
448649052a6SBarry Smith   PetscViewer viewer;
449eabae89aSBarry Smith   PetscReal   *history;
450a6570f20SBarry Smith } SNESMonitorRatioContext;
451eabae89aSBarry Smith 
4523a7fca6bSBarry Smith #undef __FUNCT__
453a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorRatio"
4543a7fca6bSBarry Smith /*@C
455a6570f20SBarry Smith    SNESMonitorRatio - Monitors progress of the SNES solvers by printing the ratio
4564b27c08aSLois Curfman McInnes    of residual norm at each iteration to the previous.
4573a7fca6bSBarry Smith 
4583a7fca6bSBarry Smith    Collective on SNES
4593a7fca6bSBarry Smith 
4603a7fca6bSBarry Smith    Input Parameters:
4613a7fca6bSBarry Smith +  snes - the SNES context
4623a7fca6bSBarry Smith .  its - iteration number
4633a7fca6bSBarry Smith .  fgnorm - 2-norm of residual (or gradient)
464eabae89aSBarry Smith -  dummy -  context of monitor
4653a7fca6bSBarry Smith 
4663a7fca6bSBarry Smith    Level: intermediate
4673a7fca6bSBarry Smith 
4683a7fca6bSBarry Smith .keywords: SNES, nonlinear, monitor, norm
4693a7fca6bSBarry Smith 
470a6570f20SBarry Smith .seealso: SNESMonitorSet(), SNESMonitorSolution()
4713a7fca6bSBarry Smith @*/
4727087cfbeSBarry Smith PetscErrorCode  SNESMonitorRatio(SNES snes,PetscInt its,PetscReal fgnorm,void *dummy)
4733a7fca6bSBarry Smith {
474dfbe8321SBarry Smith   PetscErrorCode          ierr;
47577431f27SBarry Smith   PetscInt                len;
47687828ca2SBarry Smith   PetscReal               *history;
477a6570f20SBarry Smith   SNESMonitorRatioContext *ctx = (SNESMonitorRatioContext*)dummy;
4783a7fca6bSBarry Smith 
4793a7fca6bSBarry Smith   PetscFunctionBegin;
4800298fd71SBarry Smith   ierr = SNESGetConvergenceHistory(snes,&history,NULL,&len);CHKERRQ(ierr);
481649052a6SBarry Smith   ierr = PetscViewerASCIIAddTab(ctx->viewer,((PetscObject)snes)->tablevel);CHKERRQ(ierr);
482958c9bccSBarry Smith   if (!its || !history || its > len) {
483649052a6SBarry Smith     ierr = PetscViewerASCIIPrintf(ctx->viewer,"%3D SNES Function norm %14.12e \n",its,(double)fgnorm);CHKERRQ(ierr);
4843a7fca6bSBarry Smith   } else {
48587828ca2SBarry Smith     PetscReal ratio = fgnorm/history[its-1];
4868f1a2a5eSBarry Smith     ierr = PetscViewerASCIIPrintf(ctx->viewer,"%3D SNES Function norm %14.12e %14.12e \n",its,(double)fgnorm,(double)ratio);CHKERRQ(ierr);
4873a7fca6bSBarry Smith   }
488649052a6SBarry Smith   ierr = PetscViewerASCIISubtractTab(ctx->viewer,((PetscObject)snes)->tablevel);CHKERRQ(ierr);
4893a7fca6bSBarry Smith   PetscFunctionReturn(0);
4903a7fca6bSBarry Smith }
4913a7fca6bSBarry Smith 
4923a7fca6bSBarry Smith /*
4933a7fca6bSBarry Smith    If the we set the history monitor space then we must destroy it
4943a7fca6bSBarry Smith */
4953a7fca6bSBarry Smith #undef __FUNCT__
496a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorRatioDestroy"
497c2efdce3SBarry Smith PetscErrorCode SNESMonitorRatioDestroy(void **ct)
4983a7fca6bSBarry Smith {
499dfbe8321SBarry Smith   PetscErrorCode          ierr;
500c2efdce3SBarry Smith   SNESMonitorRatioContext *ctx = *(SNESMonitorRatioContext**)ct;
5013a7fca6bSBarry Smith 
5023a7fca6bSBarry Smith   PetscFunctionBegin;
50305b42c5fSBarry Smith   ierr = PetscFree(ctx->history);CHKERRQ(ierr);
504649052a6SBarry Smith   ierr = PetscViewerDestroy(&ctx->viewer);CHKERRQ(ierr);
505eabae89aSBarry Smith   ierr = PetscFree(ctx);CHKERRQ(ierr);
5063a7fca6bSBarry Smith   PetscFunctionReturn(0);
5073a7fca6bSBarry Smith }
5083a7fca6bSBarry Smith 
5093a7fca6bSBarry Smith #undef __FUNCT__
510a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorSetRatio"
5113a7fca6bSBarry Smith /*@C
512a6570f20SBarry Smith    SNESMonitorSetRatio - Sets SNES to use a monitor that prints the
5134b27c08aSLois Curfman McInnes    ratio of the function norm at each iteration.
5143a7fca6bSBarry Smith 
5153a7fca6bSBarry Smith    Collective on SNES
5163a7fca6bSBarry Smith 
5173a7fca6bSBarry Smith    Input Parameters:
518eabae89aSBarry Smith +   snes - the SNES context
519eabae89aSBarry Smith -   viewer - ASCII viewer to print output
5203a7fca6bSBarry Smith 
5213a7fca6bSBarry Smith    Level: intermediate
5223a7fca6bSBarry Smith 
5233a7fca6bSBarry Smith .keywords: SNES, nonlinear, monitor, norm
5243a7fca6bSBarry Smith 
525a6570f20SBarry Smith .seealso: SNESMonitorSet(), SNESMonitorSolution(), SNESMonitorDefault()
5263a7fca6bSBarry Smith @*/
527649052a6SBarry Smith PetscErrorCode  SNESMonitorSetRatio(SNES snes,PetscViewer viewer)
5283a7fca6bSBarry Smith {
529dfbe8321SBarry Smith   PetscErrorCode          ierr;
530a6570f20SBarry Smith   SNESMonitorRatioContext *ctx;
53187828ca2SBarry Smith   PetscReal               *history;
5323a7fca6bSBarry Smith 
5333a7fca6bSBarry Smith   PetscFunctionBegin;
534eabae89aSBarry Smith   if (!viewer) {
535ce94432eSBarry Smith     ierr = PetscViewerASCIIOpen(PetscObjectComm((PetscObject)snes),"stdout",&viewer);CHKERRQ(ierr);
536eabae89aSBarry Smith     ierr = PetscObjectReference((PetscObject)viewer);CHKERRQ(ierr);
537eabae89aSBarry Smith   }
538b00a9115SJed Brown   ierr = PetscNewLog(snes,&ctx);CHKERRQ(ierr);
5390298fd71SBarry Smith   ierr = SNESGetConvergenceHistory(snes,&history,NULL,NULL);CHKERRQ(ierr);
5403a7fca6bSBarry Smith   if (!history) {
541785e854fSJed Brown     ierr = PetscMalloc1(100,&ctx->history);CHKERRQ(ierr);
542eabae89aSBarry Smith     ierr = SNESSetConvergenceHistory(snes,ctx->history,0,100,PETSC_TRUE);CHKERRQ(ierr);
5433a7fca6bSBarry Smith   }
544eabae89aSBarry Smith   ctx->viewer = viewer;
545f5af7f23SKarl Rupp 
546a6570f20SBarry Smith   ierr = SNESMonitorSet(snes,SNESMonitorRatio,ctx,SNESMonitorRatioDestroy);CHKERRQ(ierr);
5473a7fca6bSBarry Smith   PetscFunctionReturn(0);
5483a7fca6bSBarry Smith }
5493a7fca6bSBarry Smith 
550e7e93795SLois Curfman McInnes /* ---------------------------------------------------------------- */
5514a2ae208SSatish Balay #undef __FUNCT__
552a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorDefaultShort"
553be1f7002SBarry Smith /*
554a6570f20SBarry Smith      Default (short) SNES Monitor, same as SNESMonitorDefault() except
555be1f7002SBarry Smith   it prints fewer digits of the residual as the residual gets smaller.
556be1f7002SBarry Smith   This is because the later digits are meaningless and are often
557be1f7002SBarry Smith   different on different machines; by using this routine different
558be1f7002SBarry Smith   machines will usually generate the same output.
559be1f7002SBarry Smith */
5607087cfbeSBarry Smith PetscErrorCode  SNESMonitorDefaultShort(SNES snes,PetscInt its,PetscReal fgnorm,void *dummy)
561e7e93795SLois Curfman McInnes {
562dfbe8321SBarry Smith   PetscErrorCode ierr;
563ce94432eSBarry Smith   PetscViewer    viewer = dummy ? (PetscViewer) dummy : PETSC_VIEWER_STDOUT_(PetscObjectComm((PetscObject)snes));
564d132466eSBarry Smith 
5653a40ed3dSBarry Smith   PetscFunctionBegin;
566649052a6SBarry Smith   ierr = PetscViewerASCIIAddTab(viewer,((PetscObject)snes)->tablevel);CHKERRQ(ierr);
5678f240d10SBarry Smith   if (fgnorm > 1.e-9) {
5688fa295daSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"%3D SNES Function norm %g \n",its,(double)fgnorm);CHKERRQ(ierr);
5693a40ed3dSBarry Smith   } else if (fgnorm > 1.e-11) {
5708fa295daSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"%3D SNES Function norm %5.3e \n",its,(double)fgnorm);CHKERRQ(ierr);
5713a40ed3dSBarry Smith   } else {
572649052a6SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"%3D SNES Function norm < 1.e-11\n",its);CHKERRQ(ierr);
573a34d58ebSBarry Smith   }
574649052a6SBarry Smith   ierr = PetscViewerASCIISubtractTab(viewer,((PetscObject)snes)->tablevel);CHKERRQ(ierr);
5753a40ed3dSBarry Smith   PetscFunctionReturn(0);
576e7e93795SLois Curfman McInnes }
577e7e93795SLois Curfman McInnes /* ---------------------------------------------------------------- */
5784a2ae208SSatish Balay #undef __FUNCT__
5798d359177SBarry Smith #define __FUNCT__ "SNESConvergedDefault"
5804b828684SBarry Smith /*@C
5818d359177SBarry Smith    SNESConvergedDefault - Convergence test of the solvers for
582f525115eSLois Curfman McInnes    systems of nonlinear equations (default).
583e7e93795SLois Curfman McInnes 
584c7afd0dbSLois Curfman McInnes    Collective on SNES
585c7afd0dbSLois Curfman McInnes 
586e7e93795SLois Curfman McInnes    Input Parameters:
587c7afd0dbSLois Curfman McInnes +  snes - the SNES context
58806ee9f85SBarry Smith .  it - the iteration (0 indicates before any Newton steps)
589e7e93795SLois Curfman McInnes .  xnorm - 2-norm of current iterate
590c60f73f4SPeter Brune .  snorm - 2-norm of current step
5917f3332b4SBarry Smith .  fnorm - 2-norm of function at current iterate
592c7afd0dbSLois Curfman McInnes -  dummy - unused context
593e7e93795SLois Curfman McInnes 
594184914b5SBarry Smith    Output Parameter:
595184914b5SBarry Smith .   reason  - one of
59670441072SBarry Smith $  SNES_CONVERGED_FNORM_ABS       - (fnorm < abstol),
597c60f73f4SPeter Brune $  SNES_CONVERGED_SNORM_RELATIVE  - (snorm < stol*xnorm),
598184914b5SBarry Smith $  SNES_CONVERGED_FNORM_RELATIVE  - (fnorm < rtol*fnorm0),
599184914b5SBarry Smith $  SNES_DIVERGED_FUNCTION_COUNT   - (nfct > maxf),
600184914b5SBarry Smith $  SNES_DIVERGED_FNORM_NAN        - (fnorm == NaN),
601184914b5SBarry Smith $  SNES_CONVERGED_ITERATING       - (otherwise),
602e7e93795SLois Curfman McInnes 
603e7e93795SLois Curfman McInnes    where
604c7afd0dbSLois Curfman McInnes +    maxf - maximum number of function evaluations,
605c7afd0dbSLois Curfman McInnes             set with SNESSetTolerances()
606c7afd0dbSLois Curfman McInnes .    nfct - number of function evaluations,
60770441072SBarry Smith .    abstol - absolute function norm tolerance,
608c7afd0dbSLois Curfman McInnes             set with SNESSetTolerances()
609c7afd0dbSLois Curfman McInnes -    rtol - relative function norm tolerance, set with SNESSetTolerances()
610fee21e36SBarry Smith 
61136851e7fSLois Curfman McInnes    Level: intermediate
61236851e7fSLois Curfman McInnes 
613e7e93795SLois Curfman McInnes .keywords: SNES, nonlinear, default, converged, convergence
614e7e93795SLois Curfman McInnes 
61571f87433Sdalcinl .seealso: SNESSetConvergenceTest()
616e7e93795SLois Curfman McInnes @*/
6178d359177SBarry Smith PetscErrorCode  SNESConvergedDefault(SNES snes,PetscInt it,PetscReal xnorm,PetscReal snorm,PetscReal fnorm,SNESConvergedReason *reason,void *dummy)
618e7e93795SLois Curfman McInnes {
61963ba0a88SBarry Smith   PetscErrorCode ierr;
62063ba0a88SBarry Smith 
6213a40ed3dSBarry Smith   PetscFunctionBegin;
6220700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
6233f149594SLisandro Dalcin   PetscValidPointer(reason,6);
6243f149594SLisandro Dalcin 
62506ee9f85SBarry Smith   *reason = SNES_CONVERGED_ITERATING;
62606ee9f85SBarry Smith 
62706ee9f85SBarry Smith   if (!it) {
62806ee9f85SBarry Smith     /* set parameter for default relative tolerance convergence test */
62906ee9f85SBarry Smith     snes->ttol = fnorm*snes->rtol;
63006ee9f85SBarry Smith   }
6318146f6ebSBarry Smith   if (PetscIsInfOrNanReal(fnorm)) {
632ae15b995SBarry Smith     ierr    = PetscInfo(snes,"Failed to converged, function norm is NaN\n");CHKERRQ(ierr);
633184914b5SBarry Smith     *reason = SNES_DIVERGED_FNORM_NAN;
63470441072SBarry Smith   } else if (fnorm < snes->abstol) {
6358f1a2a5eSBarry Smith     ierr    = PetscInfo2(snes,"Converged due to function norm %14.12e < %14.12e\n",(double)fnorm,(double)snes->abstol);CHKERRQ(ierr);
636184914b5SBarry Smith     *reason = SNES_CONVERGED_FNORM_ABS;
63743e71028SBarry Smith   } else if (snes->nfuncs >= snes->max_funcs) {
638ae15b995SBarry Smith     ierr    = PetscInfo2(snes,"Exceeded maximum number of function evaluations: %D > %D\n",snes->nfuncs,snes->max_funcs);CHKERRQ(ierr);
639184914b5SBarry Smith     *reason = SNES_DIVERGED_FUNCTION_COUNT;
64006ee9f85SBarry Smith   }
64106ee9f85SBarry Smith 
64206ee9f85SBarry Smith   if (it && !*reason) {
64306ee9f85SBarry Smith     if (fnorm <= snes->ttol) {
6448f1a2a5eSBarry Smith       ierr    = PetscInfo2(snes,"Converged due to function norm %14.12e < %14.12e (relative tolerance)\n",(double)fnorm,(double)snes->ttol);CHKERRQ(ierr);
64506ee9f85SBarry Smith       *reason = SNES_CONVERGED_FNORM_RELATIVE;
646c60f73f4SPeter Brune     } else if (snorm < snes->stol*xnorm) {
647c60f73f4SPeter 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);
648c60f73f4SPeter Brune       *reason = SNES_CONVERGED_SNORM_RELATIVE;
64906ee9f85SBarry Smith     }
650e7e93795SLois Curfman McInnes   }
6513a40ed3dSBarry Smith   PetscFunctionReturn(0);
652e7e93795SLois Curfman McInnes }
6533f149594SLisandro Dalcin 
6543f149594SLisandro Dalcin #undef __FUNCT__
655e2a6519dSDmitry Karpeev #define __FUNCT__ "SNESConvergedSkip"
6563f149594SLisandro Dalcin /*@C
657e2a6519dSDmitry Karpeev    SNESConvergedSkip - Convergence test for SNES that NEVER returns as
6583f149594SLisandro Dalcin    converged, UNLESS the maximum number of iteration have been reached.
6593f149594SLisandro Dalcin 
6603f9fe445SBarry Smith    Logically Collective on SNES
6613f149594SLisandro Dalcin 
6623f149594SLisandro Dalcin    Input Parameters:
6633f149594SLisandro Dalcin +  snes - the SNES context
6643f149594SLisandro Dalcin .  it - the iteration (0 indicates before any Newton steps)
6653f149594SLisandro Dalcin .  xnorm - 2-norm of current iterate
666c60f73f4SPeter Brune .  snorm - 2-norm of current step
6673f149594SLisandro Dalcin .  fnorm - 2-norm of function at current iterate
6683f149594SLisandro Dalcin -  dummy - unused context
6693f149594SLisandro Dalcin 
6703f149594SLisandro Dalcin    Output Parameter:
67185385478SLisandro Dalcin .   reason  - SNES_CONVERGED_ITERATING, SNES_CONVERGED_ITS, or SNES_DIVERGED_FNORM_NAN
6723f149594SLisandro Dalcin 
6733f149594SLisandro Dalcin    Notes:
6743f149594SLisandro Dalcin    Convergence is then declared after a fixed number of iterations have been used.
6753f149594SLisandro Dalcin 
6763f149594SLisandro Dalcin    Level: advanced
6773f149594SLisandro Dalcin 
6783f149594SLisandro Dalcin .keywords: SNES, nonlinear, skip, converged, convergence
6793f149594SLisandro Dalcin 
6803f149594SLisandro Dalcin .seealso: SNESSetConvergenceTest()
6813f149594SLisandro Dalcin @*/
682e2a6519dSDmitry Karpeev PetscErrorCode  SNESConvergedSkip(SNES snes,PetscInt it,PetscReal xnorm,PetscReal snorm,PetscReal fnorm,SNESConvergedReason *reason,void *dummy)
6833f149594SLisandro Dalcin {
6843f149594SLisandro Dalcin   PetscErrorCode ierr;
6853f149594SLisandro Dalcin 
6863f149594SLisandro Dalcin   PetscFunctionBegin;
6870700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
6883f149594SLisandro Dalcin   PetscValidPointer(reason,6);
6893f149594SLisandro Dalcin 
6903f149594SLisandro Dalcin   *reason = SNES_CONVERGED_ITERATING;
6913f149594SLisandro Dalcin 
6923f149594SLisandro Dalcin   if (fnorm != fnorm) {
6933f149594SLisandro Dalcin     ierr    = PetscInfo(snes,"Failed to converged, function norm is NaN\n");CHKERRQ(ierr);
6943f149594SLisandro Dalcin     *reason = SNES_DIVERGED_FNORM_NAN;
6953f149594SLisandro Dalcin   } else if (it == snes->max_its) {
6963f149594SLisandro Dalcin     *reason = SNES_CONVERGED_ITS;
6973f149594SLisandro Dalcin   }
6983f149594SLisandro Dalcin   PetscFunctionReturn(0);
6993f149594SLisandro Dalcin }
7003f149594SLisandro Dalcin 
70158c9b817SLisandro Dalcin #undef __FUNCT__
702fa0ddf94SBarry Smith #define __FUNCT__ "SNESSetWorkVecs"
7038d359177SBarry Smith /*@C
704fa0ddf94SBarry Smith   SNESSetWorkVecs - Gets a number of work vectors.
70558c9b817SLisandro Dalcin 
70658c9b817SLisandro Dalcin   Input Parameters:
70758c9b817SLisandro Dalcin . snes  - the SNES context
70858c9b817SLisandro Dalcin . nw - number of work vectors to allocate
70958c9b817SLisandro Dalcin 
71058c9b817SLisandro Dalcin    Level: developer
71158c9b817SLisandro Dalcin 
712fa0ddf94SBarry Smith    Developers Note: This is PETSC_EXTERN because it may be used by user written plugin SNES implementations
713fa0ddf94SBarry Smith 
71498acb6afSMatthew G Knepley @*/
715fa0ddf94SBarry Smith PetscErrorCode SNESSetWorkVecs(SNES snes,PetscInt nw)
71658c9b817SLisandro Dalcin {
717c5ed8070SMatthew G. Knepley   DM             dm;
718c5ed8070SMatthew G. Knepley   Vec            v;
71958c9b817SLisandro Dalcin   PetscErrorCode ierr;
72058c9b817SLisandro Dalcin 
72158c9b817SLisandro Dalcin   PetscFunctionBegin;
72258c9b817SLisandro Dalcin   if (snes->work) {ierr = VecDestroyVecs(snes->nwork,&snes->work);CHKERRQ(ierr);}
72358c9b817SLisandro Dalcin   snes->nwork = nw;
724f5af7f23SKarl Rupp 
725c5ed8070SMatthew G. Knepley   ierr = SNESGetDM(snes, &dm);CHKERRQ(ierr);
726c5ed8070SMatthew G. Knepley   ierr = DMGetGlobalVector(dm, &v);CHKERRQ(ierr);
727c5ed8070SMatthew G. Knepley   ierr = VecDuplicateVecs(v,snes->nwork,&snes->work);CHKERRQ(ierr);
728c5ed8070SMatthew G. Knepley   ierr = DMRestoreGlobalVector(dm, &v);CHKERRQ(ierr);
72958c9b817SLisandro Dalcin   ierr = PetscLogObjectParents(snes,nw,snes->work);CHKERRQ(ierr);
73058c9b817SLisandro Dalcin   PetscFunctionReturn(0);
73158c9b817SLisandro Dalcin }
732