2014-09-21 3 views
1

raytracing 코드가 제대로 작동하고 있으며 문제를 격리했을 수 있습니다. 필자는 Fortran 77에 익숙하지 않지만이 언어를 사용해 더 많은 경험을 쌓고 싶습니다 (날짜가 있더라도). 하위 루틴으로 변수를 파이프하는 데 사용할 수있는 서브 루틴 중 하나에 일부 EQUIVALENCE 문이 있습니다 (이 문제는 여기 절반의 문제 일 수 있음).Fortran 77 EQUIVALENCE 문 문제 코드

서브 루틴 : 서브 루틴 또는 항목 ELECTX가 나는 RINDEX 서브 루틴/항목에 일부 인쇄 문을 배치라고 직전

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- 

.
나는 내가 코드의이 작은 부분에서 얻을 것은 바로 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 
그래서이 질문의 longwinded 방법입니다 - 무슨 일 이니? 예를 들어 f와 같은 변수가 서브 루틴 QPARAB에 전달 될 것으로 예상했기 때문에 서브 루틴에서 인쇄 할 때 F = 7을 볼 것으로 기대합니다. 저는 근본적으로 단순한 오해가있을 것입니다. 앞서 언급했듯이 F와 같은 변수를 서브 루틴 QPARAB에 넣을 수 없다는 사실은 실제로 큰 문제입니다. 그 이유는 다음 계산이 0 또는 NaN으로 나오기 때문입니다. 나는 그것이 약간의 가치가 있다고 기대할 것이다. 어쩌면 데이터가 어떻게 든 들어 가지 않을 수도 있습니다. 다른 모든 것들은 (이 시점에서) 어느 정도는 작동하고있는 것으로 보입니다. 이 코드에서 유래

:

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를 사용하여 동일한 오류, QPARAB가 인수를 취하지 않는

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) 
+2

* Fortran 77 코드의 EQUIVALENCE 문에 대한 문제 * 예, 그렇기 때문에 요즘 우리가 역병처럼 피하는 이유가 여기 있습니다. –

+0

이 경우 동등성은 배열'w'의 특정 위치에 편리한 이름을 제공하기 위해 사용 된 것으로 보입니다. 'f'와 같은 기호는 서브 루틴에 대한 * 로컬 *입니다. 서브 루틴 외부에서는 이러한 것들이 배열 위치에 의해 참조 될 필요가 있습니다 (물론 호출 루틴에서 유사한 '동등성'문을 가지고 있지 않다면 말입니다). – agentp

답변

2

서브 루틴을 얻을 . 아무것도 전달되지 않습니다. 그것은 일반적인 블록 (범위 공유 변수) MODX, X, PXPR, PXPTH, PXPPH, PXPT, HMAX, ID, W0W에서 다음 변수들을로드한다. 또한 로컬 범위 변수 modxid을 선언 한 다음 선언되지 않은 모든 변수 (범위가 로컬 임)에 암시 적 타이핑을 할당합니다.

귀사의 변수 FW(6)과 같습니다. 이것은 내재적 인 변수 F (타입 real * 8)은 W(6)과 같은 메모리 위치를 가져야한다고 말합니다. F은이 서브 루틴으로 전달되지 않으며 실제로는 W의 특정 배열 구성원 인 서브 루틴의 로컬 이름입니다. 서브 루틴에 값을 F으로 전달하려면 서브 루틴을 호출하기 전에 변수 W(6)을 설정해야합니다. 이 작업을 수행하려면 범위에 W이 필요하므로 호출하는 서브 루틴에서 참조되는 /WW/ 공용 블록이 필요합니다.

관련 문제