xref: /petsc/src/snes/interface/snesut.c (revision 4b27c08ac4c7fe27d83aaa07ba0dc5abca4ca6c8)
173f4d377SMatthew Knepley /*$Id: snesut.c,v 1.66 2001/08/06 21:17:07 bsmith Exp $*/
2e7e93795SLois Curfman McInnes 
3e090d566SSatish Balay #include "src/snes/snesimpl.h"       /*I   "petscsnes.h"   I*/
4e7e93795SLois Curfman McInnes 
54a2ae208SSatish Balay #undef __FUNCT__
64a2ae208SSatish Balay #define __FUNCT__ "SNESVecViewMonitor"
73f1db9ecSBarry Smith /*@C
836851e7fSLois Curfman McInnes    SNESVecViewMonitor - 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
16*4b27c08aSLois 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 
2336851e7fSLois Curfman McInnes .seealso: SNESSetMonitor(), SNESDefaultMonitor(), VecView()
243f1db9ecSBarry Smith @*/
25329f5518SBarry Smith int SNESVecViewMonitor(SNES snes,int its,PetscReal fgnorm,void *dummy)
263f1db9ecSBarry Smith {
273f1db9ecSBarry Smith   int         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__
445ed2d596SBarry Smith #define __FUNCT__ "SNESVecViewResidualMonitor"
455ed2d596SBarry Smith /*@C
465ed2d596SBarry Smith    SNESVecViewResidualMonitor - 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
54*4b27c08aSLois 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 
615ed2d596SBarry Smith .seealso: SNESSetMonitor(), SNESDefaultMonitor(), VecView()
625ed2d596SBarry Smith @*/
635ed2d596SBarry Smith int SNESVecViewResidualMonitor(SNES snes,int its,PetscReal fgnorm,void *dummy)
645ed2d596SBarry Smith {
655ed2d596SBarry Smith   int         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__
824a2ae208SSatish Balay #define __FUNCT__ "SNESVecViewUpdateMonitor"
83d132466eSBarry Smith /*@C
847c922b88SBarry Smith    SNESVecViewUpdateMonitor - 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
92*4b27c08aSLois 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 
99d132466eSBarry Smith .seealso: SNESSetMonitor(), SNESDefaultMonitor(), VecView()
100d132466eSBarry Smith @*/
101329f5518SBarry Smith int SNESVecViewUpdateMonitor(SNES snes,int its,PetscReal fgnorm,void *dummy)
102d132466eSBarry Smith {
103d132466eSBarry Smith   int         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__
1204a2ae208SSatish Balay #define __FUNCT__ "SNESDefaultMonitor"
1214b828684SBarry Smith /*@C
122*4b27c08aSLois Curfman McInnes    SNESDefaultMonitor - 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
129*4b27c08aSLois Curfman McInnes .  fgnorm - 2-norm of residual
130c7afd0dbSLois Curfman McInnes -  dummy - unused context
131fee21e36SBarry Smith 
132e7e93795SLois Curfman McInnes    Notes:
133*4b27c08aSLois 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 
13936851e7fSLois Curfman McInnes .seealso: SNESSetMonitor(), SNESVecViewMonitor()
140e7e93795SLois Curfman McInnes @*/
141329f5518SBarry Smith int SNESDefaultMonitor(SNES snes,int its,PetscReal fgnorm,void *dummy)
142e7e93795SLois Curfman McInnes {
143d132466eSBarry Smith   int         ierr;
144b0a32e0cSBarry Smith   PetscViewer viewer = (PetscViewer) dummy;
145d132466eSBarry Smith 
1463a40ed3dSBarry Smith   PetscFunctionBegin;
147b0a32e0cSBarry Smith   if (!viewer) viewer = PETSC_VIEWER_STDOUT_(snes->comm);
148a0e26f09SSatish Balay   ierr = PetscViewerASCIIPrintf(viewer,"%3d SNES Function norm %14.12e \n",its,fgnorm);CHKERRQ(ierr);
1493a40ed3dSBarry Smith   PetscFunctionReturn(0);
150e7e93795SLois Curfman McInnes }
1513f1db9ecSBarry Smith 
1523a7fca6bSBarry Smith #undef __FUNCT__
1533a7fca6bSBarry Smith #define __FUNCT__ "SNESRatioMonitor"
1543a7fca6bSBarry Smith /*@C
155*4b27c08aSLois Curfman McInnes    SNESRatioMonitor - Monitors progress of the SNES solvers by printing the ratio
156*4b27c08aSLois Curfman McInnes    of residual norm at each iteration to the previous.
1573a7fca6bSBarry Smith 
1583a7fca6bSBarry Smith    Collective on SNES
1593a7fca6bSBarry Smith 
1603a7fca6bSBarry Smith    Input Parameters:
1613a7fca6bSBarry Smith +  snes - the SNES context
1623a7fca6bSBarry Smith .  its - iteration number
1633a7fca6bSBarry Smith .  fgnorm - 2-norm of residual (or gradient)
1643a7fca6bSBarry Smith -  dummy - unused context
1653a7fca6bSBarry Smith 
1663a7fca6bSBarry Smith    Level: intermediate
1673a7fca6bSBarry Smith 
1683a7fca6bSBarry Smith .keywords: SNES, nonlinear, monitor, norm
1693a7fca6bSBarry Smith 
1703a7fca6bSBarry Smith .seealso: SNESSetMonitor(), SNESVecViewMonitor()
1713a7fca6bSBarry Smith @*/
1723a7fca6bSBarry Smith int SNESRatioMonitor(SNES snes,int its,PetscReal fgnorm,void *dummy)
1733a7fca6bSBarry Smith {
1743a7fca6bSBarry Smith   int         ierr,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);
1823a7fca6bSBarry Smith   if (its == 0 || !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"
1963a7fca6bSBarry Smith int SNESRatioMonitorDestroy(void *history)
1973a7fca6bSBarry Smith {
1983a7fca6bSBarry Smith   int         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
209*4b27c08aSLois 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 @*/
2223a7fca6bSBarry Smith int SNESSetRatioMonitor(SNES snes)
2233a7fca6bSBarry Smith {
2243a7fca6bSBarry Smith   int       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 */
250329f5518SBarry Smith int SNESDefaultSMonitor(SNES snes,int its,PetscReal fgnorm,void *dummy)
251e7e93795SLois Curfman McInnes {
252d132466eSBarry Smith   int ierr;
253d132466eSBarry Smith 
2543a40ed3dSBarry Smith   PetscFunctionBegin;
2558f240d10SBarry Smith   if (fgnorm > 1.e-9) {
256a0e26f09SSatish Balay     ierr = PetscPrintf(snes->comm,"%3d SNES Function norm %g \n",its,fgnorm);CHKERRQ(ierr);
2573a40ed3dSBarry Smith   } else if (fgnorm > 1.e-11){
258a0e26f09SSatish Balay     ierr = PetscPrintf(snes->comm,"%3d SNES Function norm %5.3e \n",its,fgnorm);CHKERRQ(ierr);
2593a40ed3dSBarry Smith   } else {
260a0e26f09SSatish Balay     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__
266*4b27c08aSLois Curfman McInnes #define __FUNCT__ "SNESConverged_LS"
2674b828684SBarry Smith /*@C
268*4b27c08aSLois 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
282184914b5SBarry Smith $  SNES_CONVERGED_FNORM_ABS       - (fnorm < atol),
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,
293c7afd0dbSLois Curfman McInnes .    atol - 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 @*/
303*4b27c08aSLois Curfman McInnes int 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) {
307*4b27c08aSLois 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) {
310*4b27c08aSLois 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;
312184914b5SBarry Smith   } else if (fnorm < snes->atol) {
313*4b27c08aSLois Curfman McInnes     PetscLogInfo(snes,"SNESConverged_LS:Converged due to function norm %g < %g\n",fnorm,snes->atol);
314184914b5SBarry Smith     *reason = SNES_CONVERGED_FNORM_ABS;
3153304466cSBarry Smith   } else if (pnorm < snes->xtol*xnorm) {
316*4b27c08aSLois 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) {
319*4b27c08aSLois Curfman McInnes     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 @*/
353e7e93795SLois Curfman McInnes int 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 @*/
394329f5518SBarry Smith int SNES_KSP_SetParametersEW(SNES snes,int version,PetscReal rtol_0,
395329f5518SBarry Smith                              PetscReal rtol_max,PetscReal gamma2,PetscReal alpha,
396329f5518SBarry Smith                              PetscReal alpha2,PetscReal threshold)
397e7e93795SLois Curfman McInnes {
398e7e93795SLois Curfman McInnes   SNES_KSP_EW_ConvCtx *kctx = (SNES_KSP_EW_ConvCtx*)snes->kspconvctx;
3993a40ed3dSBarry Smith 
4003a40ed3dSBarry Smith   PetscFunctionBegin;
40129bbc08cSBarry Smith   if (!kctx) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context existing");
402e7e93795SLois Curfman McInnes   if (version != PETSC_DEFAULT)   kctx->version   = version;
403e7e93795SLois Curfman McInnes   if (rtol_0 != PETSC_DEFAULT)    kctx->rtol_0    = rtol_0;
404e7e93795SLois Curfman McInnes   if (rtol_max != PETSC_DEFAULT)  kctx->rtol_max  = rtol_max;
405e7e93795SLois Curfman McInnes   if (gamma2 != PETSC_DEFAULT)    kctx->gamma     = gamma2;
406e7e93795SLois Curfman McInnes   if (alpha != PETSC_DEFAULT)     kctx->alpha     = alpha;
407e7e93795SLois Curfman McInnes   if (alpha2 != PETSC_DEFAULT)    kctx->alpha2    = alpha2;
408e7e93795SLois Curfman McInnes   if (threshold != PETSC_DEFAULT) kctx->threshold = threshold;
409a8c6a408SBarry Smith   if (kctx->rtol_0 < 0.0 || kctx->rtol_0 >= 1.0) {
41029bbc08cSBarry Smith     SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"0.0 <= rtol_0 < 1.0: %g",kctx->rtol_0);
411a8c6a408SBarry Smith   }
412a8c6a408SBarry Smith   if (kctx->rtol_max < 0.0 || kctx->rtol_max >= 1.0) {
413091e6287SMatthew Knepley     SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"0.0 <= rtol_max (%g) < 1.0\n",kctx->rtol_max);
414a8c6a408SBarry Smith   }
415a8c6a408SBarry Smith   if (kctx->threshold <= 0.0 || kctx->threshold >= 1.0) {
416091e6287SMatthew Knepley     SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"0.0 < threshold (%g) < 1.0\n",kctx->threshold);
417a8c6a408SBarry Smith   }
418a8c6a408SBarry Smith   if (kctx->gamma < 0.0 || kctx->gamma > 1.0) {
419091e6287SMatthew Knepley     SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"0.0 <= gamma (%g) <= 1.0\n",kctx->gamma);
420a8c6a408SBarry Smith   }
421a8c6a408SBarry Smith   if (kctx->alpha <= 1.0 || kctx->alpha > 2.0) {
422091e6287SMatthew Knepley     SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"1.0 < alpha (%g) <= 2.0\n",kctx->alpha);
423a8c6a408SBarry Smith   }
424a8c6a408SBarry Smith   if (kctx->version != 1 && kctx->version !=2) {
42529bbc08cSBarry Smith     SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Only versions 1 and 2 are supported: %d",kctx->version);
426a8c6a408SBarry Smith   }
4273a40ed3dSBarry Smith   PetscFunctionReturn(0);
428e7e93795SLois Curfman McInnes }
429e7e93795SLois Curfman McInnes 
4304a2ae208SSatish Balay #undef __FUNCT__
4314a2ae208SSatish Balay #define __FUNCT__ "SNES_KSP_EW_ComputeRelativeTolerance_Private"
432e7e93795SLois Curfman McInnes int SNES_KSP_EW_ComputeRelativeTolerance_Private(SNES snes,KSP ksp)
433e7e93795SLois Curfman McInnes {
434e7e93795SLois Curfman McInnes   SNES_KSP_EW_ConvCtx *kctx = (SNES_KSP_EW_ConvCtx*)snes->kspconvctx;
435329f5518SBarry Smith   PetscReal           rtol = 0.0,stol;
436e7e93795SLois Curfman McInnes   int                 ierr;
4373a40ed3dSBarry Smith 
4383a40ed3dSBarry Smith   PetscFunctionBegin;
43929bbc08cSBarry Smith   if (!kctx) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context exists");
440c38d4ed2SBarry Smith   if (!snes->iter) { /* first time in, so use the original user rtol */
441e7e93795SLois Curfman McInnes     rtol = kctx->rtol_0;
442e7e93795SLois Curfman McInnes   } else {
443e7e93795SLois Curfman McInnes     if (kctx->version == 1) {
444e7e93795SLois Curfman McInnes       rtol = (snes->norm - kctx->lresid_last)/kctx->norm_last;
445e7e93795SLois Curfman McInnes       if (rtol < 0.0) rtol = -rtol;
446e7e93795SLois Curfman McInnes       stol = pow(kctx->rtol_last,kctx->alpha2);
4470452661fSBarry Smith       if (stol > kctx->threshold) rtol = PetscMax(rtol,stol);
448e7e93795SLois Curfman McInnes     } else if (kctx->version == 2) {
449e7e93795SLois Curfman McInnes       rtol = kctx->gamma * pow(snes->norm/kctx->norm_last,kctx->alpha);
450e7e93795SLois Curfman McInnes       stol = kctx->gamma * pow(kctx->rtol_last,kctx->alpha);
4510452661fSBarry Smith       if (stol > kctx->threshold) rtol = PetscMax(rtol,stol);
45229bbc08cSBarry Smith     } else SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Only versions 1 or 2 are supported: %d",kctx->version);
453e7e93795SLois Curfman McInnes   }
4540452661fSBarry Smith   rtol = PetscMin(rtol,kctx->rtol_max);
455e7e93795SLois Curfman McInnes   kctx->rtol_last = rtol;
456b0a32e0cSBarry Smith   PetscLogInfo(snes,"SNES_KSP_EW_ComputeRelativeTolerance_Private: iter %d, Eisenstat-Walker (version %d) KSP rtol = %g\n",snes->iter,kctx->version,rtol);
4573131a8b6SLois Curfman McInnes   ierr = KSPSetTolerances(ksp,rtol,PETSC_DEFAULT,PETSC_DEFAULT,PETSC_DEFAULT);CHKERRQ(ierr);
458e7e93795SLois Curfman McInnes   kctx->norm_last = snes->norm;
4593a40ed3dSBarry Smith   PetscFunctionReturn(0);
460e7e93795SLois Curfman McInnes }
461e7e93795SLois Curfman McInnes 
4624a2ae208SSatish Balay #undef __FUNCT__
4634a2ae208SSatish Balay #define __FUNCT__ "SNES_KSP_EW_Converged_Private"
464329f5518SBarry Smith int SNES_KSP_EW_Converged_Private(KSP ksp,int n,PetscReal rnorm,KSPConvergedReason *reason,void *ctx)
465e7e93795SLois Curfman McInnes {
466e7e93795SLois Curfman McInnes   SNES                snes = (SNES)ctx;
467e7e93795SLois Curfman McInnes   SNES_KSP_EW_ConvCtx *kctx = (SNES_KSP_EW_ConvCtx*)snes->kspconvctx;
4683acb151aSSatish Balay   int                 ierr;
469e7e93795SLois Curfman McInnes 
4703a40ed3dSBarry Smith   PetscFunctionBegin;
47129bbc08cSBarry Smith   if (!kctx) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context set");
472184914b5SBarry Smith   if (n == 0) {ierr = SNES_KSP_EW_ComputeRelativeTolerance_Private(snes,ksp);CHKERRQ(ierr);}
473211a6b7eSSatish Balay   ierr = KSPDefaultConverged(ksp,n,rnorm,reason,ctx);CHKERRQ(ierr);
474e7e93795SLois Curfman McInnes   kctx->lresid_last = rnorm;
475211a6b7eSSatish Balay   if (*reason) {
476b0a32e0cSBarry Smith     PetscLogInfo(snes,"SNES_KSP_EW_Converged_Private: KSP iterations=%d, rnorm=%g\n",n,rnorm);
4773a40ed3dSBarry Smith   }
478211a6b7eSSatish Balay   PetscFunctionReturn(0);
479e7e93795SLois Curfman McInnes }
480e7e93795SLois Curfman McInnes 
481e7e93795SLois Curfman McInnes 
482