xref: /petsc/src/snes/interface/snesut.c (revision a5c2985b74b9b7f617610e6ed754de99a8c030d6)
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__
118*a5c2985bSBarry Smith #define __FUNCT__ "KSPMonitorSNES"
119*a5c2985bSBarry Smith /*@C
120*a5c2985bSBarry Smith    KSPMonitorSNES - Print the residual norm of the nonlinear function at each iteration of the linear iterative solver.
121*a5c2985bSBarry Smith 
122*a5c2985bSBarry Smith    Collective on KSP
123*a5c2985bSBarry Smith 
124*a5c2985bSBarry Smith    Input Parameters:
125*a5c2985bSBarry Smith +  ksp   - iterative context
126*a5c2985bSBarry Smith .  n     - iteration number
127*a5c2985bSBarry Smith .  rnorm - 2-norm (preconditioned) residual value (may be estimated).
128*a5c2985bSBarry Smith -  dummy - unused monitor context
129*a5c2985bSBarry Smith 
130*a5c2985bSBarry Smith    Level: intermediate
131*a5c2985bSBarry Smith 
132*a5c2985bSBarry Smith .keywords: KSP, default, monitor, residual
133*a5c2985bSBarry Smith 
134*a5c2985bSBarry Smith .seealso: KSPMonitorSet(), KSPMonitorTrueResidualNorm(), KSPMonitorLGResidualNormCreate()
135*a5c2985bSBarry Smith @*/
136*a5c2985bSBarry Smith PetscErrorCode  KSPMonitorSNES(KSP ksp,PetscInt n,PetscReal rnorm,void *dummy)
137*a5c2985bSBarry Smith {
138*a5c2985bSBarry Smith   PetscErrorCode ierr;
139*a5c2985bSBarry Smith   PetscViewer    viewer;
140*a5c2985bSBarry Smith   SNES           snes = (SNES) dummy;
141*a5c2985bSBarry Smith   Vec            snes_solution,work1,work2;
142*a5c2985bSBarry Smith   PetscReal      snorm;
143*a5c2985bSBarry Smith 
144*a5c2985bSBarry Smith   PetscFunctionBegin;
145*a5c2985bSBarry Smith   ierr = SNESGetSolution(snes,&snes_solution);CHKERRQ(ierr);
146*a5c2985bSBarry Smith   ierr = VecDuplicate(snes_solution,&work1);CHKERRQ(ierr);
147*a5c2985bSBarry Smith   ierr = VecDuplicate(snes_solution,&work2);CHKERRQ(ierr);
148*a5c2985bSBarry Smith   ierr = KSPBuildSolution(ksp,work1,NULL);CHKERRQ(ierr);
149*a5c2985bSBarry Smith   ierr = VecAYPX(work1,-1.0,snes_solution);CHKERRQ(ierr);
150*a5c2985bSBarry Smith   ierr = SNESComputeFunction(snes,work1,work2);CHKERRQ(ierr);
151*a5c2985bSBarry Smith   ierr = VecNorm(work2,NORM_2,&snorm);CHKERRQ(ierr);
152*a5c2985bSBarry Smith   ierr = VecDestroy(&work1);CHKERRQ(ierr);
153*a5c2985bSBarry Smith   ierr = VecDestroy(&work2);CHKERRQ(ierr);
154*a5c2985bSBarry Smith 
155*a5c2985bSBarry Smith   ierr = PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)ksp),&viewer);CHKERRQ(ierr);
156*a5c2985bSBarry Smith   ierr = PetscViewerASCIIAddTab(viewer,((PetscObject)ksp)->tablevel);CHKERRQ(ierr);
157*a5c2985bSBarry Smith   if (n == 0 && ((PetscObject)ksp)->prefix) {
158*a5c2985bSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  Residual norms for %s solve.\n",((PetscObject)ksp)->prefix);CHKERRQ(ierr);
159*a5c2985bSBarry Smith   }
160*a5c2985bSBarry Smith   ierr = PetscViewerASCIIPrintf(viewer,"%3D SNES Residual norm %5.3e KSP Residual norm %5.3e \n",n,(double)snorm,(double)rnorm);CHKERRQ(ierr);
161*a5c2985bSBarry Smith   ierr = PetscViewerASCIISubtractTab(viewer,((PetscObject)ksp)->tablevel);CHKERRQ(ierr);
162*a5c2985bSBarry Smith   PetscFunctionReturn(0);
163*a5c2985bSBarry Smith }
164*a5c2985bSBarry Smith 
165*a5c2985bSBarry Smith #undef __FUNCT__
166a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorDefault"
1674b828684SBarry Smith /*@C
168a6570f20SBarry Smith    SNESMonitorDefault - Monitors progress of the SNES solvers (default).
169e7e93795SLois Curfman McInnes 
170c7afd0dbSLois Curfman McInnes    Collective on SNES
171c7afd0dbSLois Curfman McInnes 
172e7e93795SLois Curfman McInnes    Input Parameters:
173c7afd0dbSLois Curfman McInnes +  snes - the SNES context
174e7e93795SLois Curfman McInnes .  its - iteration number
1754b27c08aSLois Curfman McInnes .  fgnorm - 2-norm of residual
176c7afd0dbSLois Curfman McInnes -  dummy - unused context
177fee21e36SBarry Smith 
178e7e93795SLois Curfman McInnes    Notes:
1794b27c08aSLois Curfman McInnes    This routine prints the residual norm at each iteration.
180e7e93795SLois Curfman McInnes 
18136851e7fSLois Curfman McInnes    Level: intermediate
18236851e7fSLois Curfman McInnes 
183e7e93795SLois Curfman McInnes .keywords: SNES, nonlinear, default, monitor, norm
184e7e93795SLois Curfman McInnes 
185a6570f20SBarry Smith .seealso: SNESMonitorSet(), SNESMonitorSolution()
186e7e93795SLois Curfman McInnes @*/
1877087cfbeSBarry Smith PetscErrorCode  SNESMonitorDefault(SNES snes,PetscInt its,PetscReal fgnorm,void *dummy)
188e7e93795SLois Curfman McInnes {
189dfbe8321SBarry Smith   PetscErrorCode ierr;
190ce94432eSBarry Smith   PetscViewer    viewer = dummy ? (PetscViewer) dummy : PETSC_VIEWER_STDOUT_(PetscObjectComm((PetscObject)snes));
191d132466eSBarry Smith 
1923a40ed3dSBarry Smith   PetscFunctionBegin;
193649052a6SBarry Smith   ierr = PetscViewerASCIIAddTab(viewer,((PetscObject)snes)->tablevel);CHKERRQ(ierr);
194649052a6SBarry Smith   ierr = PetscViewerASCIIPrintf(viewer,"%3D SNES Function norm %14.12e \n",its,(double)fgnorm);CHKERRQ(ierr);
195649052a6SBarry Smith   ierr = PetscViewerASCIISubtractTab(viewer,((PetscObject)snes)->tablevel);CHKERRQ(ierr);
1963a40ed3dSBarry Smith   PetscFunctionReturn(0);
197e7e93795SLois Curfman McInnes }
1983f1db9ecSBarry Smith 
199b271bb04SBarry Smith #undef __FUNCT__
2002e7541e6SPeter Brune #define __FUNCT__ "SNESMonitorJacUpdateSpectrum"
201a80ad3e0SBarry Smith PetscErrorCode SNESMonitorJacUpdateSpectrum(SNES snes,PetscInt it,PetscReal fnorm,void *ctx)
202a80ad3e0SBarry Smith {
203196da8b6SPeter Brune #if defined(PETSC_MISSING_LAPACK_GEEV)
204ce94432eSBarry Smith   SETERRQ(PetscObjectComm((PetscObject)snes),PETSC_ERR_SUP,"GEEV - Lapack routine is unavailable\nNot able to provide eigen values.");
205196da8b6SPeter Brune #elif defined(PETSC_HAVE_ESSL)
206ce94432eSBarry Smith   SETERRQ(PetscObjectComm((PetscObject)snes),PETSC_ERR_SUP,"GEEV - No support for ESSL Lapack Routines");
207196da8b6SPeter Brune #else
2082e7541e6SPeter Brune   Vec            X;
2092e7541e6SPeter Brune   Mat            J,dJ,dJdense;
2102e7541e6SPeter Brune   PetscErrorCode ierr;
211d1e9a80fSBarry Smith   PetscErrorCode (*func)(SNES,Vec,Mat,Mat,void*);
2122e7541e6SPeter Brune   PetscInt       n,i;
2132e7541e6SPeter Brune   PetscBLASInt   nb,lwork;
2142e7541e6SPeter Brune   PetscReal      *eigr,*eigi;
2152e7541e6SPeter Brune   PetscScalar    *work;
2162e7541e6SPeter Brune   PetscScalar    *a;
2172e7541e6SPeter Brune 
2182e7541e6SPeter Brune   PetscFunctionBegin;
2192e7541e6SPeter Brune   if (it == 0) PetscFunctionReturn(0);
2202e7541e6SPeter Brune   /* create the difference between the current update and the current jacobian */
2212e7541e6SPeter Brune   ierr = SNESGetSolution(snes,&X);CHKERRQ(ierr);
222d1e9a80fSBarry Smith   ierr = SNESGetJacobian(snes,NULL,&J,&func,NULL);CHKERRQ(ierr);
2232e7541e6SPeter Brune   ierr = MatDuplicate(J,MAT_COPY_VALUES,&dJ);CHKERRQ(ierr);
224d1e9a80fSBarry Smith   ierr = SNESComputeJacobian(snes,X,dJ,dJ);CHKERRQ(ierr);
2252e7541e6SPeter Brune   ierr = MatAXPY(dJ,-1.0,J,SAME_NONZERO_PATTERN);CHKERRQ(ierr);
226f5af7f23SKarl Rupp 
2272e7541e6SPeter Brune   /* compute the spectrum directly */
2282e7541e6SPeter Brune   ierr  = MatConvert(dJ,MATSEQDENSE,MAT_INITIAL_MATRIX,&dJdense);CHKERRQ(ierr);
2290298fd71SBarry Smith   ierr  = MatGetSize(dJ,&n,NULL);CHKERRQ(ierr);
230c5df96a5SBarry Smith   ierr  = PetscBLASIntCast(n,&nb);CHKERRQ(ierr);
2312e7541e6SPeter Brune   lwork = 3*nb;
232785e854fSJed Brown   ierr  = PetscMalloc1(n,&eigr);CHKERRQ(ierr);
233785e854fSJed Brown   ierr  = PetscMalloc1(n,&eigi);CHKERRQ(ierr);
234785e854fSJed Brown   ierr  = PetscMalloc1(lwork,&work);CHKERRQ(ierr);
2358c778c55SBarry Smith   ierr  = MatDenseGetArray(dJdense,&a);CHKERRQ(ierr);
2362e7541e6SPeter Brune #if !defined(PETSC_USE_COMPLEX)
2372e7541e6SPeter Brune   {
2382e7541e6SPeter Brune     PetscBLASInt lierr;
2392e7541e6SPeter Brune     ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
2408b83055fSJed Brown     PetscStackCallBLAS("LAPACKgeev",LAPACKgeev_("N","N",&nb,a,&nb,eigr,eigi,NULL,&nb,NULL,&nb,work,&lwork,&lierr));
2412e7541e6SPeter Brune     if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"geev() error %d",lierr);
2422e7541e6SPeter Brune     ierr = PetscFPTrapPop();CHKERRQ(ierr);
2432e7541e6SPeter Brune   }
2442e7541e6SPeter Brune #else
2452e7541e6SPeter Brune   SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not coded for complex");
2462e7541e6SPeter Brune #endif
247ce94432eSBarry Smith   PetscPrintf(PetscObjectComm((PetscObject)snes),"Eigenvalues of J_%d - J_%d:\n",it,it-1);CHKERRQ(ierr);
2482e7541e6SPeter Brune   for (i=0;i<n;i++) {
2498fa295daSBarry Smith     PetscPrintf(PetscObjectComm((PetscObject)snes),"%5d: %20.5g + %20.5gi\n",i,(double)eigr[i],(double)eigi[i]);CHKERRQ(ierr);
2502e7541e6SPeter Brune   }
2518c778c55SBarry Smith   ierr = MatDenseRestoreArray(dJdense,&a);CHKERRQ(ierr);
2522e7541e6SPeter Brune   ierr = MatDestroy(&dJ);CHKERRQ(ierr);
2532e7541e6SPeter Brune   ierr = MatDestroy(&dJdense);CHKERRQ(ierr);
2542e7541e6SPeter Brune   ierr = PetscFree(eigr);CHKERRQ(ierr);
2552e7541e6SPeter Brune   ierr = PetscFree(eigi);CHKERRQ(ierr);
2562e7541e6SPeter Brune   ierr = PetscFree(work);CHKERRQ(ierr);
2572e7541e6SPeter Brune   PetscFunctionReturn(0);
258196da8b6SPeter Brune #endif
2592e7541e6SPeter Brune }
2602e7541e6SPeter Brune 
2612e7541e6SPeter Brune #undef __FUNCT__
262b271bb04SBarry Smith #define __FUNCT__ "SNESMonitorRange_Private"
2637087cfbeSBarry Smith PetscErrorCode  SNESMonitorRange_Private(SNES snes,PetscInt it,PetscReal *per)
264b271bb04SBarry Smith {
265b271bb04SBarry Smith   PetscErrorCode ierr;
266b271bb04SBarry Smith   Vec            resid;
267b271bb04SBarry Smith   PetscReal      rmax,pwork;
268b271bb04SBarry Smith   PetscInt       i,n,N;
269b271bb04SBarry Smith   PetscScalar    *r;
270b271bb04SBarry Smith 
271b271bb04SBarry Smith   PetscFunctionBegin;
272b271bb04SBarry Smith   ierr  = SNESGetFunction(snes,&resid,0,0);CHKERRQ(ierr);
273b271bb04SBarry Smith   ierr  = VecNorm(resid,NORM_INFINITY,&rmax);CHKERRQ(ierr);
274b271bb04SBarry Smith   ierr  = VecGetLocalSize(resid,&n);CHKERRQ(ierr);
275b271bb04SBarry Smith   ierr  = VecGetSize(resid,&N);CHKERRQ(ierr);
276b271bb04SBarry Smith   ierr  = VecGetArray(resid,&r);CHKERRQ(ierr);
277b271bb04SBarry Smith   pwork = 0.0;
278b271bb04SBarry Smith   for (i=0; i<n; i++) {
279b271bb04SBarry Smith     pwork += (PetscAbsScalar(r[i]) > .20*rmax);
280b271bb04SBarry Smith   }
281ce94432eSBarry Smith   ierr = MPI_Allreduce(&pwork,per,1,MPIU_REAL,MPIU_SUM,PetscObjectComm((PetscObject)snes));CHKERRQ(ierr);
282b271bb04SBarry Smith   ierr = VecRestoreArray(resid,&r);CHKERRQ(ierr);
283b271bb04SBarry Smith   *per = *per/N;
284b271bb04SBarry Smith   PetscFunctionReturn(0);
285b271bb04SBarry Smith }
286b271bb04SBarry Smith 
287b271bb04SBarry Smith #undef __FUNCT__
288b271bb04SBarry Smith #define __FUNCT__ "SNESMonitorRange"
289b271bb04SBarry Smith /*@C
290b271bb04SBarry Smith    SNESMonitorRange - Prints the percentage of residual elements that are more then 10 percent of the maximum value.
291b271bb04SBarry Smith 
292b271bb04SBarry Smith    Collective on SNES
293b271bb04SBarry Smith 
294b271bb04SBarry Smith    Input Parameters:
295b271bb04SBarry Smith +  snes   - iterative context
296b271bb04SBarry Smith .  it    - iteration number
297b271bb04SBarry Smith .  rnorm - 2-norm (preconditioned) residual value (may be estimated).
298b271bb04SBarry Smith -  dummy - unused monitor context
299b271bb04SBarry Smith 
300b271bb04SBarry Smith    Options Database Key:
301b271bb04SBarry Smith .  -snes_monitor_range - Activates SNESMonitorRange()
302b271bb04SBarry Smith 
303b271bb04SBarry Smith    Level: intermediate
304b271bb04SBarry Smith 
305b271bb04SBarry Smith .keywords: SNES, default, monitor, residual
306b271bb04SBarry Smith 
307b271bb04SBarry Smith .seealso: SNESMonitorSet(), SNESMonitorDefault(), SNESMonitorLGCreate()
308b271bb04SBarry Smith @*/
3097087cfbeSBarry Smith PetscErrorCode  SNESMonitorRange(SNES snes,PetscInt it,PetscReal rnorm,void *dummy)
310b271bb04SBarry Smith {
311b271bb04SBarry Smith   PetscErrorCode ierr;
312b271bb04SBarry Smith   PetscReal      perc,rel;
313ce94432eSBarry Smith   PetscViewer    viewer = dummy ? (PetscViewer) dummy : PETSC_VIEWER_STDOUT_(PetscObjectComm((PetscObject)snes));
314b271bb04SBarry Smith   /* should be in a MonitorRangeContext */
315b271bb04SBarry Smith   static PetscReal prev;
316b271bb04SBarry Smith 
317b271bb04SBarry Smith   PetscFunctionBegin;
318b271bb04SBarry Smith   if (!it) prev = rnorm;
319b271bb04SBarry Smith   ierr = SNESMonitorRange_Private(snes,it,&perc);CHKERRQ(ierr);
320b271bb04SBarry Smith 
321b271bb04SBarry Smith   rel  = (prev - rnorm)/prev;
322b271bb04SBarry Smith   prev = rnorm;
323649052a6SBarry Smith   ierr = PetscViewerASCIIAddTab(viewer,((PetscObject)snes)->tablevel);CHKERRQ(ierr);
3246712e2f1SBarry 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);
325649052a6SBarry Smith   ierr = PetscViewerASCIISubtractTab(viewer,((PetscObject)snes)->tablevel);CHKERRQ(ierr);
326b271bb04SBarry Smith   PetscFunctionReturn(0);
327b271bb04SBarry Smith }
328b271bb04SBarry Smith 
329eabae89aSBarry Smith typedef struct {
330649052a6SBarry Smith   PetscViewer viewer;
331eabae89aSBarry Smith   PetscReal   *history;
332a6570f20SBarry Smith } SNESMonitorRatioContext;
333eabae89aSBarry Smith 
3343a7fca6bSBarry Smith #undef __FUNCT__
335a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorRatio"
3363a7fca6bSBarry Smith /*@C
337a6570f20SBarry Smith    SNESMonitorRatio - Monitors progress of the SNES solvers by printing the ratio
3384b27c08aSLois Curfman McInnes    of residual norm at each iteration to the previous.
3393a7fca6bSBarry Smith 
3403a7fca6bSBarry Smith    Collective on SNES
3413a7fca6bSBarry Smith 
3423a7fca6bSBarry Smith    Input Parameters:
3433a7fca6bSBarry Smith +  snes - the SNES context
3443a7fca6bSBarry Smith .  its - iteration number
3453a7fca6bSBarry Smith .  fgnorm - 2-norm of residual (or gradient)
346eabae89aSBarry Smith -  dummy -  context of monitor
3473a7fca6bSBarry Smith 
3483a7fca6bSBarry Smith    Level: intermediate
3493a7fca6bSBarry Smith 
3503a7fca6bSBarry Smith .keywords: SNES, nonlinear, monitor, norm
3513a7fca6bSBarry Smith 
352a6570f20SBarry Smith .seealso: SNESMonitorSet(), SNESMonitorSolution()
3533a7fca6bSBarry Smith @*/
3547087cfbeSBarry Smith PetscErrorCode  SNESMonitorRatio(SNES snes,PetscInt its,PetscReal fgnorm,void *dummy)
3553a7fca6bSBarry Smith {
356dfbe8321SBarry Smith   PetscErrorCode          ierr;
35777431f27SBarry Smith   PetscInt                len;
35887828ca2SBarry Smith   PetscReal               *history;
359a6570f20SBarry Smith   SNESMonitorRatioContext *ctx = (SNESMonitorRatioContext*)dummy;
3603a7fca6bSBarry Smith 
3613a7fca6bSBarry Smith   PetscFunctionBegin;
3620298fd71SBarry Smith   ierr = SNESGetConvergenceHistory(snes,&history,NULL,&len);CHKERRQ(ierr);
363649052a6SBarry Smith   ierr = PetscViewerASCIIAddTab(ctx->viewer,((PetscObject)snes)->tablevel);CHKERRQ(ierr);
364958c9bccSBarry Smith   if (!its || !history || its > len) {
365649052a6SBarry Smith     ierr = PetscViewerASCIIPrintf(ctx->viewer,"%3D SNES Function norm %14.12e \n",its,(double)fgnorm);CHKERRQ(ierr);
3663a7fca6bSBarry Smith   } else {
36787828ca2SBarry Smith     PetscReal ratio = fgnorm/history[its-1];
3688f1a2a5eSBarry Smith     ierr = PetscViewerASCIIPrintf(ctx->viewer,"%3D SNES Function norm %14.12e %14.12e \n",its,(double)fgnorm,(double)ratio);CHKERRQ(ierr);
3693a7fca6bSBarry Smith   }
370649052a6SBarry Smith   ierr = PetscViewerASCIISubtractTab(ctx->viewer,((PetscObject)snes)->tablevel);CHKERRQ(ierr);
3713a7fca6bSBarry Smith   PetscFunctionReturn(0);
3723a7fca6bSBarry Smith }
3733a7fca6bSBarry Smith 
3743a7fca6bSBarry Smith /*
3753a7fca6bSBarry Smith    If the we set the history monitor space then we must destroy it
3763a7fca6bSBarry Smith */
3773a7fca6bSBarry Smith #undef __FUNCT__
378a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorRatioDestroy"
379c2efdce3SBarry Smith PetscErrorCode SNESMonitorRatioDestroy(void **ct)
3803a7fca6bSBarry Smith {
381dfbe8321SBarry Smith   PetscErrorCode          ierr;
382c2efdce3SBarry Smith   SNESMonitorRatioContext *ctx = *(SNESMonitorRatioContext**)ct;
3833a7fca6bSBarry Smith 
3843a7fca6bSBarry Smith   PetscFunctionBegin;
38505b42c5fSBarry Smith   ierr = PetscFree(ctx->history);CHKERRQ(ierr);
386649052a6SBarry Smith   ierr = PetscViewerDestroy(&ctx->viewer);CHKERRQ(ierr);
387eabae89aSBarry Smith   ierr = PetscFree(ctx);CHKERRQ(ierr);
3883a7fca6bSBarry Smith   PetscFunctionReturn(0);
3893a7fca6bSBarry Smith }
3903a7fca6bSBarry Smith 
3913a7fca6bSBarry Smith #undef __FUNCT__
392a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorSetRatio"
3933a7fca6bSBarry Smith /*@C
394a6570f20SBarry Smith    SNESMonitorSetRatio - Sets SNES to use a monitor that prints the
3954b27c08aSLois Curfman McInnes    ratio of the function norm at each iteration.
3963a7fca6bSBarry Smith 
3973a7fca6bSBarry Smith    Collective on SNES
3983a7fca6bSBarry Smith 
3993a7fca6bSBarry Smith    Input Parameters:
400eabae89aSBarry Smith +   snes - the SNES context
401eabae89aSBarry Smith -   viewer - ASCII viewer to print output
4023a7fca6bSBarry Smith 
4033a7fca6bSBarry Smith    Level: intermediate
4043a7fca6bSBarry Smith 
4053a7fca6bSBarry Smith .keywords: SNES, nonlinear, monitor, norm
4063a7fca6bSBarry Smith 
407a6570f20SBarry Smith .seealso: SNESMonitorSet(), SNESMonitorSolution(), SNESMonitorDefault()
4083a7fca6bSBarry Smith @*/
409649052a6SBarry Smith PetscErrorCode  SNESMonitorSetRatio(SNES snes,PetscViewer viewer)
4103a7fca6bSBarry Smith {
411dfbe8321SBarry Smith   PetscErrorCode          ierr;
412a6570f20SBarry Smith   SNESMonitorRatioContext *ctx;
41387828ca2SBarry Smith   PetscReal               *history;
4143a7fca6bSBarry Smith 
4153a7fca6bSBarry Smith   PetscFunctionBegin;
416eabae89aSBarry Smith   if (!viewer) {
417ce94432eSBarry Smith     ierr = PetscViewerASCIIOpen(PetscObjectComm((PetscObject)snes),"stdout",&viewer);CHKERRQ(ierr);
418eabae89aSBarry Smith     ierr = PetscObjectReference((PetscObject)viewer);CHKERRQ(ierr);
419eabae89aSBarry Smith   }
420b00a9115SJed Brown   ierr = PetscNewLog(snes,&ctx);CHKERRQ(ierr);
4210298fd71SBarry Smith   ierr = SNESGetConvergenceHistory(snes,&history,NULL,NULL);CHKERRQ(ierr);
4223a7fca6bSBarry Smith   if (!history) {
423785e854fSJed Brown     ierr = PetscMalloc1(100,&ctx->history);CHKERRQ(ierr);
424eabae89aSBarry Smith     ierr = SNESSetConvergenceHistory(snes,ctx->history,0,100,PETSC_TRUE);CHKERRQ(ierr);
4253a7fca6bSBarry Smith   }
426eabae89aSBarry Smith   ctx->viewer = viewer;
427f5af7f23SKarl Rupp 
428a6570f20SBarry Smith   ierr = SNESMonitorSet(snes,SNESMonitorRatio,ctx,SNESMonitorRatioDestroy);CHKERRQ(ierr);
4293a7fca6bSBarry Smith   PetscFunctionReturn(0);
4303a7fca6bSBarry Smith }
4313a7fca6bSBarry Smith 
432e7e93795SLois Curfman McInnes /* ---------------------------------------------------------------- */
4334a2ae208SSatish Balay #undef __FUNCT__
434a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorDefaultShort"
435be1f7002SBarry Smith /*
436a6570f20SBarry Smith      Default (short) SNES Monitor, same as SNESMonitorDefault() except
437be1f7002SBarry Smith   it prints fewer digits of the residual as the residual gets smaller.
438be1f7002SBarry Smith   This is because the later digits are meaningless and are often
439be1f7002SBarry Smith   different on different machines; by using this routine different
440be1f7002SBarry Smith   machines will usually generate the same output.
441be1f7002SBarry Smith */
4427087cfbeSBarry Smith PetscErrorCode  SNESMonitorDefaultShort(SNES snes,PetscInt its,PetscReal fgnorm,void *dummy)
443e7e93795SLois Curfman McInnes {
444dfbe8321SBarry Smith   PetscErrorCode ierr;
445ce94432eSBarry Smith   PetscViewer    viewer = dummy ? (PetscViewer) dummy : PETSC_VIEWER_STDOUT_(PetscObjectComm((PetscObject)snes));
446d132466eSBarry Smith 
4473a40ed3dSBarry Smith   PetscFunctionBegin;
448649052a6SBarry Smith   ierr = PetscViewerASCIIAddTab(viewer,((PetscObject)snes)->tablevel);CHKERRQ(ierr);
4498f240d10SBarry Smith   if (fgnorm > 1.e-9) {
4508fa295daSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"%3D SNES Function norm %g \n",its,(double)fgnorm);CHKERRQ(ierr);
4513a40ed3dSBarry Smith   } else if (fgnorm > 1.e-11) {
4528fa295daSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"%3D SNES Function norm %5.3e \n",its,(double)fgnorm);CHKERRQ(ierr);
4533a40ed3dSBarry Smith   } else {
454649052a6SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"%3D SNES Function norm < 1.e-11\n",its);CHKERRQ(ierr);
455a34d58ebSBarry Smith   }
456649052a6SBarry Smith   ierr = PetscViewerASCIISubtractTab(viewer,((PetscObject)snes)->tablevel);CHKERRQ(ierr);
4573a40ed3dSBarry Smith   PetscFunctionReturn(0);
458e7e93795SLois Curfman McInnes }
459e7e93795SLois Curfman McInnes /* ---------------------------------------------------------------- */
4604a2ae208SSatish Balay #undef __FUNCT__
4618d359177SBarry Smith #define __FUNCT__ "SNESConvergedDefault"
4624b828684SBarry Smith /*@C
4638d359177SBarry Smith    SNESConvergedDefault - Convergence test of the solvers for
464f525115eSLois Curfman McInnes    systems of nonlinear equations (default).
465e7e93795SLois Curfman McInnes 
466c7afd0dbSLois Curfman McInnes    Collective on SNES
467c7afd0dbSLois Curfman McInnes 
468e7e93795SLois Curfman McInnes    Input Parameters:
469c7afd0dbSLois Curfman McInnes +  snes - the SNES context
47006ee9f85SBarry Smith .  it - the iteration (0 indicates before any Newton steps)
471e7e93795SLois Curfman McInnes .  xnorm - 2-norm of current iterate
472c60f73f4SPeter Brune .  snorm - 2-norm of current step
4737f3332b4SBarry Smith .  fnorm - 2-norm of function at current iterate
474c7afd0dbSLois Curfman McInnes -  dummy - unused context
475e7e93795SLois Curfman McInnes 
476184914b5SBarry Smith    Output Parameter:
477184914b5SBarry Smith .   reason  - one of
47870441072SBarry Smith $  SNES_CONVERGED_FNORM_ABS       - (fnorm < abstol),
479c60f73f4SPeter Brune $  SNES_CONVERGED_SNORM_RELATIVE  - (snorm < stol*xnorm),
480184914b5SBarry Smith $  SNES_CONVERGED_FNORM_RELATIVE  - (fnorm < rtol*fnorm0),
481184914b5SBarry Smith $  SNES_DIVERGED_FUNCTION_COUNT   - (nfct > maxf),
482184914b5SBarry Smith $  SNES_DIVERGED_FNORM_NAN        - (fnorm == NaN),
483184914b5SBarry Smith $  SNES_CONVERGED_ITERATING       - (otherwise),
484e7e93795SLois Curfman McInnes 
485e7e93795SLois Curfman McInnes    where
486c7afd0dbSLois Curfman McInnes +    maxf - maximum number of function evaluations,
487c7afd0dbSLois Curfman McInnes             set with SNESSetTolerances()
488c7afd0dbSLois Curfman McInnes .    nfct - number of function evaluations,
48970441072SBarry Smith .    abstol - absolute function norm tolerance,
490c7afd0dbSLois Curfman McInnes             set with SNESSetTolerances()
491c7afd0dbSLois Curfman McInnes -    rtol - relative function norm tolerance, set with SNESSetTolerances()
492fee21e36SBarry Smith 
49336851e7fSLois Curfman McInnes    Level: intermediate
49436851e7fSLois Curfman McInnes 
495e7e93795SLois Curfman McInnes .keywords: SNES, nonlinear, default, converged, convergence
496e7e93795SLois Curfman McInnes 
49771f87433Sdalcinl .seealso: SNESSetConvergenceTest()
498e7e93795SLois Curfman McInnes @*/
4998d359177SBarry Smith PetscErrorCode  SNESConvergedDefault(SNES snes,PetscInt it,PetscReal xnorm,PetscReal snorm,PetscReal fnorm,SNESConvergedReason *reason,void *dummy)
500e7e93795SLois Curfman McInnes {
50163ba0a88SBarry Smith   PetscErrorCode ierr;
50263ba0a88SBarry Smith 
5033a40ed3dSBarry Smith   PetscFunctionBegin;
5040700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
5053f149594SLisandro Dalcin   PetscValidPointer(reason,6);
5063f149594SLisandro Dalcin 
50706ee9f85SBarry Smith   *reason = SNES_CONVERGED_ITERATING;
50806ee9f85SBarry Smith 
50906ee9f85SBarry Smith   if (!it) {
51006ee9f85SBarry Smith     /* set parameter for default relative tolerance convergence test */
51106ee9f85SBarry Smith     snes->ttol = fnorm*snes->rtol;
51206ee9f85SBarry Smith   }
5138146f6ebSBarry Smith   if (PetscIsInfOrNanReal(fnorm)) {
514ae15b995SBarry Smith     ierr    = PetscInfo(snes,"Failed to converged, function norm is NaN\n");CHKERRQ(ierr);
515184914b5SBarry Smith     *reason = SNES_DIVERGED_FNORM_NAN;
51670441072SBarry Smith   } else if (fnorm < snes->abstol) {
5178f1a2a5eSBarry Smith     ierr    = PetscInfo2(snes,"Converged due to function norm %14.12e < %14.12e\n",(double)fnorm,(double)snes->abstol);CHKERRQ(ierr);
518184914b5SBarry Smith     *reason = SNES_CONVERGED_FNORM_ABS;
51943e71028SBarry Smith   } else if (snes->nfuncs >= snes->max_funcs) {
520ae15b995SBarry Smith     ierr    = PetscInfo2(snes,"Exceeded maximum number of function evaluations: %D > %D\n",snes->nfuncs,snes->max_funcs);CHKERRQ(ierr);
521184914b5SBarry Smith     *reason = SNES_DIVERGED_FUNCTION_COUNT;
52206ee9f85SBarry Smith   }
52306ee9f85SBarry Smith 
52406ee9f85SBarry Smith   if (it && !*reason) {
52506ee9f85SBarry Smith     if (fnorm <= snes->ttol) {
5268f1a2a5eSBarry Smith       ierr    = PetscInfo2(snes,"Converged due to function norm %14.12e < %14.12e (relative tolerance)\n",(double)fnorm,(double)snes->ttol);CHKERRQ(ierr);
52706ee9f85SBarry Smith       *reason = SNES_CONVERGED_FNORM_RELATIVE;
528c60f73f4SPeter Brune     } else if (snorm < snes->stol*xnorm) {
529c60f73f4SPeter 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);
530c60f73f4SPeter Brune       *reason = SNES_CONVERGED_SNORM_RELATIVE;
53106ee9f85SBarry Smith     }
532e7e93795SLois Curfman McInnes   }
5333a40ed3dSBarry Smith   PetscFunctionReturn(0);
534e7e93795SLois Curfman McInnes }
5353f149594SLisandro Dalcin 
5363f149594SLisandro Dalcin #undef __FUNCT__
537e2a6519dSDmitry Karpeev #define __FUNCT__ "SNESConvergedSkip"
5383f149594SLisandro Dalcin /*@C
539e2a6519dSDmitry Karpeev    SNESConvergedSkip - Convergence test for SNES that NEVER returns as
5403f149594SLisandro Dalcin    converged, UNLESS the maximum number of iteration have been reached.
5413f149594SLisandro Dalcin 
5423f9fe445SBarry Smith    Logically Collective on SNES
5433f149594SLisandro Dalcin 
5443f149594SLisandro Dalcin    Input Parameters:
5453f149594SLisandro Dalcin +  snes - the SNES context
5463f149594SLisandro Dalcin .  it - the iteration (0 indicates before any Newton steps)
5473f149594SLisandro Dalcin .  xnorm - 2-norm of current iterate
548c60f73f4SPeter Brune .  snorm - 2-norm of current step
5493f149594SLisandro Dalcin .  fnorm - 2-norm of function at current iterate
5503f149594SLisandro Dalcin -  dummy - unused context
5513f149594SLisandro Dalcin 
5523f149594SLisandro Dalcin    Output Parameter:
55385385478SLisandro Dalcin .   reason  - SNES_CONVERGED_ITERATING, SNES_CONVERGED_ITS, or SNES_DIVERGED_FNORM_NAN
5543f149594SLisandro Dalcin 
5553f149594SLisandro Dalcin    Notes:
5563f149594SLisandro Dalcin    Convergence is then declared after a fixed number of iterations have been used.
5573f149594SLisandro Dalcin 
5583f149594SLisandro Dalcin    Level: advanced
5593f149594SLisandro Dalcin 
5603f149594SLisandro Dalcin .keywords: SNES, nonlinear, skip, converged, convergence
5613f149594SLisandro Dalcin 
5623f149594SLisandro Dalcin .seealso: SNESSetConvergenceTest()
5633f149594SLisandro Dalcin @*/
564e2a6519dSDmitry Karpeev PetscErrorCode  SNESConvergedSkip(SNES snes,PetscInt it,PetscReal xnorm,PetscReal snorm,PetscReal fnorm,SNESConvergedReason *reason,void *dummy)
5653f149594SLisandro Dalcin {
5663f149594SLisandro Dalcin   PetscErrorCode ierr;
5673f149594SLisandro Dalcin 
5683f149594SLisandro Dalcin   PetscFunctionBegin;
5690700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
5703f149594SLisandro Dalcin   PetscValidPointer(reason,6);
5713f149594SLisandro Dalcin 
5723f149594SLisandro Dalcin   *reason = SNES_CONVERGED_ITERATING;
5733f149594SLisandro Dalcin 
5743f149594SLisandro Dalcin   if (fnorm != fnorm) {
5753f149594SLisandro Dalcin     ierr    = PetscInfo(snes,"Failed to converged, function norm is NaN\n");CHKERRQ(ierr);
5763f149594SLisandro Dalcin     *reason = SNES_DIVERGED_FNORM_NAN;
5773f149594SLisandro Dalcin   } else if (it == snes->max_its) {
5783f149594SLisandro Dalcin     *reason = SNES_CONVERGED_ITS;
5793f149594SLisandro Dalcin   }
5803f149594SLisandro Dalcin   PetscFunctionReturn(0);
5813f149594SLisandro Dalcin }
5823f149594SLisandro Dalcin 
58358c9b817SLisandro Dalcin #undef __FUNCT__
584fa0ddf94SBarry Smith #define __FUNCT__ "SNESSetWorkVecs"
5858d359177SBarry Smith /*@C
586fa0ddf94SBarry Smith   SNESSetWorkVecs - Gets a number of work vectors.
58758c9b817SLisandro Dalcin 
58858c9b817SLisandro Dalcin   Input Parameters:
58958c9b817SLisandro Dalcin . snes  - the SNES context
59058c9b817SLisandro Dalcin . nw - number of work vectors to allocate
59158c9b817SLisandro Dalcin 
59258c9b817SLisandro Dalcin    Level: developer
59358c9b817SLisandro Dalcin 
594fa0ddf94SBarry Smith    Developers Note: This is PETSC_EXTERN because it may be used by user written plugin SNES implementations
595fa0ddf94SBarry Smith 
59698acb6afSMatthew G Knepley @*/
597fa0ddf94SBarry Smith PetscErrorCode SNESSetWorkVecs(SNES snes,PetscInt nw)
59858c9b817SLisandro Dalcin {
599c5ed8070SMatthew G. Knepley   DM             dm;
600c5ed8070SMatthew G. Knepley   Vec            v;
60158c9b817SLisandro Dalcin   PetscErrorCode ierr;
60258c9b817SLisandro Dalcin 
60358c9b817SLisandro Dalcin   PetscFunctionBegin;
60458c9b817SLisandro Dalcin   if (snes->work) {ierr = VecDestroyVecs(snes->nwork,&snes->work);CHKERRQ(ierr);}
60558c9b817SLisandro Dalcin   snes->nwork = nw;
606f5af7f23SKarl Rupp 
607c5ed8070SMatthew G. Knepley   ierr = SNESGetDM(snes, &dm);CHKERRQ(ierr);
608c5ed8070SMatthew G. Knepley   ierr = DMGetGlobalVector(dm, &v);CHKERRQ(ierr);
609c5ed8070SMatthew G. Knepley   ierr = VecDuplicateVecs(v,snes->nwork,&snes->work);CHKERRQ(ierr);
610c5ed8070SMatthew G. Knepley   ierr = DMRestoreGlobalVector(dm, &v);CHKERRQ(ierr);
61158c9b817SLisandro Dalcin   ierr = PetscLogObjectParents(snes,nw,snes->work);CHKERRQ(ierr);
61258c9b817SLisandro Dalcin   PetscFunctionReturn(0);
61358c9b817SLisandro Dalcin }
614