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.

Was it helpful?

Solution

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.

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) to DO ... 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 notation

  • Modernize 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 loops

  • ALLOCATABLE arrays if appropriate

  • Good housekeeping: CLOSE statements paired with OPEN statements

  • Replace 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... :-)
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top