26) Introduction to Fortran#

Today:

  1. How to compile a Fortran program

  2. The simplest Fortran program

  3. Hello, World! and Simple I/O

  4. Arithmetic in Fortran

  5. Functions 5.1 Subroutines

  6. Interface Blocks

  7. Modules

1. How to compile a Fortran program#

Historically, Fortran 77, is an older version of the language that still is often used. It is a little simpler in some ways than later versions such as Fortran 90 and Fortran 95.

  • Similar to C, Fortran is a compiled language. Hence, before your program can be executed, it must be compiled. This converts the English-like text of a Fortran program into a binary form that the processor understands.

You compile a program by typing a line similar to the following:

gfortran do_nothing.f -o do_nothing

It is important that you understand what is happening here:

  • gfortran here is the name of the Fortran compiler. This is a free compiler that often is included in Linux distributions. Your compiler may have a different name such as ifort (from Intel) or pgf77.

  • myprogram.f is the name of the file that contains the source code of your program. The source code is the file of instructions that you actually edit and type. Your source file could be named something other than myprogram.f, such as homework1.f or some other descriptive name.

  • On many systems the name of the source file must end with the suffix .f or the compiler will not recognize it as Fortran code.

  • The -o option tells the compiler that the next word (here, myprogram) will be the name of the binary version of the program (or executable for the program). If you omit this option, most systems will use the default name a.out for the binary version regardless of the name of your program. It’s OK to use this default, though it’s usually helpful to use a more meaningful name.

  • The binary file is often called the executable file because the computer can run (execute) it.

  • On Unix systems (or Linux, or other Unix variants), to run the program, you may need to explicitly state that the program resides in your current directory. The shorthand for the current directory is . (a period, or “dot”). Then the program would be run as:

./myprogram

2. The simplest Fortran program#

The simplest Fortran program is what might be called a “do-nothing” program. It contains all of the required parts of a Fortran program. The program is as follows:

1      PROGRAM MAIN
2      STOP
3      END

The program simply starts and stops. It has a beginning (the PROGRAM instruction), and then tells the system to halt execution (STOP). Notice that there is both STOP and END. The difference is that STOP tells the system to halt the execution of the program, while END identifies the end of your instructions - that is, END will always appear as the last line of a program.

Complex programs may have more than one STOP instruction; for example, execution may be halted if an error occurs or a limit is reached. A single instruction in Fortran is usually called a statement.

Although seemingly trivial, writing and executing this program illustrates some of the basic rules of writing Fortran programs:

  • Only one instruction (or statement) may appear on a line.

  • The statement is limited to the first 72 characters of each line. Many modern Fortran 77 compilers will accept longer lines, but this is not standard.

  • The program is written in all uppercase letters. Strictly speaking, uppercase is the standard for Fortran 77 but almost all Fortran compilers will accept lowercase letters. (Such compilers are not “case sensitive”.) We will use uppercase because it helps to set off the program from the surrounding explanation. You can use either upper or lower case, whichever you like.

  • Notice that all of the lines in the example above begin with 6 blank spaces. This is because the Fortran 77 standard requires that the first 6 characters of a line be reserved for statement numbers and continuation characters. These 6 spaces originate from the punched card version of Fortran.

Exercise 14.1:#

Create your first “do nothing” Fortran program.

3. Hello, World! and Simple I/O#

The next simplest Fortran program is something programmers call the “Hello World” program. This is the simplest program that actually produces some output. An example of the “Hello World!” program in Fortran is:

1      PROGRAM HelloWorld
2      IMPLICIT NONE ! requires you to explicitly define the type for every variable that you use in your program, so to avoid undefined variables
3      WRITE(*,*) 'Hello, world!' ! this prints out on the screen
4      END PROGRAM HelloWorld
  • Notice that we used the WRITE statement rather than the PRINT statement from the one in the previous exercise.

  • The WRITE statement writes output to the screen when the program is run interactively. In fact it writes to something called “standard output,” which defaults to the screen.

  • The asterisk in the PRINT or WRITE statment specifies “free format” output. This essentially means that we aren’t interested in the exact format in which the system prints the result.

  • The text you want to print out is inside single quotes.

Exercise 14.2:#

  1. Type the “Hello World” program yourself. Compile it and run it.

  2. Change the “Hello World” program to print out something else, such as your name.

Simple I/O#

To print out on a file use the following statements in your program:

OPEN(1,file='MyFile.dat') ! this assigns an ID number to the file
WRITE(1,99)Hello world! ! this prints out to the file with the format specifier 99
CLOSE(1)
CALL flush(1)
99 FORMAT(ES15.5) ! format specifier for your data: one column of 15 digits width, with exponential format and 5 decimals.

To read from a file:

