Fortran tips and tricks
Fortran compilers
There are several free fortran compilers available now. GCC has a sufficiently good compiler called gfortran. Another free compiler is g95 which is the work of Andy Vaught. If you are using Linux then the ifort compiler from Intel is also free for non-commercial use, and probably the best choice on Intel machines.
Passing a function to a subroutine
You can pass a function as an argument to a subroutine. See the following example with two functions f and g. The subroutine testfunc is first called with f and then with g. Compile and run the code.
program main implicit real*8 (a-h,o-z) external f, g call testfunc(f) call testfunc(g) stop end subroutine testfunc(func) implicit real*8 (a-h,o-z) x=func() return end real*8 function f() implicit real*8 (a-h,o-z) print*,"This is function f" f = 1.0 return end real*8 function g() implicit real*8 (a-h,o-z) print*,"This is function g" g = 1.0 return end
You should get the following output.
This is function f This is function g
It is important to the declare the functions as external.
Measuring elapsed time
You can find out how long your program has been running by calling the built-in etime() function. This includes only time spent running your program, regardless of what else is running on the same processor. The time is reported in seconds, in three parts:
- User time, time actually spent in your program;
- System time, time spent in the operating system on your program’s behalf; and
- Total time.
To measure elapsed time, declare a real*4 array with two elements, and pass that array as an argument to etime. The first element of the array will be set to the user time, the second element will be set to the system time, and the etime() function will return the total time.
program main real etime real elapsed(2) real total integer i, j do i = 1, 5000000 j = j + 1 end do total = etime(elapsed) print *, 'End: total=', total, ' user=', elapsed(1), + ' system=', elapsed(2) stop end
Random numbers
The Fortran rand() always returns a number between 0 and 1. More specifically, it is a number in the half-open interval [0,1), so you might get a 0.0 result, but the result will never be exactly 1.0 or greater. Such a number can be scaled to produce uniformly distributed pseudorandom numbers in any interval.
- If you want an integer between m and n inclusive, use the expression:
int(rand(0)*(n+1-m))+m
- If you want a real number in the interval [x,y), use this expression:
(rand(0)*(y-x))+x
Getting current time and date
To get the current date and time, declare two arrays of type integer*4, each with three elements. Then call the built-in idate and itime functions to place the day, month, and year into the first array and the hour, minute, and second into the second array:
program when integer*4 today(3), now(3) call idate(today) ! today(1)=day, (2)=month, (3)=year call itime(now) ! now(1)=hour, (2)=minute, (3)=second write ( *, 10 ) today(2), today(1), today(3), now 10 format ( 'Date ', i2.2, '/', i2.2, '/', i4.4, '; time ', & i2.2, ':', i2.2, ':', i2.2 ) stop end
Running this program might produce output something like this:
Date 04/01/1995; time 14:07:40
Reading big-endian, unformatted files
- pgf compiler: Open the file using the “convert” option
open(10,file='case1_u.cogsg',form='unformatted',iostat=ios, & status='old', convert='BIG_ENDIAN')
- g95 compiler: This does not seem to accept the “convert” flag. You can use a compile flag as below
g95 -fendian=big convert.f

