26) Introduction to Fortran#
Today:
How to compile a Fortran program
The simplest Fortran program
Hello, World! and Simple I/O
Arithmetic in Fortran
Functions 5.1 Subroutines
Interface Blocks
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 asifort
(from Intel) orpgf77
.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 thanmyprogram.f
, such ashomework1.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 namea.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 thePRINT
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
orWRITE
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:#
Type the “Hello World” program yourself. Compile it and run it.
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
or3.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 value2.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, but2A
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:#
Type the program as listed above, compile it and run it.
What happens to the value of pi when it gets converted to an integer?
What happens to the value of e when it gets converted to an integer? Look closely: Is the result rounded to the nearest integer?
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)
orLOG(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 themain
program (unless they are internal functions - then, they need to appear inCONTAINS
section).
Common mistakes#
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.
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.
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.
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).
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).
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 beIN
. If you plan to use anINTENT
other thanIN
then consider using aSUBROUTINE
rather than aFUNCTION
(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), andINOUT
(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:
Number of arguments
Type of each argument
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
statementThe
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 statementIMPLICIT 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