OPEN(2,file='MyFile2.dat')
READ(2,99) x ! we read the data from file 2 and put it into x
CALL flush(1)
CLOSE(2)

4. Arithmetic in Fortran: Real and Integer Variables#

Fortran has several different types of variables. The two most commonly used types for computations are integer variables and real variables.

  • Integer variables do not have a fractional part. The value of an integer variable is a whole number, like 0, 2, 5, -76, and so on.

  • Real variables have a fractional part, which may be zero. These variables have values like 2.0 or 3.1416. Real variables are sometimes called floating-point variables.

Important! For an integer variable, the fractional part is not merely zero. The fractional part does not exist:

  • 2 is an integer value

  • 2.0 is a real value

The type of each variable should be declared at the beginning of the program, right after the program is named.

  • The type declarations have to appear before the first executable statement.

Additionally, your variable names should adhere to the following conventions:

  • The variable name may include both letters and digits, but the first character of the variable name has to be a letter. For example, A2 is an allowable name, but 2A is not.

  • In standard Fortran 77 each variable name has to be six characters or less, but almost all modern systems will accept longer variable names.

Following is a program that illustrates some of the differences between real and integer variables:

 1      PROGRAM MAIN
 2      INTEGER I, INTPI, INTE
 3      REAL X, REALPI, REALE
 4      I = 1
 5      X = 1
 6      PRINT *, 'THE VALUE OF 1 AS A REAL IS', X
 7      PRINT *, 'THE VALUE OF 1 AS AN INTEGER IS', I
 8      REALPI = 3.1416
 9      INTPI = REALPI
10      PRINT *, 'THE VALUE OF PI AS A REAL IS', REALPI
11      PRINT *, 'THE VALUE OF PI AS AN INTEGER IS', INTPI
12      REALE = 2.71828
13      INTE = REALE
14      PRINT *, 'THE VALUE OF E AS A REAL IS', REALE
15      PRINT *, 'THE VALUE OF E AS AN INTEGER IS', INTE
16      STOP
17      END
  • Any text that you want to print out is inside single quotes, but when printing the value of a variable you don’t put it in quotes.

  • If you want to print multiple things (whether text or values) separate them with a comma.

Exercise 14.3:#

  1. Type the program as listed above, compile it and run it.

  2. What happens to the value of pi when it gets converted to an integer?

  3. What happens to the value of e when it gets converted to an integer? Look closely: Is the result rounded to the nearest integer?

  4. Change the values of pi and e to negative numbers (that is, -3.1416 and -2.71828), then re-compile and re-run the program. What happens when the negative values are converted to integers?

Other variable types#

Examples:

      CHARACTER(len=*), PARAMETER :: Name = 'YourName' ! defines a constant string of characters of unknown length
      INTEGER, PARAMETER :: n = 10
      REAL, PARAMETER :: Dx = 1.0d0
      REAL :: x(n) ! declares an array of n real values called x

5. Functions#

  • Similar to other languages, in Fortran a function is a self-contained unit that receives some input from the outside via its arguments, performs a task, and then returns the result.

  • A Fortran function is a procedure whose result is a single number, logical value, character string or array.

  • This result can be be used to form a Fortran expression.

    • The expression may be on the right side of an assignment statement.

  • There are two types of functions, intrinsic and user-defined.

    • Intrinsic functions are those functions built into a Fortran language, such as SIN(x) or LOG(x).

User-defined functions are functions defined by programmers to meet a specific need not addressed by the standard intrinsic functions.

General form of user-defined functions:

      FUNCTION function_name(argument list)
	  !! DECLARACTIONS

	  !! EXECUTABLES

	  function_name = expression

      RETURN	! ONLY NEEDED IF WE PLAN TO REACH END FUNCTION ALL OF THE TIME
      END FUNCTION function_name
  • A function is invoked (or called) by naming it in an expression.

  • Function names follow the same rules as variable names.

  • The name of the function must appear on the left side of at least one assignment statement in the function:

      function_name = expression
  • The argument list of the function may be blank if the function can perform all calculations with no input arguments.

  • The parentheses around the argument list are required even if the list is blank. Since the function returns a value, it is necessary to assign a type to that function.

  • The type of the function must be declared both in the function procedure and the calling programs.

  • In Fortran, we need to specify the types of function arguments.

    • All arguments must be declared with a new attribute

      INTENT(IN)
  • The meaning of INTENT(IN) indicates that the function will only use this argument as input and must not change its value.

Example:

 1      REAL FUNCTION LargerRoot(a,b,c)
 2
 3        IMPLICIT NONE ! Remember that this tells the compiler that we will define all variables we will use
 4
 5        REAL, INTENT(IN) :: a
 6        REAL, INTENT(IN) :: b
 7        REAL, INTENT(IN) :: c
 8
 9        REAL             :: d, r1,r2 ! Some temporary auxiliary variables needed that will live only inside this function
