.. _ch02-fortran-modules: ============================================================= Fortran modules ============================================================= The general structure of a Fortran module:: module ! Declare variables contains ! Define subroutines or functions end module A program or subroutine can *use* this module:: program use ! Declare variables ! Executable statements end program The line:: use can be replaced by:: use , only: 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: .. literalinclude:: ./codes/sub1m.f90 :language: fortran :linenos: and a program that uses this: .. literalinclude:: ./codes/main.f90 :language: fortran :linenos: Some reasons to use modules --------------------------- * Can define global variables in modules to be used in several different routines (we will see more examples later). 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. Compiling modules ----------------- 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. Circles module example ---------------------- Here is an example of a module that defines one parameter `pi` and two functions: .. literalinclude:: ./codes/circle1/circle_mod.f90 :language: fortran :linenos: This might be used as follows: .. literalinclude:: ./codes/circle1/circle_main.f90 :language: fortran :linenos: To compile, you first need to generate ``circle_mod.o`` and ``circle_mod.mod``, followed by ``circle_main.o``. Only then, you can link the two object files together to produce a binary (or an executable) file, e.g., ``circle_main.exe`` :: $ gfortran -c circle_mod.f90 # produces circle_mod.o and circle_mod.mod $ gfortran -c circle_main.f90 # produces circle_main.o $ gfortran circle_mod.o circle_main.o -o circle_main.exe # linking to generate circle_main.exe If you reverse the order of the compilations between ``circle_mod.f90`` and ``circle_main.f90`` in the above it won't compile and fail with an error message such as:: circle_main.f90:5.6: use circle_mod, only: pi, area 1 Fatal Error: Can't open module file 'circle_mod.mod' for reading at (1): No such file or directory Executing the program by running `./circle_main.ext` after a successful compilation gives the following output:: pi = 3.14159265358979 area for a circle of radius 2: 12.5663706143592 Note that a parameter defined with a specific value in a module (e.g., `pi` as defined in `circle_mod.f90`) is available to all program units using the module (e.g., `pi` is accessible from `circle_main.f90` via `use circle_mod, only: pi`). See :ref:`module_variables`. .. note:: You now may guess that compiling :math:`N` codes via using :math:`N` command lines will be very daunting, especially when :math:`N` is large. In this case the compilation via using a ``Makefile`` becomes very handy (see :ref:`ch02-fortran-makefiles`). .. _module_variables: Module variables ----------------- 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: .. literalinclude:: ./codes/circle2/circle_mod2.f90 :language: fortran :linenos: In this case we also need to initialize the variable *pi* by means of a subroutine such as: .. literalinclude:: ./codes/circle2/circle_initialize2.f90 :language: fortran :linenos: These might be used as follows in a main program: .. literalinclude:: ./codes/circle2/circle_main2.f90 :language: fortran :linenos: This example can be compiled and executed by going into the directory ``$lecture_note/chapters/chapt02/codes/circles2/`` and typing:: $ gfortran circle_mod2.f90 circle_initialize2.f90 circle_main2.f90 -o main.exe $ ./main.exe Or by using the Makefile in this directory:: $ make main.exe $ ./main.exe Here is the Makefile: .. literalinclude:: ./codes/circle2/Makefile :language: make :linenos: In the next section we are going to learn more about Makefiles, see :ref:`ch02-fortran-makefiles`.