xref: /petsc/src/snes/interface/snesut.c (revision d1e9a80f72efc361583d2fc822de9783b227627d)
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__
118a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorDefault"
1194b828684SBarry Smith /*@C
120a6570f20SBarry Smith    SNESMonitorDefault - Monitors progress of the SNES solvers (default).
121e7e93795SLois Curfman McInnes 
122c7afd0dbSLois Curfman McInnes    Collective on SNES
123c7afd0dbSLois Curfman McInnes 
124e7e93795SLois Curfman McInnes    Input Parameters:
125c7afd0dbSLois Curfman McInnes +  snes - the SNES context
126e7e93795SLois Curfman McInnes .  its - iteration number
1274b27c08aSLois Curfman McInnes .  fgnorm - 2-norm of residual
128c7afd0dbSLois Curfman McInnes -  dummy - unused context
129fee21e36SBarry Smith 
130e7e93795SLois Curfman McInnes    Notes:
1314b27c08aSLois Curfman McInnes    This routine prints the residual norm at each iteration.
132e7e93795SLois Curfman McInnes 
13336851e7fSLois Curfman McInnes    Level: intermediate
13436851e7fSLois Curfman McInnes 
135e7e93795SLois Curfman McInnes .keywords: SNES, nonlinear, default, monitor, norm
136e7e93795SLois Curfman McInnes 
137a6570f20SBarry Smith .seealso: SNESMonitorSet(), SNESMonitorSolution()
138e7e93795SLois Curfman McInnes @*/
1397087cfbeSBarry Smith PetscErrorCode  SNESMonitorDefault(SNES snes,PetscInt its,PetscReal fgnorm,void *dummy)
140e7e93795SLois Curfman McInnes {
141dfbe8321SBarry Smith   PetscErrorCode ierr;
142ce94432eSBarry Smith   PetscViewer    viewer = dummy ? (PetscViewer) dummy : PETSC_VIEWER_STDOUT_(PetscObjectComm((PetscObject)snes));
143d132466eSBarry Smith 
1443a40ed3dSBarry Smith   PetscFunctionBegin;
145649052a6SBarry Smith   ierr = PetscViewerASCIIAddTab(viewer,((PetscObject)snes)->tablevel);CHKERRQ(ierr);
146649052a6SBarry Smith   ierr = PetscViewerASCIIPrintf(viewer,"%3D SNES Function norm %14.12e \n",its,(double)fgnorm);CHKERRQ(ierr);
147649052a6SBarry Smith   ierr = PetscViewerASCIISubtractTab(viewer,((PetscObject)snes)->tablevel);CHKERRQ(ierr);
1483a40ed3dSBarry Smith   PetscFunctionReturn(0);
149e7e93795SLois Curfman McInnes }
1503f1db9ecSBarry Smith 
151b271bb04SBarry Smith #undef __FUNCT__
1522e7541e6SPeter Brune #define __FUNCT__ "SNESMonitorJacUpdateSpectrum"
153a80ad3e0SBarry Smith PetscErrorCode SNESMonitorJacUpdateSpectrum(SNES snes,PetscInt it,PetscReal fnorm,void *ctx)
154a80ad3e0SBarry Smith {
155196da8b6SPeter Brune #if defined(PETSC_MISSING_LAPACK_GEEV)
156ce94432eSBarry Smith   SETERRQ(PetscObjectComm((PetscObject)snes),PETSC_ERR_SUP,"GEEV - Lapack routine is unavailable\nNot able to provide eigen values.");
157196da8b6SPeter Brune #elif defined(PETSC_HAVE_ESSL)
158ce94432eSBarry Smith   SETERRQ(PetscObjectComm((PetscObject)snes),PETSC_ERR_SUP,"GEEV - No support for ESSL Lapack Routines");
159196da8b6SPeter Brune #else
1602e7541e6SPeter Brune   Vec            X;
1612e7541e6SPeter Brune   Mat            J,dJ,dJdense;
1622e7541e6SPeter Brune   PetscErrorCode ierr;
163*d1e9a80fSBarry Smith   PetscErrorCode (*func)(SNES,Vec,Mat,Mat,void*);
1642e7541e6SPeter Brune   PetscInt       n,i;
1652e7541e6SPeter Brune   PetscBLASInt   nb,lwork;
1662e7541e6SPeter Brune   PetscReal      *eigr,*eigi;
1672e7541e6SPeter Brune   PetscScalar    *work;
1682e7541e6SPeter Brune   PetscScalar    *a;
1692e7541e6SPeter Brune 
1702e7541e6SPeter Brune   PetscFunctionBegin;
1712e7541e6SPeter Brune   if (it == 0) PetscFunctionReturn(0);
1722e7541e6SPeter Brune   /* create the difference between the current update and the current jacobian */
1732e7541e6SPeter Brune   ierr = SNESGetSolution(snes,&X);CHKERRQ(ierr);
174*d1e9a80fSBarry Smith   ierr = SNESGetJacobian(snes,NULL,&J,&func,NULL);CHKERRQ(ierr);
1752e7541e6SPeter Brune   ierr = MatDuplicate(J,MAT_COPY_VALUES,&dJ);CHKERRQ(ierr);
176*d1e9a80fSBarry Smith   ierr = SNESComputeJacobian(snes,X,dJ,dJ);CHKERRQ(ierr);
1772e7541e6SPeter Brune   ierr = MatAXPY(dJ,-1.0,J,SAME_NONZERO_PATTERN);CHKERRQ(ierr);
178f5af7f23SKarl Rupp 
1792e7541e6SPeter Brune   /* compute the spectrum directly */
1802e7541e6SPeter Brune   ierr  = MatConvert(dJ,MATSEQDENSE,MAT_INITIAL_MATRIX,&dJdense);CHKERRQ(ierr);
1810298fd71SBarry Smith   ierr  = MatGetSize(dJ,&n,NULL);CHKERRQ(ierr);
182c5df96a5SBarry Smith   ierr  = PetscBLASIntCast(n,&nb);CHKERRQ(ierr);
1832e7541e6SPeter Brune   lwork = 3*nb;
184785e854fSJed Brown   ierr  = PetscMalloc1(n,&eigr);CHKERRQ(ierr);
185785e854fSJed Brown   ierr  = PetscMalloc1(n,&eigi);CHKERRQ(ierr);
186785e854fSJed Brown   ierr  = PetscMalloc1(lwork,&work);CHKERRQ(ierr);
1878c778c55SBarry Smith   ierr  = MatDenseGetArray(dJdense,&a);CHKERRQ(ierr);
1882e7541e6SPeter Brune #if !defined(PETSC_USE_COMPLEX)
1892e7541e6SPeter Brune   {
1902e7541e6SPeter Brune     PetscBLASInt lierr;
1912e7541e6SPeter Brune     ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
1928b83055fSJed Brown     PetscStackCallBLAS("LAPACKgeev",LAPACKgeev_("N","N",&nb,a,&nb,eigr,eigi,NULL,&nb,NULL,&nb,work,&lwork,&lierr));
1932e7541e6SPeter Brune     if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"geev() error %d",lierr);
1942e7541e6SPeter Brune     ierr = PetscFPTrapPop();CHKERRQ(ierr);
1952e7541e6SPeter Brune   }
1962e7541e6SPeter Brune #else
1972e7541e6SPeter Brune   SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not coded for complex");
1982e7541e6SPeter Brune #endif
199ce94432eSBarry Smith   PetscPrintf(PetscObjectComm((PetscObject)snes),"Eigenvalues of J_%d - J_%d:\n",it,it-1);CHKERRQ(ierr);
2002e7541e6SPeter Brune   for (i=0;i<n;i++) {
2018fa295daSBarry Smith     PetscPrintf(PetscObjectComm((PetscObject)snes),"%5d: %20.5g + %20.5gi\n",i,(double)eigr[i],(double)eigi[i]);CHKERRQ(ierr);
2022e7541e6SPeter Brune   }
2038c778c55SBarry Smith   ierr = MatDenseRestoreArray(dJdense,&a);CHKERRQ(ierr);
2042e7541e6SPeter Brune   ierr = MatDestroy(&dJ);CHKERRQ(ierr);
2052e7541e6SPeter Brune   ierr = MatDestroy(&dJdense);CHKERRQ(ierr);
2062e7541e6SPeter Brune   ierr = PetscFree(eigr);CHKERRQ(ierr);
2072e7541e6SPeter Brune   ierr = PetscFree(eigi);CHKERRQ(ierr);
2082e7541e6SPeter Brune   ierr = PetscFree(work);CHKERRQ(ierr);
2092e7541e6SPeter Brune   PetscFunctionReturn(0);
210196da8b6SPeter Brune #endif
2112e7541e6SPeter Brune }
2122e7541e6SPeter Brune 
2132e7541e6SPeter Brune #undef __FUNCT__
214b271bb04SBarry Smith #define __FUNCT__ "SNESMonitorRange_Private"
2157087cfbeSBarry Smith PetscErrorCode  SNESMonitorRange_Private(SNES snes,PetscInt it,PetscReal *per)
216b271bb04SBarry Smith {
217b271bb04SBarry Smith   PetscErrorCode ierr;
218b271bb04SBarry Smith   Vec            resid;
219b271bb04SBarry Smith   PetscReal      rmax,pwork;
220b271bb04SBarry Smith   PetscInt       i,n,N;
221b271bb04SBarry Smith   PetscScalar    *r;
222b271bb04SBarry Smith 
223b271bb04SBarry Smith   PetscFunctionBegin;
224b271bb04SBarry Smith   ierr  = SNESGetFunction(snes,&resid,0,0);CHKERRQ(ierr);
225b271bb04SBarry Smith   ierr  = VecNorm(resid,NORM_INFINITY,&rmax);CHKERRQ(ierr);
226b271bb04SBarry Smith   ierr  = VecGetLocalSize(resid,&n);CHKERRQ(ierr);
227b271bb04SBarry Smith   ierr  = VecGetSize(resid,&N);CHKERRQ(ierr);
228b271bb04SBarry Smith   ierr  = VecGetArray(resid,&r);CHKERRQ(ierr);
229b271bb04SBarry Smith   pwork = 0.0;
230b271bb04SBarry Smith   for (i=0; i<n; i++) {
231b271bb04SBarry Smith     pwork += (PetscAbsScalar(r[i]) > .20*rmax);
232b271bb04SBarry Smith   }
233ce94432eSBarry Smith   ierr = MPI_Allreduce(&pwork,per,1,MPIU_REAL,MPIU_SUM,PetscObjectComm((PetscObject)snes));CHKERRQ(ierr);
234b271bb04SBarry Smith   ierr = VecRestoreArray(resid,&r);CHKERRQ(ierr);
235b271bb04SBarry Smith   *per = *per/N;
236b271bb04SBarry Smith   PetscFunctionReturn(0);
237b271bb04SBarry Smith }
238b271bb04SBarry Smith 
239b271bb04SBarry Smith #undef __FUNCT__
240b271bb04SBarry Smith #define __FUNCT__ "SNESMonitorRange"
241b271bb04SBarry Smith /*@C
242b271bb04SBarry Smith    SNESMonitorRange - Prints the percentage of residual elements that are more then 10 percent of the maximum value.
243b271bb04SBarry Smith 
244b271bb04SBarry Smith    Collective on SNES
245b271bb04SBarry Smith 
246b271bb04SBarry Smith    Input Parameters:
247b271bb04SBarry Smith +  snes   - iterative context
248b271bb04SBarry Smith .  it    - iteration number
249b271bb04SBarry Smith .  rnorm - 2-norm (preconditioned) residual value (may be estimated).
250b271bb04SBarry Smith -  dummy - unused monitor context
251b271bb04SBarry Smith 
252b271bb04SBarry Smith    Options Database Key:
253b271bb04SBarry Smith .  -snes_monitor_range - Activates SNESMonitorRange()
254b271bb04SBarry Smith 
255b271bb04SBarry Smith    Level: intermediate
256b271bb04SBarry Smith 
257b271bb04SBarry Smith .keywords: SNES, default, monitor, residual
258b271bb04SBarry Smith 
259b271bb04SBarry Smith .seealso: SNESMonitorSet(), SNESMonitorDefault(), SNESMonitorLGCreate()
260b271bb04SBarry Smith @*/
2617087cfbeSBarry Smith PetscErrorCode  SNESMonitorRange(SNES snes,PetscInt it,PetscReal rnorm,void *dummy)
262b271bb04SBarry Smith {
263b271bb04SBarry Smith   PetscErrorCode ierr;
264b271bb04SBarry Smith   PetscReal      perc,rel;
265ce94432eSBarry Smith   PetscViewer    viewer = dummy ? (PetscViewer) dummy : PETSC_VIEWER_STDOUT_(PetscObjectComm((PetscObject)snes));
266b271bb04SBarry Smith   /* should be in a MonitorRangeContext */
267b271bb04SBarry Smith   static PetscReal prev;
268b271bb04SBarry Smith 
269b271bb04SBarry Smith   PetscFunctionBegin;
270b271bb04SBarry Smith   if (!it) prev = rnorm;
271b271bb04SBarry Smith   ierr = SNESMonitorRange_Private(snes,it,&perc);CHKERRQ(ierr);
272b271bb04SBarry Smith 
273b271bb04SBarry Smith   rel  = (prev - rnorm)/prev;
274b271bb04SBarry Smith   prev = rnorm;
275649052a6SBarry Smith   ierr = PetscViewerASCIIAddTab(viewer,((PetscObject)snes)->tablevel);CHKERRQ(ierr);
2766712e2f1SBarry 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);
277649052a6SBarry Smith   ierr = PetscViewerASCIISubtractTab(viewer,((PetscObject)snes)->tablevel);CHKERRQ(ierr);
278b271bb04SBarry Smith   PetscFunctionReturn(0);
279b271bb04SBarry Smith }
280b271bb04SBarry Smith 
281eabae89aSBarry Smith typedef struct {
282649052a6SBarry Smith   PetscViewer viewer;
283eabae89aSBarry Smith   PetscReal   *history;
284a6570f20SBarry Smith } SNESMonitorRatioContext;
285eabae89aSBarry Smith 
2863a7fca6bSBarry Smith #undef __FUNCT__
287a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorRatio"
2883a7fca6bSBarry Smith /*@C
289a6570f20SBarry Smith    SNESMonitorRatio - Monitors progress of the SNES solvers by printing the ratio
2904b27c08aSLois Curfman McInnes    of residual norm at each iteration to the previous.
2913a7fca6bSBarry Smith 
2923a7fca6bSBarry Smith    Collective on SNES
2933a7fca6bSBarry Smith 
2943a7fca6bSBarry Smith    Input Parameters:
2953a7fca6bSBarry Smith +  snes - the SNES context
2963a7fca6bSBarry Smith .  its - iteration number
2973a7fca6bSBarry Smith .  fgnorm - 2-norm of residual (or gradient)
298eabae89aSBarry Smith -  dummy -  context of monitor
2993a7fca6bSBarry Smith 
3003a7fca6bSBarry Smith    Level: intermediate
3013a7fca6bSBarry Smith 
3023a7fca6bSBarry Smith .keywords: SNES, nonlinear, monitor, norm
3033a7fca6bSBarry Smith 
304a6570f20SBarry Smith .seealso: SNESMonitorSet(), SNESMonitorSolution()
3053a7fca6bSBarry Smith @*/
3067087cfbeSBarry Smith PetscErrorCode  SNESMonitorRatio(SNES snes,PetscInt its,PetscReal fgnorm,void *dummy)
3073a7fca6bSBarry Smith {
308dfbe8321SBarry Smith   PetscErrorCode          ierr;
30977431f27SBarry Smith   PetscInt                len;
31087828ca2SBarry Smith   PetscReal               *history;
311a6570f20SBarry Smith   SNESMonitorRatioContext *ctx = (SNESMonitorRatioContext*)dummy;
3123a7fca6bSBarry Smith 
3133a7fca6bSBarry Smith   PetscFunctionBegin;
3140298fd71SBarry Smith   ierr = SNESGetConvergenceHistory(snes,&history,NULL,&len);CHKERRQ(ierr);
315649052a6SBarry Smith   ierr = PetscViewerASCIIAddTab(ctx->viewer,((PetscObject)snes)->tablevel);CHKERRQ(ierr);
316958c9bccSBarry Smith   if (!its || !history || its > len) {
317649052a6SBarry Smith     ierr = PetscViewerASCIIPrintf(ctx->viewer,"%3D SNES Function norm %14.12e \n",its,(double)fgnorm);CHKERRQ(ierr);
3183a7fca6bSBarry Smith   } else {
31987828ca2SBarry Smith     PetscReal ratio = fgnorm/history[its-1];
3208f1a2a5eSBarry Smith     ierr = PetscViewerASCIIPrintf(ctx->viewer,"%3D SNES Function norm %14.12e %14.12e \n",its,(double)fgnorm,(double)ratio);CHKERRQ(ierr);
3213a7fca6bSBarry Smith   }
322649052a6SBarry Smith   ierr = PetscViewerASCIISubtractTab(ctx->viewer,((PetscObject)snes)->tablevel);CHKERRQ(ierr);
3233a7fca6bSBarry Smith   PetscFunctionReturn(0);
3243a7fca6bSBarry Smith }
3253a7fca6bSBarry Smith 
3263a7fca6bSBarry Smith /*
3273a7fca6bSBarry Smith    If the we set the history monitor space then we must destroy it
3283a7fca6bSBarry Smith */
3293a7fca6bSBarry Smith #undef __FUNCT__
330a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorRatioDestroy"
331c2efdce3SBarry Smith PetscErrorCode SNESMonitorRatioDestroy(void **ct)
3323a7fca6bSBarry Smith {
333dfbe8321SBarry Smith   PetscErrorCode          ierr;
334c2efdce3SBarry Smith   SNESMonitorRatioContext *ctx = *(SNESMonitorRatioContext**)ct;
3353a7fca6bSBarry Smith 
3363a7fca6bSBarry Smith   PetscFunctionBegin;
33705b42c5fSBarry Smith   ierr = PetscFree(ctx->history);CHKERRQ(ierr);
338649052a6SBarry Smith   ierr = PetscViewerDestroy(&ctx->viewer);CHKERRQ(ierr);
339eabae89aSBarry Smith   ierr = PetscFree(ctx);CHKERRQ(ierr);
3403a7fca6bSBarry Smith   PetscFunctionReturn(0);
3413a7fca6bSBarry Smith }
3423a7fca6bSBarry Smith 
3433a7fca6bSBarry Smith #undef __FUNCT__
344a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorSetRatio"
3453a7fca6bSBarry Smith /*@C
346a6570f20SBarry Smith    SNESMonitorSetRatio - Sets SNES to use a monitor that prints the
3474b27c08aSLois Curfman McInnes    ratio of the function norm at each iteration.
3483a7fca6bSBarry Smith 
3493a7fca6bSBarry Smith    Collective on SNES
3503a7fca6bSBarry Smith 
3513a7fca6bSBarry Smith    Input Parameters:
352eabae89aSBarry Smith +   snes - the SNES context
353eabae89aSBarry Smith -   viewer - ASCII viewer to print output
3543a7fca6bSBarry Smith 
3553a7fca6bSBarry Smith    Level: intermediate
3563a7fca6bSBarry Smith 
3573a7fca6bSBarry Smith .keywords: SNES, nonlinear, monitor, norm
3583a7fca6bSBarry Smith 
359a6570f20SBarry Smith .seealso: SNESMonitorSet(), SNESMonitorSolution(), SNESMonitorDefault()
3603a7fca6bSBarry Smith @*/
361649052a6SBarry Smith PetscErrorCode  SNESMonitorSetRatio(SNES snes,PetscViewer viewer)
3623a7fca6bSBarry Smith {
363dfbe8321SBarry Smith   PetscErrorCode          ierr;
364a6570f20SBarry Smith   SNESMonitorRatioContext *ctx;
36587828ca2SBarry Smith   PetscReal               *history;
3663a7fca6bSBarry Smith 
3673a7fca6bSBarry Smith   PetscFunctionBegin;
368eabae89aSBarry Smith   if (!viewer) {
369ce94432eSBarry Smith     ierr = PetscViewerASCIIOpen(PetscObjectComm((PetscObject)snes),"stdout",&viewer);CHKERRQ(ierr);
370eabae89aSBarry Smith     ierr = PetscObjectReference((PetscObject)viewer);CHKERRQ(ierr);
371eabae89aSBarry Smith   }
372b00a9115SJed Brown   ierr = PetscNewLog(snes,&ctx);CHKERRQ(ierr);
3730298fd71SBarry Smith   ierr = SNESGetConvergenceHistory(snes,&history,NULL,NULL);CHKERRQ(ierr);
3743a7fca6bSBarry Smith   if (!history) {
375785e854fSJed Brown     ierr = PetscMalloc1(100,&ctx->history);CHKERRQ(ierr);
376eabae89aSBarry Smith     ierr = SNESSetConvergenceHistory(snes,ctx->history,0,100,PETSC_TRUE);CHKERRQ(ierr);
3773a7fca6bSBarry Smith   }
378eabae89aSBarry Smith   ctx->viewer = viewer;
379f5af7f23SKarl Rupp 
380a6570f20SBarry Smith   ierr = SNESMonitorSet(snes,SNESMonitorRatio,ctx,SNESMonitorRatioDestroy);CHKERRQ(ierr);
3813a7fca6bSBarry Smith   PetscFunctionReturn(0);
3823a7fca6bSBarry Smith }
3833a7fca6bSBarry Smith 
384e7e93795SLois Curfman McInnes /* ---------------------------------------------------------------- */
3854a2ae208SSatish Balay #undef __FUNCT__
386a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorDefaultShort"
387be1f7002SBarry Smith /*
388a6570f20SBarry Smith      Default (short) SNES Monitor, same as SNESMonitorDefault() except
389be1f7002SBarry Smith   it prints fewer digits of the residual as the residual gets smaller.
390be1f7002SBarry Smith   This is because the later digits are meaningless and are often
391be1f7002SBarry Smith   different on different machines; by using this routine different
392be1f7002SBarry Smith   machines will usually generate the same output.
393be1f7002SBarry Smith */
3947087cfbeSBarry Smith PetscErrorCode  SNESMonitorDefaultShort(SNES snes,PetscInt its,PetscReal fgnorm,void *dummy)
395e7e93795SLois Curfman McInnes {
396dfbe8321SBarry Smith   PetscErrorCode ierr;
397ce94432eSBarry Smith   PetscViewer    viewer = dummy ? (PetscViewer) dummy : PETSC_VIEWER_STDOUT_(PetscObjectComm((PetscObject)snes));
398d132466eSBarry Smith 
3993a40ed3dSBarry Smith   PetscFunctionBegin;
400649052a6SBarry Smith   ierr = PetscViewerASCIIAddTab(viewer,((PetscObject)snes)->tablevel);CHKERRQ(ierr);
4018f240d10SBarry Smith   if (fgnorm > 1.e-9) {
4028fa295daSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"%3D SNES Function norm %g \n",its,(double)fgnorm);CHKERRQ(ierr);
4033a40ed3dSBarry Smith   } else if (fgnorm > 1.e-11) {
4048fa295daSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"%3D SNES Function norm %5.3e \n",its,(double)fgnorm);CHKERRQ(ierr);
4053a40ed3dSBarry Smith   } else {
406649052a6SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"%3D SNES Function norm < 1.e-11\n",its);CHKERRQ(ierr);
407a34d58ebSBarry Smith   }
408649052a6SBarry Smith   ierr = PetscViewerASCIISubtractTab(viewer,((PetscObject)snes)->tablevel);CHKERRQ(ierr);
4093a40ed3dSBarry Smith   PetscFunctionReturn(0);
410e7e93795SLois Curfman McInnes }
411e7e93795SLois Curfman McInnes /* ---------------------------------------------------------------- */
4124a2ae208SSatish Balay #undef __FUNCT__
4138d359177SBarry Smith #define __FUNCT__ "SNESConvergedDefault"
4144b828684SBarry Smith /*@C
4158d359177SBarry Smith    SNESConvergedDefault - Convergence test of the solvers for
416f525115eSLois Curfman McInnes    systems of nonlinear equations (default).
417e7e93795SLois Curfman McInnes 
418c7afd0dbSLois Curfman McInnes    Collective on SNES
419c7afd0dbSLois Curfman McInnes 
420e7e93795SLois Curfman McInnes    Input Parameters:
421c7afd0dbSLois Curfman McInnes +  snes - the SNES context
42206ee9f85SBarry Smith .  it - the iteration (0 indicates before any Newton steps)
423e7e93795SLois Curfman McInnes .  xnorm - 2-norm of current iterate
424c60f73f4SPeter Brune .  snorm - 2-norm of current step
4257f3332b4SBarry Smith .  fnorm - 2-norm of function at current iterate
426c7afd0dbSLois Curfman McInnes -  dummy - unused context
427e7e93795SLois Curfman McInnes 
428184914b5SBarry Smith    Output Parameter:
429184914b5SBarry Smith .   reason  - one of
43070441072SBarry Smith $  SNES_CONVERGED_FNORM_ABS       - (fnorm < abstol),
431c60f73f4SPeter Brune $  SNES_CONVERGED_SNORM_RELATIVE  - (snorm < stol*xnorm),
432184914b5SBarry Smith $  SNES_CONVERGED_FNORM_RELATIVE  - (fnorm < rtol*fnorm0),
433184914b5SBarry Smith $  SNES_DIVERGED_FUNCTION_COUNT   - (nfct > maxf),
434184914b5SBarry Smith $  SNES_DIVERGED_FNORM_NAN        - (fnorm == NaN),
435184914b5SBarry Smith $  SNES_CONVERGED_ITERATING       - (otherwise),
436e7e93795SLois Curfman McInnes 
437e7e93795SLois Curfman McInnes    where
438c7afd0dbSLois Curfman McInnes +    maxf - maximum number of function evaluations,
439c7afd0dbSLois Curfman McInnes             set with SNESSetTolerances()
440c7afd0dbSLois Curfman McInnes .    nfct - number of function evaluations,
44170441072SBarry Smith .    abstol - absolute function norm tolerance,
442c7afd0dbSLois Curfman McInnes             set with SNESSetTolerances()
443c7afd0dbSLois Curfman McInnes -    rtol - relative function norm tolerance, set with SNESSetTolerances()
444fee21e36SBarry Smith 
44536851e7fSLois Curfman McInnes    Level: intermediate
44636851e7fSLois Curfman McInnes 
447e7e93795SLois Curfman McInnes .keywords: SNES, nonlinear, default, converged, convergence
448e7e93795SLois Curfman McInnes 
44971f87433Sdalcinl .seealso: SNESSetConvergenceTest()
450e7e93795SLois Curfman McInnes @*/
4518d359177SBarry Smith PetscErrorCode  SNESConvergedDefault(SNES snes,PetscInt it,PetscReal xnorm,PetscReal snorm,PetscReal fnorm,SNESConvergedReason *reason,void *dummy)
452e7e93795SLois Curfman McInnes {
45363ba0a88SBarry Smith   PetscErrorCode ierr;
45463ba0a88SBarry Smith 
4553a40ed3dSBarry Smith   PetscFunctionBegin;
4560700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
4573f149594SLisandro Dalcin   PetscValidPointer(reason,6);
4583f149594SLisandro Dalcin 
45906ee9f85SBarry Smith   *reason = SNES_CONVERGED_ITERATING;
46006ee9f85SBarry Smith 
46106ee9f85SBarry Smith   if (!it) {
46206ee9f85SBarry Smith     /* set parameter for default relative tolerance convergence test */
46306ee9f85SBarry Smith     snes->ttol = fnorm*snes->rtol;
46406ee9f85SBarry Smith   }
4658146f6ebSBarry Smith   if (PetscIsInfOrNanReal(fnorm)) {
466ae15b995SBarry Smith     ierr    = PetscInfo(snes,"Failed to converged, function norm is NaN\n");CHKERRQ(ierr);
467184914b5SBarry Smith     *reason = SNES_DIVERGED_FNORM_NAN;
46870441072SBarry Smith   } else if (fnorm < snes->abstol) {
4698f1a2a5eSBarry Smith     ierr    = PetscInfo2(snes,"Converged due to function norm %14.12e < %14.12e\n",(double)fnorm,(double)snes->abstol);CHKERRQ(ierr);
470184914b5SBarry Smith     *reason = SNES_CONVERGED_FNORM_ABS;
47143e71028SBarry Smith   } else if (snes->nfuncs >= snes->max_funcs) {
472ae15b995SBarry Smith     ierr    = PetscInfo2(snes,"Exceeded maximum number of function evaluations: %D > %D\n",snes->nfuncs,snes->max_funcs);CHKERRQ(ierr);
473184914b5SBarry Smith     *reason = SNES_DIVERGED_FUNCTION_COUNT;
47406ee9f85SBarry Smith   }
47506ee9f85SBarry Smith 
47606ee9f85SBarry Smith   if (it && !*reason) {
47706ee9f85SBarry Smith     if (fnorm <= snes->ttol) {
4788f1a2a5eSBarry Smith       ierr    = PetscInfo2(snes,"Converged due to function norm %14.12e < %14.12e (relative tolerance)\n",(double)fnorm,(double)snes->ttol);CHKERRQ(ierr);
47906ee9f85SBarry Smith       *reason = SNES_CONVERGED_FNORM_RELATIVE;
480c60f73f4SPeter Brune     } else if (snorm < snes->stol*xnorm) {
481c60f73f4SPeter 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);
482c60f73f4SPeter Brune       *reason = SNES_CONVERGED_SNORM_RELATIVE;
48306ee9f85SBarry Smith     }
484e7e93795SLois Curfman McInnes   }
4853a40ed3dSBarry Smith   PetscFunctionReturn(0);
486e7e93795SLois Curfman McInnes }
4873f149594SLisandro Dalcin 
4883f149594SLisandro Dalcin #undef __FUNCT__
489e2a6519dSDmitry Karpeev #define __FUNCT__ "SNESConvergedSkip"
4903f149594SLisandro Dalcin /*@C
491e2a6519dSDmitry Karpeev    SNESConvergedSkip - Convergence test for SNES that NEVER returns as
4923f149594SLisandro Dalcin    converged, UNLESS the maximum number of iteration have been reached.
4933f149594SLisandro Dalcin 
4943f9fe445SBarry Smith    Logically Collective on SNES
4953f149594SLisandro Dalcin 
4963f149594SLisandro Dalcin    Input Parameters:
4973f149594SLisandro Dalcin +  snes - the SNES context
4983f149594SLisandro Dalcin .  it - the iteration (0 indicates before any Newton steps)
4993f149594SLisandro Dalcin .  xnorm - 2-norm of current iterate
500c60f73f4SPeter Brune .  snorm - 2-norm of current step
5013f149594SLisandro Dalcin .  fnorm - 2-norm of function at current iterate
5023f149594SLisandro Dalcin -  dummy - unused context
5033f149594SLisandro Dalcin 
5043f149594SLisandro Dalcin    Output Parameter:
50585385478SLisandro Dalcin .   reason  - SNES_CONVERGED_ITERATING, SNES_CONVERGED_ITS, or SNES_DIVERGED_FNORM_NAN
5063f149594SLisandro Dalcin 
5073f149594SLisandro Dalcin    Notes:
5083f149594SLisandro Dalcin    Convergence is then declared after a fixed number of iterations have been used.
5093f149594SLisandro Dalcin 
5103f149594SLisandro Dalcin    Level: advanced
5113f149594SLisandro Dalcin 
5123f149594SLisandro Dalcin .keywords: SNES, nonlinear, skip, converged, convergence
5133f149594SLisandro Dalcin 
5143f149594SLisandro Dalcin .seealso: SNESSetConvergenceTest()
5153f149594SLisandro Dalcin @*/
516e2a6519dSDmitry Karpeev PetscErrorCode  SNESConvergedSkip(SNES snes,PetscInt it,PetscReal xnorm,PetscReal snorm,PetscReal fnorm,SNESConvergedReason *reason,void *dummy)
5173f149594SLisandro Dalcin {
5183f149594SLisandro Dalcin   PetscErrorCode ierr;
5193f149594SLisandro Dalcin 
5203f149594SLisandro Dalcin   PetscFunctionBegin;
5210700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
5223f149594SLisandro Dalcin   PetscValidPointer(reason,6);
5233f149594SLisandro Dalcin 
5243f149594SLisandro Dalcin   *reason = SNES_CONVERGED_ITERATING;
5253f149594SLisandro Dalcin 
5263f149594SLisandro Dalcin   if (fnorm != fnorm) {
5273f149594SLisandro Dalcin     ierr    = PetscInfo(snes,"Failed to converged, function norm is NaN\n");CHKERRQ(ierr);
5283f149594SLisandro Dalcin     *reason = SNES_DIVERGED_FNORM_NAN;
5293f149594SLisandro Dalcin   } else if (it == snes->max_its) {
5303f149594SLisandro Dalcin     *reason = SNES_CONVERGED_ITS;
5313f149594SLisandro Dalcin   }
5323f149594SLisandro Dalcin   PetscFunctionReturn(0);
5333f149594SLisandro Dalcin }
5343f149594SLisandro Dalcin 
53558c9b817SLisandro Dalcin #undef __FUNCT__
536fa0ddf94SBarry Smith #define __FUNCT__ "SNESSetWorkVecs"
5378d359177SBarry Smith /*@C
538fa0ddf94SBarry Smith   SNESSetWorkVecs - Gets a number of work vectors.
53958c9b817SLisandro Dalcin 
54058c9b817SLisandro Dalcin   Input Parameters:
54158c9b817SLisandro Dalcin . snes  - the SNES context
54258c9b817SLisandro Dalcin . nw - number of work vectors to allocate
54358c9b817SLisandro Dalcin 
54458c9b817SLisandro Dalcin    Level: developer
54558c9b817SLisandro Dalcin 
546fa0ddf94SBarry Smith    Developers Note: This is PETSC_EXTERN because it may be used by user written plugin SNES implementations
547fa0ddf94SBarry Smith 
54898acb6afSMatthew G Knepley @*/
549fa0ddf94SBarry Smith PetscErrorCode SNESSetWorkVecs(SNES snes,PetscInt nw)
55058c9b817SLisandro Dalcin {
551c5ed8070SMatthew G. Knepley   DM             dm;
552c5ed8070SMatthew G. Knepley   Vec            v;
55358c9b817SLisandro Dalcin   PetscErrorCode ierr;
55458c9b817SLisandro Dalcin 
55558c9b817SLisandro Dalcin   PetscFunctionBegin;
55658c9b817SLisandro Dalcin   if (snes->work) {ierr = VecDestroyVecs(snes->nwork,&snes->work);CHKERRQ(ierr);}
55758c9b817SLisandro Dalcin   snes->nwork = nw;
558f5af7f23SKarl Rupp 
559c5ed8070SMatthew G. Knepley   ierr = SNESGetDM(snes, &dm);CHKERRQ(ierr);
560c5ed8070SMatthew G. Knepley   ierr = DMGetGlobalVector(dm, &v);CHKERRQ(ierr);
561c5ed8070SMatthew G. Knepley   ierr = VecDuplicateVecs(v,snes->nwork,&snes->work);CHKERRQ(ierr);
562c5ed8070SMatthew G. Knepley   ierr = DMRestoreGlobalVector(dm, &v);CHKERRQ(ierr);
56358c9b817SLisandro Dalcin   ierr = PetscLogObjectParents(snes,nw,snes->work);CHKERRQ(ierr);
56458c9b817SLisandro Dalcin   PetscFunctionReturn(0);
56558c9b817SLisandro Dalcin }
566