我正在努力让光线跟踪代码正常工作,我想我可能已经解决了这个问题。我是Fortran 77的新手,但希望获得使用这种语言的更多经验(即使它已过时)。我在其中一个子程序中有一些EQUIVALENCE语句可用于将变量传递到子程序中(这可能是问题的一半)。
子程序:
c s/r qparxdp
SUBROUTINE QPARAB PARA001
implicit real*8 (a-h, o-z)
character*8 modx, id
C PLAIN PARABOLIC OR QUASI-PARABOLIC PROFILE PARA002
C W(104) = 0. FOR A PLAIN PARABOLIC PROFILE PARA003
C = 1. FOR A QUASI-PARABOLIC PROFILE PARA004
COMMON /XX/ MODX(2),X,PXPR,PXPTH,PXPPH,PXPT,HMAX PARA005
COMMON R(6) /WW/ ID(10),W0,W(400) PARA006
EQUIVALENCE (EARTHR,W(2)),(F,W(6)),(FC,W(101)),(HM,W(102)), PARA007
1 (YM,W(103)),(QUASI,W(104)),(PERT,W(150)) PARA008
data ipass / 0 /
ENTRY ELECTX PARA010
print*, W(2), W(6), W(101), W(102), W(103), W(104), W(150)
print*, ' Electx W(6), f ', F, EARTHR, FC, HM, YM, QUASI, PERT, ipass
ipass = ipass + 1
if(ipass.gt.10000) ipass = 2
if(ipass.eq.1) return
modx(1) = 'qparab'
HMAX=HM PARA011
x = 0.d0
pxpr = 0.d0
pxpth = 0.d0
pxpph = 0.d0
H=R(1)-EARTHR PARA013
if(f.le.0.d0) print*, ' YM', YM
FCF2=(FC/F)**2 PARA014
CONST=1.d0 PARA015
IF (QUASI.EQ.1.d0) CONST=(EARTHR+HM-YM)/R(1) PARA016
Z=(H-HM)/YM*CONST PARA017
X=dMAX1(0.d0,FCF2*(1.d0-Z*Z)) PARA018
print*, 'X in qparx', X, Z
IF (X.EQ.0.d0) GO TO 50 PARA019
IF (QUASI.EQ.1.d0) CONST=(EARTHR+HM)*(EARTHR+HM-YM)/R(1)**2 PARA020
PXPR=-2.d0*Z*FCF2/YM*CONST PARA021
50 IF (PERT.NE.0.d0) CALL ELECT1 PARA022
RETURN PARA023
END PARA024-
在调用子程序或条目ELECTX之前,我在RINDEX子程序/条目中放置了一些打印语句。
我在调用RINDEX之前检查了一些输入
ENTRY RINDEX
write(*,*), 'Starting Rindex in ahnwfnc', F
if(ray.eq.0.d0.and.ipass.eq.0) print*, ' no magnetic field'
ipass = 1
OM=PIT2*1.d6*F
C2=C*C
K2=KR*KR+KTH*KTH+KPH*KPH
OM2=OM*OM
VR =C/OM*KR
VTH=C/OM*KTH
VPH=C/OM*KPH
write(*,*), OM, C2, K2, OM2, VR, VTH, VPH, F
CALL ELECTX
我从这一小段代码中得到的是:
fstep,fbeg,fend 1. 7. 8.
fbeg,fstep,f 7. 1. 0.
f 7. 7.
f before Rindex 7.
Starting Rindex in ahnwfnc 7.
43982297.2 8.98755431E+10 1. 1.93444246E+15 0.00640514066 0.00231408417
0.000282636641 7.
0. 0. 0. 0. 0. 0. 0.
Electx W(6),f 0. 0. 0. 0. 0. 0. 0. 1
所以这是一个长篇大论的问题 - 发生了什么?我期望像f这样的变量被传递到子程序QPARAB中,所以当我在子程序中打印时,我希望看到F = 7.我可能从根本上误解了一些简单的东西。正如我已经提到的那样,我似乎无法将F之类的变量引入子程序QPARAB这一事实实际上是个大问题,因为以下计算结果为0或NaN。我希望它有一些价值。那么也许数据不会以某种方式进入?其他一切(在这一点上)似乎在某种程度上起作用。
此代码来自:
我正在使用一个小的shell脚本(这可能是一团糟):
g77 -c -O3 raytr_dp.for readw_dp.for trace_dp.for reach_dp.for backup_d.for dummy.for \
polcar_d.for printr_d.for rkam_dp.for hamltn_d.for ahwfnc_d.for \
qparxdp.for dipoly_d.for spoints.for ggm_dp.for secnds.for
g77 -o main -O3 raytr_dp.o readw_dp.o trace_dp.o reach_dp.o backup_d.o dummy.o \
polcar_d.o printr_d.o rkam_dp.o hamltn_d.o ahwfnc_d.o \
qparxdp.o dipoly_d.o spoints.o ggm_dp.o secnds.o
我正在使用的g77例程是在http://hpc.sourceforge.net/下载的,最后我使用gfortran得到了同样的错误,
Using built-in specs.
COLLECT_GCC=gfortran
COLLECT_LTO_WRAPPER=/usr/local/gfortran/libexec/gcc/x86_64-apple-darwin13/4.9.0/lto-wrapper
Target: x86_64-apple-darwin13
Thread model: posix
gcc version 4.9.0 (GCC)
答案 0 :(得分:2)
子程序QPARAB
不带任何参数,例如没有任何东西传递给它。它从公共块(范围之间共享的变量)MODX
,X
,PXPR
,PXPTH
,PXPPH
,PXPT
加载以下变量, HMAX
,ID
,W0
和W
。此外,它声明了本地范围变量modx
和id
,然后为所有未声明的变量(范围内是本地的)变量分配隐式类型。
您感兴趣的变量F
等同于撰写W(6)
。这表示隐式变量F
(类型为真* 8)必须与W(6)
具有相同的内存位置。 F
未传递到此子例程,它是子例程的本地名称,它实际上是W
的特定数组成员。如果要将值传递到子例程F
,则需要在调用子例程之前设置变量W(6)
。请注意,为了做到这一点,您需要在范围内W
,因此您需要在您调用的子例程中引用的/WW/
公共块。