Slides
Slides
Daniel Price
School of Physics and Astronomy
Monash University
Melbourne, Australia
Part I: Introduction to FORTRAN
A brief history of Fortran (and FORTRAN)
• Prior to FORTRAN, most code was written in assembly language (i.e., machine specific)
• 1961: FORTRAN IV
• 1966: FORTRAN 66
http://en.wikipedia.org/wiki/Fortran
The future?
• Used commonly for numerical work, e.g. solving ODEs, PDEs. Not for
things like writing computer operating systems (C) or scripting (python/
perl/unix shell).
program helloworld
implicit none
print*,’hello world’
end
1 0
to run:
./myprog
What a compiler does (II):
.ascii "hello.f90\0"
implicit none LC1:
.ascii "hello"
.text
.globl _MAIN__
_MAIN__:
print*,’hello world’
pushl %ebp
movl %esp, %ebp
pushl %ebx
subl $372, %esp
call ___i686.get_pc_thunk.bx
"L00000000001$pb":
ihavebrain = .true.
inum = 1
rnum = 1
dnum = 1.0d0
print*,’vars=’,ihavebrain,inum,rnum,dnum
end
The evils of implicit types
• Implicitly in FORTRAN, undeclared variables starting with a-h and o-h are of
type real, and i-n are of type integer.
print*,’vars=’,ihavebrain,inum,rnum,dnum
end
Some basic good practice
• add comments to your code as much as possible. These are for YOU so you
remember what you did/what you were thinking at the time.
• try to avoid writing the same bit of code more than once: cut and paste is
convenient but deadly whilst writing programs! Use a short subroutine or
function instead.
Basic maths operations
program basicmaths
implicit none
real a,b,c,d,e
a = 1.
b = 2.
c=a+b
d = a*b
e = sqrt(b)
program basicmathsdbl
implicit none
double precision a,b,c,d
a = 1.0d0
b = 2.0d0
c=a+b
d = a*b
e = sqrt(b)
program array1
implicit none
real rnum(3)
rnum(1) = 1.0
rnum(2) = 2.0
rnum(3) = 3.0
print*,’rnum=’,rnum
program array2
implicit none
real rnum(3,2)
rnum(1,1) = 1.0
rnum(2,1) = 2.0
rnum(3,1) = 3.0
rnum(1,2) = 4.0
rnum(2,2) = 5.0
rnum(3,2) = 6.0
print*,’rnum=’,rnum
program ifanimal
implicit none
logical :: isacow,hastwohorns
integer, parameter :: nhorns = 2
isacow = .true.
if (isacow) then ! check if our animal is a cow
print*,’ my animal is a cow...’
if (nhorns.eq.2) print*,’ ...with two horns’
else
print*,’ my animal is not a cow’
endif
isacow = .false.
isadog = .true.
!
!--here we check the type of animal
! (and the number of horns if it is a cow)
!
if (isacow) then ! check if our animal is a cow
print*,’ my animal is a cow...’
if (nhorns.eq.2) print*,’ ...with two horns’
elseif (isadog) then ! or if it is a dog
print*,’ my animal is a dog. Woof.’
else
print*,’ my animal is not a cow or a dog’
endif
Fortran loops
program loop program loop
implicit none implicit none
integer :: i integer :: i
do i=1,10 i=0
write(*,”(a,i2)”) ‘ number ‘,i do while (i.lt.10)
enddo i=i+1
write(*,”(a,i2)”) ‘ number ‘,i
end program loop enddo
print*,’x=’,x
print “(f6.3)”, x
print “(a,2x,f6.3)”, ’x = ’,x
print “(’ x= ’,f6.3)”,x
print 10,x
10 format(‘x = ‘,f6.3)
Fortran loops: advanced
program loop
integer :: i
loop1: do i=1,10
write(*,”(a,i2)”) ‘ number ‘,i
if (i.eq.5) exit loop1
enddo loop1
program hello
character(len=20) :: name
program nametofile
character(len=20) :: name
integer :: npets
open(unit=1,file=’myname.txt’,status=’replace’)
write(1,*) name
write(1,*) npets
close(unit=1)
program namefromfile
character(len=20) :: name
open(unit=3,file=’myname.txt’,status=’old’)
read(3,*) name
read(3,*) npets
close(unit=3)
x1 = 3.
y1 = 4.
call mysub(x1,y1,z1)
print*,’z1= ’,z1
contains
subroutine mysub(x,y,z)
implicit none
real, intent(in) :: x,y
real, intent(out) :: z
z = sqrt(x**2 + y**2)
x1 = 3.
y1 = 4.
z1 = zfunc(x1,y1)
print*,’z1= ’,z1
function zfunc(x,y)
implicit none
real, intent(in) :: x,y
real :: zfunc
• modules: all subroutines should go in a module that is “used” by the calling routine - allows
interfaces to be checked. Modules also replace weird things like COMMON blocks.
• where/elsewhere statement
• forall
Fortran 2003
• interoperability with C
end
Logical constructs: select case (Fortran 90)
program animalsounds
implicit none
character(len=20) :: myanimal
character*20 :: youranimal
select case(trim(myanimal))
case(’cow’)
write(*,*) ’moo’
case(’zebra’,’donkey’,’mutated horse’)
write(*,*) ’a kind of donkey-like braying’
case default
write(*,*) ’an unspecified non-human sound’
end select
public :: area
private
contains
!
! a function to calculate the area
!
real function area(r)
implicit none
real, intent(in) :: r
• just type “make” instead of having to remember all the separate commands
• write a subroutine that solves (returns all the real roots of) a cubic equation
using the exact solution for a cubic.
• use this module in a program that reads the coefficients for the cubic as input
from the user, calls the subroutine you wrote to solve it, and checks the
answer.
• write a Makefile that will compile your program with the cubic module and the
program in different files.
Advanced Fortran 90
• write a second version of your cubic solver subroutine that works on double
precision input