0 Some basic properties#
- Fortran code is case insensitive
- Fortran code must be written in a program, similar to the
main()
function in C
Example 1 Hello World
1
2
3
| program hello_world
print *,'Hello World'
end program hello_world
|
1 Variables#
1.1 Built-in datatypes#
There are five built-in datatypes:
- integer
- real
- complex
- character
- logical
declaring a variable:
1
| <variable type> :: <variable name>
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
| program variable
implicit none
integer :: int
real :: re
complex :: com
character :: char
logical :: boolean
int = 10
re = 10.0
com = (10,1)
char = "character"
logical = .false.
end program variable
|
implicit none
should be followed by every program/function/subroutine, in modern fortran the type of variable should be declared explicitly
boolen types are .false.
and .true
integer,parameter :: i = 10
means a immutable variable, the variable can’t change its value in the function
Expressions for numbers are
Floating point precision
1.2 array and strings#
Decalre an array
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
| program arrays
implicit none
! 1D integer array
integer, dimension(10) :: array1
! An equivalent array declaration
integer :: array2(10)
! 2D real array
real, dimension(10, 10) :: array3
! Custom lower and upper index bounds
real :: array4(0:9)
real :: array5(-5:5)
end program arrays
|
Array index can be set manully
Array Slicing
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
| program array_slice
implicit none
integer :: i
integer :: array1(10) ! 1D integer array of 10 elements
integer :: array2(10, 10) ! 2D integer array of 100 elements
array1 = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] ! Array constructor
array1 = [(i, i = 1, 10)] ! Implied do loop constructor
array1(:) = 0 ! Set all elements to zero
array1(1:5) = 1 ! Set first five elements to one
array1(6:) = 1 ! Set all elements after five to one
print *, array1(1:10:2) ! Print out elements at odd indices
print *, array2(:,1) ! Print out the first column in a 2D array
print *, array1(10:1:-1) ! Print an array in reverse
end program array_slice
|
Allocatable arrays
If the length of the array is unkown
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
| program allocatable
implicit none
integer, allocatable :: array1(:)
integer, allocatable :: array2(:,:)
allocate(array1(10))
allocate(array2(10,10))
! ...
deallocate(array1)
deallocate(array2)
end program allocatable
|
Array of strings
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
| program string
implicit none
character(len=4) :: first_name
character(len=5) :: last_name
character(10) :: full_name
first_name = 'John'
last_name = 'Smith'
! String concatenation
full_name = first_name//' '//last_name
print *, full_name
end program string
|
Allocatable array of strings
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
| program allocatable_string
implicit none
character(:), allocatable :: first_name
character(:), allocatable :: last_name
! Explicit allocation statement
allocate(character(4) :: first_name)
first_name = 'John'
! Allocation on assignment
last_name = 'Smith'
print *, first_name//' '//last_name
end program allocatable_string
|
Array of strings
Logical operators and flow controls#
logical operators#
==
.eq.
(equal)
/=
.ne.
(not equal)
>
.gt.
(greater than)
<
.lt.
(less than)
>=
.ge
(greater equal)
<=
.le.
(less equal)
.and.
.or.
.not.
.eqv.
.neqv.
Conditional#
1
2
3
| if (condition) then
! some code
end if
|
1
2
3
4
5
6
7
| if (condition1) then
! some code
else if (condition2) then
! some code
else
! some code
end if
|
if
is always followed by then
, but else
does not need then
1
2
3
4
5
6
7
| if (angle < 90.0) then
print *, 'Angle is acute'
else if (angle < 180.0) then
print *, 'Angle is obtuse'
else
print *, 'Angle is reflex'
end if
|
Loop#
Do loop with counter
1
2
3
4
5
6
7
8
9
10
11
12
| program sum
implicit none
integer :: i
integer :: sum
sum = 0
do i = 1, 10
sum = sum + i
end do
print *, sum
end program sum
|
Conditional loop
1
2
3
4
5
6
7
8
9
10
11
12
13
| program sum
implicit none
integer :: i, sum
i = 1
sum = 0
do while(i<11)
sum = sum + i
i = i + 1
end do
print *, sum
end program sum
|
Loop control statements
exit
and cycle
, similar to break
and continue
in C
1
2
3
4
5
6
7
8
9
| integer :: i
do i = 1, 100
if (i > 10) then
exit ! Stop printing numbers
end if
print *, i
end do
! Here i = 11
|
1
2
3
4
5
6
7
8
| integer :: i
do i = 1, 10
if (mod(i, 2) == 0) then
cycle ! Don't print even numbers
end if
print *, i
end do
|
Tag nested loops
To avoid ambiguity of which loop to break, it’a a good habit to name the loop and designate which loop to break
1
2
3
4
5
6
7
8
9
10
| integer :: i, j
outer_loop: do i = 1, 10
inner_loop: do j = 1, 10
if ((j + i) > 10) then ! Print only pairs of i and j that add up to 10
cycle outer_loop ! Go to the next iteration of the outer loop
end if
print *, 'I=', i, ' J=', j, ' Sum=', j + i
end do inner_loop
end do outer_loop
|
Do concurent
If the loops have no interdependence, it could be computed parallel
1
2
3
4
5
6
7
8
9
10
| real, parameter :: pi = 3.14159265
integer, parameter :: n = 10
real :: result_sin(n)
integer :: i
do concurrent (i = 1:n) ! Careful, the syntax is slightly different
result_sin(i) = sin(i * pi/4.)
end do
print *, result_sin
|
Subroutine, function and module#
Subroutine: invoke by a call
statement
Function: invoke by its expression