我正在尝试使用更现代的Fortran语言更新以下Fortran 77程序,以提高其可读性。有人可以提供一些建议吗?我尝试使用find和replace将“IS”更改为更易读的变量,但这会导致类型转换问题。事实证明,对于比这个大得多的其他Fortran 77程序来说,这项任务非常繁琐。
C 3D ISING MODEL
C Critical temperature TC = 4.5116=1/.22165
DIMENSION IS(10,10,10), EX(13)
REAL *8 R(1)
DATA IS/1000*1/
ITMAX=5000
ISTART=4000
L=10
NR=1
ISEED=768521034
M=L*L*L
DO 1000 K=1,24
TR=0.05+(K-1)*.05
T=TR/.221655
MR=0.
DO 3 I=1, 13, 2
3 EX(I)=EXP(-2*(I-7.)/T)
DO 2 ITIME=1,ITMAX
DO 1 K1=1,L
K1P1=K1+1
K1M1=K1-1
IF(K1.EQ.1) K1M1=L
IF(K1.EQ.L) K1P1=1
DO 1 K2=1,L
K2P1=K2+1
K2M1=K2-1
IF(K2.EQ.1) K2M1=L
IF(K2.EQ.L) K2P1=1
DO 1 K3=1,L
K3P1=K3+1
K3M1=K3-1
IF(K3.EQ.1) K3M1=L
IF(K3.EQ.L) K3P1=1
IEN=7+IS(K3,K2,K1)*(IS(K3M1,K2,K1)+IS(K3P1,K2,K1)+IS(K3,K2M1,K1)
& +IS(K3,K2P1,K1)+IS(K3,K2,K1M1)+IS(K3,K2,K1P1))
CALL GGUBS(ISEED,NR,R)
IF(EX(IEN).LT.R(1)) GOTO 1
IS(K3,K2,K1)=-IS(K3,K2,K1)
M=M+2*IS(K3,K2,K1)
C WRITE(*,*) M,ITIME
1 CONTINUE
IF (ITIME.GT.ISTART) MR=MR+M
2 CONTINUE
WRITE(*,*) FLOAT(MR)/1000./FLOAT((ITMAX-ISTART)),TR
WRITE(1,*) FLOAT(MR)/1000./FLOAT((ITMAX-ISTART)),TR
1000 CONTINUE
STOP
END
SUBROUTINE GGUBS(ISEED,NR,R)
IMPLICIT REAL *8(A-H,O-Z)
DIMENSION R(NR)
DATA D2P31M/2147483647.D0/
DATA D2P31/2147483648.D0/
DO 7 I=1,NR
ISEED=MOD(16807.D0*ISEED, D2P31M)
R(I)=ISEED/D2P31
7 CONTINUE
RETURN
END
我还在学习Fortran。我有一本关于Fortran的非常古老的教科书应用于分子动力学,下面是Fortran示例。我面临着学习新语言的困难,并将Fortran的帮助从新的Fortran转换为古老的Fortran。我花时间研究这个问题,发现强迫非隐式有助于我更好地理解程序。我正在努力使用Fortran的一些类似于机器的功能,例如有限的行空间,字符列语法,以及在不破坏逻辑的情况下缩进代码以使其看起来更整洁。通常,在不破坏逻辑的情况下使代码看起来更具可读性对我来说是最好的学习曲线。
答案 0 :(得分:4)
有一些工具可以将FORTRAN 77转换为Fortran 90(converter software for fortran 77 to fortran 90)。你可以从其中一个开始。如果代码将继续保持不变,则将其视为遗留代码,不要修改它。如果没有损坏,请不要修理它。如果要改进或扩展代码,移植到Fortran 90将有助于程序员。从FORTRAN 77改为Fortran> = 90是一项投资;平衡要投入多少投资与您希望对代码进行多少编程工作。分阶段进行更改并对程序进行回归测试,以确保不会引入错误。这项工作可能非常重要。要拥有完全现代的代码,您应该删除隐式声明并声明所有变量。然后,您可以重命名某些变量以获得更有意义的名称,而无需考虑隐式类型。
答案 1 :(得分:1)
或者,如果您要转换并手动更新程序,您可能会了解更多信息。从this开始。其他需要考虑的事项:
使用免费格式
将DO WHILE
(已弃用)转换为DO ... IF( ) EXIT ... END DO
注意需要相反的逻辑表达式;例如,逻辑运算符<=
变为>
考虑用更具体的函数替换旧的内部函数
使用现代符号
IF( ) THEN
中的旧逻辑运算符
现代化变量声明,利用MODULE
,PARAMETER
表示[物理]常数,USE
表示函数和子程序,双精度(如果需要),{{1对于函数和子例程的虚拟变量,以及 - - - INTENT
CHARACTER(LEN= )
循环上的文字标签
DO
数组(如果适用)
良好的内务管理:ALLOCATABLE
陈述与CLOSE
陈述搭配
将常见任务替换为现代内在函数(例如OPEN
)
最后,使用maxval
进行“彻底”编译,以隔离和解决潜在问题。
可以找到更全面的可能更改列表here。
答案 2 :(得分:0)
这里有一些好的答案。我想补充三件尚未提及的内容: