Skip to content
Extraits de code Groupes Projets
Valider 23bc10e3 rédigé par Pierre-Yves Barriat's avatar Pierre-Yves Barriat
Parcourir les fichiers

First content

parent d21e76b0
Aucune branche associée trouvée
Aucune étiquette associée trouvée
Aucune requête de fusion associée trouvée
Affichage de avec 2303 ajouts et 2 suppressions
...@@ -186,3 +186,8 @@ sympy-plots-for-*.tex/ ...@@ -186,3 +186,8 @@ sympy-plots-for-*.tex/
*.bak *.bak
*.sav *.sav
# Fortran module files
*.mod
# Notebooks
notebooks/*.ipynb_checkpoints
...@@ -5,5 +5,3 @@ This is the repository for the training Learning Fortran ...@@ -5,5 +5,3 @@ This is the repository for the training Learning Fortran
### Instructor ### Instructor
**Pierre-Yves Barriat** **Pierre-Yves Barriat**
_Freelance Software Developer_
\ No newline at end of file
assets/poly.png

17,1 ko

assets/sin.png

13,1 ko

0.00000000 0.00000000
0.100000001 9.98334214E-02
0.200000003 0.198669329
0.300000012 0.295520216
0.400000006 0.389418334
0.500000000 0.479425550
0.600000024 0.564642489
0.699999988 0.644217670
0.800000012 0.717356086
0.900000036 0.783326924
1.00000000 0.841470957
1.10000002 0.891207397
1.20000005 0.932039082
1.30000007 0.963558197
1.39999998 0.985449731
1.50000000 0.997494996
1.60000002 0.999573588
1.70000005 0.991664827
1.80000007 0.973847628
1.89999998 0.946300089
2.00000000 0.909297407
2.10000014 0.863209307
2.20000005 0.808496356
2.29999995 0.745705247
2.40000010 0.675463140
2.50000000 0.598472118
2.60000014 0.515501261
2.70000005 0.427379847
2.79999995 0.334988207
2.90000010 0.239249244
3.00000000 0.141120002
3.10000014 4.15805206E-02
3.20000005 -5.83741926E-02
3.29999995 -0.157745644
3.40000010 -0.255541205
3.50000000 -0.350783229
3.60000014 -0.442520559
3.70000005 -0.529836178
3.79999995 -0.611857831
3.90000010 -0.687766254
4.00000000 -0.756802499
4.09999990 -0.818277061
4.20000029 -0.871575892
4.30000019 -0.916166008
4.40000010 -0.951602101
4.50000000 -0.977530122
4.59999990 -0.993690968
4.70000029 -0.999923289
4.80000019 -0.996164620
4.90000010 -0.982452571
5.00000000 -0.958924294
5.09999990 -0.925814748
5.20000029 -0.883454502
5.30000019 -0.832267344
5.40000010 -0.772764444
5.50000000 -0.705540299
5.59999990 -0.631266713
5.70000029 -0.550685287
5.80000019 -0.464602023
5.90000010 -0.373876572
6.00000000 -0.279415488
set xlabel 'x'
set xrange [0:6]
set ylabel 'y'
set yrange [-1.2:1.2]
plot "03_dataxy" using 1:2 title 'sin(x)' with lines lt rgb "red"
pause -1
%% Cell type:markdown id:10d0e3c5 tags:
## Introduction to structured programming with Fortran
### Why to learn Fortran ?
* Because of the execution speed of a program
* Well suited for numerical computations : more than **45% of scientific applications** are in Fortran
### Getting started
#### Hello World
%% Cell type:code id:00ec1776 tags:
``` Fortran
program hello_world
implicit none ! important
print *, "Hello World!"
end program hello_world
```
%% Cell type:markdown id:c4b788f0 tags:
#### Data Type Declarations and Assignments
%% Cell type:code id:ffd3f0c3 tags:
``` Fortran
program data_type
implicit none
real x, y
integer i, j
logical flag
integer matrix(2,2)
character(80) month
character(len=80) months(12)
character family*16
real, dimension(12) :: small_array
character(len=80), dimension(24) :: screen
integer, parameter :: it = 100
i = 1
j = i+2
x = 85.8
y = 3.5*cos(x)
month="december"
months(:)="empty"
months(12)=month
flag = .TRUE.
family = "GEORGE P. BURDELL"
print*,family(:6)
print*,family(8:9)
print*,family(11:)
print*,family(:6)//FAMILY(10:)
end
```
%% Cell type:markdown id:133046ed tags:
#### Arithmetic Assignments
The result of any integer divide is truncated to the integer value less than the correct decimal answer for the division. The result of this is that changing the order of operations can make a big difference in the answers. Notice how parentheses force more expected results.
%% Cell type:code id:13343800 tags:
``` Fortran
program arith
implicit none
real r2,r3,r4,r5,r6,ans1,ans2,ans3
integer i2,i3,i4,i5,i6,ians1,ians2,ians3,ians4
data r2/2./,r3/3./,r4/4.0/,r5/5.0/
data i2,i3,i4,i5/2,3,4,5/
ians1=i2*i3/i5
ians2=i3/i5*i2
ians3=i2*(i3/i5)
ians4=(i3/i5)*i2
print *, '2*3/5 =', ians1, ', 3/5*2 =',ians2,', 2*(3/5) =',ians3 ,', (3/5)*2 =',ians4
end program arith
```
%% Cell type:markdown id:cabea667 tags:
Real arithmetic behaves more uniformly:
%% Cell type:code id:e1de5730 tags:
``` Fortran
program arith
implicit none
real r2,r3,r4,r5,r6,ans1,ans2,ans3
integer i2,i3,i4,i5,i6,ians1,ians2,ians3,ians4
data r2/2./,r3/3./,r4/4.0/,r5/5.0/
data i2,i3,i4,i5/2,3,4,5/
ans1=r2*r3/r5
ans2=r3/r5*r2
ans3=(r3/r5)*r2
print *, '2.0*3.0/5.0 =', ans1, ', 3.0/5.0*2.0 =',ans2,', (3.0/5.0)*2.0 =',ans3
end program arith
```
%% Cell type:markdown id:f18b85ec tags:
Watch how precedence of operations effects the following:
%% Cell type:code id:9a362858 tags:
``` Fortran
program arith
implicit none
real r2,r3,r4,r5,r6,ans1,ans2,ans3
integer i2,i3,i4,i5,i6,ians1,ians2,ians3,ians4
data r2/2./,r3/3./,r4/4.0/,r5/5.0/
data i2,i3,i4,i5/2,3,4,5/
ians1=i2+i5*i3**i2
ians2=i5*i3**i2+i2
ians3=i3**i2*i5+i2
print *, '2+5*3**2 =',ians1,', 5*3**2+2 =',ians2, ', 3**2*5+2 =',ians3
end program arith
```
%% Cell type:markdown id:5297b017 tags:
You can mix real and integers, but watch what happens
%% Cell type:code id:7d50669e tags:
``` Fortran
program arith
implicit none
real r2,r3,r4,r5,r6,ans1,ans2,ans3
integer i2,i3,i4,i5,i6,ians1,ians2,ians3,ians4
data r2/2./,r3/3./,r4/4.0/,r5/5.0/
data i2,i3,i4,i5/2,3,4,5/
ans1=r5+i3/i2
ans2=5.0+3/2
print *, '5.0+3/2 =',ans1
print *, '5.0+3/2 =',ans2
end program arith
```
%% Cell type:markdown id:222cabbc tags:
Look at what happens when I put a real in either the numerator or denominator of the division term
%% Cell type:code id:78929c6e tags:
``` Fortran
program arith
implicit none
real r2,r3,r4,r5,r6,ans1,ans2,ans3
integer i2,i3,i4,i5,i6,ians1,ians2,ians3,ians4
data r2/2./,r3/3./,r4/4.0/,r5/5.0/
data i2,i3,i4,i5/2,3,4,5/
ans1=r5+i3/r2
ans2=r5+r3/i2
print *, '5.0+3/2.0 =',ans1, ', 5.0+3.0/2 =', ans2
end program arith
```
%% Cell type:markdown id:a7d37bc2 tags:
Although Fortran normally works from left to right at a given level of precedence (does all multiply and divide from left to right before moving on to adds and subtracts). It works exponentiation from right to left when it hits 2 or more sequential exponentiation operations
%% Cell type:code id:3c2da1a9 tags:
``` Fortran
program arith
implicit none
real r2,r3,r4,r5,r6,ans1,ans2,ans3
integer i2,i3,i4,i5,i6,ians1,ians2,ians3,ians4
data r2/2./,r3/3./,r4/4.0/,r5/5.0/
data i2,i3,i4,i5/2,3,4,5/
ians1= i5**i3**i2
ians2= (i5**i3)**i2
ians3= i5**(i3**i2)
print *, '5**3**2 =',ians1, ', (5**3)**2 =',ians2, ', 5**(3**2) =',ians3
end program arith
```
%% Cell type:markdown id:8387be7a tags:
When in doubt use parentheses to get the answer that you really want.
#### Assignments exercise
%% Cell type:code id:14f6e7e2 tags:
``` Fortran
program sphere
implicit none
real pi,radius,volume,area
radius = 1.0
pi = 0.0
write(*,*) 'The value of pi is ', pi
write(*,*)
area = 0.0
volume = 0.0
write(*,*) 'For a radius ', radius
write(*,*) 'the area of a sphere is ', area
write(*,*) 'and the volume is ', volume
end
```
%% Cell type:markdown id:9a1702f7 tags:
#### Execution Control
%% Cell type:code id:41f9a8f0 tags:
``` Fortran
PROGRAM gcd
! Computes the greatest common divisor, Euclidean algorithm
IMPLICIT NONE
INTEGER :: m, n, t
WRITE(*,*) "Give positive integers m and n :"
m=5464
n=484682
WRITE(*,*) 'm:', m,' n:', n
positive_check: IF (m > 0 .AND. n > 0) THEN
main_algorithm: DO WHILE (n /= 0)
t = MOD(m,n)
m = n
n = t
END DO main_algorithm
WRITE(*,*) "Greatest common divisor: ",m
ELSE
WRITE(*,*) 'Negative value entered'
END IF positive_check
END PROGRAM gcd
```
%% Cell type:markdown id:cef2ad42 tags:
#### File-Directed Input and Output
%% Cell type:code id:8fd042c4 tags:
``` Fortran
program plot
! Program to provide plots of Sin(x)
implicit none
character label*150
real x
integer i
character xlabel*32,ylabel*32,title*32
real fx
!
! label - Character string
! xlabel - Contains a label for the x-axis
! ylabel - Contains a label for the y-axis
! title - Contains a title for the plot
!
! Drive a separate true graphics program (gnuplot)
!
! First set up the command file for gnuplot
!
xlabel="'x'"
ylabel="'y'"
title="'sin(x)'"
open (112,file='03_gnuxy')
!
label='set xlabel '//xlabel
write(112,*)label
write(112,*)'set xrange [0:6]'
label='set ylabel '//ylabel
write(112,*)label
write(112,*)'set yrange [-1.2:1.2]'
label='plot "03_dataxy" using 1:2 title '//title
label=trim(label)//' with lines lt rgb "red"'
write(112,*) label
write (112,*) 'pause -1'
close(112)
!
! Generate x-y pairs for the graph
!
open (112,file='03_dataxy')
do i=0,60
x=.1*i
fx=sin(x)
write(112,*) x,fx
enddo
close(112)
!
end program
```
%% Cell type:markdown id:558d962e tags:
This code is going to create 2 files: "03_dataxy" and "03_gnuxy".
The idea is to use a linux plotting tool called "GNUplot" to make a graph: the first file is the data for the graph, the second one is the gnuplot script using these data.
```bash
gnuplot 03_gnuxy
```
<img src="../assets/sin.png">
%% Cell type:code id:4b517d6b tags:
``` Fortran
```
! Ce programme affiche "Bonjour, le monde!"
program hello_world
implicit none ! important
print *, "Bonjour, le monde!"
end program hello_world
c
c Program to demonstrate Arithmetic Assignments
c
program arith
implicit none
c
c declare the data types for all Fortran variables
c
real r2,r3,r4,r5,r6,ans1,ans2,ans3
integer i2,i3,i4,i5,i6,ians1,ians2,ians3,ians4
c
c r2 thru r6 take on the real values 2.0 thru 6.0
c
c i2 thru i6 take on the integer values 2 thru 6
c
c ans1, ans2, and ans3 will contain the answers from
c real arithmetic
c
c ians1 thru ians4 will contain the answers from
c integer arithmetic
c
c
c Set initial values of the variables with 2 valid forms
c of data statements
data r2/2./,r3/3./,r4/4.0/,r5/5.0/
data i2,i3,i4,i5/2,3,4,5/
c
c This ends the non-executable statements, nothing above
c this point results in a machine instruction to perform
c some operation.
c Executable statements follow.
c
c The result of any integer divide is truncated to the integer
c value less than the correct decimal answer for the division
c The result of this is that changing the order of operations
c can make a big difference in the answers. Notice how parentheses
c force more expected results
c
ians1=i2*i3/i5
ians2=i3/i5*i2
ians3=i2*(i3/i5)
ians4=(i3/i5)*i2
print *, '2*3/5 =', ians1, ', 3/5*2 =',ians2,
& ', 2*(3/5) =',ians3 ,', (3/5)*2 =',ians4
c
c Real arithmetic behaves more uniformly
c
ans1=r2*r3/r5
ans2=r3/r5*r2
ans3=(r3/r5)*r2
print *, '2.0*3.0/5.0 =', ans1, ', 3.0/5.0*2.0 =',ans2,
& ', (3.0/5.0)*2.0 =',ans3
c
c Watch how precedence of operations effects the following:
c
ians1=i2+i5*i3**i2
ians2=i5*i3**i2+i2
ians3=i3**i2*i5+i2
print *, '2+5*3**2 =',ians1,', 5*3**2+2 =',ians2,
& ', 3**2*5+2 =',ians3
c
c You can mix real and integers, but watch what happens
c
ans1=r5+i3/i2
print *, '5.0+3/2 =',ans1
c
c You can do the same thing with constants in the expression
c
ans2=5.0+3/2
print *, '5.0+3/2 =',ans2
c
c Look at what happens when I put a real in either the numerator
c or denominator of the division term
ans1=r5+i3/r2
ans2=r5+r3/i2
print *, '5.0+3/2.0 =',ans1, ', 5.0+3.0/2 =', ans2
c
c Although Fortran normally works from left to right at a given
c level of precedence (does all multiply and divide from left to
c right before moving on to adds and subtracts). It works
c exponentiation from right to left when it hits 2 or more
c sequential exponentiation operations
c
ians1= i5**i3**i2
ians2= (i5**i3)**i2
ians3= i5**(i3**i2)
print *, '5**3**2 =',ians1, ', (5**3)**2 =',ians2,
& ', 5**(3**2) =',ians3
c
c When in doubt use parentheses to get the answer that you
c really want.
c
stop
end
PROGRAM sphere
implicit none
real pi,radius,volume,area
WRITE(*,*) 'Enter the value for the radius of a sphere.'
READ(*,*) radius
ccccc PI value
pi =
ccccc PI value
WRITE(*,*) 'The value of pi is ', pi
ccccc Air & volume
area =
volume =
ccccc Air & volume
WRITE(*,*) 'For a radius ', radius
WRITE(*,*) 'the area of a sphere is ', area
WRITE(*,*) 'and the volume is ', volume
STOP
END
program plot
c
c Program to provide plots of Sin(x)
c
implicit none
character label*150
real x
integer i
character xlabel*32,ylabel*32,title*32
real fx
c
c label - Character string
c xlabel - Contains a label for the x-axis
c ylabel - Contains a label for the y-axis
c title - Contains a title for the plot
c
c Drive a separate true graphics program (gnuplot)
c
c First set up the command file for gnuplot
c
xlabel='''x'''
ylabel='''y'''
title="'sin(x)'"
open (112,file='03_gnuxy')
c
c write(112,*) 'set term wxt size 800, 800'
c
label='set xlabel '//xlabel
write(112,*)label
write(112,*)'set xrange [0:6]'
label='set ylabel '//ylabel
write(112,*)label
write(112,*)'set yrange [-1.2:1.2]'
label='plot "03_dataxy" using 1:2 title '//title
label=trim(label)//' with lines lt rgb "red"'
write(112,*) label
write (112,*) 'pause -1'
close(112)
c
c Generate x-y pairs for the graph
c
open (112,file='03_dataxy')
do 100 i=0,60
x=.1*i
fx=sin(x)
write(112,*) x,fx
100 continue
close(112)
c
print *, ' Hit the Return (Enter) key to continue'
c
c Tell the system to run the program gnuplot
c This call works on either IBM RS6000 or Sun, but is not part of
c the Fortran standard.
c Comment out the line if you aren't at a terminal with graphics
c
call system ('gnuplot 03_gnuxy')
stop
end
program newton
implicit none
c Use a Newton iteration to solve a polynomial equation
c
c x - current approximation to the solution
c f - polynomial function
c df - derivative of f with respect to x
c xo - previous guess for solution
c eps - convergence criterion
c dx - change in solution approximation
c it - number of iterations
c itmax - maximum number of iterations
real
integer
c Now start executable fortran statements
x=
do while ()
x=
end do
end
c ******************************************************************************************
subroutine derivate(x,f,df)
c Evaluate the function f(x)=x**3+x-10
c also return the derivative of the function
implicit none
real
return
end
c * * * *
c syntaxe common
c common /nom de la zone commune/ liste des variables
c * * * *
PROGRAM test_arg
implicit none
integer a,b,c
common /arg/ a,b,c
a = 2
c = 1
print *, 'Before the call:'
print *, 'a = ',a,', b = ',b,', c = ',c
call sub
print *, 'After the call:'
print *, 'a = ',a,', b = ',b,', c = ',c
END PROGRAM
SUBROUTINE sub
implicit none
integer a,b,c
common /arg/ a,b,c
b = a + c
c = c + 1
END SUBROUTINE
MODULE arg
implicit none
integer :: a,b,c
real(8) :: x
END MODULE arg
! * * * * * * *
PROGRAM test_arg
USE arg
implicit none
a = 2
c = 1
write(*,*) 'Before the call:'
write(*,'(3(A5,I3))') ' a = ',a,', b = ',b,', c = ',c
call sub
write(*,*) 'After the call:'
write(*,'(3(A5,I3))') 'a = ',a,', b = ',b,', c = ',c
END PROGRAM test_arg
! * * * * * * *
SUBROUTINE sub
USE arg, only : a,b,c ! seuls a b et c sont utiles
implicit none
b = a + c
c = c + 1
END SUBROUTINE sub
! Namelist definition
&namlon ! limitation on the longitude
lon_min = 0
lon_max = 360
/
&namlat ! limitation on the latitude
lat_min = -90
lat_max = 90
/
PROGRAM test_namelist
implicit none
real*8 lon_min, lon_max, lat_min, lat_max
NAMELIST/namlon/ lon_min, lon_max
NAMELIST/namlat/ lat_min, lat_max
write(*,*) 'Before:'
call print_res(lon_min, lon_max, lat_min, lat_max)
open(161,file='07_namelist.def',status='old',form='formatted')
read(161,NML=namlon)
write(*,*) 'Between:'
call print_res(lon_min, lon_max, lat_min, lat_max)
read(161,NML=namlat)
close (161)
write(*,*) 'After:'
call print_res(lon_min, lon_max, lat_min, lat_max)
END
SUBROUTINE print_res(a,b,c,d)
implicit none
real*8, intent(in) :: a,b,c,d
write(*,'(4(A12,F6.2))') ' lon_min = ',a,', lon_max = ',b, &
', lat_min = ',c,', lat_max = ',d
RETURN
END
Ce diff est replié.
ifort -o OceanGrideChange.exe 8_OceanGrideChange.f90 -I${EBROOTNETCDFMINFORTRAN}/include -L${EBROOTNETCDFMINFORTRAN}/lib -lnetcdff
gfortran -ffree-line-length-none -o OceanGrideChange.exe 8_OceanGrideChange.f90 -I${EBROOTNETCDFMINFORTRAN}/include -L${EBROOTNETCDFMINFORTRAN}/lib -lnetcdff
Fichier ajouté
CHRISTMAS TREE
--------------
The aim of this exercise is to work with loops (for or while) in order to draw in a terminal a Christmas tree with its balls:
Height=10
#
###
#o###
##o####
#o#####o#
####o#####o
#####o#####o#
####o#####o####
#o#####o#####o###
##o#####o#####o####
The program must be carried out in Fortran 90. It will take as argument the height of the tree which is a variable of the problem:
Height=7
#
###
#o###
##o####
#o#####o#
####o#####o
#####o#####o#
This parameter must be supplied at the command line when the program (for example './tree 10').
Balls must be positioned all 6 sharps as shown below:
Height=7
1
234
5!123
45!1234
5!12345!1
2345!12345!
12345!12345!1
Usefull commands:
-----------------
Read a parameter in the program argument:
call getarg (1, param)
where param is a string of sufficient length to contain the value supplied as argument
Convert a character string to integer or float:
read (mychar, *) myinteger
Write a character on the screen:
write (*, '(A)') "#"
Write a character on the screen without going back to the line:
write (*, '(A)', advance = 'no') "#"
Make a modulo:
myModulo = mod (10,3)
0% Chargement en cours ou .
You are about to add 0 people to the discussion. Proceed with caution.
Terminez d'abord l'édition de ce message.
Veuillez vous inscrire ou vous pour commenter