[Fortran] 纯文本查看 复制代码
PROGRAM MAIN
REAL N1,N2,N3
OPEN(3,FILE='透过.TXT')
OPEN(5,FILE='反射.TXT')
WRITE (*,*) '输入入射角余弦'
READ*,CC0
WRITE(*,*) '输入传输路径上依次三种介质的折射率'
READ*,N1,N2,N3
PRINT*,'输入光子数目'
READ*,N
G=1.159E-2
W0=0.9 !反照率
SL=W0
SA=1.0-SL
ZH=0.01
QET=2.261959E-1
DO 10 ROU=20,300,20
H=ZH*QET*ROU !光学厚度
CALL MCSUB(SA,SL,G,H,CC0,N,N1,N2,N3,TS,TT,RR)
WRITE (*,*) H,CC0,TS,TT,RR
WRITE (3,*) H,CC0,TT
WRITE (5,*) H,CC0,RR
10 CONTINUE
CLOSE(3)
CLOSE(5)
CLOSE(7)
STOP
END PROGRAM MAIN
!==================================================!====================================================
SUBROUTINE MCSUB(SA,SL,G,H,CC0,N,N1,N2,N3,TS,TT,RR)
INTEGER,PARAMETER::M=90
REAL,DIMENSION(2*M):: INTENSITY
REAL N1,N2,N3
REAL SA,SL,G,H,CC0
REAL TT,TS,RR
REAL SUMT,SUMR,R
W0=1.E-10
PAI=3.1415926
ST=SA+SL
SUMT=0.0
SUMR=0.0
DSITA=PAI/(2.*M)
K1=3
K2=5
K3=11
K4=17
K5=21
IF(N1.EQ.N2 .AND. N2.EQ.N3)THEN
SS=SL
ELSE
SS=ST
ENDIF
LOOP1: DO J=1,N
! 源抽样
TEMPUI=CC0
CALL RFRENEL(N1,N1,N2,TEMPUI,CC,R)
WE=1.0-R
SC=SQRT(1.-CC*CC)
CF=1.0
SF=0.0
X=0.0; Y=0.0 ; Z=0.0
RI=RAN(K1)
DO WHILE(RI.EQ.1.0)
RI=RAN(K1)
END DO
T=-ALOG(RI)/SS
Z=T*CC; X=T*SC
IF(Z.GT.H) CYCLE LOOP1
100 DO WHILE(Z.GT.0.0 .AND. Z.LT.H)
! 散射方向抽样
! 产生新的方向余弦
R1=RAN(K2)
IF (G.EQ.0.0) THEN
C=2*R1-1
ELSE
C=(1.+G*G-((1.-G*G)/(1.-G+2.*G*R1))**2)/(2.*G)
END IF
AC=SQRT(ABS(1.-C*C))
R1=RAN(K3)
F=2.*PAI*R1
U1=AC*COS(F)
V1=AC*SIN(F)
W1=C
B=V1*CC+W1*SC
U=U1*SF+CF*B
V=-U1*CF+SF*B
W=-V1*SC+W1*CC
WE=WE*EXP(-SA*T)
IF (WE.LE.W0) CYCLE LOOP1
UI=W
CALL RFRENEL(N1,N2,N3,UI,UT,R)
IF (W.LT.0.0) THEN
PRO=Z/(-W)
REW=EXP(-ST*PRO)
PROR=(1.0-R)*WE*REW
SUMR=SUMR+PROR
! 记录光子......
SITAT=ACOS(UT)
IF(ABS(SITAT-PAI).LT.1E-6)THEN
INDEX=2*M
ELSE
INDEX=INT(SITAT/DSITA+1)
ENDIF
INTENSITY(INDEX)=INTENSITY(INDEX)+PROR
ELSE IF(W.GT.0.0) THEN
TRO=(H-Z)/W
TEW=EXP(-ST*TRO)
PROT=(1.0-R)*WE*TEW
SUMT=SUMT+PROT
! 记录光子......
SITAT=ACOS(UT)
IF(ABS(SITAT-PAI/2).LT.1E-6)THEN
INDEX=M
ELSE
INDEX=INT(SITAT/DSITA+1)
ENDIF
INTENSITY(INDEX)=INTENSITY(INDEX)+PROT
END IF
! 下一状态的初始化.
RI=RAN(K4)
T=-ALOG(RI)/SS
XF=T*U; YF=T*V; ZF=T*W
X=X+XF; Y=Y+YF; Z=Z+ZF
CC=W
SC=SQRT(ABS(1.-CC*CC))
IF(SC.EQ.0.0) THEN
ELSE
CF=U/SC
SF=V/SC
END IF
END DO
IF(N1.EQ.N2 .OR. N2.EQ.N3) CYCLE LOOP1
IF(CC.LT.0.0) THEN
S1=Z/CC
ELSE IF(CC.GT.0.0) THEN
S1=(Z-H)/CC
ENDIF
XF=S1*U; YF=S1*V; ZF=S1*W
X=X-XF; Y=Y-YF; Z=Z-ZF
CC=-CC
XF=S1*U; YF=S1*V; ZF=S1*CC
X=X+XF; Y=Y+YF; Z=Z+ZF
T=S1
WE=WE*R
GOTO 100
END DO LOOP1
T0=EXP(-ST*H/CC0)
TS=SUMT/N
TT=TS+T0 !总透过
RR=SUMR/N
RETURN
END SUBROUTINE MCSUB
SUBROUTINE RFRENEL(N1,N2,N3,UI,UT,R)
REAL N1,N2,N3
REAL R,UI,UT
REAL UC
INTEGER P
IF(UI .LT. 0.0) THEN
RNI=N2
RNT=N1
P=-1
ELSE IF(UI .GT. 0.0) THEN
RNI=N2
RNT=N3
P=1
END IF
IF(RNI.EQ.RNT) THEN
R=0.0
UT=UI
RETURN
ENDIF
TEMPU=RNT/RNI
IF(RNT.GE.RNI) THEN
UC=0.0
ELSE
UC=SQRT(1-TEMPU*TEMPU)
ENDIF
IF(P*UI.GT.UC)THEN
S=1.0-UI*UI
UT=P*SQRT(1.0-S/(TEMPU*TEMPU))
S1=RNT*UI-RNI*UT
S2=RNT*UI+RNI*UT
S3=RNI*UI-RNT*UT
S4=RNI*UI+RNT*UT
R=0.5*S1*S1/(S2*S2)+0.5*S3*S3/(S4*S4)
UI=-UI
ELSE
R=1.0
UT=0.0
UI=-UI
ENDIF
RETURN
END SUBROUTINE RFRENEL
!****************************************************************!******************************************************************
!产生随机数
FUNCTION RAN(IX)
M=2**25
RM=FLOAT(M)
IX=13*IX+7
70 IF(IX.LE.M) GOTO 17
IX=IX-M
GOTO 70
17 RAN=FLOAT(IX)/RM
RETURN
END FUNCTION RAN
PROGRAM MAIN
REAL N1,N2,N3
OPEN(3,FILE='透过.TXT')
OPEN(5,FILE='反射.TXT')
WRITE (*,*) '输入入射角余弦'
READ*,CC0
WRITE(*,*) '输入传输路径上依次三种介质的折射率'
READ*,N1,N2,N3
PRINT*,'输入光子数目'
READ*,N
G=1.159E-2
W0=0.9 !反照率
SL=W0
SA=1.0-SL
ZH=0.01
QET=2.261959E-1
DO 10 ROU=20,300,20
H=ZH*QET*ROU !光学厚度
CALL MCSUB(SA,SL,G,H,CC0,N,N1,N2,N3,TS,TT,RR)
WRITE (*,*) H,CC0,TS,TT,RR
WRITE (3,*) H,CC0,TT
WRITE (5,*) H,CC0,RR
10 CONTINUE
CLOSE(3)
CLOSE(5)
CLOSE(7)
STOP
END PROGRAM MAIN
!==================================================!====================================================
SUBROUTINE MCSUB(SA,SL,G,H,CC0,N,N1,N2,N3,TS,TT,RR)
INTEGER,PARAMETER::M=90
REAL,DIMENSION(2*M):: INTENSITY
REAL N1,N2,N3
REAL SA,SL,G,H,CC0
REAL TT,TS,RR
REAL SUMT,SUMR,R
W0=1.E-10
PAI=3.1415926
ST=SA+SL
SUMT=0.0
SUMR=0.0
DSITA=PAI/(2.*M)
K1=3
K2=5
K3=11
K4=17
K5=21
IF(N1.EQ.N2 .AND. N2.EQ.N3)THEN
SS=SL
ELSE
SS=ST
ENDIF
LOOP1: DO J=1,N
! 源抽样
TEMPUI=CC0
CALL RFRENEL(N1,N1,N2,TEMPUI,CC,R)
WE=1.0-R
SC=SQRT(1.-CC*CC)
CF=1.0
SF=0.0
X=0.0; Y=0.0 ; Z=0.0
RI=RAN(K1)
DO WHILE(RI.EQ.1.0)
RI=RAN(K1)
END DO
T=-ALOG(RI)/SS
Z=T*CC; X=T*SC
IF(Z.GT.H) CYCLE LOOP1
100 DO WHILE(Z.GT.0.0 .AND. Z.LT.H)
! 散射方向抽样
! 产生新的方向余弦
R1=RAN(K2)
IF (G.EQ.0.0) THEN
C=2*R1-1
ELSE
C=(1.+G*G-((1.-G*G)/(1.-G+2.*G*R1))**2)/(2.*G)
END IF
AC=SQRT(ABS(1.-C*C))
R1=RAN(K3)
F=2.*PAI*R1
U1=AC*COS(F)
V1=AC*SIN(F)
W1=C
B=V1*CC+W1*SC
U=U1*SF+CF*B
V=-U1*CF+SF*B
W=-V1*SC+W1*CC
WE=WE*EXP(-SA*T)
IF (WE.LE.W0) CYCLE LOOP1
UI=W
CALL RFRENEL(N1,N2,N3,UI,UT,R)
IF (W.LT.0.0) THEN
PRO=Z/(-W)
REW=EXP(-ST*PRO)
PROR=(1.0-R)*WE*REW
SUMR=SUMR+PROR
! 记录光子......
SITAT=ACOS(UT)
IF(ABS(SITAT-PAI).LT.1E-6)THEN
INDEX=2*M
ELSE
INDEX=INT(SITAT/DSITA+1)
ENDIF
INTENSITY(INDEX)=INTENSITY(INDEX)+PROR
ELSE IF(W.GT.0.0) THEN
TRO=(H-Z)/W
TEW=EXP(-ST*TRO)
PROT=(1.0-R)*WE*TEW
SUMT=SUMT+PROT
! 记录光子......
SITAT=ACOS(UT)
IF(ABS(SITAT-PAI/2).LT.1E-6)THEN
INDEX=M
ELSE
INDEX=INT(SITAT/DSITA+1)
ENDIF
INTENSITY(INDEX)=INTENSITY(INDEX)+PROT
END IF
! 下一状态的初始化.
RI=RAN(K4)
T=-ALOG(RI)/SS
XF=T*U; YF=T*V; ZF=T*W
X=X+XF; Y=Y+YF; Z=Z+ZF
CC=W
SC=SQRT(ABS(1.-CC*CC))
IF(SC.EQ.0.0) THEN
ELSE
CF=U/SC
SF=V/SC
END IF
END DO
IF(N1.EQ.N2 .OR. N2.EQ.N3) CYCLE LOOP1
IF(CC.LT.0.0) THEN
S1=Z/CC
ELSE IF(CC.GT.0.0) THEN
S1=(Z-H)/CC
ENDIF
XF=S1*U; YF=S1*V; ZF=S1*W
X=X-XF; Y=Y-YF; Z=Z-ZF
CC=-CC
XF=S1*U; YF=S1*V; ZF=S1*CC
X=X+XF; Y=Y+YF; Z=Z+ZF
T=S1
WE=WE*R
GOTO 100
END DO LOOP1
T0=EXP(-ST*H/CC0)
TS=SUMT/N
TT=TS+T0 !总透过
RR=SUMR/N
RETURN
END SUBROUTINE MCSUB
SUBROUTINE RFRENEL(N1,N2,N3,UI,UT,R)
REAL N1,N2,N3
REAL R,UI,UT
REAL UC
INTEGER P
IF(UI .LT. 0.0) THEN
RNI=N2
RNT=N1
P=-1
ELSE IF(UI .GT. 0.0) THEN
RNI=N2
RNT=N3
P=1
END IF
IF(RNI.EQ.RNT) THEN
R=0.0
UT=UI
RETURN
ENDIF
TEMPU=RNT/RNI
IF(RNT.GE.RNI) THEN
UC=0.0
ELSE
UC=SQRT(1-TEMPU*TEMPU)
ENDIF
IF(P*UI.GT.UC)THEN
S=1.0-UI*UI
UT=P*SQRT(1.0-S/(TEMPU*TEMPU))
S1=RNT*UI-RNI*UT
S2=RNT*UI+RNI*UT
S3=RNI*UI-RNT*UT
S4=RNI*UI+RNT*UT
R=0.5*S1*S1/(S2*S2)+0.5*S3*S3/(S4*S4)
UI=-UI
ELSE
R=1.0
UT=0.0
UI=-UI
ENDIF
RETURN
END SUBROUTINE RFRENEL
!****************************************************************!******************************************************************
!产生随机数
FUNCTION RAN(IX)
M=2**25
RM=FLOAT(M)
IX=13*IX+7
70 IF(IX.LE.M) GOTO 17
IX=IX-M
GOTO 70
17 RAN=FLOAT(IX)/RM
RETURN
END FUNCTION RAN