There are tools to convert FORTRAN 77 to Fortran 90 (converter software for fortran 77 to fortran 90). You might start with one of those. If the code will be continued to be used unchanged, then regard it as legacy code and don't tinker with it. If its not broken, don't fix it. If the code is going to be improved or expanded, porting to Fortran 90 will help the programmer. Improving from FORTRAN 77 to Fortran >=90 is an investment; balance how much investment to make versus how much programming work you want to do on the code. Make changes in stages and regression test the program to make sure that you don't introduce bugs. The work can be non-trivial. To have fully modern code you should remove the implicit declaration and declare all of the variables. Then you can rename some variables to have more meaningful names without concern for implicit typing.
How to update Fortran 77 programs to more modern Fortran to improve readability?
-
11-06-2023 - |
Question
I am attempting to update the following Fortran 77 program using more modern Fortran languages to improve its readability. Can anyone provide some suggestions? I tried using find and replace to change "IS" to a more readable variables, but that caused type cast problems. This task proved to be very tedious for other Fortran 77 programs much larger than this one.
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
I am still learning Fortran. I have a very old text book on Fortran applied to Molecular Dynamics with the following Fortran example. I was faced with the difficulty of learning a new language and translating Fortran help from new to ancient Fortran. I have spent time researching the problem and discovered that forcing non-implicit helps me to understand the program better. I am struggling with with some of Fortran's machine-like features like limited line space, character column syntax, and indenting the code to look neater without breaking the logic. In general, making the code look more readable without breaking the logic has been the greatest learning curve for me.
Solution
OTHER TIPS
Alternatively you might learn more if you fore go the converter and update your programs manually. Start with this. Other things to consider:
Use free format
Convert
DO WHILE
(deprecated) toDO ... IF( ) EXIT ... END DO
Note Need opposite logical expressions; for example, the logical operator
<=
becomes>
Consider replacing old intrinsic functions with more specific ones
Replace old logical operators in
IF( ) THEN
with modern notationModernize variable declarations, making use of
MODULE
,PARAMETER
for [physical] constants,USE
for functions and subroutines, double precision (if needed),INTENT
for dummy variables on functions and subroutines, and--finally--CHARACTER(LEN= )
Text labels on
DO
loopsALLOCATABLE
arrays if appropriateGood housekeeping:
CLOSE
statements paired withOPEN
statementsReplace common tasks with modern intrinsic functions (e.g.
maxval
)
Finally, do a "thorough" compile using gfortran -g -std=f2008 -Wall -Wextra -O2
to isolate and address potential problems.
A more comprehensive list of possible changes can be found here.
Some good answers here already. I want to add three things that haven't been mentioned yet:
- Rename routine and variable names to something longer and more descriptive. If you get an editor with autocomplete (e.g. Photran or a plugin to most decent text editors) you can still type code effectively.
- Refactor long blocks of code into smaller subroutines. Create some automatic tests in advance to verify that you don't change the behaviour.
- Convert to lower case. Some might disagree here though... :-)