xref: /petsc/src/snes/interface/snesut.c (revision 957f8de382c65b06af86c0b9658951f90e2a375c)
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);
209*957f8de3SLisandro Dalcin   ierr = PetscDrawLGSetFromOptions(drawlg);CHKERRQ(ierr);
210e5f7ee39SBarry Smith   ierr = PetscDrawLGGetAxis(drawlg,&axis);CHKERRQ(ierr);
211e5f7ee39SBarry Smith   ierr = PetscDrawAxisSetLabels(axis,"Convergence of Residual Norm","Iteration","Residual Norm");CHKERRQ(ierr);
212e5f7ee39SBarry Smith   ierr = PetscDrawLGSetLegend(drawlg,names);CHKERRQ(ierr);
213e5f7ee39SBarry Smith   ierr = PetscLogObjectParent((PetscObject)drawlg,(PetscObject)draw);CHKERRQ(ierr);
214e5f7ee39SBarry Smith 
215435c5a64SBarry Smith   ierr = PetscMalloc1(3,objs);CHKERRQ(ierr);
216e5f7ee39SBarry Smith   (*objs)[1] = (PetscObject)drawlg;
217435c5a64SBarry Smith   (*objs)[2] = (PetscObject)draw;
218e5f7ee39SBarry Smith   PetscFunctionReturn(0);
219e5f7ee39SBarry Smith }
220e5f7ee39SBarry Smith 
221e5f7ee39SBarry Smith #undef __FUNCT__
222e5f7ee39SBarry Smith #define __FUNCT__ "KSPMonitorSNESLGResidualNorm"
223e5f7ee39SBarry Smith PetscErrorCode  KSPMonitorSNESLGResidualNorm(KSP ksp,PetscInt n,PetscReal rnorm,PetscObject *objs)
224e5f7ee39SBarry Smith {
225e5f7ee39SBarry Smith   PetscDrawLG    lg = (PetscDrawLG) objs[1];
226e5f7ee39SBarry Smith   PetscErrorCode ierr;
227e5f7ee39SBarry Smith   PetscReal      y[2];
228e5f7ee39SBarry Smith   SNES           snes = (SNES) objs[0];
229e5f7ee39SBarry Smith   Vec            snes_solution,work1,work2;
230e5f7ee39SBarry Smith 
231e5f7ee39SBarry Smith   PetscFunctionBegin;
232e5f7ee39SBarry Smith   if (rnorm > 0.0) y[0] = PetscLog10Real(rnorm);
233e5f7ee39SBarry Smith   else y[0] = -15.0;
234e5f7ee39SBarry Smith 
235e5f7ee39SBarry Smith   ierr = SNESGetSolution(snes,&snes_solution);CHKERRQ(ierr);
236e5f7ee39SBarry Smith   ierr = VecDuplicate(snes_solution,&work1);CHKERRQ(ierr);
237e5f7ee39SBarry Smith   ierr = VecDuplicate(snes_solution,&work2);CHKERRQ(ierr);
238e5f7ee39SBarry Smith   ierr = KSPBuildSolution(ksp,work1,NULL);CHKERRQ(ierr);
239e5f7ee39SBarry Smith   ierr = VecAYPX(work1,-1.0,snes_solution);CHKERRQ(ierr);
240e5f7ee39SBarry Smith   ierr = SNESComputeFunction(snes,work1,work2);CHKERRQ(ierr);
241e5f7ee39SBarry Smith   ierr = VecNorm(work2,NORM_2,y+1);CHKERRQ(ierr);
242e5f7ee39SBarry Smith   if (y[1] > 0.0) y[1] = PetscLog10Real(y[1]);
243e5f7ee39SBarry Smith   else y[1] = -15.0;
244e5f7ee39SBarry Smith   ierr = VecDestroy(&work1);CHKERRQ(ierr);
245e5f7ee39SBarry Smith   ierr = VecDestroy(&work2);CHKERRQ(ierr);
246e5f7ee39SBarry Smith 
247e5f7ee39SBarry Smith   ierr = PetscDrawLGAddPoint(lg,NULL,y);CHKERRQ(ierr);
248e5f7ee39SBarry Smith   if (n < 20 || !(n % 5)) {
249e5f7ee39SBarry Smith     ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr);
250e5f7ee39SBarry Smith   }
251e5f7ee39SBarry Smith   PetscFunctionReturn(0);
252e5f7ee39SBarry Smith }
253e5f7ee39SBarry Smith 
254e5f7ee39SBarry Smith #undef __FUNCT__
255e5f7ee39SBarry Smith #define __FUNCT__ "KSPMonitorSNESLGResidualNormDestroy"
256e5f7ee39SBarry Smith /*@
257e5f7ee39SBarry Smith    KSPMonitorSNESLGResidualNormDestroy - Destroys a line graph context that was created
258e5f7ee39SBarry Smith    with KSPMonitorSNESLGResidualNormCreate().
259e5f7ee39SBarry Smith 
260e5f7ee39SBarry Smith    Collective on KSP
261e5f7ee39SBarry Smith 
262e5f7ee39SBarry Smith    Input Parameter:
263e5f7ee39SBarry Smith .  draw - the drawing context
264e5f7ee39SBarry Smith 
265e5f7ee39SBarry Smith    Level: intermediate
266e5f7ee39SBarry Smith 
267e5f7ee39SBarry Smith .keywords: KSP, monitor, line graph, destroy
268e5f7ee39SBarry Smith 
269e5f7ee39SBarry Smith .seealso: KSPMonitorSNESLGResidualNormCreate(), KSPMonitorSNESLGTrueResidualDestroy(), KSPMonitorSet()
270e5f7ee39SBarry Smith @*/
271e5f7ee39SBarry Smith PetscErrorCode  KSPMonitorSNESLGResidualNormDestroy(PetscObject **objs)
272e5f7ee39SBarry Smith {
273e5f7ee39SBarry Smith   PetscErrorCode ierr;
274e5f7ee39SBarry Smith   PetscDrawLG    drawlg = (PetscDrawLG) (*objs)[1];
275435c5a64SBarry Smith   PetscDraw      draw = (PetscDraw) (*objs)[2];
276e5f7ee39SBarry Smith 
277e5f7ee39SBarry Smith   PetscFunctionBegin;
278e5f7ee39SBarry Smith   ierr = PetscDrawDestroy(&draw);CHKERRQ(ierr);
279e5f7ee39SBarry Smith   ierr = PetscDrawLGDestroy(&drawlg);CHKERRQ(ierr);
280e5f7ee39SBarry Smith   ierr = PetscFree(*objs);CHKERRQ(ierr);
281e5f7ee39SBarry Smith   PetscFunctionReturn(0);
282e5f7ee39SBarry Smith }
283e5f7ee39SBarry Smith 
284a5c2985bSBarry Smith #undef __FUNCT__
285a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorDefault"
2864b828684SBarry Smith /*@C
287a6570f20SBarry Smith    SNESMonitorDefault - Monitors progress of the SNES solvers (default).
288e7e93795SLois Curfman McInnes 
289c7afd0dbSLois Curfman McInnes    Collective on SNES
290c7afd0dbSLois Curfman McInnes 
291e7e93795SLois Curfman McInnes    Input Parameters:
292c7afd0dbSLois Curfman McInnes +  snes - the SNES context
293e7e93795SLois Curfman McInnes .  its - iteration number
2944b27c08aSLois Curfman McInnes .  fgnorm - 2-norm of residual
295c7afd0dbSLois Curfman McInnes -  dummy - unused context
296fee21e36SBarry Smith 
297e7e93795SLois Curfman McInnes    Notes:
2984b27c08aSLois Curfman McInnes    This routine prints the residual norm at each iteration.
299e7e93795SLois Curfman McInnes 
30036851e7fSLois Curfman McInnes    Level: intermediate
30136851e7fSLois Curfman McInnes 
302e7e93795SLois Curfman McInnes .keywords: SNES, nonlinear, default, monitor, norm
303e7e93795SLois Curfman McInnes 
304a6570f20SBarry Smith .seealso: SNESMonitorSet(), SNESMonitorSolution()
305e7e93795SLois Curfman McInnes @*/
3067087cfbeSBarry Smith PetscErrorCode  SNESMonitorDefault(SNES snes,PetscInt its,PetscReal fgnorm,void *dummy)
307e7e93795SLois Curfman McInnes {
308dfbe8321SBarry Smith   PetscErrorCode ierr;
309ce94432eSBarry Smith   PetscViewer    viewer = dummy ? (PetscViewer) dummy : PETSC_VIEWER_STDOUT_(PetscObjectComm((PetscObject)snes));
310d132466eSBarry Smith 
3113a40ed3dSBarry Smith   PetscFunctionBegin;
312649052a6SBarry Smith   ierr = PetscViewerASCIIAddTab(viewer,((PetscObject)snes)->tablevel);CHKERRQ(ierr);
313649052a6SBarry Smith   ierr = PetscViewerASCIIPrintf(viewer,"%3D SNES Function norm %14.12e \n",its,(double)fgnorm);CHKERRQ(ierr);
314649052a6SBarry Smith   ierr = PetscViewerASCIISubtractTab(viewer,((PetscObject)snes)->tablevel);CHKERRQ(ierr);
3153a40ed3dSBarry Smith   PetscFunctionReturn(0);
316e7e93795SLois Curfman McInnes }
3173f1db9ecSBarry Smith 
318b271bb04SBarry Smith #undef __FUNCT__
3192e7541e6SPeter Brune #define __FUNCT__ "SNESMonitorJacUpdateSpectrum"
320a80ad3e0SBarry Smith PetscErrorCode SNESMonitorJacUpdateSpectrum(SNES snes,PetscInt it,PetscReal fnorm,void *ctx)
321a80ad3e0SBarry Smith {
322196da8b6SPeter Brune #if defined(PETSC_MISSING_LAPACK_GEEV)
323ce94432eSBarry Smith   SETERRQ(PetscObjectComm((PetscObject)snes),PETSC_ERR_SUP,"GEEV - Lapack routine is unavailable\nNot able to provide eigen values.");
324196da8b6SPeter Brune #elif defined(PETSC_HAVE_ESSL)
325ce94432eSBarry Smith   SETERRQ(PetscObjectComm((PetscObject)snes),PETSC_ERR_SUP,"GEEV - No support for ESSL Lapack Routines");
326196da8b6SPeter Brune #else
3272e7541e6SPeter Brune   Vec            X;
3282e7541e6SPeter Brune   Mat            J,dJ,dJdense;
3292e7541e6SPeter Brune   PetscErrorCode ierr;
330d1e9a80fSBarry Smith   PetscErrorCode (*func)(SNES,Vec,Mat,Mat,void*);
3312e7541e6SPeter Brune   PetscInt       n,i;
3322e7541e6SPeter Brune   PetscBLASInt   nb,lwork;
3332e7541e6SPeter Brune   PetscReal      *eigr,*eigi;
3342e7541e6SPeter Brune   PetscScalar    *work;
3352e7541e6SPeter Brune   PetscScalar    *a;
3362e7541e6SPeter Brune 
3372e7541e6SPeter Brune   PetscFunctionBegin;
3382e7541e6SPeter Brune   if (it == 0) PetscFunctionReturn(0);
3392e7541e6SPeter Brune   /* create the difference between the current update and the current jacobian */
3402e7541e6SPeter Brune   ierr = SNESGetSolution(snes,&X);CHKERRQ(ierr);
341d1e9a80fSBarry Smith   ierr = SNESGetJacobian(snes,NULL,&J,&func,NULL);CHKERRQ(ierr);
3422e7541e6SPeter Brune   ierr = MatDuplicate(J,MAT_COPY_VALUES,&dJ);CHKERRQ(ierr);
343d1e9a80fSBarry Smith   ierr = SNESComputeJacobian(snes,X,dJ,dJ);CHKERRQ(ierr);
3442e7541e6SPeter Brune   ierr = MatAXPY(dJ,-1.0,J,SAME_NONZERO_PATTERN);CHKERRQ(ierr);
345f5af7f23SKarl Rupp 
3462e7541e6SPeter Brune   /* compute the spectrum directly */
3472e7541e6SPeter Brune   ierr  = MatConvert(dJ,MATSEQDENSE,MAT_INITIAL_MATRIX,&dJdense);CHKERRQ(ierr);
3480298fd71SBarry Smith   ierr  = MatGetSize(dJ,&n,NULL);CHKERRQ(ierr);
349c5df96a5SBarry Smith   ierr  = PetscBLASIntCast(n,&nb);CHKERRQ(ierr);
3502e7541e6SPeter Brune   lwork = 3*nb;
351785e854fSJed Brown   ierr  = PetscMalloc1(n,&eigr);CHKERRQ(ierr);
352785e854fSJed Brown   ierr  = PetscMalloc1(n,&eigi);CHKERRQ(ierr);
353785e854fSJed Brown   ierr  = PetscMalloc1(lwork,&work);CHKERRQ(ierr);
3548c778c55SBarry Smith   ierr  = MatDenseGetArray(dJdense,&a);CHKERRQ(ierr);
3552e7541e6SPeter Brune #if !defined(PETSC_USE_COMPLEX)
3562e7541e6SPeter Brune   {
3572e7541e6SPeter Brune     PetscBLASInt lierr;
3582e7541e6SPeter Brune     ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
3598b83055fSJed Brown     PetscStackCallBLAS("LAPACKgeev",LAPACKgeev_("N","N",&nb,a,&nb,eigr,eigi,NULL,&nb,NULL,&nb,work,&lwork,&lierr));
3602e7541e6SPeter Brune     if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"geev() error %d",lierr);
3612e7541e6SPeter Brune     ierr = PetscFPTrapPop();CHKERRQ(ierr);
3622e7541e6SPeter Brune   }
3632e7541e6SPeter Brune #else
3642e7541e6SPeter Brune   SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not coded for complex");
3652e7541e6SPeter Brune #endif
366ce94432eSBarry Smith   PetscPrintf(PetscObjectComm((PetscObject)snes),"Eigenvalues of J_%d - J_%d:\n",it,it-1);CHKERRQ(ierr);
3672e7541e6SPeter Brune   for (i=0;i<n;i++) {
3688fa295daSBarry Smith     PetscPrintf(PetscObjectComm((PetscObject)snes),"%5d: %20.5g + %20.5gi\n",i,(double)eigr[i],(double)eigi[i]);CHKERRQ(ierr);
3692e7541e6SPeter Brune   }
3708c778c55SBarry Smith   ierr = MatDenseRestoreArray(dJdense,&a);CHKERRQ(ierr);
3712e7541e6SPeter Brune   ierr = MatDestroy(&dJ);CHKERRQ(ierr);
3722e7541e6SPeter Brune   ierr = MatDestroy(&dJdense);CHKERRQ(ierr);
3732e7541e6SPeter Brune   ierr = PetscFree(eigr);CHKERRQ(ierr);
3742e7541e6SPeter Brune   ierr = PetscFree(eigi);CHKERRQ(ierr);
3752e7541e6SPeter Brune   ierr = PetscFree(work);CHKERRQ(ierr);
3762e7541e6SPeter Brune   PetscFunctionReturn(0);
377196da8b6SPeter Brune #endif
3782e7541e6SPeter Brune }
3792e7541e6SPeter Brune 
3802e7541e6SPeter Brune #undef __FUNCT__
381b271bb04SBarry Smith #define __FUNCT__ "SNESMonitorRange_Private"
3827087cfbeSBarry Smith PetscErrorCode  SNESMonitorRange_Private(SNES snes,PetscInt it,PetscReal *per)
383b271bb04SBarry Smith {
384b271bb04SBarry Smith   PetscErrorCode ierr;
385b271bb04SBarry Smith   Vec            resid;
386b271bb04SBarry Smith   PetscReal      rmax,pwork;
387b271bb04SBarry Smith   PetscInt       i,n,N;
388b271bb04SBarry Smith   PetscScalar    *r;
389b271bb04SBarry Smith 
390b271bb04SBarry Smith   PetscFunctionBegin;
391b271bb04SBarry Smith   ierr  = SNESGetFunction(snes,&resid,0,0);CHKERRQ(ierr);
392b271bb04SBarry Smith   ierr  = VecNorm(resid,NORM_INFINITY,&rmax);CHKERRQ(ierr);
393b271bb04SBarry Smith   ierr  = VecGetLocalSize(resid,&n);CHKERRQ(ierr);
394b271bb04SBarry Smith   ierr  = VecGetSize(resid,&N);CHKERRQ(ierr);
395b271bb04SBarry Smith   ierr  = VecGetArray(resid,&r);CHKERRQ(ierr);
396b271bb04SBarry Smith   pwork = 0.0;
397b271bb04SBarry Smith   for (i=0; i<n; i++) {
398b271bb04SBarry Smith     pwork += (PetscAbsScalar(r[i]) > .20*rmax);
399b271bb04SBarry Smith   }
400ce94432eSBarry Smith   ierr = MPI_Allreduce(&pwork,per,1,MPIU_REAL,MPIU_SUM,PetscObjectComm((PetscObject)snes));CHKERRQ(ierr);
401b271bb04SBarry Smith   ierr = VecRestoreArray(resid,&r);CHKERRQ(ierr);
402b271bb04SBarry Smith   *per = *per/N;
403b271bb04SBarry Smith   PetscFunctionReturn(0);
404b271bb04SBarry Smith }
405b271bb04SBarry Smith 
406b271bb04SBarry Smith #undef __FUNCT__
407b271bb04SBarry Smith #define __FUNCT__ "SNESMonitorRange"
408b271bb04SBarry Smith /*@C
409b271bb04SBarry Smith    SNESMonitorRange - Prints the percentage of residual elements that are more then 10 percent of the maximum value.
410b271bb04SBarry Smith 
411b271bb04SBarry Smith    Collective on SNES
412b271bb04SBarry Smith 
413b271bb04SBarry Smith    Input Parameters:
414b271bb04SBarry Smith +  snes   - iterative context
415b271bb04SBarry Smith .  it    - iteration number
416b271bb04SBarry Smith .  rnorm - 2-norm (preconditioned) residual value (may be estimated).
417b271bb04SBarry Smith -  dummy - unused monitor context
418b271bb04SBarry Smith 
419b271bb04SBarry Smith    Options Database Key:
420b271bb04SBarry Smith .  -snes_monitor_range - Activates SNESMonitorRange()
421b271bb04SBarry Smith 
422b271bb04SBarry Smith    Level: intermediate
423b271bb04SBarry Smith 
424b271bb04SBarry Smith .keywords: SNES, default, monitor, residual
425b271bb04SBarry Smith 
426b271bb04SBarry Smith .seealso: SNESMonitorSet(), SNESMonitorDefault(), SNESMonitorLGCreate()
427b271bb04SBarry Smith @*/
4287087cfbeSBarry Smith PetscErrorCode  SNESMonitorRange(SNES snes,PetscInt it,PetscReal rnorm,void *dummy)
429b271bb04SBarry Smith {
430b271bb04SBarry Smith   PetscErrorCode ierr;
431b271bb04SBarry Smith   PetscReal      perc,rel;
432ce94432eSBarry Smith   PetscViewer    viewer = dummy ? (PetscViewer) dummy : PETSC_VIEWER_STDOUT_(PetscObjectComm((PetscObject)snes));
433b271bb04SBarry Smith   /* should be in a MonitorRangeContext */
434b271bb04SBarry Smith   static PetscReal prev;
435b271bb04SBarry Smith 
436b271bb04SBarry Smith   PetscFunctionBegin;
437b271bb04SBarry Smith   if (!it) prev = rnorm;
438b271bb04SBarry Smith   ierr = SNESMonitorRange_Private(snes,it,&perc);CHKERRQ(ierr);
439b271bb04SBarry Smith 
440b271bb04SBarry Smith   rel  = (prev - rnorm)/prev;
441b271bb04SBarry Smith   prev = rnorm;
442649052a6SBarry Smith   ierr = PetscViewerASCIIAddTab(viewer,((PetscObject)snes)->tablevel);CHKERRQ(ierr);
4436712e2f1SBarry 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);
444649052a6SBarry Smith   ierr = PetscViewerASCIISubtractTab(viewer,((PetscObject)snes)->tablevel);CHKERRQ(ierr);
445b271bb04SBarry Smith   PetscFunctionReturn(0);
446b271bb04SBarry Smith }
447b271bb04SBarry Smith 
448eabae89aSBarry Smith typedef struct {
449649052a6SBarry Smith   PetscViewer viewer;
450eabae89aSBarry Smith   PetscReal   *history;
451a6570f20SBarry Smith } SNESMonitorRatioContext;
452eabae89aSBarry Smith 
4533a7fca6bSBarry Smith #undef __FUNCT__
454a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorRatio"
4553a7fca6bSBarry Smith /*@C
456a6570f20SBarry Smith    SNESMonitorRatio - Monitors progress of the SNES solvers by printing the ratio
4574b27c08aSLois Curfman McInnes    of residual norm at each iteration to the previous.
4583a7fca6bSBarry Smith 
4593a7fca6bSBarry Smith    Collective on SNES
4603a7fca6bSBarry Smith 
4613a7fca6bSBarry Smith    Input Parameters:
4623a7fca6bSBarry Smith +  snes - the SNES context
4633a7fca6bSBarry Smith .  its - iteration number
4643a7fca6bSBarry Smith .  fgnorm - 2-norm of residual (or gradient)
465eabae89aSBarry Smith -  dummy -  context of monitor
4663a7fca6bSBarry Smith 
4673a7fca6bSBarry Smith    Level: intermediate
4683a7fca6bSBarry Smith 
4693a7fca6bSBarry Smith .keywords: SNES, nonlinear, monitor, norm
4703a7fca6bSBarry Smith 
471a6570f20SBarry Smith .seealso: SNESMonitorSet(), SNESMonitorSolution()
4723a7fca6bSBarry Smith @*/
4737087cfbeSBarry Smith PetscErrorCode  SNESMonitorRatio(SNES snes,PetscInt its,PetscReal fgnorm,void *dummy)
4743a7fca6bSBarry Smith {
475dfbe8321SBarry Smith   PetscErrorCode          ierr;
47677431f27SBarry Smith   PetscInt                len;
47787828ca2SBarry Smith   PetscReal               *history;
478a6570f20SBarry Smith   SNESMonitorRatioContext *ctx = (SNESMonitorRatioContext*)dummy;
4793a7fca6bSBarry Smith 
4803a7fca6bSBarry Smith   PetscFunctionBegin;
4810298fd71SBarry Smith   ierr = SNESGetConvergenceHistory(snes,&history,NULL,&len);CHKERRQ(ierr);
482649052a6SBarry Smith   ierr = PetscViewerASCIIAddTab(ctx->viewer,((PetscObject)snes)->tablevel);CHKERRQ(ierr);
483958c9bccSBarry Smith   if (!its || !history || its > len) {
484649052a6SBarry Smith     ierr = PetscViewerASCIIPrintf(ctx->viewer,"%3D SNES Function norm %14.12e \n",its,(double)fgnorm);CHKERRQ(ierr);
4853a7fca6bSBarry Smith   } else {
48687828ca2SBarry Smith     PetscReal ratio = fgnorm/history[its-1];
4878f1a2a5eSBarry Smith     ierr = PetscViewerASCIIPrintf(ctx->viewer,"%3D SNES Function norm %14.12e %14.12e \n",its,(double)fgnorm,(double)ratio);CHKERRQ(ierr);
4883a7fca6bSBarry Smith   }
489649052a6SBarry Smith   ierr = PetscViewerASCIISubtractTab(ctx->viewer,((PetscObject)snes)->tablevel);CHKERRQ(ierr);
4903a7fca6bSBarry Smith   PetscFunctionReturn(0);
4913a7fca6bSBarry Smith }
4923a7fca6bSBarry Smith 
4933a7fca6bSBarry Smith /*
4943a7fca6bSBarry Smith    If the we set the history monitor space then we must destroy it
4953a7fca6bSBarry Smith */
4963a7fca6bSBarry Smith #undef __FUNCT__
497a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorRatioDestroy"
498c2efdce3SBarry Smith PetscErrorCode SNESMonitorRatioDestroy(void **ct)
4993a7fca6bSBarry Smith {
500dfbe8321SBarry Smith   PetscErrorCode          ierr;
501c2efdce3SBarry Smith   SNESMonitorRatioContext *ctx = *(SNESMonitorRatioContext**)ct;
5023a7fca6bSBarry Smith 
5033a7fca6bSBarry Smith   PetscFunctionBegin;
50405b42c5fSBarry Smith   ierr = PetscFree(ctx->history);CHKERRQ(ierr);
505649052a6SBarry Smith   ierr = PetscViewerDestroy(&ctx->viewer);CHKERRQ(ierr);
506eabae89aSBarry Smith   ierr = PetscFree(ctx);CHKERRQ(ierr);
5073a7fca6bSBarry Smith   PetscFunctionReturn(0);
5083a7fca6bSBarry Smith }
5093a7fca6bSBarry Smith 
5103a7fca6bSBarry Smith #undef __FUNCT__
511a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorSetRatio"
5123a7fca6bSBarry Smith /*@C
513a6570f20SBarry Smith    SNESMonitorSetRatio - Sets SNES to use a monitor that prints the
5144b27c08aSLois Curfman McInnes    ratio of the function norm at each iteration.
5153a7fca6bSBarry Smith 
5163a7fca6bSBarry Smith    Collective on SNES
5173a7fca6bSBarry Smith 
5183a7fca6bSBarry Smith    Input Parameters:
519eabae89aSBarry Smith +   snes - the SNES context
520eabae89aSBarry Smith -   viewer - ASCII viewer to print output
5213a7fca6bSBarry Smith 
5223a7fca6bSBarry Smith    Level: intermediate
5233a7fca6bSBarry Smith 
5243a7fca6bSBarry Smith .keywords: SNES, nonlinear, monitor, norm
5253a7fca6bSBarry Smith 
526a6570f20SBarry Smith .seealso: SNESMonitorSet(), SNESMonitorSolution(), SNESMonitorDefault()
5273a7fca6bSBarry Smith @*/
528649052a6SBarry Smith PetscErrorCode  SNESMonitorSetRatio(SNES snes,PetscViewer viewer)
5293a7fca6bSBarry Smith {
530dfbe8321SBarry Smith   PetscErrorCode          ierr;
531a6570f20SBarry Smith   SNESMonitorRatioContext *ctx;
53287828ca2SBarry Smith   PetscReal               *history;
5333a7fca6bSBarry Smith 
5343a7fca6bSBarry Smith   PetscFunctionBegin;
535eabae89aSBarry Smith   if (!viewer) {
536ce94432eSBarry Smith     ierr = PetscViewerASCIIOpen(PetscObjectComm((PetscObject)snes),"stdout",&viewer);CHKERRQ(ierr);
537eabae89aSBarry Smith     ierr = PetscObjectReference((PetscObject)viewer);CHKERRQ(ierr);
538eabae89aSBarry Smith   }
539b00a9115SJed Brown   ierr = PetscNewLog(snes,&ctx);CHKERRQ(ierr);
5400298fd71SBarry Smith   ierr = SNESGetConvergenceHistory(snes,&history,NULL,NULL);CHKERRQ(ierr);
5413a7fca6bSBarry Smith   if (!history) {
542785e854fSJed Brown     ierr = PetscMalloc1(100,&ctx->history);CHKERRQ(ierr);
543eabae89aSBarry Smith     ierr = SNESSetConvergenceHistory(snes,ctx->history,0,100,PETSC_TRUE);CHKERRQ(ierr);
5443a7fca6bSBarry Smith   }
545eabae89aSBarry Smith   ctx->viewer = viewer;
546f5af7f23SKarl Rupp 
547a6570f20SBarry Smith   ierr = SNESMonitorSet(snes,SNESMonitorRatio,ctx,SNESMonitorRatioDestroy);CHKERRQ(ierr);
5483a7fca6bSBarry Smith   PetscFunctionReturn(0);
5493a7fca6bSBarry Smith }
5503a7fca6bSBarry Smith 
551e7e93795SLois Curfman McInnes /* ---------------------------------------------------------------- */
5524a2ae208SSatish Balay #undef __FUNCT__
553a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorDefaultShort"
554be1f7002SBarry Smith /*
555a6570f20SBarry Smith      Default (short) SNES Monitor, same as SNESMonitorDefault() except
556be1f7002SBarry Smith   it prints fewer digits of the residual as the residual gets smaller.
557be1f7002SBarry Smith   This is because the later digits are meaningless and are often
558be1f7002SBarry Smith   different on different machines; by using this routine different
559be1f7002SBarry Smith   machines will usually generate the same output.
560be1f7002SBarry Smith */
5617087cfbeSBarry Smith PetscErrorCode  SNESMonitorDefaultShort(SNES snes,PetscInt its,PetscReal fgnorm,void *dummy)
562e7e93795SLois Curfman McInnes {
563dfbe8321SBarry Smith   PetscErrorCode ierr;
564ce94432eSBarry Smith   PetscViewer    viewer = dummy ? (PetscViewer) dummy : PETSC_VIEWER_STDOUT_(PetscObjectComm((PetscObject)snes));
565d132466eSBarry Smith 
5663a40ed3dSBarry Smith   PetscFunctionBegin;
567649052a6SBarry Smith   ierr = PetscViewerASCIIAddTab(viewer,((PetscObject)snes)->tablevel);CHKERRQ(ierr);
5688f240d10SBarry Smith   if (fgnorm > 1.e-9) {
5698fa295daSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"%3D SNES Function norm %g \n",its,(double)fgnorm);CHKERRQ(ierr);
5703a40ed3dSBarry Smith   } else if (fgnorm > 1.e-11) {
5718fa295daSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"%3D SNES Function norm %5.3e \n",its,(double)fgnorm);CHKERRQ(ierr);
5723a40ed3dSBarry Smith   } else {
573649052a6SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"%3D SNES Function norm < 1.e-11\n",its);CHKERRQ(ierr);
574a34d58ebSBarry Smith   }
575649052a6SBarry Smith   ierr = PetscViewerASCIISubtractTab(viewer,((PetscObject)snes)->tablevel);CHKERRQ(ierr);
5763a40ed3dSBarry Smith   PetscFunctionReturn(0);
577e7e93795SLois Curfman McInnes }
578e7e93795SLois Curfman McInnes /* ---------------------------------------------------------------- */
5794a2ae208SSatish Balay #undef __FUNCT__
5808d359177SBarry Smith #define __FUNCT__ "SNESConvergedDefault"
5814b828684SBarry Smith /*@C
5828d359177SBarry Smith    SNESConvergedDefault - Convergence test of the solvers for
583f525115eSLois Curfman McInnes    systems of nonlinear equations (default).
584e7e93795SLois Curfman McInnes 
585c7afd0dbSLois Curfman McInnes    Collective on SNES
586c7afd0dbSLois Curfman McInnes 
587e7e93795SLois Curfman McInnes    Input Parameters:
588c7afd0dbSLois Curfman McInnes +  snes - the SNES context
58906ee9f85SBarry Smith .  it - the iteration (0 indicates before any Newton steps)
590e7e93795SLois Curfman McInnes .  xnorm - 2-norm of current iterate
591c60f73f4SPeter Brune .  snorm - 2-norm of current step
5927f3332b4SBarry Smith .  fnorm - 2-norm of function at current iterate
593c7afd0dbSLois Curfman McInnes -  dummy - unused context
594e7e93795SLois Curfman McInnes 
595184914b5SBarry Smith    Output Parameter:
596184914b5SBarry Smith .   reason  - one of
59770441072SBarry Smith $  SNES_CONVERGED_FNORM_ABS       - (fnorm < abstol),
598c60f73f4SPeter Brune $  SNES_CONVERGED_SNORM_RELATIVE  - (snorm < stol*xnorm),
599184914b5SBarry Smith $  SNES_CONVERGED_FNORM_RELATIVE  - (fnorm < rtol*fnorm0),
600184914b5SBarry Smith $  SNES_DIVERGED_FUNCTION_COUNT   - (nfct > maxf),
601184914b5SBarry Smith $  SNES_DIVERGED_FNORM_NAN        - (fnorm == NaN),
602184914b5SBarry Smith $  SNES_CONVERGED_ITERATING       - (otherwise),
603e7e93795SLois Curfman McInnes 
604e7e93795SLois Curfman McInnes    where
605c7afd0dbSLois Curfman McInnes +    maxf - maximum number of function evaluations,
606c7afd0dbSLois Curfman McInnes             set with SNESSetTolerances()
607c7afd0dbSLois Curfman McInnes .    nfct - number of function evaluations,
60870441072SBarry Smith .    abstol - absolute function norm tolerance,
609c7afd0dbSLois Curfman McInnes             set with SNESSetTolerances()
610c7afd0dbSLois Curfman McInnes -    rtol - relative function norm tolerance, set with SNESSetTolerances()
611fee21e36SBarry Smith 
61236851e7fSLois Curfman McInnes    Level: intermediate
61336851e7fSLois Curfman McInnes 
614e7e93795SLois Curfman McInnes .keywords: SNES, nonlinear, default, converged, convergence
615e7e93795SLois Curfman McInnes 
61671f87433Sdalcinl .seealso: SNESSetConvergenceTest()
617e7e93795SLois Curfman McInnes @*/
6188d359177SBarry Smith PetscErrorCode  SNESConvergedDefault(SNES snes,PetscInt it,PetscReal xnorm,PetscReal snorm,PetscReal fnorm,SNESConvergedReason *reason,void *dummy)
619e7e93795SLois Curfman McInnes {
62063ba0a88SBarry Smith   PetscErrorCode ierr;
62163ba0a88SBarry Smith 
6223a40ed3dSBarry Smith   PetscFunctionBegin;
6230700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
6243f149594SLisandro Dalcin   PetscValidPointer(reason,6);
6253f149594SLisandro Dalcin 
62606ee9f85SBarry Smith   *reason = SNES_CONVERGED_ITERATING;
62706ee9f85SBarry Smith 
62806ee9f85SBarry Smith   if (!it) {
62906ee9f85SBarry Smith     /* set parameter for default relative tolerance convergence test */
63006ee9f85SBarry Smith     snes->ttol = fnorm*snes->rtol;
63106ee9f85SBarry Smith   }
6328146f6ebSBarry Smith   if (PetscIsInfOrNanReal(fnorm)) {
633ae15b995SBarry Smith     ierr    = PetscInfo(snes,"Failed to converged, function norm is NaN\n");CHKERRQ(ierr);
634184914b5SBarry Smith     *reason = SNES_DIVERGED_FNORM_NAN;
63570441072SBarry Smith   } else if (fnorm < snes->abstol) {
6368f1a2a5eSBarry Smith     ierr    = PetscInfo2(snes,"Converged due to function norm %14.12e < %14.12e\n",(double)fnorm,(double)snes->abstol);CHKERRQ(ierr);
637184914b5SBarry Smith     *reason = SNES_CONVERGED_FNORM_ABS;
63843e71028SBarry Smith   } else if (snes->nfuncs >= snes->max_funcs) {
639ae15b995SBarry Smith     ierr    = PetscInfo2(snes,"Exceeded maximum number of function evaluations: %D > %D\n",snes->nfuncs,snes->max_funcs);CHKERRQ(ierr);
640184914b5SBarry Smith     *reason = SNES_DIVERGED_FUNCTION_COUNT;
64106ee9f85SBarry Smith   }
64206ee9f85SBarry Smith 
64306ee9f85SBarry Smith   if (it && !*reason) {
64406ee9f85SBarry Smith     if (fnorm <= snes->ttol) {
6458f1a2a5eSBarry Smith       ierr    = PetscInfo2(snes,"Converged due to function norm %14.12e < %14.12e (relative tolerance)\n",(double)fnorm,(double)snes->ttol);CHKERRQ(ierr);
64606ee9f85SBarry Smith       *reason = SNES_CONVERGED_FNORM_RELATIVE;
647c60f73f4SPeter Brune     } else if (snorm < snes->stol*xnorm) {
648c60f73f4SPeter 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);
649c60f73f4SPeter Brune       *reason = SNES_CONVERGED_SNORM_RELATIVE;
65006ee9f85SBarry Smith     }
651e7e93795SLois Curfman McInnes   }
6523a40ed3dSBarry Smith   PetscFunctionReturn(0);
653e7e93795SLois Curfman McInnes }
6543f149594SLisandro Dalcin 
6553f149594SLisandro Dalcin #undef __FUNCT__
656e2a6519dSDmitry Karpeev #define __FUNCT__ "SNESConvergedSkip"
6573f149594SLisandro Dalcin /*@C
658e2a6519dSDmitry Karpeev    SNESConvergedSkip - Convergence test for SNES that NEVER returns as
6593f149594SLisandro Dalcin    converged, UNLESS the maximum number of iteration have been reached.
6603f149594SLisandro Dalcin 
6613f9fe445SBarry Smith    Logically Collective on SNES
6623f149594SLisandro Dalcin 
6633f149594SLisandro Dalcin    Input Parameters:
6643f149594SLisandro Dalcin +  snes - the SNES context
6653f149594SLisandro Dalcin .  it - the iteration (0 indicates before any Newton steps)
6663f149594SLisandro Dalcin .  xnorm - 2-norm of current iterate
667c60f73f4SPeter Brune .  snorm - 2-norm of current step
6683f149594SLisandro Dalcin .  fnorm - 2-norm of function at current iterate
6693f149594SLisandro Dalcin -  dummy - unused context
6703f149594SLisandro Dalcin 
6713f149594SLisandro Dalcin    Output Parameter:
67285385478SLisandro Dalcin .   reason  - SNES_CONVERGED_ITERATING, SNES_CONVERGED_ITS, or SNES_DIVERGED_FNORM_NAN
6733f149594SLisandro Dalcin 
6743f149594SLisandro Dalcin    Notes:
6753f149594SLisandro Dalcin    Convergence is then declared after a fixed number of iterations have been used.
6763f149594SLisandro Dalcin 
6773f149594SLisandro Dalcin    Level: advanced
6783f149594SLisandro Dalcin 
6793f149594SLisandro Dalcin .keywords: SNES, nonlinear, skip, converged, convergence
6803f149594SLisandro Dalcin 
6813f149594SLisandro Dalcin .seealso: SNESSetConvergenceTest()
6823f149594SLisandro Dalcin @*/
683e2a6519dSDmitry Karpeev PetscErrorCode  SNESConvergedSkip(SNES snes,PetscInt it,PetscReal xnorm,PetscReal snorm,PetscReal fnorm,SNESConvergedReason *reason,void *dummy)
6843f149594SLisandro Dalcin {
6853f149594SLisandro Dalcin   PetscErrorCode ierr;
6863f149594SLisandro Dalcin 
6873f149594SLisandro Dalcin   PetscFunctionBegin;
6880700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
6893f149594SLisandro Dalcin   PetscValidPointer(reason,6);
6903f149594SLisandro Dalcin 
6913f149594SLisandro Dalcin   *reason = SNES_CONVERGED_ITERATING;
6923f149594SLisandro Dalcin 
6933f149594SLisandro Dalcin   if (fnorm != fnorm) {
6943f149594SLisandro Dalcin     ierr    = PetscInfo(snes,"Failed to converged, function norm is NaN\n");CHKERRQ(ierr);
6953f149594SLisandro Dalcin     *reason = SNES_DIVERGED_FNORM_NAN;
6963f149594SLisandro Dalcin   } else if (it == snes->max_its) {
6973f149594SLisandro Dalcin     *reason = SNES_CONVERGED_ITS;
6983f149594SLisandro Dalcin   }
6993f149594SLisandro Dalcin   PetscFunctionReturn(0);
7003f149594SLisandro Dalcin }
7013f149594SLisandro Dalcin 
70258c9b817SLisandro Dalcin #undef __FUNCT__
703fa0ddf94SBarry Smith #define __FUNCT__ "SNESSetWorkVecs"
7048d359177SBarry Smith /*@C
705fa0ddf94SBarry Smith   SNESSetWorkVecs - Gets a number of work vectors.
70658c9b817SLisandro Dalcin 
70758c9b817SLisandro Dalcin   Input Parameters:
70858c9b817SLisandro Dalcin . snes  - the SNES context
70958c9b817SLisandro Dalcin . nw - number of work vectors to allocate
71058c9b817SLisandro Dalcin 
71158c9b817SLisandro Dalcin    Level: developer
71258c9b817SLisandro Dalcin 
713fa0ddf94SBarry Smith    Developers Note: This is PETSC_EXTERN because it may be used by user written plugin SNES implementations
714fa0ddf94SBarry Smith 
71598acb6afSMatthew G Knepley @*/
716fa0ddf94SBarry Smith PetscErrorCode SNESSetWorkVecs(SNES snes,PetscInt nw)
71758c9b817SLisandro Dalcin {
718c5ed8070SMatthew G. Knepley   DM             dm;
719c5ed8070SMatthew G. Knepley   Vec            v;
72058c9b817SLisandro Dalcin   PetscErrorCode ierr;
72158c9b817SLisandro Dalcin 
72258c9b817SLisandro Dalcin   PetscFunctionBegin;
72358c9b817SLisandro Dalcin   if (snes->work) {ierr = VecDestroyVecs(snes->nwork,&snes->work);CHKERRQ(ierr);}
72458c9b817SLisandro Dalcin   snes->nwork = nw;
725f5af7f23SKarl Rupp 
726c5ed8070SMatthew G. Knepley   ierr = SNESGetDM(snes, &dm);CHKERRQ(ierr);
727c5ed8070SMatthew G. Knepley   ierr = DMGetGlobalVector(dm, &v);CHKERRQ(ierr);
728c5ed8070SMatthew G. Knepley   ierr = VecDuplicateVecs(v,snes->nwork,&snes->work);CHKERRQ(ierr);
729c5ed8070SMatthew G. Knepley   ierr = DMRestoreGlobalVector(dm, &v);CHKERRQ(ierr);
73058c9b817SLisandro Dalcin   ierr = PetscLogObjectParents(snes,nw,snes->work);CHKERRQ(ierr);
73158c9b817SLisandro Dalcin   PetscFunctionReturn(0);
73258c9b817SLisandro Dalcin }
733