xref: /petsc/src/snes/interface/snesut.c (revision 7044107279799bb7fd2e4de09560a77cd45ddebe)
1e7e93795SLois Curfman McInnes 
2e090d566SSatish Balay #include "src/snes/snesimpl.h"       /*I   "petscsnes.h"   I*/
3e7e93795SLois Curfman McInnes 
44a2ae208SSatish Balay #undef __FUNCT__
54a2ae208SSatish Balay #define __FUNCT__ "SNESVecViewMonitor"
63f1db9ecSBarry Smith /*@C
736851e7fSLois Curfman McInnes    SNESVecViewMonitor - Monitors progress of the SNES solvers by calling
836851e7fSLois Curfman McInnes    VecView() for the approximate solution at each iteration.
93f1db9ecSBarry Smith 
103f1db9ecSBarry Smith    Collective on SNES
113f1db9ecSBarry Smith 
123f1db9ecSBarry Smith    Input Parameters:
133f1db9ecSBarry Smith +  snes - the SNES context
143f1db9ecSBarry Smith .  its - iteration number
154b27c08aSLois Curfman McInnes .  fgnorm - 2-norm of residual
163f1db9ecSBarry Smith -  dummy - either a viewer or PETSC_NULL
173f1db9ecSBarry Smith 
1836851e7fSLois Curfman McInnes    Level: intermediate
193f1db9ecSBarry Smith 
2036851e7fSLois Curfman McInnes .keywords: SNES, nonlinear, vector, monitor, view
213f1db9ecSBarry Smith 
2236851e7fSLois Curfman McInnes .seealso: SNESSetMonitor(), SNESDefaultMonitor(), VecView()
233f1db9ecSBarry Smith @*/
2477431f27SBarry Smith PetscErrorCode SNESVecViewMonitor(SNES snes,PetscInt its,PetscReal fgnorm,void *dummy)
253f1db9ecSBarry Smith {
26dfbe8321SBarry Smith   PetscErrorCode ierr;
273f1db9ecSBarry Smith   Vec            x;
28b0a32e0cSBarry Smith   PetscViewer    viewer = (PetscViewer) dummy;
293f1db9ecSBarry Smith 
303f1db9ecSBarry Smith   PetscFunctionBegin;
313f1db9ecSBarry Smith   ierr = SNESGetSolution(snes,&x);CHKERRQ(ierr);
323f1db9ecSBarry Smith   if (!viewer) {
333f1db9ecSBarry Smith     MPI_Comm comm;
343f1db9ecSBarry Smith     ierr   = PetscObjectGetComm((PetscObject)snes,&comm);CHKERRQ(ierr);
35b0a32e0cSBarry Smith     viewer = PETSC_VIEWER_DRAW_(comm);
363f1db9ecSBarry Smith   }
373f1db9ecSBarry Smith   ierr = VecView(x,viewer);CHKERRQ(ierr);
383f1db9ecSBarry Smith 
393f1db9ecSBarry Smith   PetscFunctionReturn(0);
403f1db9ecSBarry Smith }
413f1db9ecSBarry Smith 
424a2ae208SSatish Balay #undef __FUNCT__
435ed2d596SBarry Smith #define __FUNCT__ "SNESVecViewResidualMonitor"
445ed2d596SBarry Smith /*@C
455ed2d596SBarry Smith    SNESVecViewResidualMonitor - Monitors progress of the SNES solvers by calling
465ed2d596SBarry Smith    VecView() for the residual at each iteration.
475ed2d596SBarry Smith 
485ed2d596SBarry Smith    Collective on SNES
495ed2d596SBarry Smith 
505ed2d596SBarry Smith    Input Parameters:
515ed2d596SBarry Smith +  snes - the SNES context
525ed2d596SBarry Smith .  its - iteration number
534b27c08aSLois Curfman McInnes .  fgnorm - 2-norm of residual
545ed2d596SBarry Smith -  dummy - either a viewer or PETSC_NULL
555ed2d596SBarry Smith 
565ed2d596SBarry Smith    Level: intermediate
575ed2d596SBarry Smith 
585ed2d596SBarry Smith .keywords: SNES, nonlinear, vector, monitor, view
595ed2d596SBarry Smith 
605ed2d596SBarry Smith .seealso: SNESSetMonitor(), SNESDefaultMonitor(), VecView()
615ed2d596SBarry Smith @*/
6277431f27SBarry Smith PetscErrorCode SNESVecViewResidualMonitor(SNES snes,PetscInt its,PetscReal fgnorm,void *dummy)
635ed2d596SBarry Smith {
64dfbe8321SBarry Smith   PetscErrorCode ierr;
655ed2d596SBarry Smith   Vec            x;
665ed2d596SBarry Smith   PetscViewer    viewer = (PetscViewer) dummy;
675ed2d596SBarry Smith 
685ed2d596SBarry Smith   PetscFunctionBegin;
695ed2d596SBarry Smith   ierr = SNESGetFunction(snes,&x,0,0);CHKERRQ(ierr);
705ed2d596SBarry Smith   if (!viewer) {
715ed2d596SBarry Smith     MPI_Comm comm;
725ed2d596SBarry Smith     ierr   = PetscObjectGetComm((PetscObject)snes,&comm);CHKERRQ(ierr);
735ed2d596SBarry Smith     viewer = PETSC_VIEWER_DRAW_(comm);
745ed2d596SBarry Smith   }
755ed2d596SBarry Smith   ierr = VecView(x,viewer);CHKERRQ(ierr);
765ed2d596SBarry Smith 
775ed2d596SBarry Smith   PetscFunctionReturn(0);
785ed2d596SBarry Smith }
795ed2d596SBarry Smith 
805ed2d596SBarry Smith #undef __FUNCT__
814a2ae208SSatish Balay #define __FUNCT__ "SNESVecViewUpdateMonitor"
82d132466eSBarry Smith /*@C
837c922b88SBarry Smith    SNESVecViewUpdateMonitor - 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
92d132466eSBarry Smith -  dummy - either a viewer or PETSC_NULL
93d132466eSBarry Smith 
94d132466eSBarry Smith    Level: intermediate
95d132466eSBarry Smith 
96d132466eSBarry Smith .keywords: SNES, nonlinear, vector, monitor, view
97d132466eSBarry Smith 
98d132466eSBarry Smith .seealso: SNESSetMonitor(), SNESDefaultMonitor(), VecView()
99d132466eSBarry Smith @*/
10077431f27SBarry Smith PetscErrorCode SNESVecViewUpdateMonitor(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 
115d132466eSBarry Smith   PetscFunctionReturn(0);
116d132466eSBarry Smith }
117d132466eSBarry Smith 
1184a2ae208SSatish Balay #undef __FUNCT__
1194a2ae208SSatish Balay #define __FUNCT__ "SNESDefaultMonitor"
1204b828684SBarry Smith /*@C
1214b27c08aSLois Curfman McInnes    SNESDefaultMonitor - Monitors progress of the SNES solvers (default).
122e7e93795SLois Curfman McInnes 
123c7afd0dbSLois Curfman McInnes    Collective on SNES
124c7afd0dbSLois Curfman McInnes 
125e7e93795SLois Curfman McInnes    Input Parameters:
126c7afd0dbSLois Curfman McInnes +  snes - the SNES context
127e7e93795SLois Curfman McInnes .  its - iteration number
1284b27c08aSLois Curfman McInnes .  fgnorm - 2-norm of residual
129c7afd0dbSLois Curfman McInnes -  dummy - unused context
130fee21e36SBarry Smith 
131e7e93795SLois Curfman McInnes    Notes:
1324b27c08aSLois Curfman McInnes    This routine prints the residual norm at each iteration.
133e7e93795SLois Curfman McInnes 
13436851e7fSLois Curfman McInnes    Level: intermediate
13536851e7fSLois Curfman McInnes 
136e7e93795SLois Curfman McInnes .keywords: SNES, nonlinear, default, monitor, norm
137e7e93795SLois Curfman McInnes 
13836851e7fSLois Curfman McInnes .seealso: SNESSetMonitor(), SNESVecViewMonitor()
139e7e93795SLois Curfman McInnes @*/
14077431f27SBarry Smith PetscErrorCode SNESDefaultMonitor(SNES snes,PetscInt its,PetscReal fgnorm,void *dummy)
141e7e93795SLois Curfman McInnes {
142dfbe8321SBarry Smith   PetscErrorCode ierr;
143b0a32e0cSBarry Smith   PetscViewer    viewer = (PetscViewer) dummy;
144d132466eSBarry Smith 
1453a40ed3dSBarry Smith   PetscFunctionBegin;
146b0a32e0cSBarry Smith   if (!viewer) viewer = PETSC_VIEWER_STDOUT_(snes->comm);
147a0e26f09SSatish Balay   ierr = PetscViewerASCIIPrintf(viewer,"%3d SNES Function norm %14.12e \n",its,fgnorm);CHKERRQ(ierr);
1483a40ed3dSBarry Smith   PetscFunctionReturn(0);
149e7e93795SLois Curfman McInnes }
1503f1db9ecSBarry Smith 
1513a7fca6bSBarry Smith #undef __FUNCT__
1523a7fca6bSBarry Smith #define __FUNCT__ "SNESRatioMonitor"
1533a7fca6bSBarry Smith /*@C
1544b27c08aSLois Curfman McInnes    SNESRatioMonitor - Monitors progress of the SNES solvers by printing the ratio
1554b27c08aSLois Curfman McInnes    of residual norm at each iteration to the previous.
1563a7fca6bSBarry Smith 
1573a7fca6bSBarry Smith    Collective on SNES
1583a7fca6bSBarry Smith 
1593a7fca6bSBarry Smith    Input Parameters:
1603a7fca6bSBarry Smith +  snes - the SNES context
1613a7fca6bSBarry Smith .  its - iteration number
1623a7fca6bSBarry Smith .  fgnorm - 2-norm of residual (or gradient)
1633a7fca6bSBarry Smith -  dummy - unused context
1643a7fca6bSBarry Smith 
1653a7fca6bSBarry Smith    Level: intermediate
1663a7fca6bSBarry Smith 
1673a7fca6bSBarry Smith .keywords: SNES, nonlinear, monitor, norm
1683a7fca6bSBarry Smith 
1693a7fca6bSBarry Smith .seealso: SNESSetMonitor(), SNESVecViewMonitor()
1703a7fca6bSBarry Smith @*/
17177431f27SBarry Smith PetscErrorCode SNESRatioMonitor(SNES snes,PetscInt its,PetscReal fgnorm,void *dummy)
1723a7fca6bSBarry Smith {
173dfbe8321SBarry Smith   PetscErrorCode ierr;
17477431f27SBarry Smith   PetscInt       len;
17587828ca2SBarry Smith   PetscReal      *history;
1763a7fca6bSBarry Smith   PetscViewer    viewer;
1773a7fca6bSBarry Smith 
1783a7fca6bSBarry Smith   PetscFunctionBegin;
1793a7fca6bSBarry Smith   viewer = PETSC_VIEWER_STDOUT_(snes->comm);
1803a7fca6bSBarry Smith 
1813a7fca6bSBarry Smith   ierr = SNESGetConvergenceHistory(snes,&history,PETSC_NULL,&len);CHKERRQ(ierr);
182958c9bccSBarry Smith   if (!its || !history || its > len) {
1833a7fca6bSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"%3d SNES Function norm %14.12e \n",its,fgnorm);CHKERRQ(ierr);
1843a7fca6bSBarry Smith   } else {
18587828ca2SBarry Smith     PetscReal ratio = fgnorm/history[its-1];
1863a7fca6bSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"%3d SNES Function norm %14.12e %g \n",its,fgnorm,ratio);CHKERRQ(ierr);
1873a7fca6bSBarry Smith   }
1883a7fca6bSBarry Smith   PetscFunctionReturn(0);
1893a7fca6bSBarry Smith }
1903a7fca6bSBarry Smith 
1913a7fca6bSBarry Smith /*
1923a7fca6bSBarry Smith    If the we set the history monitor space then we must destroy it
1933a7fca6bSBarry Smith */
1943a7fca6bSBarry Smith #undef __FUNCT__
1953a7fca6bSBarry Smith #define __FUNCT__ "SNESRatioMonitorDestroy"
196dfbe8321SBarry Smith PetscErrorCode SNESRatioMonitorDestroy(void *history)
1973a7fca6bSBarry Smith {
198dfbe8321SBarry Smith   PetscErrorCode ierr;
1993a7fca6bSBarry Smith 
2003a7fca6bSBarry Smith   PetscFunctionBegin;
2013a7fca6bSBarry Smith   ierr = PetscFree(history);CHKERRQ(ierr);
2023a7fca6bSBarry Smith   PetscFunctionReturn(0);
2033a7fca6bSBarry Smith }
2043a7fca6bSBarry Smith 
2053a7fca6bSBarry Smith #undef __FUNCT__
2063a7fca6bSBarry Smith #define __FUNCT__ "SNESSetRatioMonitor"
2073a7fca6bSBarry Smith /*@C
2083a7fca6bSBarry Smith    SNESSetRatioMonitor - Sets SNES to use a monitor that prints the
2094b27c08aSLois Curfman McInnes    ratio of the function norm at each iteration.
2103a7fca6bSBarry Smith 
2113a7fca6bSBarry Smith    Collective on SNES
2123a7fca6bSBarry Smith 
2133a7fca6bSBarry Smith    Input Parameters:
2143a7fca6bSBarry Smith .   snes - the SNES context
2153a7fca6bSBarry Smith 
2163a7fca6bSBarry Smith    Level: intermediate
2173a7fca6bSBarry Smith 
2183a7fca6bSBarry Smith .keywords: SNES, nonlinear, monitor, norm
2193a7fca6bSBarry Smith 
2203a7fca6bSBarry Smith .seealso: SNESSetMonitor(), SNESVecViewMonitor(), SNESDefaultMonitor()
2213a7fca6bSBarry Smith @*/
222dfbe8321SBarry Smith PetscErrorCode SNESSetRatioMonitor(SNES snes)
2233a7fca6bSBarry Smith {
224dfbe8321SBarry Smith   PetscErrorCode ierr;
22587828ca2SBarry Smith   PetscReal      *history;
2263a7fca6bSBarry Smith 
2273a7fca6bSBarry Smith   PetscFunctionBegin;
2283a7fca6bSBarry Smith 
2293a7fca6bSBarry Smith   ierr = SNESGetConvergenceHistory(snes,&history,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr);
2303a7fca6bSBarry Smith   if (!history) {
2313a7fca6bSBarry Smith     ierr = PetscMalloc(100*sizeof(double),&history);CHKERRQ(ierr);
2323a7fca6bSBarry Smith     ierr = SNESSetConvergenceHistory(snes,history,0,100,PETSC_TRUE);CHKERRQ(ierr);
2333a7fca6bSBarry Smith     ierr = SNESSetMonitor(snes,SNESRatioMonitor,history,SNESRatioMonitorDestroy);CHKERRQ(ierr);
2343a7fca6bSBarry Smith   } else {
2353a7fca6bSBarry Smith     ierr = SNESSetMonitor(snes,SNESRatioMonitor,0,0);CHKERRQ(ierr);
2363a7fca6bSBarry Smith   }
2373a7fca6bSBarry Smith   PetscFunctionReturn(0);
2383a7fca6bSBarry Smith }
2393a7fca6bSBarry Smith 
240e7e93795SLois Curfman McInnes /* ---------------------------------------------------------------- */
2414a2ae208SSatish Balay #undef __FUNCT__
2424a2ae208SSatish Balay #define __FUNCT__ "SNESDefaultSMonitor"
243be1f7002SBarry Smith /*
244be1f7002SBarry Smith      Default (short) SNES Monitor, same as SNESDefaultMonitor() except
245be1f7002SBarry Smith   it prints fewer digits of the residual as the residual gets smaller.
246be1f7002SBarry Smith   This is because the later digits are meaningless and are often
247be1f7002SBarry Smith   different on different machines; by using this routine different
248be1f7002SBarry Smith   machines will usually generate the same output.
249be1f7002SBarry Smith */
25077431f27SBarry Smith PetscErrorCode SNESDefaultSMonitor(SNES snes,PetscInt its,PetscReal fgnorm,void *dummy)
251e7e93795SLois Curfman McInnes {
252dfbe8321SBarry Smith   PetscErrorCode ierr;
253d132466eSBarry Smith 
2543a40ed3dSBarry Smith   PetscFunctionBegin;
2558f240d10SBarry Smith   if (fgnorm > 1.e-9) {
25677431f27SBarry Smith     ierr = PetscPrintf(snes->comm,"%3D SNES Function norm %g \n",its,fgnorm);CHKERRQ(ierr);
2573a40ed3dSBarry Smith   } else if (fgnorm > 1.e-11){
25877431f27SBarry Smith     ierr = PetscPrintf(snes->comm,"%3D SNES Function norm %5.3e \n",its,fgnorm);CHKERRQ(ierr);
2593a40ed3dSBarry Smith   } else {
26077431f27SBarry Smith     ierr = PetscPrintf(snes->comm,"%3D SNES Function norm < 1.e-11\n",its);CHKERRQ(ierr);
261e7e93795SLois Curfman McInnes   }
2623a40ed3dSBarry Smith   PetscFunctionReturn(0);
263e7e93795SLois Curfman McInnes }
264e7e93795SLois Curfman McInnes /* ---------------------------------------------------------------- */
2654a2ae208SSatish Balay #undef __FUNCT__
2664b27c08aSLois Curfman McInnes #define __FUNCT__ "SNESConverged_LS"
2674b828684SBarry Smith /*@C
2684b27c08aSLois Curfman McInnes    SNESConverged_LS - Monitors the convergence of the solvers for
269f525115eSLois Curfman McInnes    systems of nonlinear equations (default).
270e7e93795SLois Curfman McInnes 
271c7afd0dbSLois Curfman McInnes    Collective on SNES
272c7afd0dbSLois Curfman McInnes 
273e7e93795SLois Curfman McInnes    Input Parameters:
274c7afd0dbSLois Curfman McInnes +  snes - the SNES context
275e7e93795SLois Curfman McInnes .  xnorm - 2-norm of current iterate
276e7e93795SLois Curfman McInnes .  pnorm - 2-norm of current step
277e7e93795SLois Curfman McInnes .  fnorm - 2-norm of function
278c7afd0dbSLois Curfman McInnes -  dummy - unused context
279e7e93795SLois Curfman McInnes 
280184914b5SBarry Smith    Output Parameter:
281184914b5SBarry Smith .   reason  - one of
282*70441072SBarry Smith $  SNES_CONVERGED_FNORM_ABS       - (fnorm < abstol),
2833304466cSBarry Smith $  SNES_CONVERGED_PNORM_RELATIVE  - (pnorm < xtol*xnorm),
284184914b5SBarry Smith $  SNES_CONVERGED_FNORM_RELATIVE  - (fnorm < rtol*fnorm0),
285184914b5SBarry Smith $  SNES_DIVERGED_FUNCTION_COUNT   - (nfct > maxf),
286184914b5SBarry Smith $  SNES_DIVERGED_FNORM_NAN        - (fnorm == NaN),
287184914b5SBarry Smith $  SNES_CONVERGED_ITERATING       - (otherwise),
288e7e93795SLois Curfman McInnes 
289e7e93795SLois Curfman McInnes    where
290c7afd0dbSLois Curfman McInnes +    maxf - maximum number of function evaluations,
291c7afd0dbSLois Curfman McInnes             set with SNESSetTolerances()
292c7afd0dbSLois Curfman McInnes .    nfct - number of function evaluations,
293*70441072SBarry Smith .    abstol - absolute function norm tolerance,
294c7afd0dbSLois Curfman McInnes             set with SNESSetTolerances()
295c7afd0dbSLois Curfman McInnes -    rtol - relative function norm tolerance, set with SNESSetTolerances()
296fee21e36SBarry Smith 
29736851e7fSLois Curfman McInnes    Level: intermediate
29836851e7fSLois Curfman McInnes 
299e7e93795SLois Curfman McInnes .keywords: SNES, nonlinear, default, converged, convergence
300e7e93795SLois Curfman McInnes 
301e7e93795SLois Curfman McInnes .seealso: SNESSetConvergenceTest(), SNESEisenstatWalkerConverged()
302e7e93795SLois Curfman McInnes @*/
303dfbe8321SBarry Smith PetscErrorCode SNESConverged_LS(SNES snes,PetscReal xnorm,PetscReal pnorm,PetscReal fnorm,SNESConvergedReason *reason,void *dummy)
304e7e93795SLois Curfman McInnes {
3053a40ed3dSBarry Smith   PetscFunctionBegin;
306d252947aSBarry Smith   if (fnorm != fnorm) {
3074b27c08aSLois Curfman McInnes     PetscLogInfo(snes,"SNESConverged_LS:Failed to converged, function norm is NaN\n");
308184914b5SBarry Smith     *reason = SNES_DIVERGED_FNORM_NAN;
309184914b5SBarry Smith   } else if (fnorm <= snes->ttol) {
3104b27c08aSLois Curfman McInnes     PetscLogInfo(snes,"SNESConverged_LS:Converged due to function norm %g < %g (relative tolerance)\n",fnorm,snes->ttol);
311184914b5SBarry Smith     *reason = SNES_CONVERGED_FNORM_RELATIVE;
312*70441072SBarry Smith   } else if (fnorm < snes->abstol) {
313*70441072SBarry Smith     PetscLogInfo(snes,"SNESConverged_LS:Converged due to function norm %g < %g\n",fnorm,snes->abstol);
314184914b5SBarry Smith     *reason = SNES_CONVERGED_FNORM_ABS;
3153304466cSBarry Smith   } else if (pnorm < snes->xtol*xnorm) {
3164b27c08aSLois Curfman McInnes     PetscLogInfo(snes,"SNESConverged_LS:Converged due to small update length: %g < %g * %g\n",pnorm,snes->xtol,xnorm);
317184914b5SBarry Smith     *reason = SNES_CONVERGED_PNORM_RELATIVE;
318184914b5SBarry Smith   } else if (snes->nfuncs > snes->max_funcs) {
31977431f27SBarry Smith     PetscLogInfo(snes,"SNESConverged_LS:Exceeded maximum number of function evaluations: %D > %D\n",snes->nfuncs,snes->max_funcs);
320184914b5SBarry Smith     *reason = SNES_DIVERGED_FUNCTION_COUNT ;
321184914b5SBarry Smith   } else {
322184914b5SBarry Smith     *reason = SNES_CONVERGED_ITERATING;
323e7e93795SLois Curfman McInnes   }
3243a40ed3dSBarry Smith   PetscFunctionReturn(0);
325e7e93795SLois Curfman McInnes }
326e7e93795SLois Curfman McInnes /* ------------------------------------------------------------ */
3274a2ae208SSatish Balay #undef __FUNCT__
3284a2ae208SSatish Balay #define __FUNCT__ "SNES_KSP_SetConvergenceTestEW"
329e7e93795SLois Curfman McInnes /*@
330f525115eSLois Curfman McInnes    SNES_KSP_SetConvergenceTestEW - Sets alternative convergence test
331e7e93795SLois Curfman McInnes    for the linear solvers within an inexact Newton method.
332e7e93795SLois Curfman McInnes 
333c7afd0dbSLois Curfman McInnes    Collective on SNES
334c7afd0dbSLois Curfman McInnes 
335e7e93795SLois Curfman McInnes    Input Parameter:
336e7e93795SLois Curfman McInnes .  snes - SNES context
337e7e93795SLois Curfman McInnes 
338e7e93795SLois Curfman McInnes    Notes:
339e7e93795SLois Curfman McInnes    Currently, the default is to use a constant relative tolerance for
340e7e93795SLois Curfman McInnes    the inner linear solvers.  Alternatively, one can use the
341e7e93795SLois Curfman McInnes    Eisenstat-Walker method, where the relative convergence tolerance
342e7e93795SLois Curfman McInnes    is reset at each Newton iteration according progress of the nonlinear
343e7e93795SLois Curfman McInnes    solver.
344e7e93795SLois Curfman McInnes 
34536851e7fSLois Curfman McInnes    Level: advanced
34636851e7fSLois Curfman McInnes 
347e7e93795SLois Curfman McInnes    Reference:
348e7e93795SLois Curfman McInnes    S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an
349e30ad881SLois Curfman McInnes    inexact Newton method", SISC 17 (1), pp.16-32, 1996.
350e7e93795SLois Curfman McInnes 
351e7e93795SLois Curfman McInnes .keywords: SNES, KSP, Eisenstat, Walker, convergence, test, inexact, Newton
352e7e93795SLois Curfman McInnes @*/
353dfbe8321SBarry Smith PetscErrorCode SNES_KSP_SetConvergenceTestEW(SNES snes)
354e7e93795SLois Curfman McInnes {
3553a40ed3dSBarry Smith   PetscFunctionBegin;
356186905e3SBarry Smith   snes->ksp_ewconv = PETSC_TRUE;
3573a40ed3dSBarry Smith   PetscFunctionReturn(0);
358e7e93795SLois Curfman McInnes }
359e7e93795SLois Curfman McInnes 
3604a2ae208SSatish Balay #undef __FUNCT__
3614a2ae208SSatish Balay #define __FUNCT__ "SNES_KSP_SetParametersEW"
362e7e93795SLois Curfman McInnes /*@
363e7e93795SLois Curfman McInnes    SNES_KSP_SetParametersEW - Sets parameters for Eisenstat-Walker
364e7e93795SLois Curfman McInnes    convergence criteria for the linear solvers within an inexact
365e7e93795SLois Curfman McInnes    Newton method.
366e7e93795SLois Curfman McInnes 
367c7afd0dbSLois Curfman McInnes    Collective on SNES
368c7afd0dbSLois Curfman McInnes 
369e7e93795SLois Curfman McInnes    Input Parameters:
370c7afd0dbSLois Curfman McInnes +    snes - SNES context
371e7e93795SLois Curfman McInnes .    version - version 1 or 2 (default is 2)
372c7afd0dbSLois Curfman McInnes .    rtol_0 - initial relative tolerance (0 <= rtol_0 < 1)
373c7afd0dbSLois Curfman McInnes .    rtol_max - maximum relative tolerance (0 <= rtol_max < 1)
374c7afd0dbSLois Curfman McInnes .    alpha - power for version 2 rtol computation (1 < alpha <= 2)
375e7e93795SLois Curfman McInnes .    alpha2 - power for safeguard
376e7e93795SLois Curfman McInnes .    gamma2 - multiplicative factor for version 2 rtol computation
377c7afd0dbSLois Curfman McInnes               (0 <= gamma2 <= 1)
378c7afd0dbSLois Curfman McInnes -    threshold - threshold for imposing safeguard (0 < threshold < 1)
379fee21e36SBarry Smith 
380e7e93795SLois Curfman McInnes    Note:
381e7e93795SLois Curfman McInnes    Use PETSC_DEFAULT to retain the default for any of the parameters.
382e7e93795SLois Curfman McInnes 
38336851e7fSLois Curfman McInnes    Level: advanced
38436851e7fSLois Curfman McInnes 
385e7e93795SLois Curfman McInnes    Reference:
386e7e93795SLois Curfman McInnes    S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an
387e7e93795SLois Curfman McInnes    inexact Newton method", Utah State University Math. Stat. Dept. Res.
388e7e93795SLois Curfman McInnes    Report 6/94/75, June, 1994, to appear in SIAM J. Sci. Comput.
389e7e93795SLois Curfman McInnes 
390e7e93795SLois Curfman McInnes .keywords: SNES, KSP, Eisenstat, Walker, set, parameters
391e7e93795SLois Curfman McInnes 
392e7e93795SLois Curfman McInnes .seealso: SNES_KSP_SetConvergenceTestEW()
393e7e93795SLois Curfman McInnes @*/
39477431f27SBarry Smith PetscErrorCode SNES_KSP_SetParametersEW(SNES snes,PetscInt version,PetscReal rtol_0,PetscReal rtol_max,PetscReal gamma2,PetscReal alpha,
395329f5518SBarry Smith                                         PetscReal alpha2,PetscReal threshold)
396e7e93795SLois Curfman McInnes {
397e7e93795SLois Curfman McInnes   SNES_KSP_EW_ConvCtx *kctx = (SNES_KSP_EW_ConvCtx*)snes->kspconvctx;
3983a40ed3dSBarry Smith 
3993a40ed3dSBarry Smith   PetscFunctionBegin;
40029bbc08cSBarry Smith   if (!kctx) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context existing");
401e7e93795SLois Curfman McInnes   if (version != PETSC_DEFAULT)   kctx->version   = version;
402e7e93795SLois Curfman McInnes   if (rtol_0 != PETSC_DEFAULT)    kctx->rtol_0    = rtol_0;
403e7e93795SLois Curfman McInnes   if (rtol_max != PETSC_DEFAULT)  kctx->rtol_max  = rtol_max;
404e7e93795SLois Curfman McInnes   if (gamma2 != PETSC_DEFAULT)    kctx->gamma     = gamma2;
405e7e93795SLois Curfman McInnes   if (alpha != PETSC_DEFAULT)     kctx->alpha     = alpha;
406e7e93795SLois Curfman McInnes   if (alpha2 != PETSC_DEFAULT)    kctx->alpha2    = alpha2;
407e7e93795SLois Curfman McInnes   if (threshold != PETSC_DEFAULT) kctx->threshold = threshold;
408a8c6a408SBarry Smith   if (kctx->rtol_0 < 0.0 || kctx->rtol_0 >= 1.0) {
40929bbc08cSBarry Smith     SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"0.0 <= rtol_0 < 1.0: %g",kctx->rtol_0);
410a8c6a408SBarry Smith   }
411a8c6a408SBarry Smith   if (kctx->rtol_max < 0.0 || kctx->rtol_max >= 1.0) {
412091e6287SMatthew Knepley     SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"0.0 <= rtol_max (%g) < 1.0\n",kctx->rtol_max);
413a8c6a408SBarry Smith   }
414a8c6a408SBarry Smith   if (kctx->threshold <= 0.0 || kctx->threshold >= 1.0) {
415091e6287SMatthew Knepley     SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"0.0 < threshold (%g) < 1.0\n",kctx->threshold);
416a8c6a408SBarry Smith   }
417a8c6a408SBarry Smith   if (kctx->gamma < 0.0 || kctx->gamma > 1.0) {
418091e6287SMatthew Knepley     SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"0.0 <= gamma (%g) <= 1.0\n",kctx->gamma);
419a8c6a408SBarry Smith   }
420a8c6a408SBarry Smith   if (kctx->alpha <= 1.0 || kctx->alpha > 2.0) {
421091e6287SMatthew Knepley     SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"1.0 < alpha (%g) <= 2.0\n",kctx->alpha);
422a8c6a408SBarry Smith   }
423a8c6a408SBarry Smith   if (kctx->version != 1 && kctx->version !=2) {
42477431f27SBarry Smith     SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Only versions 1 and 2 are supported: %D",kctx->version);
425a8c6a408SBarry Smith   }
4263a40ed3dSBarry Smith   PetscFunctionReturn(0);
427e7e93795SLois Curfman McInnes }
428e7e93795SLois Curfman McInnes 
4294a2ae208SSatish Balay #undef __FUNCT__
4304a2ae208SSatish Balay #define __FUNCT__ "SNES_KSP_EW_ComputeRelativeTolerance_Private"
431dfbe8321SBarry Smith PetscErrorCode SNES_KSP_EW_ComputeRelativeTolerance_Private(SNES snes,KSP ksp)
432e7e93795SLois Curfman McInnes {
433e7e93795SLois Curfman McInnes   SNES_KSP_EW_ConvCtx *kctx = (SNES_KSP_EW_ConvCtx*)snes->kspconvctx;
434329f5518SBarry Smith   PetscReal           rtol = 0.0,stol;
435dfbe8321SBarry Smith   PetscErrorCode      ierr;
4363a40ed3dSBarry Smith 
4373a40ed3dSBarry Smith   PetscFunctionBegin;
43829bbc08cSBarry Smith   if (!kctx) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context exists");
439c38d4ed2SBarry Smith   if (!snes->iter) { /* first time in, so use the original user rtol */
440e7e93795SLois Curfman McInnes     rtol = kctx->rtol_0;
441e7e93795SLois Curfman McInnes   } else {
442e7e93795SLois Curfman McInnes     if (kctx->version == 1) {
443e7e93795SLois Curfman McInnes       rtol = (snes->norm - kctx->lresid_last)/kctx->norm_last;
444e7e93795SLois Curfman McInnes       if (rtol < 0.0) rtol = -rtol;
445e7e93795SLois Curfman McInnes       stol = pow(kctx->rtol_last,kctx->alpha2);
4460452661fSBarry Smith       if (stol > kctx->threshold) rtol = PetscMax(rtol,stol);
447e7e93795SLois Curfman McInnes     } else if (kctx->version == 2) {
448e7e93795SLois Curfman McInnes       rtol = kctx->gamma * pow(snes->norm/kctx->norm_last,kctx->alpha);
449e7e93795SLois Curfman McInnes       stol = kctx->gamma * pow(kctx->rtol_last,kctx->alpha);
4500452661fSBarry Smith       if (stol > kctx->threshold) rtol = PetscMax(rtol,stol);
45177431f27SBarry Smith     } else SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Only versions 1 or 2 are supported: %D",kctx->version);
452e7e93795SLois Curfman McInnes   }
4530452661fSBarry Smith   rtol = PetscMin(rtol,kctx->rtol_max);
454e7e93795SLois Curfman McInnes   kctx->rtol_last = rtol;
45577431f27SBarry Smith   PetscLogInfo(snes,"SNES_KSP_EW_ComputeRelativeTolerance_Private: iter %D, Eisenstat-Walker (version %D) KSP rtol = %g\n",snes->iter,kctx->version,rtol);
4563131a8b6SLois Curfman McInnes   ierr = KSPSetTolerances(ksp,rtol,PETSC_DEFAULT,PETSC_DEFAULT,PETSC_DEFAULT);CHKERRQ(ierr);
457e7e93795SLois Curfman McInnes   kctx->norm_last = snes->norm;
4583a40ed3dSBarry Smith   PetscFunctionReturn(0);
459e7e93795SLois Curfman McInnes }
460e7e93795SLois Curfman McInnes 
4614a2ae208SSatish Balay #undef __FUNCT__
4624a2ae208SSatish Balay #define __FUNCT__ "SNES_KSP_EW_Converged_Private"
463dfbe8321SBarry Smith PetscErrorCode SNES_KSP_EW_Converged_Private(KSP ksp,int n,PetscReal rnorm,KSPConvergedReason *reason,void *ctx)
464e7e93795SLois Curfman McInnes {
465e7e93795SLois Curfman McInnes   SNES                snes = (SNES)ctx;
466e7e93795SLois Curfman McInnes   SNES_KSP_EW_ConvCtx *kctx = (SNES_KSP_EW_ConvCtx*)snes->kspconvctx;
467dfbe8321SBarry Smith   PetscErrorCode      ierr;
468e7e93795SLois Curfman McInnes 
4693a40ed3dSBarry Smith   PetscFunctionBegin;
47029bbc08cSBarry Smith   if (!kctx) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context set");
471958c9bccSBarry Smith   if (!n) {ierr = SNES_KSP_EW_ComputeRelativeTolerance_Private(snes,ksp);CHKERRQ(ierr);}
472211a6b7eSSatish Balay   ierr = KSPDefaultConverged(ksp,n,rnorm,reason,ctx);CHKERRQ(ierr);
473e7e93795SLois Curfman McInnes   kctx->lresid_last = rnorm;
474211a6b7eSSatish Balay   if (*reason) {
47577431f27SBarry Smith     PetscLogInfo(snes,"SNES_KSP_EW_Converged_Private: KSP iterations=%D, rnorm=%g\n",n,rnorm);
4763a40ed3dSBarry Smith   }
477211a6b7eSSatish Balay   PetscFunctionReturn(0);
478e7e93795SLois Curfman McInnes }
479e7e93795SLois Curfman McInnes 
480e7e93795SLois Curfman McInnes 
481