10
11        d = SQRT(b*b - 4.0*a*c)
12
13        r1 = (-b+d) / (2.0*a)
14
15        r2 = (-b-d) / (2.0*a)
16
17        IF(r1 >= r2) THEN
18          LargerRoot = r1
19        ELSE
20          LargerRoot = r2
21        END IF
22
23      END FUNCTION LargerRoot

Note

Remember that to be able to call this function, we need at least a main PROGRAM.

  • Function subprograms and any other subprograms are placed after the END statement of the main program (unless they are internal functions - then, they need to appear in CONTAINS section).

Common mistakes#

  1. Forget the function type Example:

      FUNCTION DoSomething(a,b)
        IMPLICIT NONE

        INTEGER, INTENT (IN) :: a, b

        DoSomething = SQRT(a*a+b*b)
      END FUNCTION DoSomething

If there is no type, you will not be able to determine the returned value type.

  1. Forget INTENT(IN) Example:

      REAL FUNCTION DoSomething(a,b)

        IMPLICIT NONE
        INTEGER :: a,b

        DoSomething = SQRT(a*a + b*b)
      END FUNCTION DoSomething

Actually, this is not an error. But, without INTENT (IN), the compiler will not be able to check many potential errors.

  1. Change value of formal argument declared with INTENT(IN) Example:

      REAL FUNCTION DoSomething(a,b)

        IMPLICIT NONE
        INTEGER, INTENT (IN) :: a,b

        IF(a>b) THEN
            a = a - b
        ELSE
            a = a + b
        END IF

        DoSomething = SQRT(a*a+b*b)
      END FUNCTION DoSomething

Since a was declared with INTENT(IN), its value cannot be changed.

  1. Forget to store value to function name Example:

      REAL FUNCTION DoSomething(a,b)

        IMPLICIT NONE

        INTEGER, INTENT(IN) :: a,b
        INTEGER :: c
        c = SQRT( a  a + b  b )
      END FUNCTION DoSomething

Since there is no value ever stored in DoSomething, the returned value could be anything (garbage).

  1. Function name used in right hand side of expression Example:

      REAL FUNCTION DoSomething (a,b)

        IMPLICIT NONE
        INTEGER, INTENT(IN) :: a,b

        DoSomething = a*a+b*b
        DoSomething = SQRT(DoSomething)
      END FUNCTION DoSomething

Only a special type of functions, recursive functions, could have their names on the right-hand side of expressions (we didn’t treat recursion in this class because it is pretty impractical).

  1. Most recent value stored in function name is returned Example:

      REAL FUNCTION DoSomething(a,b)

        IMPLICIT NONE
        INTEGER, INTENT(IN) :: a,b
        DoSomething = a*a+b*b
        DoSomething = SQRT(a*a-b*b)
      END FUNCTION DoSomething

The second assignment overwrites the previous value.

Some important rules for Fortran function arguments:

  • If an actual argument is an expression, it is evaluated and the result is saved into a temporary location. Then, the value in this temporary location is passed.

  • If an actual argument is a constant, it is considered as an expression. Therefore, its value is saved to a temporary location and then passed.

  • If an actual argument is a variable, its value is taken and passed to the corresponding formal argument.

  • If an actual argument is a variable enclosed in a pair of parenthesis like (A), then this is an expression and its value is evaluated and saved to a temporary location. Then, this value (in the temporary location) is passed.

  • For a formal argument declared with INTENT(IN), any attempt to change its value in the function will cause a compiler error.

  • In a Fortran function, the INTENT should always be IN. If you plan to use an INTENT other than IN then consider using a SUBROUTINE rather than a FUNCTION (see below).

5.1 Subroutines#

  • We saw that Fortran functions have an explicit type and are intended to return one value.

  • Subroutine subprograms, on the other hand, have no explicit type and return multiple or no values through a parameter call list.

  • Unlike functions, calls to subroutines cannot be placed in an expression.

  • In the main program, a subroutine is activated by using a CALL statement which include the subroutine name followed by the list of inputs to and outputs from the subroutine surrounded by parenthesis. The inputs and outputs are collectively called the arguments.

  • A subroutine name follows the same rules as for function names and variable names: less than six letters and numbers and beginning with a letter. Because of this, subroutine names should be different than those used for variables or functions.

  • As with functions, there are some rules for using subroutines. Keep these in mind when writing your subroutines:

    • You do not need to declare the subroutine name in the main program as you do with a function name.

    • They begin with a line that includes the word SUBROUTINE, the name of the subroutine, and the arguments for the subroutine.

  • The INTENT of arguments in subroutines can be multiple: IN (the value of the dummy argument may be used, but not modified, within the procedure.), OUT (the dummy argument may be set and then modified within the procedure, and the values returned to the caller), and INOUT (initial values of the dummy argument may be both used and modified within the procedure, and then returned to the caller).

