xref: /petsc/src/snes/interface/snesut.c (revision 2e7541e6c89139c3c9f20d115be3bed9f3d98f9d)
1e7e93795SLois Curfman McInnes 
2b45d2f2cSJed Brown #include <petsc-private/snesimpl.h>       /*I   "petscsnes.h"   I*/
3*2e7541e6SPeter Brune #include <petscblaslapack.h>
4e7e93795SLois Curfman McInnes 
54a2ae208SSatish Balay #undef __FUNCT__
6a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorSolution"
73f1db9ecSBarry Smith /*@C
8a6570f20SBarry Smith    SNESMonitorSolution - Monitors progress of the SNES solvers by calling
936851e7fSLois Curfman McInnes    VecView() for the approximate solution at each iteration.
103f1db9ecSBarry Smith 
113f1db9ecSBarry Smith    Collective on SNES
123f1db9ecSBarry Smith 
133f1db9ecSBarry Smith    Input Parameters:
143f1db9ecSBarry Smith +  snes - the SNES context
153f1db9ecSBarry Smith .  its - iteration number
164b27c08aSLois Curfman McInnes .  fgnorm - 2-norm of residual
173f1db9ecSBarry Smith -  dummy - either a viewer or PETSC_NULL
183f1db9ecSBarry Smith 
1936851e7fSLois Curfman McInnes    Level: intermediate
203f1db9ecSBarry Smith 
2136851e7fSLois Curfman McInnes .keywords: SNES, nonlinear, vector, monitor, view
223f1db9ecSBarry Smith 
23a6570f20SBarry Smith .seealso: SNESMonitorSet(), SNESMonitorDefault(), VecView()
243f1db9ecSBarry Smith @*/
257087cfbeSBarry Smith PetscErrorCode  SNESMonitorSolution(SNES snes,PetscInt its,PetscReal fgnorm,void *dummy)
263f1db9ecSBarry Smith {
27dfbe8321SBarry Smith   PetscErrorCode ierr;
283f1db9ecSBarry Smith   Vec            x;
29b0a32e0cSBarry Smith   PetscViewer    viewer = (PetscViewer) dummy;
303f1db9ecSBarry Smith 
313f1db9ecSBarry Smith   PetscFunctionBegin;
323f1db9ecSBarry Smith   ierr = SNESGetSolution(snes,&x);CHKERRQ(ierr);
333f1db9ecSBarry Smith   if (!viewer) {
343f1db9ecSBarry Smith     MPI_Comm comm;
353f1db9ecSBarry Smith     ierr   = PetscObjectGetComm((PetscObject)snes,&comm);CHKERRQ(ierr);
36b0a32e0cSBarry Smith     viewer = PETSC_VIEWER_DRAW_(comm);
373f1db9ecSBarry Smith   }
383f1db9ecSBarry Smith   ierr = VecView(x,viewer);CHKERRQ(ierr);
393f1db9ecSBarry Smith 
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
555ed2d596SBarry Smith -  dummy - either a viewer or PETSC_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 
785ed2d596SBarry Smith   PetscFunctionReturn(0);
795ed2d596SBarry Smith }
805ed2d596SBarry Smith 
815ed2d596SBarry Smith #undef __FUNCT__
82a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorSolutionUpdate"
83d132466eSBarry Smith /*@C
84a6570f20SBarry Smith    SNESMonitorSolutionUpdate - Monitors progress of the SNES solvers by calling
85d132466eSBarry Smith    VecView() for the UPDATE to the solution at each iteration.
86d132466eSBarry Smith 
87d132466eSBarry Smith    Collective on SNES
88d132466eSBarry Smith 
89d132466eSBarry Smith    Input Parameters:
90d132466eSBarry Smith +  snes - the SNES context
91d132466eSBarry Smith .  its - iteration number
924b27c08aSLois Curfman McInnes .  fgnorm - 2-norm of residual
93d132466eSBarry Smith -  dummy - either a viewer or PETSC_NULL
94d132466eSBarry Smith 
95d132466eSBarry Smith    Level: intermediate
96d132466eSBarry Smith 
97d132466eSBarry Smith .keywords: SNES, nonlinear, vector, monitor, view
98d132466eSBarry Smith 
99a6570f20SBarry Smith .seealso: SNESMonitorSet(), SNESMonitorDefault(), VecView()
100d132466eSBarry Smith @*/
1017087cfbeSBarry Smith PetscErrorCode  SNESMonitorSolutionUpdate(SNES snes,PetscInt its,PetscReal fgnorm,void *dummy)
102d132466eSBarry Smith {
103dfbe8321SBarry Smith   PetscErrorCode ierr;
104d132466eSBarry Smith   Vec            x;
105b0a32e0cSBarry Smith   PetscViewer    viewer = (PetscViewer) dummy;
106d132466eSBarry Smith 
107d132466eSBarry Smith   PetscFunctionBegin;
108d132466eSBarry Smith   ierr = SNESGetSolutionUpdate(snes,&x);CHKERRQ(ierr);
109d132466eSBarry Smith   if (!viewer) {
110d132466eSBarry Smith     MPI_Comm comm;
111d132466eSBarry Smith     ierr   = PetscObjectGetComm((PetscObject)snes,&comm);CHKERRQ(ierr);
112b0a32e0cSBarry Smith     viewer = PETSC_VIEWER_DRAW_(comm);
113d132466eSBarry Smith   }
114d132466eSBarry Smith   ierr = VecView(x,viewer);CHKERRQ(ierr);
115d132466eSBarry Smith 
116d132466eSBarry Smith   PetscFunctionReturn(0);
117d132466eSBarry Smith }
118d132466eSBarry Smith 
1194a2ae208SSatish Balay #undef __FUNCT__
120a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorDefault"
1214b828684SBarry Smith /*@C
122a6570f20SBarry Smith    SNESMonitorDefault - Monitors progress of the SNES solvers (default).
123e7e93795SLois Curfman McInnes 
124c7afd0dbSLois Curfman McInnes    Collective on SNES
125c7afd0dbSLois Curfman McInnes 
126e7e93795SLois Curfman McInnes    Input Parameters:
127c7afd0dbSLois Curfman McInnes +  snes - the SNES context
128e7e93795SLois Curfman McInnes .  its - iteration number
1294b27c08aSLois Curfman McInnes .  fgnorm - 2-norm of residual
130c7afd0dbSLois Curfman McInnes -  dummy - unused context
131fee21e36SBarry Smith 
132e7e93795SLois Curfman McInnes    Notes:
1334b27c08aSLois Curfman McInnes    This routine prints the residual norm at each iteration.
134e7e93795SLois Curfman McInnes 
13536851e7fSLois Curfman McInnes    Level: intermediate
13636851e7fSLois Curfman McInnes 
137e7e93795SLois Curfman McInnes .keywords: SNES, nonlinear, default, monitor, norm
138e7e93795SLois Curfman McInnes 
139a6570f20SBarry Smith .seealso: SNESMonitorSet(), SNESMonitorSolution()
140e7e93795SLois Curfman McInnes @*/
1417087cfbeSBarry Smith PetscErrorCode  SNESMonitorDefault(SNES snes,PetscInt its,PetscReal fgnorm,void *dummy)
142e7e93795SLois Curfman McInnes {
143dfbe8321SBarry Smith   PetscErrorCode ierr;
144649052a6SBarry Smith   PetscViewer    viewer = dummy ? (PetscViewer) dummy : PETSC_VIEWER_STDOUT_(((PetscObject)snes)->comm);
145d132466eSBarry Smith 
1463a40ed3dSBarry Smith   PetscFunctionBegin;
147649052a6SBarry Smith   ierr = PetscViewerASCIIAddTab(viewer,((PetscObject)snes)->tablevel);CHKERRQ(ierr);
148649052a6SBarry Smith   ierr = PetscViewerASCIIPrintf(viewer,"%3D SNES Function norm %14.12e \n",its,(double)fgnorm);CHKERRQ(ierr);
149649052a6SBarry Smith   ierr = PetscViewerASCIISubtractTab(viewer,((PetscObject)snes)->tablevel);CHKERRQ(ierr);
1503a40ed3dSBarry Smith   PetscFunctionReturn(0);
151e7e93795SLois Curfman McInnes }
1523f1db9ecSBarry Smith 
153b271bb04SBarry Smith #undef __FUNCT__
154*2e7541e6SPeter Brune #define __FUNCT__ "SNESMonitorJacUpdateSpectrum"
155*2e7541e6SPeter Brune PetscErrorCode SNESMonitorJacUpdateSpectrum(SNES snes,PetscInt it,PetscReal fnorm,void *ctx) {
156*2e7541e6SPeter Brune 
157*2e7541e6SPeter Brune   Vec            X;
158*2e7541e6SPeter Brune   Mat            J,dJ,dJdense;
159*2e7541e6SPeter Brune   PetscErrorCode ierr;
160*2e7541e6SPeter Brune   PetscErrorCode (*func)(SNES,Vec,Mat*,Mat*,MatStructure*,void*);
161*2e7541e6SPeter Brune   PetscInt       n,i;
162*2e7541e6SPeter Brune   PetscBLASInt   nb,lwork;
163*2e7541e6SPeter Brune   PetscReal      *eigr,*eigi;
164*2e7541e6SPeter Brune   MatStructure   flg = DIFFERENT_NONZERO_PATTERN;
165*2e7541e6SPeter Brune   PetscScalar    *work;
166*2e7541e6SPeter Brune   PetscScalar    *a;
167*2e7541e6SPeter Brune 
168*2e7541e6SPeter Brune   PetscFunctionBegin;
169*2e7541e6SPeter Brune   if (it == 0) PetscFunctionReturn(0);
170*2e7541e6SPeter Brune   /* create the difference between the current update and the current jacobian */
171*2e7541e6SPeter Brune   ierr = SNESGetSolution(snes,&X);CHKERRQ(ierr);
172*2e7541e6SPeter Brune   ierr = SNESGetJacobian(snes,&J,PETSC_NULL,&func,PETSC_NULL);CHKERRQ(ierr);
173*2e7541e6SPeter Brune   ierr = MatDuplicate(J,MAT_COPY_VALUES,&dJ);CHKERRQ(ierr);
174*2e7541e6SPeter Brune   ierr = SNESComputeJacobian(snes,X,&dJ,&dJ,&flg);CHKERRQ(ierr);
175*2e7541e6SPeter Brune   ierr = MatAXPY(dJ,-1.0,J,SAME_NONZERO_PATTERN);CHKERRQ(ierr);
176*2e7541e6SPeter Brune   /* compute the spectrum directly */
177*2e7541e6SPeter Brune   ierr = MatConvert(dJ,MATSEQDENSE,MAT_INITIAL_MATRIX,&dJdense);CHKERRQ(ierr);
178*2e7541e6SPeter Brune   ierr = MatGetSize(dJ,&n,PETSC_NULL);CHKERRQ(ierr);
179*2e7541e6SPeter Brune   nb    = PetscBLASIntCast(n);
180*2e7541e6SPeter Brune   lwork = 3*nb;
181*2e7541e6SPeter Brune   ierr = PetscMalloc(n*sizeof(PetscReal),&eigr);CHKERRQ(ierr);
182*2e7541e6SPeter Brune   ierr = PetscMalloc(n*sizeof(PetscReal),&eigi);CHKERRQ(ierr);
183*2e7541e6SPeter Brune   ierr = PetscMalloc(lwork*sizeof(PetscScalar),&work);CHKERRQ(ierr);
184*2e7541e6SPeter Brune   ierr = MatGetArray(dJdense,&a);CHKERRQ(ierr);
185*2e7541e6SPeter Brune #if !defined(PETSC_USE_COMPLEX)
186*2e7541e6SPeter Brune   {
187*2e7541e6SPeter Brune     PetscBLASInt lierr;
188*2e7541e6SPeter Brune     ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
189*2e7541e6SPeter Brune     LAPACKgeev_("N","N",&nb,a,&nb,eigr,eigi,PETSC_NULL,&nb,PETSC_NULL,&nb,work,&lwork,&lierr);
190*2e7541e6SPeter Brune     if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"geev() error %d",lierr);
191*2e7541e6SPeter Brune     ierr = PetscFPTrapPop();CHKERRQ(ierr);
192*2e7541e6SPeter Brune   }
193*2e7541e6SPeter Brune #else
194*2e7541e6SPeter Brune   SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not coded for complex");
195*2e7541e6SPeter Brune #endif
196*2e7541e6SPeter Brune   PetscPrintf(((PetscObject)snes)->comm,"Eigenvalues of J_%d - J_%d:\n",it,it-1);CHKERRQ(ierr);
197*2e7541e6SPeter Brune   for (i=0;i<n;i++) {
198*2e7541e6SPeter Brune     PetscPrintf(((PetscObject)snes)->comm,"%5d: %20.5g + %20.5gi\n",i,eigr[i],eigi[i]);CHKERRQ(ierr);
199*2e7541e6SPeter Brune   }
200*2e7541e6SPeter Brune   ierr = MatRestoreArray(dJdense,&a);CHKERRQ(ierr);
201*2e7541e6SPeter Brune   ierr = MatDestroy(&dJ);CHKERRQ(ierr);
202*2e7541e6SPeter Brune   ierr = MatDestroy(&dJdense);CHKERRQ(ierr);
203*2e7541e6SPeter Brune   ierr = PetscFree(eigr);CHKERRQ(ierr);
204*2e7541e6SPeter Brune   ierr = PetscFree(eigi);CHKERRQ(ierr);
205*2e7541e6SPeter Brune   ierr = PetscFree(work);CHKERRQ(ierr);
206*2e7541e6SPeter Brune   PetscFunctionReturn(0);
207*2e7541e6SPeter Brune }
208*2e7541e6SPeter Brune 
209*2e7541e6SPeter Brune #undef __FUNCT__
210b271bb04SBarry Smith #define __FUNCT__ "SNESMonitorRange_Private"
2117087cfbeSBarry Smith PetscErrorCode  SNESMonitorRange_Private(SNES snes,PetscInt it,PetscReal *per)
212b271bb04SBarry Smith {
213b271bb04SBarry Smith   PetscErrorCode          ierr;
214b271bb04SBarry Smith   Vec                     resid;
215b271bb04SBarry Smith   PetscReal               rmax,pwork;
216b271bb04SBarry Smith   PetscInt                i,n,N;
217b271bb04SBarry Smith   PetscScalar             *r;
218b271bb04SBarry Smith 
219b271bb04SBarry Smith   PetscFunctionBegin;
220b271bb04SBarry Smith   ierr = SNESGetFunction(snes,&resid,0,0);CHKERRQ(ierr);
221b271bb04SBarry Smith   ierr = VecNorm(resid,NORM_INFINITY,&rmax);CHKERRQ(ierr);
222b271bb04SBarry Smith   ierr = VecGetLocalSize(resid,&n);CHKERRQ(ierr);
223b271bb04SBarry Smith   ierr = VecGetSize(resid,&N);CHKERRQ(ierr);
224b271bb04SBarry Smith   ierr = VecGetArray(resid,&r);CHKERRQ(ierr);
225b271bb04SBarry Smith   pwork = 0.0;
226b271bb04SBarry Smith   for (i=0; i<n; i++) {
227b271bb04SBarry Smith     pwork += (PetscAbsScalar(r[i]) > .20*rmax);
228b271bb04SBarry Smith   }
22906a205a8SBarry Smith   ierr = MPI_Allreduce(&pwork,per,1,MPIU_REAL,MPIU_SUM,((PetscObject)snes)->comm);CHKERRQ(ierr);
230b271bb04SBarry Smith   ierr = VecRestoreArray(resid,&r);CHKERRQ(ierr);
231b271bb04SBarry Smith   *per  = *per/N;
232b271bb04SBarry Smith   PetscFunctionReturn(0);
233b271bb04SBarry Smith }
234b271bb04SBarry Smith 
235b271bb04SBarry Smith #undef __FUNCT__
236b271bb04SBarry Smith #define __FUNCT__ "SNESMonitorRange"
237b271bb04SBarry Smith /*@C
238b271bb04SBarry Smith    SNESMonitorRange - Prints the percentage of residual elements that are more then 10 percent of the maximum value.
239b271bb04SBarry Smith 
240b271bb04SBarry Smith    Collective on SNES
241b271bb04SBarry Smith 
242b271bb04SBarry Smith    Input Parameters:
243b271bb04SBarry Smith +  snes   - iterative context
244b271bb04SBarry Smith .  it    - iteration number
245b271bb04SBarry Smith .  rnorm - 2-norm (preconditioned) residual value (may be estimated).
246b271bb04SBarry Smith -  dummy - unused monitor context
247b271bb04SBarry Smith 
248b271bb04SBarry Smith    Options Database Key:
249b271bb04SBarry Smith .  -snes_monitor_range - Activates SNESMonitorRange()
250b271bb04SBarry Smith 
251b271bb04SBarry Smith    Level: intermediate
252b271bb04SBarry Smith 
253b271bb04SBarry Smith .keywords: SNES, default, monitor, residual
254b271bb04SBarry Smith 
255b271bb04SBarry Smith .seealso: SNESMonitorSet(), SNESMonitorDefault(), SNESMonitorLGCreate()
256b271bb04SBarry Smith @*/
2577087cfbeSBarry Smith PetscErrorCode  SNESMonitorRange(SNES snes,PetscInt it,PetscReal rnorm,void *dummy)
258b271bb04SBarry Smith {
259b271bb04SBarry Smith   PetscErrorCode   ierr;
260b271bb04SBarry Smith   PetscReal        perc,rel;
261649052a6SBarry Smith   PetscViewer      viewer = dummy ? (PetscViewer) dummy : PETSC_VIEWER_STDOUT_(((PetscObject)snes)->comm);
262b271bb04SBarry Smith   /* should be in a MonitorRangeContext */
263b271bb04SBarry Smith   static PetscReal prev;
264b271bb04SBarry Smith 
265b271bb04SBarry Smith   PetscFunctionBegin;
266b271bb04SBarry Smith   if (!it) prev = rnorm;
267b271bb04SBarry Smith   ierr = SNESMonitorRange_Private(snes,it,&perc);CHKERRQ(ierr);
268b271bb04SBarry Smith 
269b271bb04SBarry Smith   rel  = (prev - rnorm)/prev;
270b271bb04SBarry Smith   prev = rnorm;
271649052a6SBarry Smith   ierr = PetscViewerASCIIAddTab(viewer,((PetscObject)snes)->tablevel);CHKERRQ(ierr);
272649052a6SBarry 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);
273649052a6SBarry Smith   ierr = PetscViewerASCIISubtractTab(viewer,((PetscObject)snes)->tablevel);CHKERRQ(ierr);
274b271bb04SBarry Smith   PetscFunctionReturn(0);
275b271bb04SBarry Smith }
276b271bb04SBarry Smith 
277eabae89aSBarry Smith typedef struct {
278649052a6SBarry Smith   PetscViewer viewer;
279eabae89aSBarry Smith   PetscReal   *history;
280a6570f20SBarry Smith } SNESMonitorRatioContext;
281eabae89aSBarry Smith 
2823a7fca6bSBarry Smith #undef __FUNCT__
283a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorRatio"
2843a7fca6bSBarry Smith /*@C
285a6570f20SBarry Smith    SNESMonitorRatio - Monitors progress of the SNES solvers by printing the ratio
2864b27c08aSLois Curfman McInnes    of residual norm at each iteration to the previous.
2873a7fca6bSBarry Smith 
2883a7fca6bSBarry Smith    Collective on SNES
2893a7fca6bSBarry Smith 
2903a7fca6bSBarry Smith    Input Parameters:
2913a7fca6bSBarry Smith +  snes - the SNES context
2923a7fca6bSBarry Smith .  its - iteration number
2933a7fca6bSBarry Smith .  fgnorm - 2-norm of residual (or gradient)
294eabae89aSBarry Smith -  dummy -  context of monitor
2953a7fca6bSBarry Smith 
2963a7fca6bSBarry Smith    Level: intermediate
2973a7fca6bSBarry Smith 
2983a7fca6bSBarry Smith .keywords: SNES, nonlinear, monitor, norm
2993a7fca6bSBarry Smith 
300a6570f20SBarry Smith .seealso: SNESMonitorSet(), SNESMonitorSolution()
3013a7fca6bSBarry Smith @*/
3027087cfbeSBarry Smith PetscErrorCode  SNESMonitorRatio(SNES snes,PetscInt its,PetscReal fgnorm,void *dummy)
3033a7fca6bSBarry Smith {
304dfbe8321SBarry Smith   PetscErrorCode          ierr;
30577431f27SBarry Smith   PetscInt                len;
30687828ca2SBarry Smith   PetscReal               *history;
307a6570f20SBarry Smith   SNESMonitorRatioContext *ctx = (SNESMonitorRatioContext*)dummy;
3083a7fca6bSBarry Smith 
3093a7fca6bSBarry Smith   PetscFunctionBegin;
3103a7fca6bSBarry Smith   ierr = SNESGetConvergenceHistory(snes,&history,PETSC_NULL,&len);CHKERRQ(ierr);
311649052a6SBarry Smith   ierr = PetscViewerASCIIAddTab(ctx->viewer,((PetscObject)snes)->tablevel);CHKERRQ(ierr);
312958c9bccSBarry Smith   if (!its || !history || its > len) {
313649052a6SBarry Smith     ierr = PetscViewerASCIIPrintf(ctx->viewer,"%3D SNES Function norm %14.12e \n",its,(double)fgnorm);CHKERRQ(ierr);
3143a7fca6bSBarry Smith   } else {
31587828ca2SBarry Smith     PetscReal ratio = fgnorm/history[its-1];
3168f1a2a5eSBarry Smith     ierr = PetscViewerASCIIPrintf(ctx->viewer,"%3D SNES Function norm %14.12e %14.12e \n",its,(double)fgnorm,(double)ratio);CHKERRQ(ierr);
3173a7fca6bSBarry Smith   }
318649052a6SBarry Smith   ierr = PetscViewerASCIISubtractTab(ctx->viewer,((PetscObject)snes)->tablevel);CHKERRQ(ierr);
3193a7fca6bSBarry Smith   PetscFunctionReturn(0);
3203a7fca6bSBarry Smith }
3213a7fca6bSBarry Smith 
3223a7fca6bSBarry Smith /*
3233a7fca6bSBarry Smith    If the we set the history monitor space then we must destroy it
3243a7fca6bSBarry Smith */
3253a7fca6bSBarry Smith #undef __FUNCT__
326a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorRatioDestroy"
327c2efdce3SBarry Smith PetscErrorCode SNESMonitorRatioDestroy(void **ct)
3283a7fca6bSBarry Smith {
329dfbe8321SBarry Smith   PetscErrorCode          ierr;
330c2efdce3SBarry Smith   SNESMonitorRatioContext *ctx = *(SNESMonitorRatioContext**)ct;
3313a7fca6bSBarry Smith 
3323a7fca6bSBarry Smith   PetscFunctionBegin;
33305b42c5fSBarry Smith   ierr = PetscFree(ctx->history);CHKERRQ(ierr);
334649052a6SBarry Smith   ierr = PetscViewerDestroy(&ctx->viewer);CHKERRQ(ierr);
335eabae89aSBarry Smith   ierr = PetscFree(ctx);CHKERRQ(ierr);
3363a7fca6bSBarry Smith   PetscFunctionReturn(0);
3373a7fca6bSBarry Smith }
3383a7fca6bSBarry Smith 
3393a7fca6bSBarry Smith #undef __FUNCT__
340a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorSetRatio"
3413a7fca6bSBarry Smith /*@C
342a6570f20SBarry Smith    SNESMonitorSetRatio - Sets SNES to use a monitor that prints the
3434b27c08aSLois Curfman McInnes    ratio of the function norm at each iteration.
3443a7fca6bSBarry Smith 
3453a7fca6bSBarry Smith    Collective on SNES
3463a7fca6bSBarry Smith 
3473a7fca6bSBarry Smith    Input Parameters:
348eabae89aSBarry Smith +   snes - the SNES context
349eabae89aSBarry Smith -   viewer - ASCII viewer to print output
3503a7fca6bSBarry Smith 
3513a7fca6bSBarry Smith    Level: intermediate
3523a7fca6bSBarry Smith 
3533a7fca6bSBarry Smith .keywords: SNES, nonlinear, monitor, norm
3543a7fca6bSBarry Smith 
355a6570f20SBarry Smith .seealso: SNESMonitorSet(), SNESMonitorSolution(), SNESMonitorDefault()
3563a7fca6bSBarry Smith @*/
357649052a6SBarry Smith PetscErrorCode  SNESMonitorSetRatio(SNES snes,PetscViewer viewer)
3583a7fca6bSBarry Smith {
359dfbe8321SBarry Smith   PetscErrorCode          ierr;
360a6570f20SBarry Smith   SNESMonitorRatioContext *ctx;
36187828ca2SBarry Smith   PetscReal               *history;
3623a7fca6bSBarry Smith 
3633a7fca6bSBarry Smith   PetscFunctionBegin;
364eabae89aSBarry Smith   if (!viewer) {
365649052a6SBarry Smith     ierr = PetscViewerASCIIOpen(((PetscObject)snes)->comm,"stdout",&viewer);CHKERRQ(ierr);
366eabae89aSBarry Smith     ierr = PetscObjectReference((PetscObject)viewer);CHKERRQ(ierr);
367eabae89aSBarry Smith   }
36838f2d2fdSLisandro Dalcin   ierr = PetscNewLog(snes,SNESMonitorRatioContext,&ctx);
3693a7fca6bSBarry Smith   ierr = SNESGetConvergenceHistory(snes,&history,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr);
3703a7fca6bSBarry Smith   if (!history) {
371eabae89aSBarry Smith     ierr = PetscMalloc(100*sizeof(PetscReal),&ctx->history);CHKERRQ(ierr);
372eabae89aSBarry Smith     ierr = SNESSetConvergenceHistory(snes,ctx->history,0,100,PETSC_TRUE);CHKERRQ(ierr);
3733a7fca6bSBarry Smith   }
374eabae89aSBarry Smith   ctx->viewer = viewer;
375a6570f20SBarry Smith   ierr = SNESMonitorSet(snes,SNESMonitorRatio,ctx,SNESMonitorRatioDestroy);CHKERRQ(ierr);
3763a7fca6bSBarry Smith   PetscFunctionReturn(0);
3773a7fca6bSBarry Smith }
3783a7fca6bSBarry Smith 
379e7e93795SLois Curfman McInnes /* ---------------------------------------------------------------- */
3804a2ae208SSatish Balay #undef __FUNCT__
381a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorDefaultShort"
382be1f7002SBarry Smith /*
383a6570f20SBarry Smith      Default (short) SNES Monitor, same as SNESMonitorDefault() except
384be1f7002SBarry Smith   it prints fewer digits of the residual as the residual gets smaller.
385be1f7002SBarry Smith   This is because the later digits are meaningless and are often
386be1f7002SBarry Smith   different on different machines; by using this routine different
387be1f7002SBarry Smith   machines will usually generate the same output.
388be1f7002SBarry Smith */
3897087cfbeSBarry Smith PetscErrorCode  SNESMonitorDefaultShort(SNES snes,PetscInt its,PetscReal fgnorm,void *dummy)
390e7e93795SLois Curfman McInnes {
391dfbe8321SBarry Smith   PetscErrorCode ierr;
392649052a6SBarry Smith   PetscViewer    viewer = dummy ? (PetscViewer) dummy : PETSC_VIEWER_STDOUT_(((PetscObject)snes)->comm);
393d132466eSBarry Smith 
3943a40ed3dSBarry Smith   PetscFunctionBegin;
395649052a6SBarry Smith   ierr = PetscViewerASCIIAddTab(viewer,((PetscObject)snes)->tablevel);CHKERRQ(ierr);
3968f240d10SBarry Smith   if (fgnorm > 1.e-9) {
397649052a6SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"%3D SNES Function norm %G \n",its,fgnorm);CHKERRQ(ierr);
3983a40ed3dSBarry Smith   } else if (fgnorm > 1.e-11){
399649052a6SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"%3D SNES Function norm %5.3e \n",its,fgnorm);CHKERRQ(ierr);
4003a40ed3dSBarry Smith   } else {
401649052a6SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"%3D SNES Function norm < 1.e-11\n",its);CHKERRQ(ierr);
402a34d58ebSBarry Smith   }
403649052a6SBarry Smith   ierr = PetscViewerASCIISubtractTab(viewer,((PetscObject)snes)->tablevel);CHKERRQ(ierr);
4043a40ed3dSBarry Smith   PetscFunctionReturn(0);
405e7e93795SLois Curfman McInnes }
406e7e93795SLois Curfman McInnes /* ---------------------------------------------------------------- */
4074a2ae208SSatish Balay #undef __FUNCT__
4083f149594SLisandro Dalcin #define __FUNCT__ "SNESDefaultConverged"
4094b828684SBarry Smith /*@C
4103f149594SLisandro Dalcin    SNESDefaultConverged - Convergence test of the solvers for
411f525115eSLois Curfman McInnes    systems of nonlinear equations (default).
412e7e93795SLois Curfman McInnes 
413c7afd0dbSLois Curfman McInnes    Collective on SNES
414c7afd0dbSLois Curfman McInnes 
415e7e93795SLois Curfman McInnes    Input Parameters:
416c7afd0dbSLois Curfman McInnes +  snes - the SNES context
41706ee9f85SBarry Smith .  it - the iteration (0 indicates before any Newton steps)
418e7e93795SLois Curfman McInnes .  xnorm - 2-norm of current iterate
419c60f73f4SPeter Brune .  snorm - 2-norm of current step
4207f3332b4SBarry Smith .  fnorm - 2-norm of function at current iterate
421c7afd0dbSLois Curfman McInnes -  dummy - unused context
422e7e93795SLois Curfman McInnes 
423184914b5SBarry Smith    Output Parameter:
424184914b5SBarry Smith .   reason  - one of
42570441072SBarry Smith $  SNES_CONVERGED_FNORM_ABS       - (fnorm < abstol),
426c60f73f4SPeter Brune $  SNES_CONVERGED_SNORM_RELATIVE  - (snorm < stol*xnorm),
427184914b5SBarry Smith $  SNES_CONVERGED_FNORM_RELATIVE  - (fnorm < rtol*fnorm0),
428184914b5SBarry Smith $  SNES_DIVERGED_FUNCTION_COUNT   - (nfct > maxf),
429184914b5SBarry Smith $  SNES_DIVERGED_FNORM_NAN        - (fnorm == NaN),
430184914b5SBarry Smith $  SNES_CONVERGED_ITERATING       - (otherwise),
431e7e93795SLois Curfman McInnes 
432e7e93795SLois Curfman McInnes    where
433c7afd0dbSLois Curfman McInnes +    maxf - maximum number of function evaluations,
434c7afd0dbSLois Curfman McInnes             set with SNESSetTolerances()
435c7afd0dbSLois Curfman McInnes .    nfct - number of function evaluations,
43670441072SBarry Smith .    abstol - absolute function norm tolerance,
437c7afd0dbSLois Curfman McInnes             set with SNESSetTolerances()
438c7afd0dbSLois Curfman McInnes -    rtol - relative function norm tolerance, set with SNESSetTolerances()
439fee21e36SBarry Smith 
44036851e7fSLois Curfman McInnes    Level: intermediate
44136851e7fSLois Curfman McInnes 
442e7e93795SLois Curfman McInnes .keywords: SNES, nonlinear, default, converged, convergence
443e7e93795SLois Curfman McInnes 
44471f87433Sdalcinl .seealso: SNESSetConvergenceTest()
445e7e93795SLois Curfman McInnes @*/
446c60f73f4SPeter Brune PetscErrorCode  SNESDefaultConverged(SNES snes,PetscInt it,PetscReal xnorm,PetscReal snorm,PetscReal fnorm,SNESConvergedReason *reason,void *dummy)
447e7e93795SLois Curfman McInnes {
44863ba0a88SBarry Smith   PetscErrorCode ierr;
44963ba0a88SBarry Smith 
4503a40ed3dSBarry Smith   PetscFunctionBegin;
4510700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
4523f149594SLisandro Dalcin   PetscValidPointer(reason,6);
4533f149594SLisandro Dalcin 
45406ee9f85SBarry Smith   *reason = SNES_CONVERGED_ITERATING;
45506ee9f85SBarry Smith 
45606ee9f85SBarry Smith   if (!it) {
45706ee9f85SBarry Smith     /* set parameter for default relative tolerance convergence test */
45806ee9f85SBarry Smith     snes->ttol = fnorm*snes->rtol;
45906ee9f85SBarry Smith   }
4608146f6ebSBarry Smith   if (PetscIsInfOrNanReal(fnorm)) {
461ae15b995SBarry Smith     ierr = PetscInfo(snes,"Failed to converged, function norm is NaN\n");CHKERRQ(ierr);
462184914b5SBarry Smith     *reason = SNES_DIVERGED_FNORM_NAN;
46370441072SBarry Smith   } else if (fnorm < snes->abstol) {
4648f1a2a5eSBarry Smith     ierr = PetscInfo2(snes,"Converged due to function norm %14.12e < %14.12e\n",(double)fnorm,(double)snes->abstol);CHKERRQ(ierr);
465184914b5SBarry Smith     *reason = SNES_CONVERGED_FNORM_ABS;
46643e71028SBarry Smith   } else if (snes->nfuncs >= snes->max_funcs) {
467ae15b995SBarry Smith     ierr = PetscInfo2(snes,"Exceeded maximum number of function evaluations: %D > %D\n",snes->nfuncs,snes->max_funcs);CHKERRQ(ierr);
468184914b5SBarry Smith     *reason = SNES_DIVERGED_FUNCTION_COUNT;
46906ee9f85SBarry Smith   }
47006ee9f85SBarry Smith 
47106ee9f85SBarry Smith   if (it && !*reason) {
47206ee9f85SBarry Smith     if (fnorm <= snes->ttol) {
4738f1a2a5eSBarry Smith       ierr = PetscInfo2(snes,"Converged due to function norm %14.12e < %14.12e (relative tolerance)\n",(double)fnorm,(double)snes->ttol);CHKERRQ(ierr);
47406ee9f85SBarry Smith       *reason = SNES_CONVERGED_FNORM_RELATIVE;
475c60f73f4SPeter Brune     } else if (snorm < snes->stol*xnorm) {
476c60f73f4SPeter 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);
477c60f73f4SPeter Brune       *reason = SNES_CONVERGED_SNORM_RELATIVE;
47806ee9f85SBarry Smith     }
479e7e93795SLois Curfman McInnes   }
4803a40ed3dSBarry Smith   PetscFunctionReturn(0);
481e7e93795SLois Curfman McInnes }
4823f149594SLisandro Dalcin 
4833f149594SLisandro Dalcin #undef __FUNCT__
4843f149594SLisandro Dalcin #define __FUNCT__ "SNESSkipConverged"
4853f149594SLisandro Dalcin /*@C
4863f149594SLisandro Dalcin    SNESSkipConverged - Convergence test for SNES that NEVER returns as
4873f149594SLisandro Dalcin    converged, UNLESS the maximum number of iteration have been reached.
4883f149594SLisandro Dalcin 
4893f9fe445SBarry Smith    Logically Collective on SNES
4903f149594SLisandro Dalcin 
4913f149594SLisandro Dalcin    Input Parameters:
4923f149594SLisandro Dalcin +  snes - the SNES context
4933f149594SLisandro Dalcin .  it - the iteration (0 indicates before any Newton steps)
4943f149594SLisandro Dalcin .  xnorm - 2-norm of current iterate
495c60f73f4SPeter Brune .  snorm - 2-norm of current step
4963f149594SLisandro Dalcin .  fnorm - 2-norm of function at current iterate
4973f149594SLisandro Dalcin -  dummy - unused context
4983f149594SLisandro Dalcin 
4993f149594SLisandro Dalcin    Output Parameter:
50085385478SLisandro Dalcin .   reason  - SNES_CONVERGED_ITERATING, SNES_CONVERGED_ITS, or SNES_DIVERGED_FNORM_NAN
5013f149594SLisandro Dalcin 
5023f149594SLisandro Dalcin    Notes:
5033f149594SLisandro Dalcin    Convergence is then declared after a fixed number of iterations have been used.
5043f149594SLisandro Dalcin 
5053f149594SLisandro Dalcin    Level: advanced
5063f149594SLisandro Dalcin 
5073f149594SLisandro Dalcin .keywords: SNES, nonlinear, skip, converged, convergence
5083f149594SLisandro Dalcin 
5093f149594SLisandro Dalcin .seealso: SNESSetConvergenceTest()
5103f149594SLisandro Dalcin @*/
511c60f73f4SPeter Brune PetscErrorCode  SNESSkipConverged(SNES snes,PetscInt it,PetscReal xnorm,PetscReal snorm,PetscReal fnorm,SNESConvergedReason *reason,void *dummy)
5123f149594SLisandro Dalcin {
5133f149594SLisandro Dalcin   PetscErrorCode ierr;
5143f149594SLisandro Dalcin 
5153f149594SLisandro Dalcin   PetscFunctionBegin;
5160700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
5173f149594SLisandro Dalcin   PetscValidPointer(reason,6);
5183f149594SLisandro Dalcin 
5193f149594SLisandro Dalcin   *reason = SNES_CONVERGED_ITERATING;
5203f149594SLisandro Dalcin 
5213f149594SLisandro Dalcin   if (fnorm != fnorm) {
5223f149594SLisandro Dalcin     ierr = PetscInfo(snes,"Failed to converged, function norm is NaN\n");CHKERRQ(ierr);
5233f149594SLisandro Dalcin     *reason = SNES_DIVERGED_FNORM_NAN;
5243f149594SLisandro Dalcin   } else if(it == snes->max_its) {
5253f149594SLisandro Dalcin     *reason = SNES_CONVERGED_ITS;
5263f149594SLisandro Dalcin   }
5273f149594SLisandro Dalcin   PetscFunctionReturn(0);
5283f149594SLisandro Dalcin }
5293f149594SLisandro Dalcin 
53058c9b817SLisandro Dalcin #undef __FUNCT__
53158c9b817SLisandro Dalcin #define __FUNCT__ "SNESDefaultGetWork"
53298acb6afSMatthew G Knepley /*@
53358c9b817SLisandro Dalcin   SNESDefaultGetWork - Gets a number of work vectors.
53458c9b817SLisandro Dalcin 
53558c9b817SLisandro Dalcin   Input Parameters:
53658c9b817SLisandro Dalcin . snes  - the SNES context
53758c9b817SLisandro Dalcin . nw - number of work vectors to allocate
53858c9b817SLisandro Dalcin 
53958c9b817SLisandro Dalcin    Level: developer
54058c9b817SLisandro Dalcin 
54158c9b817SLisandro Dalcin   Notes:
54258c9b817SLisandro Dalcin   Call this only if no work vectors have been allocated
54398acb6afSMatthew G Knepley @*/
54458c9b817SLisandro Dalcin PetscErrorCode SNESDefaultGetWork(SNES snes,PetscInt nw)
54558c9b817SLisandro Dalcin {
54658c9b817SLisandro Dalcin   PetscErrorCode ierr;
54758c9b817SLisandro Dalcin 
54858c9b817SLisandro Dalcin   PetscFunctionBegin;
54958c9b817SLisandro Dalcin   if (snes->work) {ierr = VecDestroyVecs(snes->nwork,&snes->work);CHKERRQ(ierr);}
55058c9b817SLisandro Dalcin   snes->nwork = nw;
55158c9b817SLisandro Dalcin   ierr = VecDuplicateVecs(snes->vec_sol,snes->nwork,&snes->work);CHKERRQ(ierr);
55258c9b817SLisandro Dalcin   ierr = PetscLogObjectParents(snes,nw,snes->work);CHKERRQ(ierr);
55358c9b817SLisandro Dalcin   PetscFunctionReturn(0);
55458c9b817SLisandro Dalcin }
555