FORTRAN is a bit different from, say, Matalab. It is a low level language. Concretely this means that the steps needed to run some code are distinct:
1. writing the code
2. compiling the code
3. executing the code
To write the code use any text editor. It might be more convenient to use an editor specialized in FORTRAN such as Atom (from Github) or SublimeText. In these editors the syntax is colored according to FORTRAN conventions.
To start writing code, create a new a file and call itmyprogram.f90
. That's your main file. It has the following structure.
program main
the code here
end programtr
You do not need to call the programmain
. You can also call it myprogram
or any other name, as long as the file starts withprogram
and ends withend program
.
The the code here
part is some FORTRAN code that we will cover later. For now, note that the code must be closed, meaning that the whole structure must be consistent. In this case it means that we start with a keyword program
and ends with the keywords end program
. This is different from Matlab where your code might only contains something like
a = 3
b = 2
c = a + b
To compile the code one needs a compiler (see Chapter 1). On Unix machine, open the terminal, navigate to the directory where your fortran file is located (using cd
command, see Appendix - Bash) and type
gfortran myprogram.f90
This will produce a new file (an executable). By default, the new file is called a
. You can change this to give the file a more convenient name, for example myprog_exe
. To do so, use the option -o(
(small letter o, for output):
gfortran -o myprogr_exe myprogram.f90
This tells the compiler to name the output file myprog_exe
. It uses the flag (or option) -o
followed by the argument to this flag.
To compile a program with modules or a library, see next chapters.
It is only when executing the file that the code will be executed and the computations run. To execute the file, type in the terminal
./a
Or, if you used the -o
flag with a different output name:
./myprog_exe
You need to declare all the variables you will use. Here is how
program myprogram
implicit none
real :: a, b, c
the code that uses a b and c here
end program
The key words implicit none
means that you want that all the variables used in the code have to be first declared. Hence, if in the the code here
part you use other letters, such as d
, the code will return an error when you try to compile it. It is possible no to use implicit none
which allows you to use variables not declared. However, you should never do this (mostly because each letter of the alphabet has a default type if not declared). The double colon after real
is optional. Note that here we declared the variables asreal
. There are other types, and the most usual types are
real
integer
character
logical
The type character
is for strings. To declare a string you need to use single or double quotes and write
string :: stringvar="text in the variable"
You can specify the number of bytes to be used for your variables (hence the precision) by using the kind
specifier.
integer(kind=2) :: shortinteger
integer(kind=4) :: longinteger
integer(kind=16) :: verylonginteger
To declare an array (vector) a
and a matrix b
use
real :: a(5)
real :: b(5,4)
or, equivalently
real, dimension(5) :: a
real, dimension(5,4) :: b
The first way is convenient to declare arrays of different dimensions on the same line
real :: a(5), b(5,4)
You can also use the keyword parameter
. This means that the variable cannot change value. You must therefore initialize it at the same time you declare it.
real, parameter :: d = 5
The usual operations are: addition +
, subtracction -
, division /
, multiplication *
, exponention **
.
A very common error is to use integer instead of real when doing arithmetic operations. Operations on integers always return an integer. For example 9/4
will return 2.
In FORTRAN you can use two types of blocs of code which you provide with input: the function and the subroutine. They both work the same way but with slight differences.
A function is defined as follows:
function myfunction(a,b,c)
implicit none
real :: a,b,c, myfunction
the code here
end function
As you can see, one needs to declare all the variables that are passed as arguments (here a
, b
and c
) as well as the output variable which must have the same name as the function. For example, the function could be
function myfunction(a,b,c)
implicit none
real :: a,b,c, myfunction
myfunction = a + b + c
end function
One can actually choose a different name for the output (rather than the same name as the function) but one must then use the following syntax
function myfunction(a,b,c) res(var)
implicit none
real:: a,b,c
real:: var
var = a + b + c
end function
To call this function into the main program you would write altogether
program myprogram
implicit none
real :: x1,x2,x3, easy_sum
x1 = 1
x2 = 2
x3 = 3
easy_sum = myfunction(x1,x2,x3)
contains
function myfunction(a,b,c)
implicit none
real :: a,b,c, myfunction
myfunction = a + b + c
end function
end program
keywordThe key word contains
tells the compiler that the code following this key word contains the definitions of functions and subroutines.
In the definition of the function, the variables passed as argument are local: they can have the same name as variables in the main part (above contains
), this will not affect them. One can however use variables defined above contains
inside the function, such as:
program myprogram
implicit none
real :: x1,x2,x3, easy_sum, big_number
big_number = 1000
x1 = 1
x2 = 2
x3 = 3
easy_sum = myfunction(x1,x2,x3)
contains
function myfunction(a,b,c)
implicit none
real :: a,b,c, myfunction
myfunction = a + b + c + bignumber
end function
end program
In this example, easy_sum
will be equal to 1000 + x1 + x2 + x3,
, i.e. 1+2+3+1000 = 1006
.
A subroutine is similar to a function but it does not necessarily return a variable. Instead, it executes the code inside it. Declaring a subroutine is done as follows
subroutine mysubroutine(a,b,c)
implicit none
real :: a, b, cr
a = 0
b = -1000
c = a + b
end subroutine
This subroutine will change the value of the three variables. You use a subroutine into your program with the following code:
program myprogram
implicit none
real :: x1,x2,x3
call mysubroutine(x1,x2,x3)
contains
subroutine mysubroutine(a,b,c)
implicit none
real :: a, b, c
a = 0
b = -1000
c = a + b
end subroutine
end program
In both functions and subroutines, one can specify if the arguments of the function/subroutine are to be altered by using the keywords intent(in)
, intent(out)
and intent(inout)
. intent(in)
means that the variable should not be altered inside the function (input only). intent(out)
means that whatever the value given to the variable before it enters the function as an argument, this value is ignored. With intent(inout)
the variable can be altered and the value it has before entering the function is still assigned to it at the beginning of the function. For example
function myfunction(a,b,c)
implicit none
real, intent(in) :: b, c
real :: myfunction
real, intent(inout) :: a
a = a + b + c
myfunc = a
end function
Note that you should not have an intent(out)
before the return of the function (here myfunction
).
A function can also be a pure function
. This implies that the function will only change the behavior of the output (i.e. the variable myfunction
above). It is a keyword used to make sure that nothing else is altered.
pure function myfunction(a,b,c)
implicit none
real, intent(in) :: b, c
real :: myfunction
real, intent(inout) :: a
a = a + b + c
myfunc = a + b + c
end function
This will not work (to check) because a
is an argument of a pure function, but the function tries to modify it (the inout
classification is enough to provoke an error as a pure function cannot modify an input argument). To have something working one needs to change the intent(inout) :: a
into intent(in) :: a
as well as delete a = a + b + c
(or create an intermediate variable intvar = a + b + c
, and not forgetting to declare it with: real :: intvar
).
The keyword save
is used to make a variable global (see next chapter). More specifically, save
is a specification statement which can be used to ensure that variables used within a procedure (local variable) preserve their values between successive calls to the procedure (often the procedure is in a module).
Another way to make a variable global is to assign it a value at the same time as the declaration.
real, save :: a
real :: b = 5
That is why it is dangerous to assign a value at the same time one declares a variable: at each iterative call, the starting value of the variable is the last one assigned to it, not the one assigned in the declaration (here b = 5
).
Overall, it is preferable to use modules instead of save
(see next chapter).
To write a comment in FORTRAN, use !
at the beginning of the comment.
! this is a line with only comments
real, save :: a ! this is a comment
real :: b
To break a line in FORTRAN, use &
at the end of the line you want to break, and start the next line right below.
program main
implicit none
real :: a
real :: b
a = 5.0
b = 2.3 + 3.0 &
+ a
end program
It is useful to break lines because each line has a maximum length (which depends on the compiler). It is wise to limit the length to no more than 300 characters.
STOP
The STOP statement terminates the program. One can pass a message as an argument to STOP (either an integer or a string). The message will be displayed when STOP is reached and the program terminates.
stop "Error"
stop 1