xref: /petsc/src/snes/interface/snesut.c (revision af0996ce37bc06907c37d8d91773840993d61e62)
1e7e93795SLois Curfman McInnes 
2*af0996ceSBarry 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);
209957f8de3SLisandro 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 }
5782db13446SMatthew G. Knepley 
5792db13446SMatthew G. Knepley #undef __FUNCT__
5802db13446SMatthew G. Knepley #define __FUNCT__ "SNESMonitorDefaultField"
5812db13446SMatthew G. Knepley /*@C
5822db13446SMatthew G. Knepley   SNESMonitorDefaultField - Monitors progress of the SNES solvers, separated into fields.
5832db13446SMatthew G. Knepley 
5842db13446SMatthew G. Knepley   Collective on SNES
5852db13446SMatthew G. Knepley 
5862db13446SMatthew G. Knepley   Input Parameters:
5872db13446SMatthew G. Knepley + snes   - the SNES context
5882db13446SMatthew G. Knepley . its    - iteration number
5892db13446SMatthew G. Knepley . fgnorm - 2-norm of residual
5902db13446SMatthew G. Knepley - ctx    - the PetscViewer
5912db13446SMatthew G. Knepley 
5922db13446SMatthew G. Knepley   Notes:
5932db13446SMatthew G. Knepley   This routine uses the DM attached to the residual vector
5942db13446SMatthew G. Knepley 
5952db13446SMatthew G. Knepley   Level: intermediate
5962db13446SMatthew G. Knepley 
5972db13446SMatthew G. Knepley .keywords: SNES, nonlinear, field, monitor, norm
5982db13446SMatthew G. Knepley .seealso: SNESMonitorSet(), SNESMonitorSolution(), SNESMonitorDefault(), SNESMonitorDefaultShort()
5992db13446SMatthew G. Knepley @*/
6002db13446SMatthew G. Knepley PetscErrorCode SNESMonitorDefaultField(SNES snes, PetscInt its, PetscReal fgnorm, void *ctx)
6012db13446SMatthew G. Knepley {
6022db13446SMatthew G. Knepley   PetscViewer    viewer = ctx ? (PetscViewer) ctx : PETSC_VIEWER_STDOUT_(PetscObjectComm((PetscObject) snes));
6032db13446SMatthew G. Knepley   Vec            r;
6042db13446SMatthew G. Knepley   DM             dm;
6052db13446SMatthew G. Knepley   PetscReal      res[256];
6062db13446SMatthew G. Knepley   PetscInt       tablevel;
6072db13446SMatthew G. Knepley   PetscErrorCode ierr;
6082db13446SMatthew G. Knepley 
6092db13446SMatthew G. Knepley   PetscFunctionBegin;
6102db13446SMatthew G. Knepley   ierr = SNESGetFunction(snes, &r, NULL, NULL);CHKERRQ(ierr);
6112db13446SMatthew G. Knepley   ierr = VecGetDM(r, &dm);CHKERRQ(ierr);
6122db13446SMatthew G. Knepley   if (!dm) {ierr = SNESMonitorDefault(snes, its, fgnorm, ctx);CHKERRQ(ierr);}
6132db13446SMatthew G. Knepley   else {
6142db13446SMatthew G. Knepley     PetscSection s, gs;
6152db13446SMatthew G. Knepley     PetscInt     Nf, f;
6162db13446SMatthew G. Knepley 
6172db13446SMatthew G. Knepley     ierr = DMGetDefaultSection(dm, &s);CHKERRQ(ierr);
6182db13446SMatthew G. Knepley     ierr = DMGetDefaultGlobalSection(dm, &gs);CHKERRQ(ierr);
6192db13446SMatthew G. Knepley     if (!s || !gs) {ierr = SNESMonitorDefault(snes, its, fgnorm, ctx);CHKERRQ(ierr);}
6202db13446SMatthew G. Knepley     ierr = PetscSectionGetNumFields(s, &Nf);CHKERRQ(ierr);
6212db13446SMatthew G. Knepley     if (Nf > 256) SETERRQ1(PetscObjectComm((PetscObject) snes), PETSC_ERR_SUP, "Do not support %d fields > 256", Nf);
6222db13446SMatthew G. Knepley     ierr = PetscSectionVecNorm(s, gs, r, NORM_2, res);CHKERRQ(ierr);
6232db13446SMatthew G. Knepley     ierr = PetscObjectGetTabLevel((PetscObject) snes, &tablevel);CHKERRQ(ierr);
6242db13446SMatthew G. Knepley     ierr = PetscViewerASCIIAddTab(viewer, tablevel);CHKERRQ(ierr);
6252db13446SMatthew G. Knepley     ierr = PetscViewerASCIIPrintf(viewer, "%3D SNES Function norm %14.12e [", its, (double) fgnorm);CHKERRQ(ierr);
6262db13446SMatthew G. Knepley     for (f = 0; f < Nf; ++f) {
6272db13446SMatthew G. Knepley       if (f) {ierr = PetscViewerASCIIPrintf(viewer, ", ");CHKERRQ(ierr);}
6282db13446SMatthew G. Knepley       ierr = PetscViewerASCIIPrintf(viewer, "%14.12e", res[f]);CHKERRQ(ierr);
6292db13446SMatthew G. Knepley     }
6302db13446SMatthew G. Knepley     ierr = PetscViewerASCIIPrintf(viewer, "] \n");CHKERRQ(ierr);
6312db13446SMatthew G. Knepley     ierr = PetscViewerASCIISubtractTab(viewer, tablevel);CHKERRQ(ierr);
6322db13446SMatthew G. Knepley   }
6332db13446SMatthew G. Knepley   PetscFunctionReturn(0);
6342db13446SMatthew G. Knepley }
635e7e93795SLois Curfman McInnes /* ---------------------------------------------------------------- */
6364a2ae208SSatish Balay #undef __FUNCT__
6378d359177SBarry Smith #define __FUNCT__ "SNESConvergedDefault"
6384b828684SBarry Smith /*@C
6398d359177SBarry Smith    SNESConvergedDefault - Convergence test of the solvers for
640f525115eSLois Curfman McInnes    systems of nonlinear equations (default).
641e7e93795SLois Curfman McInnes 
642c7afd0dbSLois Curfman McInnes    Collective on SNES
643c7afd0dbSLois Curfman McInnes 
644e7e93795SLois Curfman McInnes    Input Parameters:
645c7afd0dbSLois Curfman McInnes +  snes - the SNES context
64606ee9f85SBarry Smith .  it - the iteration (0 indicates before any Newton steps)
647e7e93795SLois Curfman McInnes .  xnorm - 2-norm of current iterate
648c60f73f4SPeter Brune .  snorm - 2-norm of current step
6497f3332b4SBarry Smith .  fnorm - 2-norm of function at current iterate
650c7afd0dbSLois Curfman McInnes -  dummy - unused context
651e7e93795SLois Curfman McInnes 
652184914b5SBarry Smith    Output Parameter:
653184914b5SBarry Smith .   reason  - one of
65470441072SBarry Smith $  SNES_CONVERGED_FNORM_ABS       - (fnorm < abstol),
655c60f73f4SPeter Brune $  SNES_CONVERGED_SNORM_RELATIVE  - (snorm < stol*xnorm),
656184914b5SBarry Smith $  SNES_CONVERGED_FNORM_RELATIVE  - (fnorm < rtol*fnorm0),
657184914b5SBarry Smith $  SNES_DIVERGED_FUNCTION_COUNT   - (nfct > maxf),
658184914b5SBarry Smith $  SNES_DIVERGED_FNORM_NAN        - (fnorm == NaN),
659184914b5SBarry Smith $  SNES_CONVERGED_ITERATING       - (otherwise),
660e7e93795SLois Curfman McInnes 
661e7e93795SLois Curfman McInnes    where
662c7afd0dbSLois Curfman McInnes +    maxf - maximum number of function evaluations,
663c7afd0dbSLois Curfman McInnes             set with SNESSetTolerances()
664c7afd0dbSLois Curfman McInnes .    nfct - number of function evaluations,
66570441072SBarry Smith .    abstol - absolute function norm tolerance,
666c7afd0dbSLois Curfman McInnes             set with SNESSetTolerances()
667c7afd0dbSLois Curfman McInnes -    rtol - relative function norm tolerance, set with SNESSetTolerances()
668fee21e36SBarry Smith 
66936851e7fSLois Curfman McInnes    Level: intermediate
67036851e7fSLois Curfman McInnes 
671e7e93795SLois Curfman McInnes .keywords: SNES, nonlinear, default, converged, convergence
672e7e93795SLois Curfman McInnes 
67371f87433Sdalcinl .seealso: SNESSetConvergenceTest()
674e7e93795SLois Curfman McInnes @*/
6758d359177SBarry Smith PetscErrorCode  SNESConvergedDefault(SNES snes,PetscInt it,PetscReal xnorm,PetscReal snorm,PetscReal fnorm,SNESConvergedReason *reason,void *dummy)
676e7e93795SLois Curfman McInnes {
67763ba0a88SBarry Smith   PetscErrorCode ierr;
67863ba0a88SBarry Smith 
6793a40ed3dSBarry Smith   PetscFunctionBegin;
6800700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
6813f149594SLisandro Dalcin   PetscValidPointer(reason,6);
6823f149594SLisandro Dalcin 
68306ee9f85SBarry Smith   *reason = SNES_CONVERGED_ITERATING;
68406ee9f85SBarry Smith 
68506ee9f85SBarry Smith   if (!it) {
68606ee9f85SBarry Smith     /* set parameter for default relative tolerance convergence test */
68706ee9f85SBarry Smith     snes->ttol = fnorm*snes->rtol;
68806ee9f85SBarry Smith   }
6898146f6ebSBarry Smith   if (PetscIsInfOrNanReal(fnorm)) {
690ae15b995SBarry Smith     ierr    = PetscInfo(snes,"Failed to converged, function norm is NaN\n");CHKERRQ(ierr);
691184914b5SBarry Smith     *reason = SNES_DIVERGED_FNORM_NAN;
69270441072SBarry Smith   } else if (fnorm < snes->abstol) {
6938f1a2a5eSBarry Smith     ierr    = PetscInfo2(snes,"Converged due to function norm %14.12e < %14.12e\n",(double)fnorm,(double)snes->abstol);CHKERRQ(ierr);
694184914b5SBarry Smith     *reason = SNES_CONVERGED_FNORM_ABS;
69543e71028SBarry Smith   } else if (snes->nfuncs >= snes->max_funcs) {
696ae15b995SBarry Smith     ierr    = PetscInfo2(snes,"Exceeded maximum number of function evaluations: %D > %D\n",snes->nfuncs,snes->max_funcs);CHKERRQ(ierr);
697184914b5SBarry Smith     *reason = SNES_DIVERGED_FUNCTION_COUNT;
69806ee9f85SBarry Smith   }
69906ee9f85SBarry Smith 
70006ee9f85SBarry Smith   if (it && !*reason) {
70106ee9f85SBarry Smith     if (fnorm <= snes->ttol) {
7028f1a2a5eSBarry Smith       ierr    = PetscInfo2(snes,"Converged due to function norm %14.12e < %14.12e (relative tolerance)\n",(double)fnorm,(double)snes->ttol);CHKERRQ(ierr);
70306ee9f85SBarry Smith       *reason = SNES_CONVERGED_FNORM_RELATIVE;
704c60f73f4SPeter Brune     } else if (snorm < snes->stol*xnorm) {
705c60f73f4SPeter 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);
706c60f73f4SPeter Brune       *reason = SNES_CONVERGED_SNORM_RELATIVE;
70706ee9f85SBarry Smith     }
708e7e93795SLois Curfman McInnes   }
7093a40ed3dSBarry Smith   PetscFunctionReturn(0);
710e7e93795SLois Curfman McInnes }
7113f149594SLisandro Dalcin 
7123f149594SLisandro Dalcin #undef __FUNCT__
713e2a6519dSDmitry Karpeev #define __FUNCT__ "SNESConvergedSkip"
7143f149594SLisandro Dalcin /*@C
715e2a6519dSDmitry Karpeev    SNESConvergedSkip - Convergence test for SNES that NEVER returns as
7163f149594SLisandro Dalcin    converged, UNLESS the maximum number of iteration have been reached.
7173f149594SLisandro Dalcin 
7183f9fe445SBarry Smith    Logically Collective on SNES
7193f149594SLisandro Dalcin 
7203f149594SLisandro Dalcin    Input Parameters:
7213f149594SLisandro Dalcin +  snes - the SNES context
7223f149594SLisandro Dalcin .  it - the iteration (0 indicates before any Newton steps)
7233f149594SLisandro Dalcin .  xnorm - 2-norm of current iterate
724c60f73f4SPeter Brune .  snorm - 2-norm of current step
7253f149594SLisandro Dalcin .  fnorm - 2-norm of function at current iterate
7263f149594SLisandro Dalcin -  dummy - unused context
7273f149594SLisandro Dalcin 
7283f149594SLisandro Dalcin    Output Parameter:
72985385478SLisandro Dalcin .   reason  - SNES_CONVERGED_ITERATING, SNES_CONVERGED_ITS, or SNES_DIVERGED_FNORM_NAN
7303f149594SLisandro Dalcin 
7313f149594SLisandro Dalcin    Notes:
7323f149594SLisandro Dalcin    Convergence is then declared after a fixed number of iterations have been used.
7333f149594SLisandro Dalcin 
7343f149594SLisandro Dalcin    Level: advanced
7353f149594SLisandro Dalcin 
7363f149594SLisandro Dalcin .keywords: SNES, nonlinear, skip, converged, convergence
7373f149594SLisandro Dalcin 
7383f149594SLisandro Dalcin .seealso: SNESSetConvergenceTest()
7393f149594SLisandro Dalcin @*/
740e2a6519dSDmitry Karpeev PetscErrorCode  SNESConvergedSkip(SNES snes,PetscInt it,PetscReal xnorm,PetscReal snorm,PetscReal fnorm,SNESConvergedReason *reason,void *dummy)
7413f149594SLisandro Dalcin {
7423f149594SLisandro Dalcin   PetscErrorCode ierr;
7433f149594SLisandro Dalcin 
7443f149594SLisandro Dalcin   PetscFunctionBegin;
7450700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
7463f149594SLisandro Dalcin   PetscValidPointer(reason,6);
7473f149594SLisandro Dalcin 
7483f149594SLisandro Dalcin   *reason = SNES_CONVERGED_ITERATING;
7493f149594SLisandro Dalcin 
7503f149594SLisandro Dalcin   if (fnorm != fnorm) {
7513f149594SLisandro Dalcin     ierr    = PetscInfo(snes,"Failed to converged, function norm is NaN\n");CHKERRQ(ierr);
7523f149594SLisandro Dalcin     *reason = SNES_DIVERGED_FNORM_NAN;
7533f149594SLisandro Dalcin   } else if (it == snes->max_its) {
7543f149594SLisandro Dalcin     *reason = SNES_CONVERGED_ITS;
7553f149594SLisandro Dalcin   }
7563f149594SLisandro Dalcin   PetscFunctionReturn(0);
7573f149594SLisandro Dalcin }
7583f149594SLisandro Dalcin 
75958c9b817SLisandro Dalcin #undef __FUNCT__
760fa0ddf94SBarry Smith #define __FUNCT__ "SNESSetWorkVecs"
7618d359177SBarry Smith /*@C
762fa0ddf94SBarry Smith   SNESSetWorkVecs - Gets a number of work vectors.
76358c9b817SLisandro Dalcin 
76458c9b817SLisandro Dalcin   Input Parameters:
76558c9b817SLisandro Dalcin . snes  - the SNES context
76658c9b817SLisandro Dalcin . nw - number of work vectors to allocate
76758c9b817SLisandro Dalcin 
76858c9b817SLisandro Dalcin    Level: developer
76958c9b817SLisandro Dalcin 
770fa0ddf94SBarry Smith    Developers Note: This is PETSC_EXTERN because it may be used by user written plugin SNES implementations
771fa0ddf94SBarry Smith 
77298acb6afSMatthew G Knepley @*/
773fa0ddf94SBarry Smith PetscErrorCode SNESSetWorkVecs(SNES snes,PetscInt nw)
77458c9b817SLisandro Dalcin {
775c5ed8070SMatthew G. Knepley   DM             dm;
776c5ed8070SMatthew G. Knepley   Vec            v;
77758c9b817SLisandro Dalcin   PetscErrorCode ierr;
77858c9b817SLisandro Dalcin 
77958c9b817SLisandro Dalcin   PetscFunctionBegin;
78058c9b817SLisandro Dalcin   if (snes->work) {ierr = VecDestroyVecs(snes->nwork,&snes->work);CHKERRQ(ierr);}
78158c9b817SLisandro Dalcin   snes->nwork = nw;
782f5af7f23SKarl Rupp 
783c5ed8070SMatthew G. Knepley   ierr = SNESGetDM(snes, &dm);CHKERRQ(ierr);
784c5ed8070SMatthew G. Knepley   ierr = DMGetGlobalVector(dm, &v);CHKERRQ(ierr);
785c5ed8070SMatthew G. Knepley   ierr = VecDuplicateVecs(v,snes->nwork,&snes->work);CHKERRQ(ierr);
786c5ed8070SMatthew G. Knepley   ierr = DMRestoreGlobalVector(dm, &v);CHKERRQ(ierr);
78758c9b817SLisandro Dalcin   ierr = PetscLogObjectParents(snes,nw,snes->work);CHKERRQ(ierr);
78858c9b817SLisandro Dalcin   PetscFunctionReturn(0);
78958c9b817SLisandro Dalcin }
790