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. 8-O

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
 
comp/fortran.txt · Last modified: 2008/04/25 15:57 by pc     Back to top
Get Firefox! Recent changes RSS feed Creative Commons License Donate Powered by PHP Valid XHTML 1.0 Valid CSS Driven by DokuWiki
This site will render correctly in Mozilla/Firefox.