xref: /petsc/src/snes/interface/snesut.c (revision 63dd3a1af947c5d07342e150a17d503f381a847e)
1*63dd3a1aSKris Buschelman #define PETSCSNES_DLL
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
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 
2336851e7fSLois Curfman McInnes .seealso: SNESSetMonitor(), SNESDefaultMonitor(), VecView()
243f1db9ecSBarry Smith @*/
25*63dd3a1aSKris Buschelman PetscErrorCode PETSCSNES_DLLEXPORT SNESVecViewMonitor(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__
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
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 
615ed2d596SBarry Smith .seealso: SNESSetMonitor(), SNESDefaultMonitor(), VecView()
625ed2d596SBarry Smith @*/
63*63dd3a1aSKris Buschelman PetscErrorCode PETSCSNES_DLLEXPORT SNESVecViewResidualMonitor(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__
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
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 
99d132466eSBarry Smith .seealso: SNESSetMonitor(), SNESDefaultMonitor(), VecView()
100d132466eSBarry Smith @*/
101*63dd3a1aSKris Buschelman PetscErrorCode PETSCSNES_DLLEXPORT SNESVecViewUpdateMonitor(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__
1204a2ae208SSatish Balay #define __FUNCT__ "SNESDefaultMonitor"
1214b828684SBarry Smith /*@C
1224b27c08aSLois 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
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 
13936851e7fSLois Curfman McInnes .seealso: SNESSetMonitor(), SNESVecViewMonitor()
140e7e93795SLois Curfman McInnes @*/
141*63dd3a1aSKris Buschelman PetscErrorCode PETSCSNES_DLLEXPORT SNESDefaultMonitor(SNES snes,PetscInt its,PetscReal fgnorm,void *dummy)
142e7e93795SLois Curfman McInnes {
143dfbe8321SBarry Smith   PetscErrorCode ierr;
144b0a32e0cSBarry Smith   PetscViewer    viewer = (PetscViewer) dummy;
145d132466eSBarry Smith 
1463a40ed3dSBarry Smith   PetscFunctionBegin;
147b0a32e0cSBarry Smith   if (!viewer) viewer = PETSC_VIEWER_STDOUT_(snes->comm);
148a7cc72afSBarry Smith   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
1554b27c08aSLois Curfman McInnes    SNESRatioMonitor - Monitors progress of the SNES solvers by printing the ratio
1564b27c08aSLois 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 @*/
172*63dd3a1aSKris Buschelman PetscErrorCode PETSCSNES_DLLEXPORT SNESRatioMonitor(SNES snes,PetscInt its,PetscReal fgnorm,void *dummy)
1733a7fca6bSBarry Smith {
174dfbe8321SBarry Smith   PetscErrorCode ierr;
17577431f27SBarry Smith   PetscInt       len;
17687828ca2SBarry Smith   PetscReal      *history;
1773a7fca6bSBarry Smith   PetscViewer    viewer;
1783a7fca6bSBarry Smith 
1793a7fca6bSBarry Smith   PetscFunctionBegin;
1803a7fca6bSBarry Smith   viewer = PETSC_VIEWER_STDOUT_(snes->comm);
1813a7fca6bSBarry Smith 
1823a7fca6bSBarry Smith   ierr = SNESGetConvergenceHistory(snes,&history,PETSC_NULL,&len);CHKERRQ(ierr);
183958c9bccSBarry Smith   if (!its || !history || its > len) {
184a7cc72afSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"%3D SNES Function norm %14.12e \n",its,fgnorm);CHKERRQ(ierr);
1853a7fca6bSBarry Smith   } else {
18687828ca2SBarry Smith     PetscReal ratio = fgnorm/history[its-1];
187a7cc72afSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"%3D SNES Function norm %14.12e %g \n",its,fgnorm,ratio);CHKERRQ(ierr);
1883a7fca6bSBarry Smith   }
1893a7fca6bSBarry Smith   PetscFunctionReturn(0);
1903a7fca6bSBarry Smith }
1913a7fca6bSBarry Smith 
1923a7fca6bSBarry Smith /*
1933a7fca6bSBarry Smith    If the we set the history monitor space then we must destroy it
1943a7fca6bSBarry Smith */
1953a7fca6bSBarry Smith #undef __FUNCT__
1963a7fca6bSBarry Smith #define __FUNCT__ "SNESRatioMonitorDestroy"
197dfbe8321SBarry Smith PetscErrorCode SNESRatioMonitorDestroy(void *history)
1983a7fca6bSBarry Smith {
199dfbe8321SBarry Smith   PetscErrorCode ierr;
2003a7fca6bSBarry Smith 
2013a7fca6bSBarry Smith   PetscFunctionBegin;
2023a7fca6bSBarry Smith   ierr = PetscFree(history);CHKERRQ(ierr);
2033a7fca6bSBarry Smith   PetscFunctionReturn(0);
2043a7fca6bSBarry Smith }
2053a7fca6bSBarry Smith 
2063a7fca6bSBarry Smith #undef __FUNCT__
2073a7fca6bSBarry Smith #define __FUNCT__ "SNESSetRatioMonitor"
2083a7fca6bSBarry Smith /*@C
2093a7fca6bSBarry Smith    SNESSetRatioMonitor - Sets SNES to use a monitor that prints the
2104b27c08aSLois Curfman McInnes    ratio of the function norm at each iteration.
2113a7fca6bSBarry Smith 
2123a7fca6bSBarry Smith    Collective on SNES
2133a7fca6bSBarry Smith 
2143a7fca6bSBarry Smith    Input Parameters:
2153a7fca6bSBarry Smith .   snes - the SNES context
2163a7fca6bSBarry Smith 
2173a7fca6bSBarry Smith    Level: intermediate
2183a7fca6bSBarry Smith 
2193a7fca6bSBarry Smith .keywords: SNES, nonlinear, monitor, norm
2203a7fca6bSBarry Smith 
2213a7fca6bSBarry Smith .seealso: SNESSetMonitor(), SNESVecViewMonitor(), SNESDefaultMonitor()
2223a7fca6bSBarry Smith @*/
223*63dd3a1aSKris Buschelman PetscErrorCode PETSCSNES_DLLEXPORT SNESSetRatioMonitor(SNES snes)
2243a7fca6bSBarry Smith {
225dfbe8321SBarry Smith   PetscErrorCode ierr;
22687828ca2SBarry Smith   PetscReal      *history;
2273a7fca6bSBarry Smith 
2283a7fca6bSBarry Smith   PetscFunctionBegin;
2293a7fca6bSBarry Smith 
2303a7fca6bSBarry Smith   ierr = SNESGetConvergenceHistory(snes,&history,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr);
2313a7fca6bSBarry Smith   if (!history) {
2323a7fca6bSBarry Smith     ierr = PetscMalloc(100*sizeof(double),&history);CHKERRQ(ierr);
2333a7fca6bSBarry Smith     ierr = SNESSetConvergenceHistory(snes,history,0,100,PETSC_TRUE);CHKERRQ(ierr);
2343a7fca6bSBarry Smith     ierr = SNESSetMonitor(snes,SNESRatioMonitor,history,SNESRatioMonitorDestroy);CHKERRQ(ierr);
2353a7fca6bSBarry Smith   } else {
2363a7fca6bSBarry Smith     ierr = SNESSetMonitor(snes,SNESRatioMonitor,0,0);CHKERRQ(ierr);
2373a7fca6bSBarry Smith   }
2383a7fca6bSBarry Smith   PetscFunctionReturn(0);
2393a7fca6bSBarry Smith }
2403a7fca6bSBarry Smith 
241e7e93795SLois Curfman McInnes /* ---------------------------------------------------------------- */
2424a2ae208SSatish Balay #undef __FUNCT__
2434a2ae208SSatish Balay #define __FUNCT__ "SNESDefaultSMonitor"
244be1f7002SBarry Smith /*
245be1f7002SBarry Smith      Default (short) SNES Monitor, same as SNESDefaultMonitor() except
246be1f7002SBarry Smith   it prints fewer digits of the residual as the residual gets smaller.
247be1f7002SBarry Smith   This is because the later digits are meaningless and are often
248be1f7002SBarry Smith   different on different machines; by using this routine different
249be1f7002SBarry Smith   machines will usually generate the same output.
250be1f7002SBarry Smith */
251*63dd3a1aSKris Buschelman PetscErrorCode PETSCSNES_DLLEXPORT SNESDefaultSMonitor(SNES snes,PetscInt its,PetscReal fgnorm,void *dummy)
252e7e93795SLois Curfman McInnes {
253dfbe8321SBarry Smith   PetscErrorCode ierr;
254d132466eSBarry Smith 
2553a40ed3dSBarry Smith   PetscFunctionBegin;
2568f240d10SBarry Smith   if (fgnorm > 1.e-9) {
25777431f27SBarry Smith     ierr = PetscPrintf(snes->comm,"%3D SNES Function norm %g \n",its,fgnorm);CHKERRQ(ierr);
2583a40ed3dSBarry Smith   } else if (fgnorm > 1.e-11){
25977431f27SBarry Smith     ierr = PetscPrintf(snes->comm,"%3D SNES Function norm %5.3e \n",its,fgnorm);CHKERRQ(ierr);
2603a40ed3dSBarry Smith   } else {
26177431f27SBarry Smith     ierr = PetscPrintf(snes->comm,"%3D SNES Function norm < 1.e-11\n",its);CHKERRQ(ierr);
262e7e93795SLois Curfman McInnes   }
2633a40ed3dSBarry Smith   PetscFunctionReturn(0);
264e7e93795SLois Curfman McInnes }
265e7e93795SLois Curfman McInnes /* ---------------------------------------------------------------- */
2664a2ae208SSatish Balay #undef __FUNCT__
2674b27c08aSLois Curfman McInnes #define __FUNCT__ "SNESConverged_LS"
2684b828684SBarry Smith /*@C
2694b27c08aSLois Curfman McInnes    SNESConverged_LS - Monitors the convergence of the solvers for
270f525115eSLois Curfman McInnes    systems of nonlinear equations (default).
271e7e93795SLois Curfman McInnes 
272c7afd0dbSLois Curfman McInnes    Collective on SNES
273c7afd0dbSLois Curfman McInnes 
274e7e93795SLois Curfman McInnes    Input Parameters:
275c7afd0dbSLois Curfman McInnes +  snes - the SNES context
276e7e93795SLois Curfman McInnes .  xnorm - 2-norm of current iterate
277e7e93795SLois Curfman McInnes .  pnorm - 2-norm of current step
278e7e93795SLois Curfman McInnes .  fnorm - 2-norm of function
279c7afd0dbSLois Curfman McInnes -  dummy - unused context
280e7e93795SLois Curfman McInnes 
281184914b5SBarry Smith    Output Parameter:
282184914b5SBarry Smith .   reason  - one of
28370441072SBarry Smith $  SNES_CONVERGED_FNORM_ABS       - (fnorm < abstol),
2843304466cSBarry Smith $  SNES_CONVERGED_PNORM_RELATIVE  - (pnorm < xtol*xnorm),
285184914b5SBarry Smith $  SNES_CONVERGED_FNORM_RELATIVE  - (fnorm < rtol*fnorm0),
286184914b5SBarry Smith $  SNES_DIVERGED_FUNCTION_COUNT   - (nfct > maxf),
287184914b5SBarry Smith $  SNES_DIVERGED_FNORM_NAN        - (fnorm == NaN),
288184914b5SBarry Smith $  SNES_CONVERGED_ITERATING       - (otherwise),
289e7e93795SLois Curfman McInnes 
290e7e93795SLois Curfman McInnes    where
291c7afd0dbSLois Curfman McInnes +    maxf - maximum number of function evaluations,
292c7afd0dbSLois Curfman McInnes             set with SNESSetTolerances()
293c7afd0dbSLois Curfman McInnes .    nfct - number of function evaluations,
29470441072SBarry Smith .    abstol - absolute function norm tolerance,
295c7afd0dbSLois Curfman McInnes             set with SNESSetTolerances()
296c7afd0dbSLois Curfman McInnes -    rtol - relative function norm tolerance, set with SNESSetTolerances()
297fee21e36SBarry Smith 
29836851e7fSLois Curfman McInnes    Level: intermediate
29936851e7fSLois Curfman McInnes 
300e7e93795SLois Curfman McInnes .keywords: SNES, nonlinear, default, converged, convergence
301e7e93795SLois Curfman McInnes 
302e7e93795SLois Curfman McInnes .seealso: SNESSetConvergenceTest(), SNESEisenstatWalkerConverged()
303e7e93795SLois Curfman McInnes @*/
304*63dd3a1aSKris Buschelman PetscErrorCode PETSCSNES_DLLEXPORT SNESConverged_LS(SNES snes,PetscReal xnorm,PetscReal pnorm,PetscReal fnorm,SNESConvergedReason *reason,void *dummy)
305e7e93795SLois Curfman McInnes {
30663ba0a88SBarry Smith   PetscErrorCode ierr;
30763ba0a88SBarry Smith 
3083a40ed3dSBarry Smith   PetscFunctionBegin;
309d252947aSBarry Smith   if (fnorm != fnorm) {
31063ba0a88SBarry Smith     ierr = PetscLogInfo((snes,"SNESConverged_LS:Failed to converged, function norm is NaN\n"));CHKERRQ(ierr);
311184914b5SBarry Smith     *reason = SNES_DIVERGED_FNORM_NAN;
312184914b5SBarry Smith   } else if (fnorm <= snes->ttol) {
31363ba0a88SBarry Smith     ierr = PetscLogInfo((snes,"SNESConverged_LS:Converged due to function norm %g < %g (relative tolerance)\n",fnorm,snes->ttol));CHKERRQ(ierr);
314184914b5SBarry Smith     *reason = SNES_CONVERGED_FNORM_RELATIVE;
31570441072SBarry Smith   } else if (fnorm < snes->abstol) {
31663ba0a88SBarry Smith     ierr = PetscLogInfo((snes,"SNESConverged_LS:Converged due to function norm %g < %g\n",fnorm,snes->abstol));CHKERRQ(ierr);
317184914b5SBarry Smith     *reason = SNES_CONVERGED_FNORM_ABS;
3183304466cSBarry Smith   } else if (pnorm < snes->xtol*xnorm) {
31963ba0a88SBarry Smith     ierr = PetscLogInfo((snes,"SNESConverged_LS:Converged due to small update length: %g < %g * %g\n",pnorm,snes->xtol,xnorm));CHKERRQ(ierr);
320184914b5SBarry Smith     *reason = SNES_CONVERGED_PNORM_RELATIVE;
32143e71028SBarry Smith   } else if (snes->nfuncs >= snes->max_funcs) {
32263ba0a88SBarry Smith     ierr = PetscLogInfo((snes,"SNESConverged_LS:Exceeded maximum number of function evaluations: %D > %D\n",snes->nfuncs,snes->max_funcs));CHKERRQ(ierr);
323184914b5SBarry Smith     *reason = SNES_DIVERGED_FUNCTION_COUNT ;
324184914b5SBarry Smith   } else {
325184914b5SBarry Smith     *reason = SNES_CONVERGED_ITERATING;
326e7e93795SLois Curfman McInnes   }
3273a40ed3dSBarry Smith   PetscFunctionReturn(0);
328e7e93795SLois Curfman McInnes }
329e7e93795SLois Curfman McInnes /* ------------------------------------------------------------ */
3304a2ae208SSatish Balay #undef __FUNCT__
3314a2ae208SSatish Balay #define __FUNCT__ "SNES_KSP_SetConvergenceTestEW"
332e7e93795SLois Curfman McInnes /*@
333f525115eSLois Curfman McInnes    SNES_KSP_SetConvergenceTestEW - Sets alternative convergence test
334e7e93795SLois Curfman McInnes    for the linear solvers within an inexact Newton method.
335e7e93795SLois Curfman McInnes 
336c7afd0dbSLois Curfman McInnes    Collective on SNES
337c7afd0dbSLois Curfman McInnes 
338e7e93795SLois Curfman McInnes    Input Parameter:
339e7e93795SLois Curfman McInnes .  snes - SNES context
340e7e93795SLois Curfman McInnes 
341e7e93795SLois Curfman McInnes    Notes:
342e7e93795SLois Curfman McInnes    Currently, the default is to use a constant relative tolerance for
343e7e93795SLois Curfman McInnes    the inner linear solvers.  Alternatively, one can use the
344e7e93795SLois Curfman McInnes    Eisenstat-Walker method, where the relative convergence tolerance
345e7e93795SLois Curfman McInnes    is reset at each Newton iteration according progress of the nonlinear
346e7e93795SLois Curfman McInnes    solver.
347e7e93795SLois Curfman McInnes 
34836851e7fSLois Curfman McInnes    Level: advanced
34936851e7fSLois Curfman McInnes 
350e7e93795SLois Curfman McInnes    Reference:
351e7e93795SLois Curfman McInnes    S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an
352e30ad881SLois Curfman McInnes    inexact Newton method", SISC 17 (1), pp.16-32, 1996.
353e7e93795SLois Curfman McInnes 
354e7e93795SLois Curfman McInnes .keywords: SNES, KSP, Eisenstat, Walker, convergence, test, inexact, Newton
355e7e93795SLois Curfman McInnes @*/
356*63dd3a1aSKris Buschelman PetscErrorCode PETSCSNES_DLLEXPORT SNES_KSP_SetConvergenceTestEW(SNES snes)
357e7e93795SLois Curfman McInnes {
3583a40ed3dSBarry Smith   PetscFunctionBegin;
359186905e3SBarry Smith   snes->ksp_ewconv = PETSC_TRUE;
3603a40ed3dSBarry Smith   PetscFunctionReturn(0);
361e7e93795SLois Curfman McInnes }
362e7e93795SLois Curfman McInnes 
3634a2ae208SSatish Balay #undef __FUNCT__
3644a2ae208SSatish Balay #define __FUNCT__ "SNES_KSP_SetParametersEW"
365e7e93795SLois Curfman McInnes /*@
366e7e93795SLois Curfman McInnes    SNES_KSP_SetParametersEW - Sets parameters for Eisenstat-Walker
367e7e93795SLois Curfman McInnes    convergence criteria for the linear solvers within an inexact
368e7e93795SLois Curfman McInnes    Newton method.
369e7e93795SLois Curfman McInnes 
370c7afd0dbSLois Curfman McInnes    Collective on SNES
371c7afd0dbSLois Curfman McInnes 
372e7e93795SLois Curfman McInnes    Input Parameters:
373c7afd0dbSLois Curfman McInnes +    snes - SNES context
374e7e93795SLois Curfman McInnes .    version - version 1 or 2 (default is 2)
375c7afd0dbSLois Curfman McInnes .    rtol_0 - initial relative tolerance (0 <= rtol_0 < 1)
376c7afd0dbSLois Curfman McInnes .    rtol_max - maximum relative tolerance (0 <= rtol_max < 1)
377c7afd0dbSLois Curfman McInnes .    alpha - power for version 2 rtol computation (1 < alpha <= 2)
378e7e93795SLois Curfman McInnes .    alpha2 - power for safeguard
379e7e93795SLois Curfman McInnes .    gamma2 - multiplicative factor for version 2 rtol computation
380c7afd0dbSLois Curfman McInnes               (0 <= gamma2 <= 1)
381c7afd0dbSLois Curfman McInnes -    threshold - threshold for imposing safeguard (0 < threshold < 1)
382fee21e36SBarry Smith 
383e7e93795SLois Curfman McInnes    Note:
384e7e93795SLois Curfman McInnes    Use PETSC_DEFAULT to retain the default for any of the parameters.
385e7e93795SLois Curfman McInnes 
38636851e7fSLois Curfman McInnes    Level: advanced
38736851e7fSLois Curfman McInnes 
388e7e93795SLois Curfman McInnes    Reference:
389e7e93795SLois Curfman McInnes    S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an
390e7e93795SLois Curfman McInnes    inexact Newton method", Utah State University Math. Stat. Dept. Res.
391e7e93795SLois Curfman McInnes    Report 6/94/75, June, 1994, to appear in SIAM J. Sci. Comput.
392e7e93795SLois Curfman McInnes 
393e7e93795SLois Curfman McInnes .keywords: SNES, KSP, Eisenstat, Walker, set, parameters
394e7e93795SLois Curfman McInnes 
395e7e93795SLois Curfman McInnes .seealso: SNES_KSP_SetConvergenceTestEW()
396e7e93795SLois Curfman McInnes @*/
397*63dd3a1aSKris Buschelman PetscErrorCode PETSCSNES_DLLEXPORT SNES_KSP_SetParametersEW(SNES snes,PetscInt version,PetscReal rtol_0,PetscReal rtol_max,PetscReal gamma2,PetscReal alpha,
398329f5518SBarry Smith                                         PetscReal alpha2,PetscReal threshold)
399e7e93795SLois Curfman McInnes {
400e7e93795SLois Curfman McInnes   SNES_KSP_EW_ConvCtx *kctx = (SNES_KSP_EW_ConvCtx*)snes->kspconvctx;
4013a40ed3dSBarry Smith 
4023a40ed3dSBarry Smith   PetscFunctionBegin;
40329bbc08cSBarry Smith   if (!kctx) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context existing");
404e7e93795SLois Curfman McInnes   if (version != PETSC_DEFAULT)   kctx->version   = version;
405e7e93795SLois Curfman McInnes   if (rtol_0 != PETSC_DEFAULT)    kctx->rtol_0    = rtol_0;
406e7e93795SLois Curfman McInnes   if (rtol_max != PETSC_DEFAULT)  kctx->rtol_max  = rtol_max;
407e7e93795SLois Curfman McInnes   if (gamma2 != PETSC_DEFAULT)    kctx->gamma     = gamma2;
408e7e93795SLois Curfman McInnes   if (alpha != PETSC_DEFAULT)     kctx->alpha     = alpha;
409e7e93795SLois Curfman McInnes   if (alpha2 != PETSC_DEFAULT)    kctx->alpha2    = alpha2;
410e7e93795SLois Curfman McInnes   if (threshold != PETSC_DEFAULT) kctx->threshold = threshold;
411a8c6a408SBarry Smith   if (kctx->rtol_0 < 0.0 || kctx->rtol_0 >= 1.0) {
41229bbc08cSBarry Smith     SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"0.0 <= rtol_0 < 1.0: %g",kctx->rtol_0);
413a8c6a408SBarry Smith   }
414a8c6a408SBarry Smith   if (kctx->rtol_max < 0.0 || kctx->rtol_max >= 1.0) {
415091e6287SMatthew Knepley     SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"0.0 <= rtol_max (%g) < 1.0\n",kctx->rtol_max);
416a8c6a408SBarry Smith   }
417a8c6a408SBarry Smith   if (kctx->threshold <= 0.0 || kctx->threshold >= 1.0) {
418091e6287SMatthew Knepley     SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"0.0 < threshold (%g) < 1.0\n",kctx->threshold);
419a8c6a408SBarry Smith   }
420a8c6a408SBarry Smith   if (kctx->gamma < 0.0 || kctx->gamma > 1.0) {
421091e6287SMatthew Knepley     SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"0.0 <= gamma (%g) <= 1.0\n",kctx->gamma);
422a8c6a408SBarry Smith   }
423a8c6a408SBarry Smith   if (kctx->alpha <= 1.0 || kctx->alpha > 2.0) {
424091e6287SMatthew Knepley     SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"1.0 < alpha (%g) <= 2.0\n",kctx->alpha);
425a8c6a408SBarry Smith   }
426a8c6a408SBarry Smith   if (kctx->version != 1 && kctx->version !=2) {
42777431f27SBarry Smith     SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Only versions 1 and 2 are supported: %D",kctx->version);
428a8c6a408SBarry Smith   }
4293a40ed3dSBarry Smith   PetscFunctionReturn(0);
430e7e93795SLois Curfman McInnes }
431e7e93795SLois Curfman McInnes 
4324a2ae208SSatish Balay #undef __FUNCT__
4334a2ae208SSatish Balay #define __FUNCT__ "SNES_KSP_EW_ComputeRelativeTolerance_Private"
434dfbe8321SBarry Smith PetscErrorCode SNES_KSP_EW_ComputeRelativeTolerance_Private(SNES snes,KSP ksp)
435e7e93795SLois Curfman McInnes {
436e7e93795SLois Curfman McInnes   SNES_KSP_EW_ConvCtx *kctx = (SNES_KSP_EW_ConvCtx*)snes->kspconvctx;
437329f5518SBarry Smith   PetscReal           rtol = 0.0,stol;
438dfbe8321SBarry Smith   PetscErrorCode      ierr;
4393a40ed3dSBarry Smith 
4403a40ed3dSBarry Smith   PetscFunctionBegin;
44129bbc08cSBarry Smith   if (!kctx) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context exists");
442c38d4ed2SBarry Smith   if (!snes->iter) { /* first time in, so use the original user rtol */
443e7e93795SLois Curfman McInnes     rtol = kctx->rtol_0;
444e7e93795SLois Curfman McInnes   } else {
445e7e93795SLois Curfman McInnes     if (kctx->version == 1) {
446e7e93795SLois Curfman McInnes       rtol = (snes->norm - kctx->lresid_last)/kctx->norm_last;
447e7e93795SLois Curfman McInnes       if (rtol < 0.0) rtol = -rtol;
448e7e93795SLois Curfman McInnes       stol = pow(kctx->rtol_last,kctx->alpha2);
4490452661fSBarry Smith       if (stol > kctx->threshold) rtol = PetscMax(rtol,stol);
450e7e93795SLois Curfman McInnes     } else if (kctx->version == 2) {
451e7e93795SLois Curfman McInnes       rtol = kctx->gamma * pow(snes->norm/kctx->norm_last,kctx->alpha);
452e7e93795SLois Curfman McInnes       stol = kctx->gamma * pow(kctx->rtol_last,kctx->alpha);
4530452661fSBarry Smith       if (stol > kctx->threshold) rtol = PetscMax(rtol,stol);
45477431f27SBarry Smith     } else SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Only versions 1 or 2 are supported: %D",kctx->version);
455e7e93795SLois Curfman McInnes   }
4560452661fSBarry Smith   rtol = PetscMin(rtol,kctx->rtol_max);
457e7e93795SLois Curfman McInnes   kctx->rtol_last = rtol;
45863ba0a88SBarry Smith   ierr = PetscLogInfo((snes,"SNES_KSP_EW_ComputeRelativeTolerance_Private: iter %D, Eisenstat-Walker (version %D) KSP rtol = %g\n",snes->iter,kctx->version,rtol));CHKERRQ(ierr);
4593131a8b6SLois Curfman McInnes   ierr = KSPSetTolerances(ksp,rtol,PETSC_DEFAULT,PETSC_DEFAULT,PETSC_DEFAULT);CHKERRQ(ierr);
460e7e93795SLois Curfman McInnes   kctx->norm_last = snes->norm;
4613a40ed3dSBarry Smith   PetscFunctionReturn(0);
462e7e93795SLois Curfman McInnes }
463e7e93795SLois Curfman McInnes 
4644a2ae208SSatish Balay #undef __FUNCT__
4654a2ae208SSatish Balay #define __FUNCT__ "SNES_KSP_EW_Converged_Private"
466a7cc72afSBarry Smith PetscErrorCode SNES_KSP_EW_Converged_Private(KSP ksp,PetscInt n,PetscReal rnorm,KSPConvergedReason *reason,void *ctx)
467e7e93795SLois Curfman McInnes {
468e7e93795SLois Curfman McInnes   SNES                snes = (SNES)ctx;
469e7e93795SLois Curfman McInnes   SNES_KSP_EW_ConvCtx *kctx = (SNES_KSP_EW_ConvCtx*)snes->kspconvctx;
470dfbe8321SBarry Smith   PetscErrorCode      ierr;
471e7e93795SLois Curfman McInnes 
4723a40ed3dSBarry Smith   PetscFunctionBegin;
47329bbc08cSBarry Smith   if (!kctx) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context set");
474958c9bccSBarry Smith   if (!n) {ierr = SNES_KSP_EW_ComputeRelativeTolerance_Private(snes,ksp);CHKERRQ(ierr);}
475211a6b7eSSatish Balay   ierr = KSPDefaultConverged(ksp,n,rnorm,reason,ctx);CHKERRQ(ierr);
476e7e93795SLois Curfman McInnes   kctx->lresid_last = rnorm;
477211a6b7eSSatish Balay   if (*reason) {
47863ba0a88SBarry Smith     ierr = PetscLogInfo((snes,"SNES_KSP_EW_Converged_Private: KSP iterations=%D, rnorm=%g\n",n,rnorm));CHKERRQ(ierr);
4793a40ed3dSBarry Smith   }
480211a6b7eSSatish Balay   PetscFunctionReturn(0);
481e7e93795SLois Curfman McInnes }
482e7e93795SLois Curfman McInnes 
483e7e93795SLois Curfman McInnes 
484