6. Interface blocks#

  • Safety feature which allows main programs and external subprograms to interface appropriately with your user-defined function/subroutine.

  • Ensures that the calling program and the subprogram have the correct number and type of arguments

  • Helps compiler to detect incorrect usage of a subprogram at compile time

  • It consists of:

    1. Number of arguments

    2. Type of each argument

    3. Type of values returned by the subprogram

Example:

 1      PROGRAM Area
 2        IMPLICIT NONE
 3
 4        INTERFACE
 5
 6            FUNCTION Area_Circle(r)
 7
 8            REAL :: Area_Circle
 9
10            REAL, INTENT(IN) :: r
11
12            END FUNCTION Area_Circle
13        END INTERFACE
14
15        REAL :: radius
16
17        write(*, '(A)', ADVANCE = "NO") "Enter radius of circle: "
18        read(*,*) radius
19
20        ! Write out area of circle using function call
21        write(*, 100) "Area of circle with radius", radius, " is", Area_Circle(radius)
22100 FORMAT(A, 2x, F6.2, A, 2x, F11.2) ! Need Fortran90 specification, i.e., name your file with the .f90 extension
23      END PROGRAM Area
24
25      FUNCTION Area_Circle(r)
26
27        IMPLICIT NONE
28        REAL :: Area_Circle
29        REAL, INTENT (IN) :: r
30
31        REAL, PARAMETER :: Pi = 3.1415927
32
33        Area_Circle = Pi*r*r
34
35      END FUNCTION Area_Circle

7. Modules#

  • It is often the case that there are parameters, variables, and subprograms that must be shared by several program units

  • Fortran 90 provides a special program unit known as a MODULE that conveniently packages collections of declarations and subprograms so that they may be imported into other program units

Syntax:

      MODULE module_name
      ! some specifications
      END MODULE module_name
  • A program module is made accessible to the various program units by way of the USE statement

  • The USE statement must appear at the beginning of the declaration part of the program unit making use of the module. It must appear even before the statement IMPLICIT NONE.

Example:

 1      PROGRAM Area
 2        IMPLICIT NONE
 3
 4        INTERFACE
 5
 6            FUNCTION Area_Circle(r)
 7
 8            REAL :: Area_Circle
 9
10            REAL, INTENT(IN) :: r
11
12            END FUNCTION Area_Circle
13        END INTERFACE
14
15        REAL :: radius
16
17        write(*, '(A)', ADVANCE = "NO") "Enter radius of circle: "
18        read(*,*) radius
19
20        ! Write out area of circle using function call
21        write(*, 100) "Area of circle with radius", radius, " is", Area_Circle(radius)
22100 FORMAT(A, 2x, F6.2, A, 2x, F11.2) ! Need Fortran90 specification, i.e., name your file with the .f90 extension
23      END PROGRAM Area
24
25      FUNCTION Area_Circle(r)
26
27        IMPLICIT NONE
28        REAL :: Area_Circle
29        REAL, INTENT (IN) :: r
30
31        REAL, PARAMETER :: Pi = 3.1415927
32
33        Area_Circle = Pi*r*r
34
35      END FUNCTION Area_Circle
  • Each module unit must be compiled independently.

  • To compile a module use:

gfortran -c math_consts_module.f

which will produce math_consts_module.o and math_consts_module.mod files

  • To compile the main program that uses the module, use:

gfortran -Wall using_modules.f math_consts_module.o -o using_modules

This will both compile your main program using_modules.f and link your compiled module.

Alternatively, you could have compiled the module and main program together, as in:

 gfortran -ffree-fortran -c math_consts_module.f using_modules.f

And then you could have done the linking of the object files:

gfortran math_consts_module.o using_modules.o -o using_modules

Review of Fortran modules:

  • Modules provide you a way of splitting your programs between multiple files

  • Modules are used for:

    • Packaging subprograms, data and interface blocks

    • Defining global data that can be used by more than one routine

    • Declaring variables that can be made available within any routines you choose

    • Importing a module entirely, for use, into another program or subroutine

  • Syntax of a module (two parts):

    • a specification part for statements declaration

    • a contains part for subroutine and function definitions

General form:

      MODULE module_name
      ! [ statement declarations ]
      ! [ contains subroutine and function definitions]
      END MODULE module_name

Using a module:

      USE module_name

Note:

  • Can add as many modules as needed, each will be in separate files and compiled separately

  • A module can be used in various different programs

  • A module can be used many times in the same program

  • The variables declared in a module specification part, are global to the module

  • The variables declared in a module become global variables in any program or routine where the module is used

  • The use statement can appear in the main program, or any other subroutine or module which uses the routines or variables declared in a particular module