* F12ASF Example Program Text * Mark 21 Release. NAG Copyright 2004. * .. Parameters .. INTEGER IMON, LICOMM, NERR, NIN, NOUT PARAMETER (IMON=1,LICOMM=140,NERR=6,NIN=5,NOUT=6) INTEGER MAXN, MAXNCV, LDV PARAMETER (MAXN=256,MAXNCV=30,LDV=MAXN) INTEGER LCOMM PARAMETER (LCOMM=3*MAXN+3*MAXNCV*MAXNCV+5*MAXNCV+60) COMPLEX *16 ONE, TWO, FOUR, SIX PARAMETER (ONE=(1.0D+0,0.0D+0),TWO=(2.0D+0,0.0D+0), + FOUR=(4.0D+0,0.0D+0),SIX=(6.0D+0,0.0D+0)) * .. Local Scalars .. COMPLEX *16 H, RHO, S, S1, S2, S3, SIGMA INTEGER IFAIL, IFAIL1, INFO, IREVCM, J, N, NCONV, NCV, + NEV, NITER, NSHIFT, NX * .. Local Arrays .. COMPLEX *16 AX(MAXN), COMM(LCOMM), D(MAXNCV,2), DD(MAXN), + DL(MAXN), DU(MAXN), DU2(MAXN), MX(MAXN), + RESID(MAXN), V(LDV,MAXNCV), X(MAXN) INTEGER ICOMM(LICOMM), IPIV(MAXN) * .. External Functions .. DOUBLE PRECISION DZNRM2 EXTERNAL DZNRM2 * .. External Subroutines .. EXTERNAL F12ANF, F12APF, F12AQF, F12ARF, F12ASF, MV, + ZCOPY, ZGTTRF, ZGTTRS * .. Intrinsic Functions .. INTRINSIC CMPLX * .. Executable Statements .. WRITE (NOUT,*) 'F12ASF Example Program Results' WRITE (NOUT,*) * Skip heading in data file READ (NIN,*) READ (NIN,*) NX, NEV, NCV N = NX*NX IF (N.LT.1 .OR. N.GT.MAXN) THEN WRITE (NOUT,99999) 'N is out of range: N = ', N ELSE IF (NCV.GT.MAXNCV) THEN WRITE (NOUT,99999) 'NCV is out of range: NCV = ', NCV ELSE IFAIL = 0 CALL F12ANF(N,NEV,NCV,ICOMM,LICOMM,COMM,LCOMM,IFAIL) * Set the mode. CALL F12ARF('SHIFTED INVERSE',ICOMM,COMM,IFAIL) * Set problem type. CALL F12ARF('GENERALIZED',ICOMM,COMM,IFAIL) * SIGMA = ONE SIGMA = (5.0D+3,0.0D0) RHO = (1.0D+1,0.0D0) H = ONE/CMPLX(N+1,KIND=KIND(H)) S = RHO/TWO S1 = -ONE/H - S - SIGMA*H/SIX S2 = TWO/H - FOUR*SIGMA*H/SIX S3 = -ONE/H + S - SIGMA*H/SIX * DO 20 J = 1, N - 1 DL(J) = S1 DD(J) = S2 DU(J) = S3 20 CONTINUE DD(N) = S2 * CALL ZGTTRF(N,DL,DD,DU,DU2,IPIV,INFO) IF (INFO.NE.0) THEN WRITE (NERR,99998) INFO GO TO 80 END IF * IREVCM = 0 IFAIL = -1 40 CONTINUE CALL F12APF(IREVCM,RESID,V,LDV,X,MX,NSHIFT,COMM,ICOMM,IFAIL) IF (IREVCM.NE.5) THEN IF (IREVCM.EQ.-1) THEN * Perform x <--- OP*x = inv[A-SIGMA*M]*M*x CALL MV(NX,X,AX) CALL ZCOPY(N,AX,1,X,1) CALL ZGTTRS('N',N,1,DL,DD,DU,DU2,IPIV,X,N,INFO) IF (INFO.NE.0) THEN WRITE (NERR,99997) INFO GO TO 80 END IF ELSE IF (IREVCM.EQ.1) THEN * Perform x <--- OP*x = inv[A-SIGMA*M]*M*x, * MX stored in COMM from location IPNTR(3) CALL ZGTTRS('N',N,1,DL,DD,DU,DU2,IPIV,MX,N,INFO) CALL ZCOPY(N,MX,1,X,1) IF (INFO.NE.0) THEN WRITE (NERR,99997) INFO GO TO 80 END IF ELSE IF (IREVCM.EQ.2) THEN * Perform y <--- M*x CALL MV(NX,X,AX) CALL ZCOPY(N,AX,1,X,1) ELSE IF (IREVCM.EQ.4 .AND. IMON.NE.0) THEN * Output monitoring information CALL F12ASF(NITER,NCONV,D,D(1,2),ICOMM,COMM) WRITE (6,99996) NITER, NCONV, DZNRM2(NEV,D(1,2),1) END IF GO TO 40 END IF IF (IFAIL.EQ.0) THEN * Post-Process using F12AQF to compute eigenvalues/vectors. IFAIL1 = 0 CALL F12AQF(NCONV,D,V,LDV,SIGMA,RESID,V,LDV,COMM,ICOMM, + IFAIL1) WRITE (NOUT,99994) NCONV, SIGMA DO 60 J = 1, NCONV WRITE (NOUT,99993) J, D(J,1) 60 CONTINUE ELSE WRITE (NOUT,99995) IFAIL END IF 80 CONTINUE END IF STOP * 99999 FORMAT (1X,A,I5) 99998 FORMAT (1X,'** Error status returned by ZGTTRF, INFO =',I12) 99997 FORMAT (1X,'** Error status returned by ZGTTRS, INFO =',I12) 99996 FORMAT (1X,'Iteration',1X,I3,', No. converged =',1X,I3,', norm o', + 'f estimates =',E12.4) 99995 FORMAT (1X,' NAG Routine F12APF Returned with IFAIL = ',I6) 99994 FORMAT (1X,/' The ',I4,' generalized Ritz values closest to',' (', + F8.3,',',F8.3,') are:',/) 99993 FORMAT (1X,I8,5X,'( ',F10.4,' , ',F10.4,' )') END * SUBROUTINE MV(NX,V,W) * Compute the out-of--place matrix vector multiplication Y<---M*X, * where M is mass matrix formed by using piecewise linear elements * on [0,1]. * * .. Parameters .. COMPLEX *16 ONE, FOUR, SIX PARAMETER (ONE=(1.0D+0,0.0D+0),FOUR=(4.0D+0,0.0D+0), + SIX=(6.0D+0,0.0D+0)) * .. Scalar Arguments .. INTEGER NX * .. Array Arguments .. COMPLEX *16 V(NX*NX), W(NX*NX) * .. Local Scalars .. COMPLEX *16 H INTEGER J, N * .. External Subroutines .. EXTERNAL ZSCAL * .. Intrinsic Functions .. INTRINSIC CMPLX * .. Executable Statements .. N = NX*NX W(1) = (FOUR*V(1)+V(2))/SIX DO 20 J = 2, N - 1 W(J) = (V(J-1)+FOUR*V(J)+V(J+1))/SIX 20 CONTINUE W(N) = (V(N-1)+FOUR*V(N))/SIX * H = ONE/CMPLX(N+1,KIND=KIND(H)) CALL ZSCAL(N,H,W,1) RETURN END