24) Introduction to Fortran#
Last time:#
Community Projects
Final Project overview
Today:#
How to compile a Fortran program
The simplest Fortran program
Hello, World! and Simple I/O
Arithmetic in Fortran
Functions 5.1 Scope Rules
Interface Blocks
Subroutines
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. You can see the list of all versions on the Fortran wiki page.
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 24.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.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 24.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:
WRITE(*,*) 'Hello, world!' ! this prints out on the screen
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(A25) ! format specifier for your data. You need the file extension .f90 for this
To read from a file:
CHARACTER(len = 25) :: x
OPEN(1,file='MyFile.dat')
READ(1,99) x ! we read the data from file and put it into x
OPEN(2,file='MyFile2.dat',STATUS='REPLACE',ACTION='WRITE') ! this assigns an ID number to the file MyFile2
WRITE(2,99)'Hello world, again!' ! this prints out to the file with the format specifier 99
CALL flush(1)
CALL flush(2)
CLOSE(1)
CLOSE(2)
99 FORMAT(A25)
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 24.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
Note that in the example above we have used the
PARAMETER
keyword, which is used to assign a symbolic name to a constant. In many places, one just wants to assign a name to a particular value. For example, keep typing 3.1415926 is tedious. In this case, one could assign a name, sayPI
, to 3.1415926 so that one could usePI
rather than 3.1415926.To declare a
PARAMETER
, addPARAMETER
in front of the double colon (::
) and use a comma to separate the type name (i.e.,REAL
) and the wordPARAMETER
.Following each name, one should add an equal sign (
=
) followed by an expression. The value of this expression is then assigned the indicated name.After assigning a name to a value, one can use the name, rather than its value throughout the program. The compiler would convert that name to its corresponding value.
It is important to note that the name assigned to a value is simply an alias of the value. Therefore, that name is not a variable.
After assigning a name to a value, that name can be used in a program, even in subsequent type statements.
Restrictions#
A symbolic constant must not be defined more than once in a program unit.
If a symbolic name appears in a
PARAMETER
statement, then it cannot represent anything else in that program unit.A symbolic name cannot be used in a constant format specification, but it can be used in a variable format specification.
If you pass a parameter as an argument, and the subprogram tries to change it, you may get a runtime error.
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:
RETURN_TYPE 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#
Forgetting the function type (i.e., the type of the return argument).
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.
Forgetting
INTENT(IN)
for input variables.
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.
Changing 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.
Forgetting 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 don’t cover recursion in this lecture, because as we’ve seen before it is pretty impractical).
The 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 Scope rules#
Local entities: entities declared in a function or in the main program are said local to that function or the main program.
Global: entities declared in all containing functions or the main program are said global.
Scope Rule: A global entity is visible to all contained functions, including the function in which that entity is declared.
Example:
1 PROGRAM Scope
2 IMPLICIT NONE
3 INTEGER :: a = 1, b = 2, c = 3 ! a,b,c are global
4
5 WRITE (*,*) Add(a) ! a = 4
6 c = 4
7 WRITE (*,*) Add(a) ! a = 5
8 WRITE (*,*) Mul (b,c)
9
10 CONTAINS
11 INTEGER FUNCTION Add(q)
12 IMPLICIT NONE
13 INTEGER , INTENT (IN) :: q
14
15 Add = q + c ! c is used here, from global scope
16 END FUNCTION Add
17
18 INTEGER FUNCTION Mul(x,y)
19 IMPLICIT NONE
20
21 INTEGER, INTENT (IN) :: x,y
22
23 Mul = x * y
24 END FUNCTION Mul
25 END PROGRAM Scope
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 REAL FUNCTION Area_Circle(r)
6
7 REAL, INTENT(IN) :: r
8
9 END FUNCTION Area_Circle
10 END INTERFACE
11
12 REAL :: radius
13
14 write(*, '(A)', ADVANCE = "NO") "Enter radius of circle: "
15 read(*,*) radius
16
17 ! Write out area of circle using function call
18 write(*, 100) "Area of circle with radius", radius, " is", Area_Circle(radius)
19100 FORMAT(A, 2x, F6.2, A, 2x, F11.2) ! Need Fortran90 specification, i.e., name your file with the .f90 extension
20 END PROGRAM Area
21
22 REAL FUNCTION Area_Circle(r)
23
24 IMPLICIT NONE
25 REAL, INTENT (IN) :: r
26
27 REAL, PARAMETER :: Pi = 3.1415927
28
29 Area_Circle = Pi*r*r
30
31 END FUNCTION Area_Circle
7. Subroutines#
We saw that Fortran functions have an explicit return type and are intended to return only 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 and outputs surrounded by parenthesis. The inputs and outputs are collectively called the argumentsA subroutine name follows the same rules as for function names and variable names: historically, less than six letters and numbers, and must begin 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).
Example:
Example:
1PROGRAM Area
2 IMPLICIT NONE
3
4 INTERFACE
5 SUBROUTINE Compute_Area(r, Area)
6
7 REAL, INTENT(IN) :: r
8 REAL, INTENT(OUT) :: Area
9
10 END SUBROUTINE Compute_Area
11 END INTERFACE
12
13 REAL :: radius, Area_Circle
14
15 write(*, '(A)', ADVANCE = "NO") "Enter radius of circle: "
16 read(*,*) radius
17
18 CALL Compute_Area(radius, Area_Circle)
19
20 ! Write out area of circle using function call
21 write(*, 100) "Area of circle with radius", radius, " is", Area_Circle
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 SUBROUTINE Compute_Area(r, Area)
26
27 IMPLICIT NONE
28 REAL, INTENT(IN) :: r
29 REAL, INTENT(OUT) :: Area
30 REAL, PARAMETER :: Pi = 3.1415927
31
32 Area = Pi*r*r
33
34 END SUBROUTINE Compute_Area
8. 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 statementIMPLICIT NONE
.
Example:
1 PROGRAM program_using_module
2 USE math_consts_module
3
4 real :: x
5 x = cos(pi)
6
7 write(*,*) "The cosine of pi is ", x
8 x = log(e)
9
10 write(*,*) "The natural log of e is ", x
11
12 END PROGRAM program_using_module
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-form -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