camfort-0.700: samples/book/two/code210.f90
!!!!!!!!!!!!!!!!!!!!!!!!!!! Program 2.10 !!!!!!!!!!!!!!!!!!!!!!!!!!!!
!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
! !
! Please Note: !
! !
! (1) This computer program is written by Tao Pang in conjunction with !
! his book, "An Introduction to Computational Physics," published !
! by Cambridge University Press in 1997. !
! !
! (2) No warranties, express or implied, are made for this program. !
! !
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!
MODULE CB
REAL :: B,E,A
END MODULE CB
!
PROGRAM SCATTERING
!
! This is the main program for the scattering problem.
! Copyright (c) Tao Pang 1997.
!
USE CB
IMPLICIT NONE
INTEGER, PARAMETER :: M=21,N=10001
INTEGER I,J,ISTEP
REAL :: DL,B0,DB,DX,X0,X,DX0,F,FX,FB,FBX,G1,G2,RU,RUTH,SI
REAL, DIMENSION (N) :: FI
REAL, DIMENSION (M) :: THETA,SIG,SIG1
!
DL = 1.E-06
B0 = 0.01
DB = 0.5
DX = 0.01
E = 1.0
A = 100.0
DO I = 1, M
B = B0+(I-1)*DB
!
! Calculate the first term of theta
!
DO J = 1, N
X = B+DX*J
FI(J) = 1.0/(X*X*SQRT(FBX(X)))
END DO
CALL SIMP(N,DX,FI,G1)
!
! Find r_m from 1-b*b/(r*r)-U/E=0
!
X0 = B
DX0 = DX
CALL SECANT (DL,X0,DX0,ISTEP)
!
! Calculate the second term of theta
!
DO J = 1, N
X = X0+DX*J
FI(J) = 1.0/(X*X*SQRT(FX(X)))
END DO
CALL SIMP (N,DX,FI,G2)
THETA(I) = 2.0*B*(G1-G2)
END DO
!
! Calculate d_theta/d_b
!
CALL THREE (M,DB,THETA,SIG,SIG1)
!
! Put the cross section in log form with the exact result of
! the Coulomb scattering (RUTH)
!
DO I = M, 1, -1
B = B0+(I-1)*DB
SIG(I) = B/ABS(SIG(I))/SIN(THETA(I))
RUTH = 1.0/SIN(THETA(I)/2.0)**4/16.0
SI = ALOG(SIG(I))
RU = ALOG(RUTH)
WRITE (6,"(3F16.8)") THETA(I),SI,RU
END DO
END PROGRAM SCATTERING
!
SUBROUTINE SIMP (N,H,FI,S)
!
! Subroutine for integration over f(x) with the Simpson rule. FI:
! integrand f(x); H: interval; S: integral. Copyright (c) Tao Pang 1997.
!
IMPLICIT NONE
INTEGER, INTENT (IN) :: N
INTEGER :: I
REAL, INTENT (IN) :: H
REAL :: S0,S1,S2
REAL, INTENT (OUT) :: S
REAL, INTENT (IN), DIMENSION (N) :: FI
!
S = 0.0
S0 = 0.0
S1 = 0.0
S2 = 0.0
DO I = 2, N-1, 2
S1 = S1+FI(I-1)
S0 = S0+FI(I)
S2 = S2+FI(I+1)
END DO
S = H*(S1+4.0*S0+S2)/3.0
!
! If N is even, add the last slice separately
!
IF (MOD(N,2).EQ.0) S = S &
+H*(5.0*FI(N)+8.0*FI(N-1)-FI(N-2))/12.0
END SUBROUTINE SIMP
!
SUBROUTINE SECANT (DL,X0,DX,ISTEP)
!
! Subroutine for the root of f(x)=0 with the secant method.
! Copyright (c) Tao Pang 1997.
!
IMPLICIT NONE
INTEGER, INTENT (INOUT) :: ISTEP
REAL, INTENT (INOUT) :: X0,DX
REAL :: X1,X2,D,F,FX
REAL, INTENT (IN) :: DL
!
ISTEP = 0
X1 = X0+DX
DO WHILE (ABS(DX).GT.DL)
D = FX(X1)-FX(X0)
X2 = X1-FX(X1)*(X1-X0)/D
X0 = X1
X1 = X2
DX = X1-X0
ISTEP = ISTEP+1
END DO
END SUBROUTINE SECANT
!
SUBROUTINE THREE (N,H,FI,F1,F2)
!
! Subroutine for 1st and 2nd order derivatives with the three-point
! formulas. Extrapolations are made at the boundaries. FI: input
! f(x); H: interval; F1: f'; and F2: f". Copyright (c) Tao Pang 1997.
!
IMPLICIT NONE
INTEGER, INTENT (IN) :: N
INTEGER :: I
REAL, INTENT (IN) :: H
REAL, INTENT (IN), DIMENSION (N) :: FI
REAL, INTENT (OUT), DIMENSION (N) :: F1,F2
!
! f' and f" from three-point formulas
!
DO I = 2, N-1
F1(I) = (FI(I+1)-FI(I-1))/(2.*H)
F2(I) = (FI(I+1)-2.0*FI(I)+FI(I-1))/(H*H)
END DO
!
! Linear extrapolation for the boundary points
!
F1(1) = 2.0*F1(2)-F1(3)
F1(N) = 2.0*F1(N-1)-F1(N-2)
F2(1) = 2.0*F2(2)-F2(3)
F2(N) = 2.0*F2(N-1)-F2(N-2)
END SUBROUTINE THREE
!
FUNCTION FX(X) RESULT (F)
USE CB
IMPLICIT NONE
REAL :: X,F,U,UX
!
F = 1.0-B*B/(X*X)-UX(X)/E
END FUNCTION FX
!
FUNCTION FBX(X) RESULT (FB)
USE CB
IMPLICIT NONE
REAL :: X,FB
!
FB = 1.0-B*B/(X*X)
END FUNCTION FBX
!
FUNCTION UX(X) RESULT (U)
USE CB
IMPLICIT NONE
REAL :: X,U
!
U = 1.0/X*EXP(-X/A)
END FUNCTION UX