The general structure of a Fortran module:
module <MODULE-NAME>
! Declare variables
contains
! Define subroutines or functions
end module <MODULE-NAME>
A program or subroutine can use this module:
program <NAME>
use <MODULE-NAME>
! Declare variables
! Executable statements
end program <NAME>
The line:
use <MODULE-NAME>
can be replaced by:
use <MODULE-NAME>, only: <LIST OF SYMBOLS>
to specify that only certain variables/subroutines/functions from the module should be used. Doing it this way also makes it clear exactly what symbols are coming from which module in the case where you use several modules.
A very simple module is:
1 2 3 4 5 6 7 8 9 10 11 | ! $UWHPSC/codes/fortran/multifile2/sub1m.f90
module sub1m
contains
subroutine sub1()
print *, "In sub1"
end subroutine sub1
end module sub1m
|
and a program that uses this:
1 2 3 4 5 6 7 | ! $UWHPSC/codes/fortran/multifile2/main.f90
program demo
use sub1m, only: sub1
print *, "In main program"
call sub1()
end program demo
|
Can define global variables in modules to be used in several different routines.
In Fortran 77 this had to be done with common blocks — much less elegant.
Subroutine/function interface information is generated to aid in checking that proper arguments are passed.
It’s often best to put all subroutines and functions in modules for this reason.
Can define new data types to be used in several routines.
Modules must be compiled before any program units that use the module. When a module is compiled, a .o file is created, but also a .mod file is created that must be present in order to compile a unit that uses the module.
Here is an example of a module that defines one parameter pi and two functions:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | ! $UWHPSC/codes/fortran/circles/circle_mod.f90
module circle_mod
implicit none
real(kind=8), parameter :: pi = 3.141592653589793d0
contains
real(kind=8) function area(r)
real(kind=8), intent(in) :: r
area = pi * r**2
end function area
real(kind=8) function circumference(r)
real(kind=8), intent(in) :: r
circumference = 2.d0 * pi * r
end function circumference
end module circle_mod
|
This might be used as follows:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | ! $UWHPSC/codes/fortran/circles/main.f90
program main
use circle_mod, only: pi, area
implicit none
real(kind=8) :: a
! print parameter pi defined in module:
print *, 'pi = ', pi
! test the area function from module:
a = area(2.d0)
print *, 'area for a circle of radius 2: ', a
end program main
|
This gives the following output:
pi = 3.14159265358979
area for a circle of radius 2: 12.5663706143592
Note: that a parameter can be defined with a specific value that will then be available to all program units using the module.
It is also possible to declare variables that can be shared between all program units using the module. This is a way to define “global variables” that might be set in one program unit and used in another, without the need to pass the variable as a subroutine or function argument. Module variables can be defined in a module and the Fortran statement
save
is used to indicate that variables defined in the module should have values saved between one use of the module to another. You should generally specify this if you use any module variables.
Here is another version of the circles code that stores pi as a module variable rather than a parameter:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | ! $UWHPSC/codes/fortran/circles/circle_mod.f90
! Version where pi is a module variable.
module circle_mod
implicit none
real(kind=8) :: pi
save
contains
real(kind=8) function area(r)
real(kind=8), intent(in) :: r
area = pi * r**2
end function area
real(kind=8) function circumference(r)
real(kind=8), intent(in) :: r
circumference = 2.d0 * pi * r
end function circumference
end module circle_mod
|
In this case we also need to initialize the variable pi by means of a subroutine such as:
1 2 3 4 5 6 7 8 9 | ! $UWHPSC/codes/fortran/circles/initialize.f90
subroutine initialize()
! Set the value of pi used elsewhere.
use circle_mod, only: pi
pi = acos(-1.d0)
end subroutine initialize
|
These might be used as follows in a main program:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | ! $UWHPSC/codes/fortran/circles/main.f90
program main
use circle_mod, only: pi, area
implicit none
real(kind=8) :: a
call initialize() ! sets pi
! print module variable pi:
print *, 'pi = ', pi
! test the area function from module:
a = area(2.d0)
print *, 'area for a circle of radius 2: ', a
end program main
|
This example can be compiled and executed by going into the directory $UWHPSC/fortran/circles2/ and typing:
$ gfortran circle_mod.f90 initialize.f90 main.f90 -o main.exe
$ ./main.exe
Or by using the Makefile in this directory:
$ make main.exe
$ ./main.exe
Here is the Makefile:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | # $UWHPSC/codes/fortran/circles2/Makefile
OBJECTS = circle_mod.o \
main.o \
initialize.o
MODULES = circle_mod.mod
.PHONY: clean
output.txt: main.exe
./main.exe > output.txt
main.exe: $(MODULES) $(OBJECTS)
gfortran $(OBJECTS) -o main.exe
%.o: %.f90
gfortran -c $<
%.mod: %.f90
gfortran -c $<
clean:
rm -f $(OBJECTS) $(MODULES) main.exe
|
For more about Makefiles, see Makefiles and Makefile references.