xref: /petsc/src/snes/interface/snesut.c (revision b9147fbb7375951b83d4ce6f264c883d157e3a5b)
163dd3a1aSKris Buschelman #define PETSCSNES_DLL
2e7e93795SLois Curfman McInnes 
3*b9147fbbSdalcinl #include "include/private/snesimpl.h"       /*I   "petscsnes.h"   I*/
4e7e93795SLois Curfman McInnes 
54a2ae208SSatish Balay #undef __FUNCT__
6a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorSolution"
73f1db9ecSBarry Smith /*@C
8a6570f20SBarry Smith    SNESMonitorSolution - Monitors progress of the SNES solvers by calling
936851e7fSLois Curfman McInnes    VecView() for the approximate solution at each iteration.
103f1db9ecSBarry Smith 
113f1db9ecSBarry Smith    Collective on SNES
123f1db9ecSBarry Smith 
133f1db9ecSBarry Smith    Input Parameters:
143f1db9ecSBarry Smith +  snes - the SNES context
153f1db9ecSBarry Smith .  its - iteration number
164b27c08aSLois Curfman McInnes .  fgnorm - 2-norm of residual
173f1db9ecSBarry Smith -  dummy - either a viewer or PETSC_NULL
183f1db9ecSBarry Smith 
1936851e7fSLois Curfman McInnes    Level: intermediate
203f1db9ecSBarry Smith 
2136851e7fSLois Curfman McInnes .keywords: SNES, nonlinear, vector, monitor, view
223f1db9ecSBarry Smith 
23a6570f20SBarry Smith .seealso: SNESMonitorSet(), SNESMonitorDefault(), VecView()
243f1db9ecSBarry Smith @*/
25a6570f20SBarry Smith PetscErrorCode PETSCSNES_DLLEXPORT SNESMonitorSolution(SNES snes,PetscInt its,PetscReal fgnorm,void *dummy)
263f1db9ecSBarry Smith {
27dfbe8321SBarry Smith   PetscErrorCode ierr;
283f1db9ecSBarry Smith   Vec            x;
29b0a32e0cSBarry Smith   PetscViewer    viewer = (PetscViewer) dummy;
303f1db9ecSBarry Smith 
313f1db9ecSBarry Smith   PetscFunctionBegin;
323f1db9ecSBarry Smith   ierr = SNESGetSolution(snes,&x);CHKERRQ(ierr);
333f1db9ecSBarry Smith   if (!viewer) {
343f1db9ecSBarry Smith     MPI_Comm comm;
353f1db9ecSBarry Smith     ierr   = PetscObjectGetComm((PetscObject)snes,&comm);CHKERRQ(ierr);
36b0a32e0cSBarry Smith     viewer = PETSC_VIEWER_DRAW_(comm);
373f1db9ecSBarry Smith   }
383f1db9ecSBarry Smith   ierr = VecView(x,viewer);CHKERRQ(ierr);
393f1db9ecSBarry Smith 
403f1db9ecSBarry Smith   PetscFunctionReturn(0);
413f1db9ecSBarry Smith }
423f1db9ecSBarry Smith 
434a2ae208SSatish Balay #undef __FUNCT__
44a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorResidual"
455ed2d596SBarry Smith /*@C
46a6570f20SBarry Smith    SNESMonitorResidual - Monitors progress of the SNES solvers by calling
475ed2d596SBarry Smith    VecView() for the residual at each iteration.
485ed2d596SBarry Smith 
495ed2d596SBarry Smith    Collective on SNES
505ed2d596SBarry Smith 
515ed2d596SBarry Smith    Input Parameters:
525ed2d596SBarry Smith +  snes - the SNES context
535ed2d596SBarry Smith .  its - iteration number
544b27c08aSLois Curfman McInnes .  fgnorm - 2-norm of residual
555ed2d596SBarry Smith -  dummy - either a viewer or PETSC_NULL
565ed2d596SBarry Smith 
575ed2d596SBarry Smith    Level: intermediate
585ed2d596SBarry Smith 
595ed2d596SBarry Smith .keywords: SNES, nonlinear, vector, monitor, view
605ed2d596SBarry Smith 
61a6570f20SBarry Smith .seealso: SNESMonitorSet(), SNESMonitorDefault(), VecView()
625ed2d596SBarry Smith @*/
63a6570f20SBarry Smith PetscErrorCode PETSCSNES_DLLEXPORT SNESMonitorResidual(SNES snes,PetscInt its,PetscReal fgnorm,void *dummy)
645ed2d596SBarry Smith {
65dfbe8321SBarry Smith   PetscErrorCode ierr;
665ed2d596SBarry Smith   Vec            x;
675ed2d596SBarry Smith   PetscViewer    viewer = (PetscViewer) dummy;
685ed2d596SBarry Smith 
695ed2d596SBarry Smith   PetscFunctionBegin;
705ed2d596SBarry Smith   ierr = SNESGetFunction(snes,&x,0,0);CHKERRQ(ierr);
715ed2d596SBarry Smith   if (!viewer) {
725ed2d596SBarry Smith     MPI_Comm comm;
735ed2d596SBarry Smith     ierr   = PetscObjectGetComm((PetscObject)snes,&comm);CHKERRQ(ierr);
745ed2d596SBarry Smith     viewer = PETSC_VIEWER_DRAW_(comm);
755ed2d596SBarry Smith   }
765ed2d596SBarry Smith   ierr = VecView(x,viewer);CHKERRQ(ierr);
775ed2d596SBarry Smith 
785ed2d596SBarry Smith   PetscFunctionReturn(0);
795ed2d596SBarry Smith }
805ed2d596SBarry Smith 
815ed2d596SBarry Smith #undef __FUNCT__
82a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorSolutionUpdate"
83d132466eSBarry Smith /*@C
84a6570f20SBarry Smith    SNESMonitorSolutionUpdate - Monitors progress of the SNES solvers by calling
85d132466eSBarry Smith    VecView() for the UPDATE to the solution at each iteration.
86d132466eSBarry Smith 
87d132466eSBarry Smith    Collective on SNES
88d132466eSBarry Smith 
89d132466eSBarry Smith    Input Parameters:
90d132466eSBarry Smith +  snes - the SNES context
91d132466eSBarry Smith .  its - iteration number
924b27c08aSLois Curfman McInnes .  fgnorm - 2-norm of residual
93d132466eSBarry Smith -  dummy - either a viewer or PETSC_NULL
94d132466eSBarry Smith 
95d132466eSBarry Smith    Level: intermediate
96d132466eSBarry Smith 
97d132466eSBarry Smith .keywords: SNES, nonlinear, vector, monitor, view
98d132466eSBarry Smith 
99a6570f20SBarry Smith .seealso: SNESMonitorSet(), SNESMonitorDefault(), VecView()
100d132466eSBarry Smith @*/
101a6570f20SBarry Smith PetscErrorCode PETSCSNES_DLLEXPORT SNESMonitorSolutionUpdate(SNES snes,PetscInt its,PetscReal fgnorm,void *dummy)
102d132466eSBarry Smith {
103dfbe8321SBarry Smith   PetscErrorCode ierr;
104d132466eSBarry Smith   Vec            x;
105b0a32e0cSBarry Smith   PetscViewer    viewer = (PetscViewer) dummy;
106d132466eSBarry Smith 
107d132466eSBarry Smith   PetscFunctionBegin;
108d132466eSBarry Smith   ierr = SNESGetSolutionUpdate(snes,&x);CHKERRQ(ierr);
109d132466eSBarry Smith   if (!viewer) {
110d132466eSBarry Smith     MPI_Comm comm;
111d132466eSBarry Smith     ierr   = PetscObjectGetComm((PetscObject)snes,&comm);CHKERRQ(ierr);
112b0a32e0cSBarry Smith     viewer = PETSC_VIEWER_DRAW_(comm);
113d132466eSBarry Smith   }
114d132466eSBarry Smith   ierr = VecView(x,viewer);CHKERRQ(ierr);
115d132466eSBarry Smith 
116d132466eSBarry Smith   PetscFunctionReturn(0);
117d132466eSBarry Smith }
118d132466eSBarry Smith 
1194a2ae208SSatish Balay #undef __FUNCT__
120a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorDefault"
1214b828684SBarry Smith /*@C
122a6570f20SBarry Smith    SNESMonitorDefault - Monitors progress of the SNES solvers (default).
123e7e93795SLois Curfman McInnes 
124c7afd0dbSLois Curfman McInnes    Collective on SNES
125c7afd0dbSLois Curfman McInnes 
126e7e93795SLois Curfman McInnes    Input Parameters:
127c7afd0dbSLois Curfman McInnes +  snes - the SNES context
128e7e93795SLois Curfman McInnes .  its - iteration number
1294b27c08aSLois Curfman McInnes .  fgnorm - 2-norm of residual
130c7afd0dbSLois Curfman McInnes -  dummy - unused context
131fee21e36SBarry Smith 
132e7e93795SLois Curfman McInnes    Notes:
1334b27c08aSLois Curfman McInnes    This routine prints the residual norm at each iteration.
134e7e93795SLois Curfman McInnes 
13536851e7fSLois Curfman McInnes    Level: intermediate
13636851e7fSLois Curfman McInnes 
137e7e93795SLois Curfman McInnes .keywords: SNES, nonlinear, default, monitor, norm
138e7e93795SLois Curfman McInnes 
139a6570f20SBarry Smith .seealso: SNESMonitorSet(), SNESMonitorSolution()
140e7e93795SLois Curfman McInnes @*/
141a6570f20SBarry Smith PetscErrorCode PETSCSNES_DLLEXPORT SNESMonitorDefault(SNES snes,PetscInt its,PetscReal fgnorm,void *dummy)
142e7e93795SLois Curfman McInnes {
143dfbe8321SBarry Smith   PetscErrorCode          ierr;
144a34d58ebSBarry Smith   PetscViewerASCIIMonitor viewer = (PetscViewerASCIIMonitor) dummy;
145d132466eSBarry Smith 
1463a40ed3dSBarry Smith   PetscFunctionBegin;
147a34d58ebSBarry Smith   if (!dummy) {
148a34d58ebSBarry Smith     ierr = PetscViewerASCIIMonitorCreate(snes->comm,"stdout",0,&viewer);CHKERRQ(ierr);
149a34d58ebSBarry Smith   }
150a34d58ebSBarry Smith   ierr = PetscViewerASCIIMonitorPrintf(viewer,"%3D SNES Function norm %14.12e \n",its,fgnorm);CHKERRQ(ierr);
151a34d58ebSBarry Smith   if (!dummy) {
152a34d58ebSBarry Smith     ierr = PetscViewerASCIIMonitorDestroy(viewer);CHKERRQ(ierr);
153a34d58ebSBarry Smith   }
1543a40ed3dSBarry Smith   PetscFunctionReturn(0);
155e7e93795SLois Curfman McInnes }
1563f1db9ecSBarry Smith 
157eabae89aSBarry Smith typedef struct {
158a34d58ebSBarry Smith   PetscViewerASCIIMonitor viewer;
159eabae89aSBarry Smith   PetscReal               *history;
160a6570f20SBarry Smith } SNESMonitorRatioContext;
161eabae89aSBarry Smith 
1623a7fca6bSBarry Smith #undef __FUNCT__
163a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorRatio"
1643a7fca6bSBarry Smith /*@C
165a6570f20SBarry Smith    SNESMonitorRatio - Monitors progress of the SNES solvers by printing the ratio
1664b27c08aSLois Curfman McInnes    of residual norm at each iteration to the previous.
1673a7fca6bSBarry Smith 
1683a7fca6bSBarry Smith    Collective on SNES
1693a7fca6bSBarry Smith 
1703a7fca6bSBarry Smith    Input Parameters:
1713a7fca6bSBarry Smith +  snes - the SNES context
1723a7fca6bSBarry Smith .  its - iteration number
1733a7fca6bSBarry Smith .  fgnorm - 2-norm of residual (or gradient)
174eabae89aSBarry Smith -  dummy -  context of monitor
1753a7fca6bSBarry Smith 
1763a7fca6bSBarry Smith    Level: intermediate
1773a7fca6bSBarry Smith 
1783a7fca6bSBarry Smith .keywords: SNES, nonlinear, monitor, norm
1793a7fca6bSBarry Smith 
180a6570f20SBarry Smith .seealso: SNESMonitorSet(), SNESMonitorSolution()
1813a7fca6bSBarry Smith @*/
182a6570f20SBarry Smith PetscErrorCode PETSCSNES_DLLEXPORT SNESMonitorRatio(SNES snes,PetscInt its,PetscReal fgnorm,void *dummy)
1833a7fca6bSBarry Smith {
184dfbe8321SBarry Smith   PetscErrorCode          ierr;
18577431f27SBarry Smith   PetscInt                len;
18687828ca2SBarry Smith   PetscReal               *history;
187a6570f20SBarry Smith   SNESMonitorRatioContext *ctx = (SNESMonitorRatioContext*)dummy;
1883a7fca6bSBarry Smith 
1893a7fca6bSBarry Smith   PetscFunctionBegin;
1903a7fca6bSBarry Smith   ierr = SNESGetConvergenceHistory(snes,&history,PETSC_NULL,&len);CHKERRQ(ierr);
191958c9bccSBarry Smith   if (!its || !history || its > len) {
192a34d58ebSBarry Smith     ierr = PetscViewerASCIIMonitorPrintf(ctx->viewer,"%3D SNES Function norm %14.12e \n",its,fgnorm);CHKERRQ(ierr);
1933a7fca6bSBarry Smith   } else {
19487828ca2SBarry Smith     PetscReal ratio = fgnorm/history[its-1];
195a34d58ebSBarry Smith     ierr = PetscViewerASCIIMonitorPrintf(ctx->viewer,"%3D SNES Function norm %14.12e %G \n",its,fgnorm,ratio);CHKERRQ(ierr);
1963a7fca6bSBarry Smith   }
1973a7fca6bSBarry Smith   PetscFunctionReturn(0);
1983a7fca6bSBarry Smith }
1993a7fca6bSBarry Smith 
2003a7fca6bSBarry Smith /*
2013a7fca6bSBarry Smith    If the we set the history monitor space then we must destroy it
2023a7fca6bSBarry Smith */
2033a7fca6bSBarry Smith #undef __FUNCT__
204a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorRatioDestroy"
205a6570f20SBarry Smith PetscErrorCode SNESMonitorRatioDestroy(void *ct)
2063a7fca6bSBarry Smith {
207dfbe8321SBarry Smith   PetscErrorCode          ierr;
208a6570f20SBarry Smith   SNESMonitorRatioContext *ctx = (SNESMonitorRatioContext*)ct;
2093a7fca6bSBarry Smith 
2103a7fca6bSBarry Smith   PetscFunctionBegin;
21105b42c5fSBarry Smith   ierr = PetscFree(ctx->history);CHKERRQ(ierr);
212a34d58ebSBarry Smith   ierr = PetscViewerASCIIMonitorDestroy(ctx->viewer);CHKERRQ(ierr);
213eabae89aSBarry Smith   ierr = PetscFree(ctx);CHKERRQ(ierr);
2143a7fca6bSBarry Smith   PetscFunctionReturn(0);
2153a7fca6bSBarry Smith }
2163a7fca6bSBarry Smith 
2173a7fca6bSBarry Smith #undef __FUNCT__
218a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorSetRatio"
2193a7fca6bSBarry Smith /*@C
220a6570f20SBarry Smith    SNESMonitorSetRatio - Sets SNES to use a monitor that prints the
2214b27c08aSLois Curfman McInnes    ratio of the function norm at each iteration.
2223a7fca6bSBarry Smith 
2233a7fca6bSBarry Smith    Collective on SNES
2243a7fca6bSBarry Smith 
2253a7fca6bSBarry Smith    Input Parameters:
226eabae89aSBarry Smith +   snes - the SNES context
227eabae89aSBarry Smith -   viewer - ASCII viewer to print output
2283a7fca6bSBarry Smith 
2293a7fca6bSBarry Smith    Level: intermediate
2303a7fca6bSBarry Smith 
2313a7fca6bSBarry Smith .keywords: SNES, nonlinear, monitor, norm
2323a7fca6bSBarry Smith 
233a6570f20SBarry Smith .seealso: SNESMonitorSet(), SNESMonitorSolution(), SNESMonitorDefault()
2343a7fca6bSBarry Smith @*/
235a34d58ebSBarry Smith PetscErrorCode PETSCSNES_DLLEXPORT SNESMonitorSetRatio(SNES snes,PetscViewerASCIIMonitor viewer)
2363a7fca6bSBarry Smith {
237dfbe8321SBarry Smith   PetscErrorCode          ierr;
238a6570f20SBarry Smith   SNESMonitorRatioContext *ctx;
23987828ca2SBarry Smith   PetscReal               *history;
2403a7fca6bSBarry Smith 
2413a7fca6bSBarry Smith   PetscFunctionBegin;
242eabae89aSBarry Smith   if (!viewer) {
243a34d58ebSBarry Smith     ierr = PetscViewerASCIIMonitorCreate(snes->comm,"stdout",0,&viewer);CHKERRQ(ierr);
244eabae89aSBarry Smith     ierr   = PetscObjectReference((PetscObject)viewer);CHKERRQ(ierr);
245eabae89aSBarry Smith   }
246a6570f20SBarry Smith   ierr = PetscNew(SNESMonitorRatioContext,&ctx);
2473a7fca6bSBarry Smith   ierr = SNESGetConvergenceHistory(snes,&history,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr);
2483a7fca6bSBarry Smith   if (!history) {
249eabae89aSBarry Smith     ierr = PetscMalloc(100*sizeof(PetscReal),&ctx->history);CHKERRQ(ierr);
250eabae89aSBarry Smith     ierr = SNESSetConvergenceHistory(snes,ctx->history,0,100,PETSC_TRUE);CHKERRQ(ierr);
2513a7fca6bSBarry Smith   }
252eabae89aSBarry Smith   ctx->viewer = viewer;
253a6570f20SBarry Smith   ierr = SNESMonitorSet(snes,SNESMonitorRatio,ctx,SNESMonitorRatioDestroy);CHKERRQ(ierr);
2543a7fca6bSBarry Smith   PetscFunctionReturn(0);
2553a7fca6bSBarry Smith }
2563a7fca6bSBarry Smith 
257e7e93795SLois Curfman McInnes /* ---------------------------------------------------------------- */
2584a2ae208SSatish Balay #undef __FUNCT__
259a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorDefaultShort"
260be1f7002SBarry Smith /*
261a6570f20SBarry Smith      Default (short) SNES Monitor, same as SNESMonitorDefault() except
262be1f7002SBarry Smith   it prints fewer digits of the residual as the residual gets smaller.
263be1f7002SBarry Smith   This is because the later digits are meaningless and are often
264be1f7002SBarry Smith   different on different machines; by using this routine different
265be1f7002SBarry Smith   machines will usually generate the same output.
266be1f7002SBarry Smith */
267a6570f20SBarry Smith PetscErrorCode PETSCSNES_DLLEXPORT SNESMonitorDefaultShort(SNES snes,PetscInt its,PetscReal fgnorm,void *dummy)
268e7e93795SLois Curfman McInnes {
269dfbe8321SBarry Smith   PetscErrorCode          ierr;
270a34d58ebSBarry Smith   PetscViewerASCIIMonitor viewer = (PetscViewerASCIIMonitor) dummy;
271d132466eSBarry Smith 
2723a40ed3dSBarry Smith   PetscFunctionBegin;
273a34d58ebSBarry Smith   if (!dummy) {
274a34d58ebSBarry Smith     ierr = PetscViewerASCIIMonitorCreate(snes->comm,"stdout",0,&viewer);CHKERRQ(ierr);
275a34d58ebSBarry Smith   }
2768f240d10SBarry Smith   if (fgnorm > 1.e-9) {
277a34d58ebSBarry Smith     ierr = PetscViewerASCIIMonitorPrintf(viewer,"%3D SNES Function norm %G \n",its,fgnorm);CHKERRQ(ierr);
2783a40ed3dSBarry Smith   } else if (fgnorm > 1.e-11){
279a34d58ebSBarry Smith     ierr = PetscViewerASCIIMonitorPrintf(viewer,"%3D SNES Function norm %5.3e \n",its,fgnorm);CHKERRQ(ierr);
2803a40ed3dSBarry Smith   } else {
281a34d58ebSBarry Smith     ierr = PetscViewerASCIIMonitorPrintf(viewer,"%3D SNES Function norm < 1.e-11\n",its);CHKERRQ(ierr);
282a34d58ebSBarry Smith   }
283a34d58ebSBarry Smith   if (!dummy) {
284a34d58ebSBarry Smith     ierr = PetscViewerASCIIMonitorDestroy(viewer);CHKERRQ(ierr);
285e7e93795SLois Curfman McInnes   }
2863a40ed3dSBarry Smith   PetscFunctionReturn(0);
287e7e93795SLois Curfman McInnes }
288e7e93795SLois Curfman McInnes /* ---------------------------------------------------------------- */
2894a2ae208SSatish Balay #undef __FUNCT__
2904b27c08aSLois Curfman McInnes #define __FUNCT__ "SNESConverged_LS"
2914b828684SBarry Smith /*@C
2924b27c08aSLois Curfman McInnes    SNESConverged_LS - Monitors the convergence of the solvers for
293f525115eSLois Curfman McInnes    systems of nonlinear equations (default).
294e7e93795SLois Curfman McInnes 
295c7afd0dbSLois Curfman McInnes    Collective on SNES
296c7afd0dbSLois Curfman McInnes 
297e7e93795SLois Curfman McInnes    Input Parameters:
298c7afd0dbSLois Curfman McInnes +  snes - the SNES context
29906ee9f85SBarry Smith .  it - the iteration (0 indicates before any Newton steps)
300e7e93795SLois Curfman McInnes .  xnorm - 2-norm of current iterate
301e7e93795SLois Curfman McInnes .  pnorm - 2-norm of current step
3027f3332b4SBarry Smith .  fnorm - 2-norm of function at current iterate
303c7afd0dbSLois Curfman McInnes -  dummy - unused context
304e7e93795SLois Curfman McInnes 
305184914b5SBarry Smith    Output Parameter:
306184914b5SBarry Smith .   reason  - one of
30770441072SBarry Smith $  SNES_CONVERGED_FNORM_ABS       - (fnorm < abstol),
3083304466cSBarry Smith $  SNES_CONVERGED_PNORM_RELATIVE  - (pnorm < xtol*xnorm),
309184914b5SBarry Smith $  SNES_CONVERGED_FNORM_RELATIVE  - (fnorm < rtol*fnorm0),
310184914b5SBarry Smith $  SNES_DIVERGED_FUNCTION_COUNT   - (nfct > maxf),
311184914b5SBarry Smith $  SNES_DIVERGED_FNORM_NAN        - (fnorm == NaN),
312184914b5SBarry Smith $  SNES_CONVERGED_ITERATING       - (otherwise),
313e7e93795SLois Curfman McInnes 
314e7e93795SLois Curfman McInnes    where
315c7afd0dbSLois Curfman McInnes +    maxf - maximum number of function evaluations,
316c7afd0dbSLois Curfman McInnes             set with SNESSetTolerances()
317c7afd0dbSLois Curfman McInnes .    nfct - number of function evaluations,
31870441072SBarry Smith .    abstol - absolute function norm tolerance,
319c7afd0dbSLois Curfman McInnes             set with SNESSetTolerances()
320c7afd0dbSLois Curfman McInnes -    rtol - relative function norm tolerance, set with SNESSetTolerances()
321fee21e36SBarry Smith 
32236851e7fSLois Curfman McInnes    Level: intermediate
32336851e7fSLois Curfman McInnes 
324e7e93795SLois Curfman McInnes .keywords: SNES, nonlinear, default, converged, convergence
325e7e93795SLois Curfman McInnes 
326e7e93795SLois Curfman McInnes .seealso: SNESSetConvergenceTest(), SNESEisenstatWalkerConverged()
327e7e93795SLois Curfman McInnes @*/
32806ee9f85SBarry Smith PetscErrorCode PETSCSNES_DLLEXPORT SNESConverged_LS(SNES snes,PetscInt it,PetscReal xnorm,PetscReal pnorm,PetscReal fnorm,SNESConvergedReason *reason,void *dummy)
329e7e93795SLois Curfman McInnes {
33063ba0a88SBarry Smith   PetscErrorCode ierr;
33163ba0a88SBarry Smith 
3323a40ed3dSBarry Smith   PetscFunctionBegin;
33306ee9f85SBarry Smith   *reason = SNES_CONVERGED_ITERATING;
33406ee9f85SBarry Smith 
33506ee9f85SBarry Smith   if (!it) {
33606ee9f85SBarry Smith     /* set parameter for default relative tolerance convergence test */
33706ee9f85SBarry Smith     snes->ttol = fnorm*snes->rtol;
33806ee9f85SBarry Smith   }
339d252947aSBarry Smith   if (fnorm != fnorm) {
340ae15b995SBarry Smith     ierr = PetscInfo(snes,"Failed to converged, function norm is NaN\n");CHKERRQ(ierr);
341184914b5SBarry Smith     *reason = SNES_DIVERGED_FNORM_NAN;
34270441072SBarry Smith   } else if (fnorm < snes->abstol) {
343ae15b995SBarry Smith     ierr = PetscInfo2(snes,"Converged due to function norm %G < %G\n",fnorm,snes->abstol);CHKERRQ(ierr);
344184914b5SBarry Smith     *reason = SNES_CONVERGED_FNORM_ABS;
34543e71028SBarry Smith   } else if (snes->nfuncs >= snes->max_funcs) {
346ae15b995SBarry Smith     ierr = PetscInfo2(snes,"Exceeded maximum number of function evaluations: %D > %D\n",snes->nfuncs,snes->max_funcs);CHKERRQ(ierr);
347184914b5SBarry Smith     *reason = SNES_DIVERGED_FUNCTION_COUNT;
34806ee9f85SBarry Smith   }
34906ee9f85SBarry Smith 
35006ee9f85SBarry Smith   if (it && !*reason) {
35106ee9f85SBarry Smith     if (fnorm <= snes->ttol) {
35206ee9f85SBarry Smith       ierr = PetscInfo2(snes,"Converged due to function norm %G < %G (relative tolerance)\n",fnorm,snes->ttol);CHKERRQ(ierr);
35306ee9f85SBarry Smith       *reason = SNES_CONVERGED_FNORM_RELATIVE;
35406ee9f85SBarry Smith     } else if (pnorm < snes->xtol*xnorm) {
35506ee9f85SBarry Smith       ierr = PetscInfo3(snes,"Converged due to small update length: %G < %G * %G\n",pnorm,snes->xtol,xnorm);CHKERRQ(ierr);
35606ee9f85SBarry Smith       *reason = SNES_CONVERGED_PNORM_RELATIVE;
35706ee9f85SBarry Smith     }
358e7e93795SLois Curfman McInnes   }
3593a40ed3dSBarry Smith   PetscFunctionReturn(0);
360e7e93795SLois Curfman McInnes }
361e7e93795SLois Curfman McInnes /* ------------------------------------------------------------ */
3624a2ae208SSatish Balay #undef __FUNCT__
3634a2ae208SSatish Balay #define __FUNCT__ "SNES_KSP_SetConvergenceTestEW"
364e7e93795SLois Curfman McInnes /*@
365f525115eSLois Curfman McInnes    SNES_KSP_SetConvergenceTestEW - Sets alternative convergence test
366e7e93795SLois Curfman McInnes    for the linear solvers within an inexact Newton method.
367e7e93795SLois Curfman McInnes 
368c7afd0dbSLois Curfman McInnes    Collective on SNES
369c7afd0dbSLois Curfman McInnes 
370e7e93795SLois Curfman McInnes    Input Parameter:
371e7e93795SLois Curfman McInnes .  snes - SNES context
372e7e93795SLois Curfman McInnes 
373e7e93795SLois Curfman McInnes    Notes:
374e7e93795SLois Curfman McInnes    Currently, the default is to use a constant relative tolerance for
375e7e93795SLois Curfman McInnes    the inner linear solvers.  Alternatively, one can use the
376e7e93795SLois Curfman McInnes    Eisenstat-Walker method, where the relative convergence tolerance
377e7e93795SLois Curfman McInnes    is reset at each Newton iteration according progress of the nonlinear
378e7e93795SLois Curfman McInnes    solver.
379e7e93795SLois Curfman McInnes 
38036851e7fSLois Curfman McInnes    Level: advanced
38136851e7fSLois Curfman McInnes 
382e7e93795SLois Curfman McInnes    Reference:
383e7e93795SLois Curfman McInnes    S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an
384e30ad881SLois Curfman McInnes    inexact Newton method", SISC 17 (1), pp.16-32, 1996.
385e7e93795SLois Curfman McInnes 
386e7e93795SLois Curfman McInnes .keywords: SNES, KSP, Eisenstat, Walker, convergence, test, inexact, Newton
387e7e93795SLois Curfman McInnes @*/
38863dd3a1aSKris Buschelman PetscErrorCode PETSCSNES_DLLEXPORT SNES_KSP_SetConvergenceTestEW(SNES snes)
389e7e93795SLois Curfman McInnes {
3903a40ed3dSBarry Smith   PetscFunctionBegin;
391186905e3SBarry Smith   snes->ksp_ewconv = PETSC_TRUE;
3923a40ed3dSBarry Smith   PetscFunctionReturn(0);
393e7e93795SLois Curfman McInnes }
394e7e93795SLois Curfman McInnes 
3954a2ae208SSatish Balay #undef __FUNCT__
3964a2ae208SSatish Balay #define __FUNCT__ "SNES_KSP_SetParametersEW"
397e7e93795SLois Curfman McInnes /*@
398e7e93795SLois Curfman McInnes    SNES_KSP_SetParametersEW - Sets parameters for Eisenstat-Walker
399e7e93795SLois Curfman McInnes    convergence criteria for the linear solvers within an inexact
400e7e93795SLois Curfman McInnes    Newton method.
401e7e93795SLois Curfman McInnes 
402c7afd0dbSLois Curfman McInnes    Collective on SNES
403c7afd0dbSLois Curfman McInnes 
404e7e93795SLois Curfman McInnes    Input Parameters:
405c7afd0dbSLois Curfman McInnes +    snes - SNES context
406cf502942SBarry Smith .    version - version 1, 2 (default is 2) or 3
407c7afd0dbSLois Curfman McInnes .    rtol_0 - initial relative tolerance (0 <= rtol_0 < 1)
408c7afd0dbSLois Curfman McInnes .    rtol_max - maximum relative tolerance (0 <= rtol_max < 1)
409c7afd0dbSLois Curfman McInnes .    alpha - power for version 2 rtol computation (1 < alpha <= 2)
410e7e93795SLois Curfman McInnes .    alpha2 - power for safeguard
411e7e93795SLois Curfman McInnes .    gamma2 - multiplicative factor for version 2 rtol computation
412c7afd0dbSLois Curfman McInnes               (0 <= gamma2 <= 1)
413c7afd0dbSLois Curfman McInnes -    threshold - threshold for imposing safeguard (0 < threshold < 1)
414fee21e36SBarry Smith 
415e7e93795SLois Curfman McInnes    Note:
41609f38230SBarry Smith    Version 3 was contributed by Luis Chacon, June 2006.
417cf502942SBarry Smith 
418e7e93795SLois Curfman McInnes    Use PETSC_DEFAULT to retain the default for any of the parameters.
419e7e93795SLois Curfman McInnes 
42036851e7fSLois Curfman McInnes    Level: advanced
42136851e7fSLois Curfman McInnes 
422e7e93795SLois Curfman McInnes    Reference:
423e7e93795SLois Curfman McInnes    S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an
424e7e93795SLois Curfman McInnes    inexact Newton method", Utah State University Math. Stat. Dept. Res.
425e7e93795SLois Curfman McInnes    Report 6/94/75, June, 1994, to appear in SIAM J. Sci. Comput.
426e7e93795SLois Curfman McInnes 
427e7e93795SLois Curfman McInnes .keywords: SNES, KSP, Eisenstat, Walker, set, parameters
428e7e93795SLois Curfman McInnes 
429e7e93795SLois Curfman McInnes .seealso: SNES_KSP_SetConvergenceTestEW()
430e7e93795SLois Curfman McInnes @*/
43163dd3a1aSKris Buschelman PetscErrorCode PETSCSNES_DLLEXPORT SNES_KSP_SetParametersEW(SNES snes,PetscInt version,PetscReal rtol_0,PetscReal rtol_max,PetscReal gamma2,PetscReal alpha,
432329f5518SBarry Smith                                         PetscReal alpha2,PetscReal threshold)
433e7e93795SLois Curfman McInnes {
434e7e93795SLois Curfman McInnes   SNES_KSP_EW_ConvCtx *kctx = (SNES_KSP_EW_ConvCtx*)snes->kspconvctx;
4353a40ed3dSBarry Smith 
4363a40ed3dSBarry Smith   PetscFunctionBegin;
43729bbc08cSBarry Smith   if (!kctx) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context existing");
438e7e93795SLois Curfman McInnes   if (version != PETSC_DEFAULT)   kctx->version   = version;
439e7e93795SLois Curfman McInnes   if (rtol_0 != PETSC_DEFAULT)    kctx->rtol_0    = rtol_0;
440e7e93795SLois Curfman McInnes   if (rtol_max != PETSC_DEFAULT)  kctx->rtol_max  = rtol_max;
441e7e93795SLois Curfman McInnes   if (gamma2 != PETSC_DEFAULT)    kctx->gamma     = gamma2;
442e7e93795SLois Curfman McInnes   if (alpha != PETSC_DEFAULT)     kctx->alpha     = alpha;
443e7e93795SLois Curfman McInnes   if (alpha2 != PETSC_DEFAULT)    kctx->alpha2    = alpha2;
444e7e93795SLois Curfman McInnes   if (threshold != PETSC_DEFAULT) kctx->threshold = threshold;
445a8c6a408SBarry Smith   if (kctx->rtol_0 < 0.0 || kctx->rtol_0 >= 1.0) {
446a83599f4SBarry Smith     SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"0.0 <= rtol_0 < 1.0: %G",kctx->rtol_0);
447a8c6a408SBarry Smith   }
448a8c6a408SBarry Smith   if (kctx->rtol_max < 0.0 || kctx->rtol_max >= 1.0) {
449a83599f4SBarry Smith     SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"0.0 <= rtol_max (%G) < 1.0\n",kctx->rtol_max);
450a8c6a408SBarry Smith   }
451a8c6a408SBarry Smith   if (kctx->threshold <= 0.0 || kctx->threshold >= 1.0) {
452a83599f4SBarry Smith     SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"0.0 < threshold (%G) < 1.0\n",kctx->threshold);
453a8c6a408SBarry Smith   }
454a8c6a408SBarry Smith   if (kctx->gamma < 0.0 || kctx->gamma > 1.0) {
455a83599f4SBarry Smith     SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"0.0 <= gamma (%G) <= 1.0\n",kctx->gamma);
456a8c6a408SBarry Smith   }
457a8c6a408SBarry Smith   if (kctx->alpha <= 1.0 || kctx->alpha > 2.0) {
458a83599f4SBarry Smith     SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"1.0 < alpha (%G) <= 2.0\n",kctx->alpha);
459a8c6a408SBarry Smith   }
46009f38230SBarry Smith   if (kctx->version < 1 || kctx->version > 3) {
46109f38230SBarry Smith     SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Only versions 1, 2 and 3 are supported: %D",kctx->version);
462a8c6a408SBarry Smith   }
4633a40ed3dSBarry Smith   PetscFunctionReturn(0);
464e7e93795SLois Curfman McInnes }
465e7e93795SLois Curfman McInnes 
4664a2ae208SSatish Balay #undef __FUNCT__
4674a2ae208SSatish Balay #define __FUNCT__ "SNES_KSP_EW_ComputeRelativeTolerance_Private"
468dfbe8321SBarry Smith PetscErrorCode SNES_KSP_EW_ComputeRelativeTolerance_Private(SNES snes,KSP ksp)
469e7e93795SLois Curfman McInnes {
470e7e93795SLois Curfman McInnes   SNES_KSP_EW_ConvCtx *kctx = (SNES_KSP_EW_ConvCtx*)snes->kspconvctx;
471329f5518SBarry Smith   PetscReal           rtol = 0.0,stol;
472dfbe8321SBarry Smith   PetscErrorCode      ierr;
4733a40ed3dSBarry Smith 
4743a40ed3dSBarry Smith   PetscFunctionBegin;
47529bbc08cSBarry Smith   if (!kctx) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context exists");
476c38d4ed2SBarry Smith   if (!snes->iter) { /* first time in, so use the original user rtol */
477e7e93795SLois Curfman McInnes     rtol = kctx->rtol_0;
478e7e93795SLois Curfman McInnes   } else {
479e7e93795SLois Curfman McInnes     if (kctx->version == 1) {
480e7e93795SLois Curfman McInnes       rtol = (snes->norm - kctx->lresid_last)/kctx->norm_last;
481e7e93795SLois Curfman McInnes       if (rtol < 0.0) rtol = -rtol;
482e7e93795SLois Curfman McInnes       stol = pow(kctx->rtol_last,kctx->alpha2);
4830452661fSBarry Smith       if (stol > kctx->threshold) rtol = PetscMax(rtol,stol);
484e7e93795SLois Curfman McInnes     } else if (kctx->version == 2) {
485e7e93795SLois Curfman McInnes       rtol = kctx->gamma * pow(snes->norm/kctx->norm_last,kctx->alpha);
486e7e93795SLois Curfman McInnes       stol = kctx->gamma * pow(kctx->rtol_last,kctx->alpha);
4870452661fSBarry Smith       if (stol > kctx->threshold) rtol = PetscMax(rtol,stol);
488cf502942SBarry Smith     } else if (kctx->version == 3) {
489cf502942SBarry Smith       rtol = kctx->gamma * pow(snes->norm/kctx->norm_last,kctx->alpha);
490cf502942SBarry Smith       /* safeguard: avoid sharp decrease of rtol */
491cf502942SBarry Smith       rtol = PetscMin(kctx->rtol_0,PetscMax(rtol,kctx->gamma*pow(kctx->rtol_last,kctx->alpha)));
492cf502942SBarry Smith       /* safeguard: avoid oversolving */
493cf502942SBarry Smith       rtol = PetscMin(kctx->rtol_0,PetscMax(rtol,kctx->gamma*(snes->ttol)/snes->norm));
494cf502942SBarry Smith 
495cf502942SBarry Smith     } else SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Only versions 1, 2 or 3 are supported: %D",kctx->version);
496e7e93795SLois Curfman McInnes   }
4970452661fSBarry Smith   rtol = PetscMin(rtol,kctx->rtol_max);
498e7e93795SLois Curfman McInnes   kctx->rtol_last = rtol;
499ae15b995SBarry Smith   ierr = PetscInfo3(snes,"iter %D, Eisenstat-Walker (version %D) KSP rtol = %G\n",snes->iter,kctx->version,rtol);CHKERRQ(ierr);
5003131a8b6SLois Curfman McInnes   ierr = KSPSetTolerances(ksp,rtol,PETSC_DEFAULT,PETSC_DEFAULT,PETSC_DEFAULT);CHKERRQ(ierr);
501e7e93795SLois Curfman McInnes   kctx->norm_last = snes->norm;
5023a40ed3dSBarry Smith   PetscFunctionReturn(0);
503e7e93795SLois Curfman McInnes }
504e7e93795SLois Curfman McInnes 
5054a2ae208SSatish Balay #undef __FUNCT__
5064a2ae208SSatish Balay #define __FUNCT__ "SNES_KSP_EW_Converged_Private"
507a7cc72afSBarry Smith PetscErrorCode SNES_KSP_EW_Converged_Private(KSP ksp,PetscInt n,PetscReal rnorm,KSPConvergedReason *reason,void *ctx)
508e7e93795SLois Curfman McInnes {
509e7e93795SLois Curfman McInnes   SNES                snes = (SNES)ctx;
510e7e93795SLois Curfman McInnes   SNES_KSP_EW_ConvCtx *kctx = (SNES_KSP_EW_ConvCtx*)snes->kspconvctx;
511dfbe8321SBarry Smith   PetscErrorCode      ierr;
512e7e93795SLois Curfman McInnes 
5133a40ed3dSBarry Smith   PetscFunctionBegin;
51429bbc08cSBarry Smith   if (!kctx) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context set");
515958c9bccSBarry Smith   if (!n) {ierr = SNES_KSP_EW_ComputeRelativeTolerance_Private(snes,ksp);CHKERRQ(ierr);}
516211a6b7eSSatish Balay   ierr = KSPDefaultConverged(ksp,n,rnorm,reason,ctx);CHKERRQ(ierr);
517e7e93795SLois Curfman McInnes   kctx->lresid_last = rnorm;
518211a6b7eSSatish Balay   if (*reason) {
519ae15b995SBarry Smith     ierr = PetscInfo2(snes,"KSP iterations=%D, rnorm=%G\n",n,rnorm);CHKERRQ(ierr);
5203a40ed3dSBarry Smith   }
521211a6b7eSSatish Balay   PetscFunctionReturn(0);
522e7e93795SLois Curfman McInnes }
523e7e93795SLois Curfman McInnes 
524e7e93795SLois Curfman McInnes 
525