xref: /petsc/src/snes/interface/snesut.c (revision 06ee9f85ecda6adaae627a28ca41c24bdb6deb84)
163dd3a1aSKris 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 @*/
2563dd3a1aSKris 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 @*/
6363dd3a1aSKris 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 @*/
10163dd3a1aSKris 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 @*/
14163dd3a1aSKris 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 
152eabae89aSBarry Smith typedef struct {
153eabae89aSBarry Smith   PetscViewer viewer;
154eabae89aSBarry Smith   PetscReal   *history;
155eabae89aSBarry Smith } SNESRatioMonitorContext;
156eabae89aSBarry Smith 
1573a7fca6bSBarry Smith #undef __FUNCT__
1583a7fca6bSBarry Smith #define __FUNCT__ "SNESRatioMonitor"
1593a7fca6bSBarry Smith /*@C
1604b27c08aSLois Curfman McInnes    SNESRatioMonitor - Monitors progress of the SNES solvers by printing the ratio
1614b27c08aSLois Curfman McInnes    of residual norm at each iteration to the previous.
1623a7fca6bSBarry Smith 
1633a7fca6bSBarry Smith    Collective on SNES
1643a7fca6bSBarry Smith 
1653a7fca6bSBarry Smith    Input Parameters:
1663a7fca6bSBarry Smith +  snes - the SNES context
1673a7fca6bSBarry Smith .  its - iteration number
1683a7fca6bSBarry Smith .  fgnorm - 2-norm of residual (or gradient)
169eabae89aSBarry Smith -  dummy -  context of monitor
1703a7fca6bSBarry Smith 
1713a7fca6bSBarry Smith    Level: intermediate
1723a7fca6bSBarry Smith 
1733a7fca6bSBarry Smith .keywords: SNES, nonlinear, monitor, norm
1743a7fca6bSBarry Smith 
1753a7fca6bSBarry Smith .seealso: SNESSetMonitor(), SNESVecViewMonitor()
1763a7fca6bSBarry Smith @*/
17763dd3a1aSKris Buschelman PetscErrorCode PETSCSNES_DLLEXPORT SNESRatioMonitor(SNES snes,PetscInt its,PetscReal fgnorm,void *dummy)
1783a7fca6bSBarry Smith {
179dfbe8321SBarry Smith   PetscErrorCode          ierr;
18077431f27SBarry Smith   PetscInt                len;
18187828ca2SBarry Smith   PetscReal               *history;
182eabae89aSBarry Smith   SNESRatioMonitorContext *ctx = (SNESRatioMonitorContext*)dummy;
1833a7fca6bSBarry Smith 
1843a7fca6bSBarry Smith   PetscFunctionBegin;
1853a7fca6bSBarry Smith   ierr = SNESGetConvergenceHistory(snes,&history,PETSC_NULL,&len);CHKERRQ(ierr);
186958c9bccSBarry Smith   if (!its || !history || its > len) {
187eabae89aSBarry Smith     ierr = PetscViewerASCIIPrintf(ctx->viewer,"%3D SNES Function norm %14.12e \n",its,fgnorm);CHKERRQ(ierr);
1883a7fca6bSBarry Smith   } else {
18987828ca2SBarry Smith     PetscReal ratio = fgnorm/history[its-1];
190a83599f4SBarry Smith     ierr = PetscViewerASCIIPrintf(ctx->viewer,"%3D SNES Function norm %14.12e %G \n",its,fgnorm,ratio);CHKERRQ(ierr);
1913a7fca6bSBarry Smith   }
1923a7fca6bSBarry Smith   PetscFunctionReturn(0);
1933a7fca6bSBarry Smith }
1943a7fca6bSBarry Smith 
1953a7fca6bSBarry Smith /*
1963a7fca6bSBarry Smith    If the we set the history monitor space then we must destroy it
1973a7fca6bSBarry Smith */
1983a7fca6bSBarry Smith #undef __FUNCT__
1993a7fca6bSBarry Smith #define __FUNCT__ "SNESRatioMonitorDestroy"
200eabae89aSBarry Smith PetscErrorCode SNESRatioMonitorDestroy(void *ct)
2013a7fca6bSBarry Smith {
202dfbe8321SBarry Smith   PetscErrorCode          ierr;
203eabae89aSBarry Smith   SNESRatioMonitorContext *ctx = (SNESRatioMonitorContext*)ct;
2043a7fca6bSBarry Smith 
2053a7fca6bSBarry Smith   PetscFunctionBegin;
20605b42c5fSBarry Smith   ierr = PetscFree(ctx->history);CHKERRQ(ierr);
207eabae89aSBarry Smith   ierr = PetscViewerDestroy(ctx->viewer);CHKERRQ(ierr);
208eabae89aSBarry Smith   ierr = PetscFree(ctx);CHKERRQ(ierr);
2093a7fca6bSBarry Smith   PetscFunctionReturn(0);
2103a7fca6bSBarry Smith }
2113a7fca6bSBarry Smith 
2123a7fca6bSBarry Smith #undef __FUNCT__
2133a7fca6bSBarry Smith #define __FUNCT__ "SNESSetRatioMonitor"
2143a7fca6bSBarry Smith /*@C
2153a7fca6bSBarry Smith    SNESSetRatioMonitor - Sets SNES to use a monitor that prints the
2164b27c08aSLois Curfman McInnes    ratio of the function norm at each iteration.
2173a7fca6bSBarry Smith 
2183a7fca6bSBarry Smith    Collective on SNES
2193a7fca6bSBarry Smith 
2203a7fca6bSBarry Smith    Input Parameters:
221eabae89aSBarry Smith +   snes - the SNES context
222eabae89aSBarry Smith -   viewer - ASCII viewer to print output
2233a7fca6bSBarry Smith 
2243a7fca6bSBarry Smith    Level: intermediate
2253a7fca6bSBarry Smith 
2263a7fca6bSBarry Smith .keywords: SNES, nonlinear, monitor, norm
2273a7fca6bSBarry Smith 
2283a7fca6bSBarry Smith .seealso: SNESSetMonitor(), SNESVecViewMonitor(), SNESDefaultMonitor()
2293a7fca6bSBarry Smith @*/
230eabae89aSBarry Smith PetscErrorCode PETSCSNES_DLLEXPORT SNESSetRatioMonitor(SNES snes,PetscViewer viewer)
2313a7fca6bSBarry Smith {
232dfbe8321SBarry Smith   PetscErrorCode          ierr;
233eabae89aSBarry Smith   SNESRatioMonitorContext *ctx;
23487828ca2SBarry Smith   PetscReal               *history;
2353a7fca6bSBarry Smith 
2363a7fca6bSBarry Smith   PetscFunctionBegin;
237eabae89aSBarry Smith   if (!viewer) {
238eabae89aSBarry Smith     viewer = PETSC_VIEWER_STDOUT_(snes->comm);
239eabae89aSBarry Smith     ierr   = PetscObjectReference((PetscObject)viewer);CHKERRQ(ierr);
240eabae89aSBarry Smith   }
241eabae89aSBarry Smith   ierr = PetscNew(SNESRatioMonitorContext,&ctx);
2423a7fca6bSBarry Smith   ierr = SNESGetConvergenceHistory(snes,&history,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr);
2433a7fca6bSBarry Smith   if (!history) {
244eabae89aSBarry Smith     ierr = PetscMalloc(100*sizeof(PetscReal),&ctx->history);CHKERRQ(ierr);
245eabae89aSBarry Smith     ierr = SNESSetConvergenceHistory(snes,ctx->history,0,100,PETSC_TRUE);CHKERRQ(ierr);
2463a7fca6bSBarry Smith   }
247eabae89aSBarry Smith   ctx->viewer = viewer;
248eabae89aSBarry Smith   ierr = SNESSetMonitor(snes,SNESRatioMonitor,ctx,SNESRatioMonitorDestroy);CHKERRQ(ierr);
2493a7fca6bSBarry Smith   PetscFunctionReturn(0);
2503a7fca6bSBarry Smith }
2513a7fca6bSBarry Smith 
252e7e93795SLois Curfman McInnes /* ---------------------------------------------------------------- */
2534a2ae208SSatish Balay #undef __FUNCT__
2544a2ae208SSatish Balay #define __FUNCT__ "SNESDefaultSMonitor"
255be1f7002SBarry Smith /*
256be1f7002SBarry Smith      Default (short) SNES Monitor, same as SNESDefaultMonitor() except
257be1f7002SBarry Smith   it prints fewer digits of the residual as the residual gets smaller.
258be1f7002SBarry Smith   This is because the later digits are meaningless and are often
259be1f7002SBarry Smith   different on different machines; by using this routine different
260be1f7002SBarry Smith   machines will usually generate the same output.
261be1f7002SBarry Smith */
26263dd3a1aSKris Buschelman PetscErrorCode PETSCSNES_DLLEXPORT SNESDefaultSMonitor(SNES snes,PetscInt its,PetscReal fgnorm,void *dummy)
263e7e93795SLois Curfman McInnes {
264dfbe8321SBarry Smith   PetscErrorCode ierr;
265eabae89aSBarry Smith   PetscViewer    viewer = (PetscViewer) dummy;
266d132466eSBarry Smith 
2673a40ed3dSBarry Smith   PetscFunctionBegin;
268eabae89aSBarry Smith   if (!viewer) viewer = PETSC_VIEWER_STDOUT_(snes->comm);
2698f240d10SBarry Smith   if (fgnorm > 1.e-9) {
270a83599f4SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"%3D SNES Function norm %G \n",its,fgnorm);CHKERRQ(ierr);
2713a40ed3dSBarry Smith   } else if (fgnorm > 1.e-11){
272eabae89aSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"%3D SNES Function norm %5.3e \n",its,fgnorm);CHKERRQ(ierr);
2733a40ed3dSBarry Smith   } else {
274eabae89aSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"%3D SNES Function norm < 1.e-11\n",its);CHKERRQ(ierr);
275e7e93795SLois Curfman McInnes   }
2763a40ed3dSBarry Smith   PetscFunctionReturn(0);
277e7e93795SLois Curfman McInnes }
278e7e93795SLois Curfman McInnes /* ---------------------------------------------------------------- */
2794a2ae208SSatish Balay #undef __FUNCT__
2804b27c08aSLois Curfman McInnes #define __FUNCT__ "SNESConverged_LS"
2814b828684SBarry Smith /*@C
2824b27c08aSLois Curfman McInnes    SNESConverged_LS - Monitors the convergence of the solvers for
283f525115eSLois Curfman McInnes    systems of nonlinear equations (default).
284e7e93795SLois Curfman McInnes 
285c7afd0dbSLois Curfman McInnes    Collective on SNES
286c7afd0dbSLois Curfman McInnes 
287e7e93795SLois Curfman McInnes    Input Parameters:
288c7afd0dbSLois Curfman McInnes +  snes - the SNES context
289*06ee9f85SBarry Smith .  it - the iteration (0 indicates before any Newton steps)
290e7e93795SLois Curfman McInnes .  xnorm - 2-norm of current iterate
291e7e93795SLois Curfman McInnes .  pnorm - 2-norm of current step
2927f3332b4SBarry Smith .  fnorm - 2-norm of function at current iterate
293c7afd0dbSLois Curfman McInnes -  dummy - unused context
294e7e93795SLois Curfman McInnes 
295184914b5SBarry Smith    Output Parameter:
296184914b5SBarry Smith .   reason  - one of
29770441072SBarry Smith $  SNES_CONVERGED_FNORM_ABS       - (fnorm < abstol),
2983304466cSBarry Smith $  SNES_CONVERGED_PNORM_RELATIVE  - (pnorm < xtol*xnorm),
299184914b5SBarry Smith $  SNES_CONVERGED_FNORM_RELATIVE  - (fnorm < rtol*fnorm0),
300184914b5SBarry Smith $  SNES_DIVERGED_FUNCTION_COUNT   - (nfct > maxf),
301184914b5SBarry Smith $  SNES_DIVERGED_FNORM_NAN        - (fnorm == NaN),
302184914b5SBarry Smith $  SNES_CONVERGED_ITERATING       - (otherwise),
303e7e93795SLois Curfman McInnes 
304e7e93795SLois Curfman McInnes    where
305c7afd0dbSLois Curfman McInnes +    maxf - maximum number of function evaluations,
306c7afd0dbSLois Curfman McInnes             set with SNESSetTolerances()
307c7afd0dbSLois Curfman McInnes .    nfct - number of function evaluations,
30870441072SBarry Smith .    abstol - absolute function norm tolerance,
309c7afd0dbSLois Curfman McInnes             set with SNESSetTolerances()
310c7afd0dbSLois Curfman McInnes -    rtol - relative function norm tolerance, set with SNESSetTolerances()
311fee21e36SBarry Smith 
31236851e7fSLois Curfman McInnes    Level: intermediate
31336851e7fSLois Curfman McInnes 
314e7e93795SLois Curfman McInnes .keywords: SNES, nonlinear, default, converged, convergence
315e7e93795SLois Curfman McInnes 
316e7e93795SLois Curfman McInnes .seealso: SNESSetConvergenceTest(), SNESEisenstatWalkerConverged()
317e7e93795SLois Curfman McInnes @*/
318*06ee9f85SBarry Smith PetscErrorCode PETSCSNES_DLLEXPORT SNESConverged_LS(SNES snes,PetscInt it,PetscReal xnorm,PetscReal pnorm,PetscReal fnorm,SNESConvergedReason *reason,void *dummy)
319e7e93795SLois Curfman McInnes {
32063ba0a88SBarry Smith   PetscErrorCode ierr;
32163ba0a88SBarry Smith 
3223a40ed3dSBarry Smith   PetscFunctionBegin;
323*06ee9f85SBarry Smith   *reason = SNES_CONVERGED_ITERATING;
324*06ee9f85SBarry Smith 
325*06ee9f85SBarry Smith   if (!it) {
326*06ee9f85SBarry Smith     /* set parameter for default relative tolerance convergence test */
327*06ee9f85SBarry Smith     snes->ttol = fnorm*snes->rtol;
328*06ee9f85SBarry Smith   }
329d252947aSBarry Smith   if (fnorm != fnorm) {
330ae15b995SBarry Smith     ierr = PetscInfo(snes,"Failed to converged, function norm is NaN\n");CHKERRQ(ierr);
331184914b5SBarry Smith     *reason = SNES_DIVERGED_FNORM_NAN;
33270441072SBarry Smith   } else if (fnorm < snes->abstol) {
333ae15b995SBarry Smith     ierr = PetscInfo2(snes,"Converged due to function norm %G < %G\n",fnorm,snes->abstol);CHKERRQ(ierr);
334184914b5SBarry Smith     *reason = SNES_CONVERGED_FNORM_ABS;
33543e71028SBarry Smith   } else if (snes->nfuncs >= snes->max_funcs) {
336ae15b995SBarry Smith     ierr = PetscInfo2(snes,"Exceeded maximum number of function evaluations: %D > %D\n",snes->nfuncs,snes->max_funcs);CHKERRQ(ierr);
337184914b5SBarry Smith     *reason = SNES_DIVERGED_FUNCTION_COUNT;
338*06ee9f85SBarry Smith   }
339*06ee9f85SBarry Smith 
340*06ee9f85SBarry Smith   if (it && !*reason) {
341*06ee9f85SBarry Smith     if (fnorm <= snes->ttol) {
342*06ee9f85SBarry Smith       ierr = PetscInfo2(snes,"Converged due to function norm %G < %G (relative tolerance)\n",fnorm,snes->ttol);CHKERRQ(ierr);
343*06ee9f85SBarry Smith       *reason = SNES_CONVERGED_FNORM_RELATIVE;
344*06ee9f85SBarry Smith     } else if (pnorm < snes->xtol*xnorm) {
345*06ee9f85SBarry Smith       ierr = PetscInfo3(snes,"Converged due to small update length: %G < %G * %G\n",pnorm,snes->xtol,xnorm);CHKERRQ(ierr);
346*06ee9f85SBarry Smith       *reason = SNES_CONVERGED_PNORM_RELATIVE;
347*06ee9f85SBarry Smith     }
348e7e93795SLois Curfman McInnes   }
3493a40ed3dSBarry Smith   PetscFunctionReturn(0);
350e7e93795SLois Curfman McInnes }
351e7e93795SLois Curfman McInnes /* ------------------------------------------------------------ */
3524a2ae208SSatish Balay #undef __FUNCT__
3534a2ae208SSatish Balay #define __FUNCT__ "SNES_KSP_SetConvergenceTestEW"
354e7e93795SLois Curfman McInnes /*@
355f525115eSLois Curfman McInnes    SNES_KSP_SetConvergenceTestEW - Sets alternative convergence test
356e7e93795SLois Curfman McInnes    for the linear solvers within an inexact Newton method.
357e7e93795SLois Curfman McInnes 
358c7afd0dbSLois Curfman McInnes    Collective on SNES
359c7afd0dbSLois Curfman McInnes 
360e7e93795SLois Curfman McInnes    Input Parameter:
361e7e93795SLois Curfman McInnes .  snes - SNES context
362e7e93795SLois Curfman McInnes 
363e7e93795SLois Curfman McInnes    Notes:
364e7e93795SLois Curfman McInnes    Currently, the default is to use a constant relative tolerance for
365e7e93795SLois Curfman McInnes    the inner linear solvers.  Alternatively, one can use the
366e7e93795SLois Curfman McInnes    Eisenstat-Walker method, where the relative convergence tolerance
367e7e93795SLois Curfman McInnes    is reset at each Newton iteration according progress of the nonlinear
368e7e93795SLois Curfman McInnes    solver.
369e7e93795SLois Curfman McInnes 
37036851e7fSLois Curfman McInnes    Level: advanced
37136851e7fSLois Curfman McInnes 
372e7e93795SLois Curfman McInnes    Reference:
373e7e93795SLois Curfman McInnes    S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an
374e30ad881SLois Curfman McInnes    inexact Newton method", SISC 17 (1), pp.16-32, 1996.
375e7e93795SLois Curfman McInnes 
376e7e93795SLois Curfman McInnes .keywords: SNES, KSP, Eisenstat, Walker, convergence, test, inexact, Newton
377e7e93795SLois Curfman McInnes @*/
37863dd3a1aSKris Buschelman PetscErrorCode PETSCSNES_DLLEXPORT SNES_KSP_SetConvergenceTestEW(SNES snes)
379e7e93795SLois Curfman McInnes {
3803a40ed3dSBarry Smith   PetscFunctionBegin;
381186905e3SBarry Smith   snes->ksp_ewconv = PETSC_TRUE;
3823a40ed3dSBarry Smith   PetscFunctionReturn(0);
383e7e93795SLois Curfman McInnes }
384e7e93795SLois Curfman McInnes 
3854a2ae208SSatish Balay #undef __FUNCT__
3864a2ae208SSatish Balay #define __FUNCT__ "SNES_KSP_SetParametersEW"
387e7e93795SLois Curfman McInnes /*@
388e7e93795SLois Curfman McInnes    SNES_KSP_SetParametersEW - Sets parameters for Eisenstat-Walker
389e7e93795SLois Curfman McInnes    convergence criteria for the linear solvers within an inexact
390e7e93795SLois Curfman McInnes    Newton method.
391e7e93795SLois Curfman McInnes 
392c7afd0dbSLois Curfman McInnes    Collective on SNES
393c7afd0dbSLois Curfman McInnes 
394e7e93795SLois Curfman McInnes    Input Parameters:
395c7afd0dbSLois Curfman McInnes +    snes - SNES context
396cf502942SBarry Smith .    version - version 1, 2 (default is 2) or 3
397c7afd0dbSLois Curfman McInnes .    rtol_0 - initial relative tolerance (0 <= rtol_0 < 1)
398c7afd0dbSLois Curfman McInnes .    rtol_max - maximum relative tolerance (0 <= rtol_max < 1)
399c7afd0dbSLois Curfman McInnes .    alpha - power for version 2 rtol computation (1 < alpha <= 2)
400e7e93795SLois Curfman McInnes .    alpha2 - power for safeguard
401e7e93795SLois Curfman McInnes .    gamma2 - multiplicative factor for version 2 rtol computation
402c7afd0dbSLois Curfman McInnes               (0 <= gamma2 <= 1)
403c7afd0dbSLois Curfman McInnes -    threshold - threshold for imposing safeguard (0 < threshold < 1)
404fee21e36SBarry Smith 
405e7e93795SLois Curfman McInnes    Note:
406cf502942SBarry Smith    Version 3 was contributed by .....
407cf502942SBarry Smith 
408e7e93795SLois Curfman McInnes    Use PETSC_DEFAULT to retain the default for any of the parameters.
409e7e93795SLois Curfman McInnes 
41036851e7fSLois Curfman McInnes    Level: advanced
41136851e7fSLois Curfman McInnes 
412e7e93795SLois Curfman McInnes    Reference:
413e7e93795SLois Curfman McInnes    S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an
414e7e93795SLois Curfman McInnes    inexact Newton method", Utah State University Math. Stat. Dept. Res.
415e7e93795SLois Curfman McInnes    Report 6/94/75, June, 1994, to appear in SIAM J. Sci. Comput.
416e7e93795SLois Curfman McInnes 
417e7e93795SLois Curfman McInnes .keywords: SNES, KSP, Eisenstat, Walker, set, parameters
418e7e93795SLois Curfman McInnes 
419e7e93795SLois Curfman McInnes .seealso: SNES_KSP_SetConvergenceTestEW()
420e7e93795SLois Curfman McInnes @*/
42163dd3a1aSKris Buschelman PetscErrorCode PETSCSNES_DLLEXPORT SNES_KSP_SetParametersEW(SNES snes,PetscInt version,PetscReal rtol_0,PetscReal rtol_max,PetscReal gamma2,PetscReal alpha,
422329f5518SBarry Smith                                         PetscReal alpha2,PetscReal threshold)
423e7e93795SLois Curfman McInnes {
424e7e93795SLois Curfman McInnes   SNES_KSP_EW_ConvCtx *kctx = (SNES_KSP_EW_ConvCtx*)snes->kspconvctx;
4253a40ed3dSBarry Smith 
4263a40ed3dSBarry Smith   PetscFunctionBegin;
42729bbc08cSBarry Smith   if (!kctx) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context existing");
428e7e93795SLois Curfman McInnes   if (version != PETSC_DEFAULT)   kctx->version   = version;
429e7e93795SLois Curfman McInnes   if (rtol_0 != PETSC_DEFAULT)    kctx->rtol_0    = rtol_0;
430e7e93795SLois Curfman McInnes   if (rtol_max != PETSC_DEFAULT)  kctx->rtol_max  = rtol_max;
431e7e93795SLois Curfman McInnes   if (gamma2 != PETSC_DEFAULT)    kctx->gamma     = gamma2;
432e7e93795SLois Curfman McInnes   if (alpha != PETSC_DEFAULT)     kctx->alpha     = alpha;
433e7e93795SLois Curfman McInnes   if (alpha2 != PETSC_DEFAULT)    kctx->alpha2    = alpha2;
434e7e93795SLois Curfman McInnes   if (threshold != PETSC_DEFAULT) kctx->threshold = threshold;
435a8c6a408SBarry Smith   if (kctx->rtol_0 < 0.0 || kctx->rtol_0 >= 1.0) {
436a83599f4SBarry Smith     SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"0.0 <= rtol_0 < 1.0: %G",kctx->rtol_0);
437a8c6a408SBarry Smith   }
438a8c6a408SBarry Smith   if (kctx->rtol_max < 0.0 || kctx->rtol_max >= 1.0) {
439a83599f4SBarry Smith     SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"0.0 <= rtol_max (%G) < 1.0\n",kctx->rtol_max);
440a8c6a408SBarry Smith   }
441a8c6a408SBarry Smith   if (kctx->threshold <= 0.0 || kctx->threshold >= 1.0) {
442a83599f4SBarry Smith     SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"0.0 < threshold (%G) < 1.0\n",kctx->threshold);
443a8c6a408SBarry Smith   }
444a8c6a408SBarry Smith   if (kctx->gamma < 0.0 || kctx->gamma > 1.0) {
445a83599f4SBarry Smith     SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"0.0 <= gamma (%G) <= 1.0\n",kctx->gamma);
446a8c6a408SBarry Smith   }
447a8c6a408SBarry Smith   if (kctx->alpha <= 1.0 || kctx->alpha > 2.0) {
448a83599f4SBarry Smith     SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"1.0 < alpha (%G) <= 2.0\n",kctx->alpha);
449a8c6a408SBarry Smith   }
450a8c6a408SBarry Smith   if (kctx->version != 1 && kctx->version !=2) {
45177431f27SBarry Smith     SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Only versions 1 and 2 are supported: %D",kctx->version);
452a8c6a408SBarry Smith   }
4533a40ed3dSBarry Smith   PetscFunctionReturn(0);
454e7e93795SLois Curfman McInnes }
455e7e93795SLois Curfman McInnes 
4564a2ae208SSatish Balay #undef __FUNCT__
4574a2ae208SSatish Balay #define __FUNCT__ "SNES_KSP_EW_ComputeRelativeTolerance_Private"
458dfbe8321SBarry Smith PetscErrorCode SNES_KSP_EW_ComputeRelativeTolerance_Private(SNES snes,KSP ksp)
459e7e93795SLois Curfman McInnes {
460e7e93795SLois Curfman McInnes   SNES_KSP_EW_ConvCtx *kctx = (SNES_KSP_EW_ConvCtx*)snes->kspconvctx;
461329f5518SBarry Smith   PetscReal           rtol = 0.0,stol;
462dfbe8321SBarry Smith   PetscErrorCode      ierr;
4633a40ed3dSBarry Smith 
4643a40ed3dSBarry Smith   PetscFunctionBegin;
46529bbc08cSBarry Smith   if (!kctx) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context exists");
466c38d4ed2SBarry Smith   if (!snes->iter) { /* first time in, so use the original user rtol */
467e7e93795SLois Curfman McInnes     rtol = kctx->rtol_0;
468e7e93795SLois Curfman McInnes   } else {
469e7e93795SLois Curfman McInnes     if (kctx->version == 1) {
470e7e93795SLois Curfman McInnes       rtol = (snes->norm - kctx->lresid_last)/kctx->norm_last;
471e7e93795SLois Curfman McInnes       if (rtol < 0.0) rtol = -rtol;
472e7e93795SLois Curfman McInnes       stol = pow(kctx->rtol_last,kctx->alpha2);
4730452661fSBarry Smith       if (stol > kctx->threshold) rtol = PetscMax(rtol,stol);
474e7e93795SLois Curfman McInnes     } else if (kctx->version == 2) {
475e7e93795SLois Curfman McInnes       rtol = kctx->gamma * pow(snes->norm/kctx->norm_last,kctx->alpha);
476e7e93795SLois Curfman McInnes       stol = kctx->gamma * pow(kctx->rtol_last,kctx->alpha);
4770452661fSBarry Smith       if (stol > kctx->threshold) rtol = PetscMax(rtol,stol);
478cf502942SBarry Smith     } else if (kctx->version == 3) {
479cf502942SBarry Smith       rtol = kctx->gamma * pow(snes->norm/kctx->norm_last,kctx->alpha);
480cf502942SBarry Smith       /* safeguard: avoid sharp decrease of rtol */
481cf502942SBarry Smith       rtol = PetscMin(kctx->rtol_0,PetscMax(rtol,kctx->gamma*pow(kctx->rtol_last,kctx->alpha)));
482cf502942SBarry Smith       /* safeguard: avoid oversolving */
483cf502942SBarry Smith       rtol = PetscMin(kctx->rtol_0,PetscMax(rtol,kctx->gamma*(snes->ttol)/snes->norm));
484cf502942SBarry Smith 
485cf502942SBarry Smith     } else SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Only versions 1, 2 or 3 are supported: %D",kctx->version);
486e7e93795SLois Curfman McInnes   }
4870452661fSBarry Smith   rtol = PetscMin(rtol,kctx->rtol_max);
488e7e93795SLois Curfman McInnes   kctx->rtol_last = rtol;
489ae15b995SBarry Smith   ierr = PetscInfo3(snes,"iter %D, Eisenstat-Walker (version %D) KSP rtol = %G\n",snes->iter,kctx->version,rtol);CHKERRQ(ierr);
4903131a8b6SLois Curfman McInnes   ierr = KSPSetTolerances(ksp,rtol,PETSC_DEFAULT,PETSC_DEFAULT,PETSC_DEFAULT);CHKERRQ(ierr);
491e7e93795SLois Curfman McInnes   kctx->norm_last = snes->norm;
4923a40ed3dSBarry Smith   PetscFunctionReturn(0);
493e7e93795SLois Curfman McInnes }
494e7e93795SLois Curfman McInnes 
4954a2ae208SSatish Balay #undef __FUNCT__
4964a2ae208SSatish Balay #define __FUNCT__ "SNES_KSP_EW_Converged_Private"
497a7cc72afSBarry Smith PetscErrorCode SNES_KSP_EW_Converged_Private(KSP ksp,PetscInt n,PetscReal rnorm,KSPConvergedReason *reason,void *ctx)
498e7e93795SLois Curfman McInnes {
499e7e93795SLois Curfman McInnes   SNES                snes = (SNES)ctx;
500e7e93795SLois Curfman McInnes   SNES_KSP_EW_ConvCtx *kctx = (SNES_KSP_EW_ConvCtx*)snes->kspconvctx;
501dfbe8321SBarry Smith   PetscErrorCode      ierr;
502e7e93795SLois Curfman McInnes 
5033a40ed3dSBarry Smith   PetscFunctionBegin;
50429bbc08cSBarry Smith   if (!kctx) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context set");
505958c9bccSBarry Smith   if (!n) {ierr = SNES_KSP_EW_ComputeRelativeTolerance_Private(snes,ksp);CHKERRQ(ierr);}
506211a6b7eSSatish Balay   ierr = KSPDefaultConverged(ksp,n,rnorm,reason,ctx);CHKERRQ(ierr);
507e7e93795SLois Curfman McInnes   kctx->lresid_last = rnorm;
508211a6b7eSSatish Balay   if (*reason) {
509ae15b995SBarry Smith     ierr = PetscInfo2(snes,"KSP iterations=%D, rnorm=%G\n",n,rnorm);CHKERRQ(ierr);
5103a40ed3dSBarry Smith   }
511211a6b7eSSatish Balay   PetscFunctionReturn(0);
512e7e93795SLois Curfman McInnes }
513e7e93795SLois Curfman McInnes 
514e7e93795SLois Curfman McInnes 
515