* D03PPA Example Program Text * Mark 20 Release. NAG Copyright 2001. * .. Parameters .. INTEGER NOUT PARAMETER (NOUT=6) INTEGER NPDE, NPTS, NCODE, M, NXI, NXFIX, NEQN, NIW, + NWKRES, LENODE, NW, INTPTS, ITYPE PARAMETER (NPDE=1,NPTS=61,NCODE=0,M=0,NXI=0,NXFIX=0, + NEQN=NPDE*NPTS+NCODE,NIW=25+NXFIX, + NWKRES=NPDE*(NPTS+3*NPDE+21)+7*NPTS+NXFIX+3, + LENODE=11*NEQN+50,NW=NEQN*NEQN+NEQN+NWKRES+ + LENODE,INTPTS=5,ITYPE=1) * .. Local Scalars .. DOUBLE PRECISION CONST, DXMESH, E, TOUT, TRMESH, TS, XRATIO INTEGER I, IFAIL, IND, IPMINF, IT, ITASK, ITOL, ITRACE, + NRMESH LOGICAL REMESH, THETA CHARACTER LAOPT, NORM * .. Local Arrays .. DOUBLE PRECISION ALGOPT(30), ATOL(1), RTOL(1), RUSER(1), + RWSAV(1100), U(NEQN), UE(INTPTS), + UOUT(NPDE,INTPTS,ITYPE), W(NW), X(NPTS), XFIX(1), + XI(1), XOUT(INTPTS) INTEGER IUSER(1), IW(NIW), IWSAV(505) LOGICAL LWSAV(100) CHARACTER*80 CWSAV(10) * .. External Subroutines .. EXTERNAL BNDARY, D03PPA, D03PZF, D53PCK, EXACT, MONITF, + PDEDEF, UVINIT * .. Executable Statements .. WRITE (NOUT,*) 'D03PPA Example Program Results' E = 0.005D0 RUSER(1) = E ITRACE = 0 ITOL = 1 ATOL(1) = 0.5D-4 RTOL(1) = ATOL(1) WRITE (NOUT,99998) ATOL, NPTS * * Initialise mesh * DO 20 I = 1, NPTS X(I) = (I-1.0D0)/(NPTS-1.0D0) 20 CONTINUE * * Set remesh parameters * REMESH = .TRUE. NRMESH = 3 DXMESH = 0.5D0 CONST = 2.0D0/(NPTS-1.0D0) XRATIO = 1.5D0 IPMINF = 0 * WRITE (NOUT,99993) NRMESH WRITE (NOUT,99992) E WRITE (NOUT,*) * XI(1) = 0.0D0 NORM = 'A' LAOPT = 'F' IND = 0 ITASK = 1 * * Set THETA to .TRUE. if the Theta integrator is required * THETA = .FALSE. DO 40 I = 1, 30 ALGOPT(I) = 0.0D0 40 CONTINUE IF (THETA) THEN ALGOPT(1) = 2.0D0 ELSE ALGOPT(1) = 0.0D0 END IF * * Loop over output value of t * TS = 0.0D0 TOUT = 0.0D0 DO 60 IT = 1, 5 TOUT = 0.2D0*IT IFAIL = 0 * CALL D03PPA(NPDE,M,TS,TOUT,PDEDEF,BNDARY,UVINIT,U,NPTS,X,NCODE, + D53PCK,NXI,XI,NEQN,RTOL,ATOL,ITOL,NORM,LAOPT, + ALGOPT,REMESH,NXFIX,XFIX,NRMESH,DXMESH,TRMESH, + IPMINF,XRATIO,CONST,MONITF,W,NW,IW,NIW,ITASK, + ITRACE,IND,IUSER,RUSER,CWSAV,LWSAV,IWSAV,RWSAV, + IFAIL) * * Set output points * IF (IT.EQ.1) THEN XOUT(1) = 0.3D0 XOUT(2) = 0.4D0 XOUT(3) = 0.5D0 XOUT(4) = 0.6D0 XOUT(5) = 0.7D0 ELSE IF (IT.EQ.2) THEN XOUT(1) = 0.4D0 XOUT(2) = 0.5D0 XOUT(3) = 0.6D0 XOUT(4) = 0.7D0 XOUT(5) = 0.8D0 ELSE IF (IT.EQ.3) THEN XOUT(1) = 0.6D0 XOUT(2) = 0.65D0 XOUT(3) = 0.7D0 XOUT(4) = 0.75D0 XOUT(5) = 0.8D0 ELSE IF (IT.EQ.4) THEN XOUT(1) = 0.7D0 XOUT(2) = 0.75D0 XOUT(3) = 0.8D0 XOUT(4) = 0.85D0 XOUT(5) = 0.9D0 ELSE IF (IT.EQ.5) THEN XOUT(1) = 0.8D0 XOUT(2) = 0.85D0 XOUT(3) = 0.9D0 XOUT(4) = 0.95D0 XOUT(5) = 1.0D0 END IF * WRITE (NOUT,99999) TS WRITE (NOUT,99996) (XOUT(I),I=1,INTPTS) * * Interpolate at output points * CALL D03PZF(NPDE,M,U,NPTS,X,XOUT,INTPTS,ITYPE,UOUT,IFAIL) * * Check against exact solution * CALL EXACT(TS,XOUT,INTPTS,UE,IUSER,RUSER) * WRITE (NOUT,99995) (UOUT(1,I,1),I=1,INTPTS) WRITE (NOUT,99994) (UE(I),I=1,INTPTS) * 60 CONTINUE WRITE (NOUT,99997) IW(1), IW(2), IW(3), IW(5) STOP * 99999 FORMAT (' T = ',F6.3) 99998 FORMAT (//' Accuracy requirement =',D10.3,' Number of points = ', + I3,/) 99997 FORMAT (' Number of integration steps in time = ',I6,/' Number o', + 'f function evaluations = ',I6,/' Number of Jacobian eval', + 'uations =',I6,/' Number of iterations = ',I6,/) 99996 FORMAT (1X,'X ',5F9.4) 99995 FORMAT (1X,'Approx sol. ',5F9.4) 99994 FORMAT (1X,'Exact sol. ',5F9.4,/) 99993 FORMAT (2X,'Remeshing every',I3,' time steps',/) 99992 FORMAT (2X,'E =',F8.3) END * SUBROUTINE UVINIT(NPDE,NPTS,NXI,X,XI,U,NCODE,V,IUSER,RUSER) * .. Scalar Arguments .. INTEGER NCODE, NPDE, NPTS, NXI * .. Array Arguments .. DOUBLE PRECISION RUSER(*), U(NPDE,NPTS), V(*), X(NPTS), XI(*) INTEGER IUSER(*) * .. Local Scalars .. DOUBLE PRECISION A, B, C, E, T INTEGER I * .. Intrinsic Functions .. INTRINSIC EXP * .. Executable Statements .. E = RUSER(1) T = 0.0D0 DO 20 I = 1, NPTS A = (X(I)-0.25D0-0.75D0*T)/(4.0D0*E) B = (0.9D0*X(I)-0.325D0-0.495D0*T)/(2.0D0*E) IF (A.GT.0.0D0 .AND. A.GT.B) THEN A = EXP(-A) C = (0.8D0*X(I)-0.4D0-0.24D0*T)/(4.0D0*E) C = EXP(C) U(1,I) = (0.5D0+0.1D0*C+A)/(1.0D0+C+A) ELSE IF (B.GT.0.0D0 .AND. B.GE.A) THEN B = EXP(-B) C = (-0.8D0*X(I)+0.4D0+0.24D0*T)/(4.0D0*E) C = EXP(C) U(1,I) = (0.1D0+0.5D0*C+B)/(1.0D0+C+B) ELSE A = EXP(A) B = EXP(B) U(1,I) = (1.0D0+0.5D0*A+0.1D0*B)/(1.0D0+A+B) END IF 20 CONTINUE RETURN END * SUBROUTINE PDEDEF(NPDE,T,X,U,UX,NCODE,V,VDOT,P,Q,R,IRES,IUSER, + RUSER) * .. Scalar Arguments .. DOUBLE PRECISION T, X INTEGER IRES, NCODE, NPDE * .. Array Arguments .. DOUBLE PRECISION P(NPDE,NPDE), Q(NPDE), R(NPDE), RUSER(*), + U(NPDE), UX(NPDE), V(*), VDOT(*) INTEGER IUSER(*) * .. Local Scalars .. DOUBLE PRECISION E * .. Executable Statements .. E = RUSER(1) P(1,1) = 1.0D0 R(1) = E*UX(1) Q(1) = U(1)*UX(1) RETURN END * SUBROUTINE BNDARY(NPDE,T,U,UX,NCODE,V,VDOT,IBND,BETA,GAMMA,IRES, + IUSER,RUSER) * .. Scalar Arguments .. DOUBLE PRECISION T INTEGER IBND, IRES, NCODE, NPDE * .. Array Arguments .. DOUBLE PRECISION BETA(NPDE), GAMMA(NPDE), RUSER(*), U(NPDE), + UX(NPDE), V(*), VDOT(*) INTEGER IUSER(*) * .. Local Scalars .. DOUBLE PRECISION A, B, C, E, UE, X * .. Intrinsic Functions .. INTRINSIC EXP * .. Executable Statements .. E = RUSER(1) BETA(1) = 0.0D0 IF (IBND.EQ.0) THEN X = 0.0D0 A = (X-0.25D0-0.75D0*T)/(4.0D0*E) B = (0.9D0*X-0.325D0-0.495D0*T)/(2.0D0*E) IF (A.GT.0.0D0 .AND. A.GT.B) THEN A = EXP(-A) C = (0.8D0*X-0.4D0-0.24D0*T)/(4.0D0*E) C = EXP(C) UE = (0.5D0+0.1D0*C+A)/(1.0D0+C+A) ELSE IF (B.GT.0.0D0 .AND. B.GE.A) THEN B = EXP(-B) C = (-0.8D0*X+0.4D0+0.24D0*T)/(4.0D0*E) C = EXP(C) UE = (0.1D0+0.5D0*C+B)/(1.0D0+C+B) ELSE A = EXP(A) B = EXP(B) UE = (1.0D0+0.5D0*A+0.1D0*B)/(1.0D0+A+B) END IF ELSE X = 1.0D0 A = (X-0.25D0-0.75D0*T)/(4.0D0*E) B = (0.9D0*X-0.325D0-0.495D0*T)/(2.0D0*E) IF (A.GT.0.0D0 .AND. A.GT.B) THEN A = EXP(-A) C = (0.8D0*X-0.4D0-0.24D0*T)/(4.0D0*E) C = EXP(C) UE = (0.5D0+0.1D0*C+A)/(1.0D0+C+A) ELSE IF (B.GT.0.0D0 .AND. B.GE.A) THEN B = EXP(-B) C = (-0.8D0*X+0.4D0+0.24D0*T)/(4.0D0*E) C = EXP(C) UE = (0.1D0+0.5D0*C+B)/(1.0D0+C+B) ELSE A = EXP(A) B = EXP(B) UE = (1.0D0+0.5D0*A+0.1D0*B)/(1.0D0+A+B) END IF END IF GAMMA(1) = U(1) - UE RETURN END * SUBROUTINE EXACT(T,X,NPTS,U,IUSER,RUSER) * Exact solution (for comparison purposes) * .. Scalar Arguments .. DOUBLE PRECISION T INTEGER NPTS * .. Array Arguments .. DOUBLE PRECISION RUSER(*), U(NPTS), X(NPTS) INTEGER IUSER(*) * .. Local Scalars .. DOUBLE PRECISION A, B, C, E INTEGER I * .. Intrinsic Functions .. INTRINSIC EXP * .. Executable Statements .. E = RUSER(1) DO 20 I = 1, NPTS A = (X(I)-0.25D0-0.75D0*T)/(4.0D0*E) B = (0.9D0*X(I)-0.325D0-0.495D0*T)/(2.0D0*E) IF (A.GT.0.0D0 .AND. A.GT.B) THEN A = EXP(-A) C = (0.8D0*X(I)-0.4D0-0.24D0*T)/(4.0D0*E) C = EXP(C) U(I) = (0.5D0+0.1D0*C+A)/(1.0D0+C+A) ELSE IF (B.GT.0.0D0 .AND. B.GE.A) THEN B = EXP(-B) C = (-0.8D0*X(I)+0.4D0+0.24D0*T)/(4.0D0*E) C = EXP(C) U(I) = (0.1D0+0.5D0*C+B)/(1.0D0+C+B) ELSE A = EXP(A) B = EXP(B) U(I) = (1.0D0+0.5D0*A+0.1D0*B)/(1.0D0+A+B) END IF 20 CONTINUE RETURN END * SUBROUTINE MONITF(T,NPTS,NPDE,X,U,R,FMON,IUSER,RUSER) * .. Scalar Arguments .. DOUBLE PRECISION T INTEGER NPDE, NPTS * .. Array Arguments .. DOUBLE PRECISION FMON(NPTS), R(NPDE,NPTS), RUSER(*), + U(NPDE,NPTS), X(NPTS) INTEGER IUSER(*) * .. Local Scalars .. DOUBLE PRECISION DRDX, H INTEGER I, K, L * .. Intrinsic Functions .. INTRINSIC ABS, MAX, MIN * .. Executable Statements .. DO 20 I = 1, NPTS - 1 K = MAX(1,I-1) L = MIN(NPTS,I+1) H = (X(L)-X(K))*0.5D0 * Second derivative .. DRDX = (R(1,I+1)-R(1,I))/H FMON(I) = ABS(DRDX) 20 CONTINUE FMON(NPTS) = FMON(NPTS-1) RETURN END