Vous êtes sur la page 1sur 29

En début de séance

1) Connectez-vous :
Connexion Sorbonne U avec le login et le mot de passe annuaire
2) Allez dans le gestionnaire de fichiers (dossier jaune en bas de l’écran)
puis aller dans Ce PC, Windows (C:), puis msys64
3) Lancez l’appli mingw64, un terminal s’ouvre…
4) Tapez la commande cd pour vous positionner dans le répertoire
d’accueil (ce dossier correspond au dossier Documents de Windows)

En cas de problème d’accès internet, taper dans la barre en bas à gauche :


gpupdate /force puis cliquez sur « Exécuter la commande »
REMISE A NIVEAU

FORTRAN
90

Ivan DELBENDE – Sorbonne Université, Licence Mécanique – 2022-23


FORTRAN ?!?


FORmula TRANslator
(IBM, 1954-1957)… ●
Langage fortement
modernisé
FORTRAN 66 (IV) ●
Relativement simple et
puissant
FORTRAN 77 (V)

Très bien adapté à la
Format libre,
allocation dyn.
mécanique (en particulier la
de mémoire, manipulation des tableaux)
FORTRAN 90/95 types dérivés,
fonctionnalités ●
Encore couramment utilisé
des tableaux...
0 – Edition du programme


Dans un terminal, tapez les instructions
suivantes
Terminal

N’oubliez pas
ce « & » !!!

Ceci permet de créer des dossiers et d’ouvrir


un éditeur de texte pour saisir le code
FORTRAN 90 du programme prog.f90
1 – Structure du programme

prog.f90 « prog.f90 » est le nom du


programme sur le disque dur
PROGRAM nom_prog
IMPLICIT NONE Les mots du FORTRAN sont mis ici
en majuscules par convention, mais
  ! Déclarations FORTRAN ne fait pas la différence
entre les majuscules et les
Fenêtre de l’éditeur de texte

minuscules :
« PROGRAM » est équivalent à
« program » ou à « pRoGrAm »
! Instructions
« nom_prog » est le nom du bloc
PROGRAM/END PROGRAM,
choisi par l’utilisateur, on le met ici
en minuscules par convention.

On peut mettre des


END PROGRAM nom_prog commentaires après
le symbole « ! »
2 – Déclaration des variables

type [, attributs]  :: nom_var1 [, nom_var2, ...]


INTEGER PARAMETER Ce qui est entre
crochets est
REAL facultatif.
CHARACTER
Les constantes symboliques ont
CHARACTER(LEN=128) l’attribut « PARAMETER » et
LOGICAL doivent être initialisées par une
valeur dès leur déclaration.
Exemples
INTEGER :: age
INTEGER, PARAMETER :: age_majorite = 18
REAL, PARAMETER :: pi = 3.141592  ! ou encore mieux pi = ACOS (- 1 . )
CHARACTER :: c
LOGICAL :: est_majeur
3 – Premières instructions :
Entrées/Sorties standard

Entrez les instructions ●
Sauvegardez
suivantes puis compilez
! Instructions le programme
PRINT * , ’’Entrez votre age’’
READ * , age
PRINT * , ’’Vous avez’’ , age, ’’ans.’’ ●
Vérifiez que

Quelle déclaration est l’exécutable a
nécessaire ? bien été généré
! Déclarations
INTEGER :: age ●
Exécutez-le
Compilation et exécution


La compilation transforme le code Fortran en un
fichier exécutable (nom spécifié après -o)
Exemple
PROGRAM precis
IMPLICIT NONE
REAL, PARAMETER :: pi=ACOS(-1.)

Exécution
PRINT *, pi Affiche une
END PROGRAM precis valeur approchée
de pi


On peut doubler la précision avec l’option -r8
Affiche deux fois
plus de chiffres
significatifs.
4a – Test IF / THEN / ELSE

IF ( condition ) THEN Opérateurs  


………………………. ●
relationnels :
[ ELSE < > <= >= == /=
………………………. ] ●
logiques : !
END IF .AND. .OR. .NOT. TEST D’
EGALITE
Exemple
IF (x >= 0) THEN
PRINT * , ’’La racine carree de ’’ , x, ’’ est’’ , SQRT (x)
ELSE
PRINT * , x , ’’ n ’ admet pas de racine carree ! ’’
END IF
4b – Test IF / THEN / ELSE IF /...

IF ( condition1 ) THEN Exemple


………………………. IF (age>=age_majorite) THEN
ELSE IF ( condition2 ) THEN PRINT * , ’’Vous etes majeur’’
………………………. ELSE IF (age >= 0) THEN
[ ELSE IF ( condition3) THEN
PRINT * , ’’Vous etes mineur’’
………………………. etc. ]
ELSE
[ ELSE
………………………. ] PRINT * , ’’Saisie incorrecte !’’
END IF END IF


Utilisez cette syntaxe dans le programme, pour faire
afficher « Vous êtes majeur » ou « Vous êtes mineur »
ou « Saisie incorrecte ! » si l’âge entré est négatif.
4c – Branchement suivant les
valeurs d’une variable (var)
SELECT CASE ( var ) Exemple
CASE ( valeurs1 ) SELECT CASE ( age )
………………………. CASE ( 0:17 )
PRINT * , ’’Vous etes mineur’’
[ CASE ( valeurs2 )
CASE ( 18 )
………………………. etc. ] PRINT *, ’’Vous etes tout juste majeur’’
CASE ( 19: )
[ CASE DEFAULT PRINT * , ’’Vous etes majeur’’
………………………. ] CASE DEFAULT
END SELECT PRINT * , ’’Saisie incorrecte !’’
END SELECT

« var » est de type INTEGER ou CHARACTER seulement

« valeurs1 », « valeurs2 » est une valeur ou une liste de valeurs

liste de valeurs arbitraires : séparer par une virgule → CASE (1, 8, 9, 23)
Deux pièges à éviter
TEST D’EGALITE DE DEUX REELS a et b
!
IF (a == b) THEN ← à éviter à cause de la précision numérique
IF ( ABS(a-b) < eps ) THEN ← préférable : égalité à eps près
où « eps » est une constante (1E-6 par exemple).

DIVISION DE DEUX ENTIERS


!
Le résultat d’une division entre deux quantités est réel si l’une
d’elles est réelle, mais il est entier si les deux sont entières !
⇒ 1.5/2 donne 0.75, 1./2 donne 0.5, mais 1/2 donne 0 !
5a – Boucle « pour »

INTEGER :: i, idep, iarr , pas Exemple


PROGRAM calcul
DO i = idep, iarr [, pas] IMPLICIT NONE
………………………. INTEGER :: i
………………………. REAL, PARAMETER :: pi=ACOS(-1.)
END DO
DO i = 1, 15, 2
« i » est une variable entière, PRINT *, i*pi/8
« idep », « iarr » et « pas » END DO
sont des expressions entières.

Quand « ,pas » n’ est pas spécifié, il vaut +1. END PROGRAM calcul

Ecrivez un programme qui affiche les valeurs décimales
de π/8, 3π/8, 5π/8, …, 15π/8 .
5b – Boucles « faire tant que »
et « faire jusqu’à ce que »
DO WHILE ( condition1 ) DO
………………………. ……………………….
………………………. IF ( condition2 ) EXIT
END DO END DO
Exemple Exemple
PRINT * , ’’Entrez x > 0’’ PRINT * , ’’Entrez x > 0’’
READ * , x DO
DO WHILE ( x <= 0 ) READ * , x
PRINT *, ’’Incorrect, entrez x > 0’’ IF ( x > 0 ) EXIT
READ * , x PRINT *, ’’Incorrect, entrez x > 0’’
END DO END DO
Toujours vérifier que les Noter que « condition2 » est
! variables utilisées dans la l’inverse de « condition1 ».
« condition1 » ont bien été Souvent cette forme est plus
initialisées préalablement ! commode à utiliser.
… PAUSE 1 ...
6a – Tableau statique

Les tableaux statiques sont ceux dont on connaît les dimensions à l’étape de compilation.
Déclaration

type, DIMENSION ( dim ) :: tab1 [, tab2, ...]


( 20 ) vecteur à 20 numérotés
éléments de 1 à 20
( -2:17 ) vecteur à 20 numérotés
Exemples
éléments de -2 à 17
( 0:19, 5 ) matrice lignes de 0 à 19,
20 x 5 colonnes de 1 à 5

INTEGER, DIMENSION ( 20 ) :: vecteur1, vecteur2 Leurs


INTEGER, DIMENSION ( -2:17 ) :: nb_bureaux
! étendues
sont des
INTEGER, PARAMETER :: nb_lgn = 20, nb_col = 5 expressions
constantes.
REAL, DIMENSION ( 0:nb_lgn-1, nb_col ) :: matrice
6b – Tableau dynamique

Comment faire si la dimension est inconnue au moment de la compilation ? Par


exemple, si elle est demandée à l’utilisateur à l’exécution ⇒ tableau dynamique.
Déclaration

type, DIMENSION ( : [, : ][, : ]... ), ALLOCATABLE :: tab1 [, tab2, ...]


( : ) vecteur
( : , : ) matrice
( : , : , : ) cube...
Une fois les dimensions connues, on procède à l’allocation du tableau dynamique...
ALLOCATE ( tab1 ( dim1 ) [, tab2 ( dim2 ), …], STAT = ok )
Instructions

… à la vérification du succès de l’opération...


IF ( ok /= 0 ) STOP ’’Probleme allocation tableau tab1 !’’
… on peut alors utiliser le tableau, l’initialiser...
Les étendues « dim1 », « dim2 », …
Quand on en n’ a plus besoin...
peuvent dans ce cas contenir des
DEALLOCATE ( tab1 [, tab2, ...]) expressions variables.
6c – Tableau statique et
dynamique : exercice

Complétez ce programme. ●
Ecrivez la version avec allocation
Que fait-il ? dynamique de mémoire.
PROGRAM tab_statique PROGRAM tab_dynamique
IMPLICIT NONE IMPLICIT NONE
! Déclarations INTEGER :: n_max, ok, n
REAL :: x
……………………………………..
REAL, DIMENSION ( : ), &
! Instructions
ALLOCATABLE :: puiss
PRINT *, ’’Entrez un reel >0’’
READ *, x PRINT *, ’’Entrez un entier >0’’
DO n = 0, n_max READ *, n_max
puiss ( n ) = x ** n ALLOCATE ( puiss(0:n_max), &
STAT = ok )
END DO
IF ( ok /= 0 ) STOP ’’Pblm alloc !’’
PRINT * , puiss
PRINT *, ’’Entrez un reel >0’’
END PROGRAM tab_statique  ! etc.
6d – Section de tableau

On peut accéder aux éléments d’un tableau de façon classique.


Le FORTRAN 90 permet d’accéder à toute une section d’un tableau.
Une section est elle-même un tableau qui contient, par exemple :

Exemples vect ( 2:9 ) les éléments n°2 à 9 de « vect »


vect ( 2:9:3 ) les éléments n°2,5,8 de « vect »
Ici, « vect » est un
vect ( 9:2:-1 ) les éléments n°9,8,7,…,2 de « vect »
vecteur (tableau à vect ( :5 ) les éléments de « vect » jusqu ’au n°5
une dimension)
vect ( : ) « vect » tout entier
vect ( : :-1 ) « vect » entier inversé
mat ( : , : ) « mat » tout entière
mat ( i , : ) la i-ème ligne de « mat » Ici, «mat» est une
mat ( : , j ) la j-ème colonne de « mat » matrice (tableau à
deux dimensions)
mat ( 3:4, 5: ) une sous-matrice de « mat »
6e – Initialiser un tableau ou
une section de tableau
Quand il existe une Eléments : Aij = 2 i j3 DO i = 1, nb_lignes
DO j = 1, nb_colonnes
formule analytique,
A ( i , j ) = 2*i*j**3
on initialise élément END DO
par élément. END DO

Quand on doit affecter Tableau : vi ← 0 v=0


une même valeur,
on fait une affectation Section : Aij ← 3/2 A (2, 2:5) = 1.5
globale. pour i = 2 et j = 2,3,4,5

Quand on doit affecter v1 ← 1 , v2 ← 1.5 , v = (/ 1., 1.5, pi, 0.2 /)


A = RESHAPE ( v , (/ 2, 2 /) )
des valeurs arbitraires,
v3 ← π , v4 ← 0.2 Vecteur de
on peut utiliser un
tous les
constructeur de A11 ← 1 , A12 ← π éléments de A A : matrice 2x2
vecteur (+ RESHAPE) A21 ← 1.5 , A22 ← 0.2 col par col
6f – Opérations globales
entre tableaux conformants
Des tableaux conformants sont des tableaux de même taille dans chaque dimension.
On peut effectuer des opérations globales qui vont affecter tous les éléments d’un coup.
Exemples
Exemples avec des sections de tableau
REAL, DIMENSION ( 20, 10 ) :: A, B, C
D = A( 2:11 , :5 ) + B( 11: , 6: )
REAL, DIMENSION ( 10, 5 )  :: D
REAL, DIMENSION ( 20, 5 )  :: P D( : , 1 ) = A( 1 , : ) * B( :10, 10 )

A=B Affectation Ne pas confondre


A = 2*A Multiplication scalaire
! produit terme à terme
entre tableaux
A = ABS ( A ) Fonctions usuelles conformants,
A = COS ( B ) et produit matriciel :
A=B+C Somme Pij = Σk AikDkj
A=B*C Produit terme à terme Aij=BijCij P =s ’MATMUL
obtient par
(A, D)
6g – Quelques fonctions
intrinsèques sur les tableaux

Corriger, compléter, compiler et exécuter le programme suivant :
PROGRAM exo ! Plus grand element de M
IMPLICIT NONE PRINT *, ’’ max (M_ij) = ’’ , MAXVAL (M)
INTEGER :: n=6
REAL, DIMENSION (n) :: v   ! Norme infinie de v ( = max |v_i|)
REAL, DIMENSION (n, n) :: M PRINT *, …………………..

CALL RANDOM_SEED   ! Norme 2 de v ( = racine(somme v_i^2) )


  ! Initialisation des tableaux v et M PRINT *, ……… SUM (………) ….…..
CALL RANDOM_NUMBER (v)
CALL RANDOM_NUMBER (M)   ! Norme 1 de v ( = sum |v_i| )
v = v – 1/2 ; M = M – 1/2 PRINT *, …………………..
 ! Affichage ligne par ligne de M puis v
DO i = 1, n   ! Produit matrice-vecteur Mv
PRINT ’(100E14.5)’ , M (……..) PRINT *, …………………..
END DO
DO i = 1, n ; PRINT ……., v(i) ; END DO END PROGRAM exo
6g – Quelques fonctions
intrinsèques sur les tableaux

Version corrigée et complétée :
PROGRAM exo ! Plus grand element de M
IMPLICIT NONE PRINT *, ’’ max (M_ij) = ’’ , MAXVAL (M)
INTEGER, PARAMETER :: n=6
REAL, DIMENSION (n) :: v   ! Norme infinie de v ( = max |v_i|)
REAL, DIMENSION (n, n) :: M PRINT *, MAXVAL ( ABS ( v ) )

CALL RANDOM_SEED   ! Norme 2 de v ( = racine(somme v_i^2) )


  ! Initialisation des tableaux v et M PRINT *, SQRT ( SUM ( v**2 ) ) ! ou v*v
CALL RANDOM_NUMBER (v)
CALL RANDOM_NUMBER (M)   ! Norme 1 de v ( = sum |v_i| )
v = v – 0.5 ; M = M – 0.5 PRINT *, SUM ( ABS ( v ) )
 ! Affichage ligne par ligne de M puis v
DO i = 1, n   ! Produit matrice-vecteur Mv
PRINT ’(100E14.5)’ , M ( i, : ) PRINT *, MATMUL ( M, v )
END DO
DO i = 1, n ; PRINT ’(E14.5)’, v(i) ; END DO END PROGRAM exo
… PAUSE 2 ...
7a – Procédures fonction et
sous-programme
Les procédures sont des portions de code placées hors du programme
principal et appelées par celui-ci ou par d’autres procédures.
But : éviter des écritures répétées (et donc des erreurs répétées…), et/ou
programmer de manière modulaire pour rendre le code compréhensible.
FUNCTION SUBROUTINE
utilisée quand on attend utilisée dans les autres cas...
un résultat unique Exemple
Exemple Sous-programme qui convertit la
Fonction qui retourne la température température tC (°Celsius) en K et °Farenheit
en Kelvin à partir de la température tC SUBROUTINE convert ( tC, tK, tF )
transmise en °Celsius REAL, INTENT ( IN ) :: tC
REAL FUNCTION tempK ( tC ) REAL, INTENT ( OUT ) :: tK, tF
REAL, INTENT ( IN ) :: tC tK = tC + 273.15 
tempK = tC + 273.15 tF = 9*tC/5 + 32
END FUNCTION tempK END SUBROUTINE convert
7b – Appel des procédures

La fonction Le sous-programme
REAL FUNCTION tempK ( tC ) SUBROUTINE convert ( tC, tK, tF )
REAL, INTENT ( IN ) :: tC REAL, INTENT ( IN ) :: tC
tempK = tC + 273.15 REAL, INTENT ( OUT ) :: tK, tF
END FUNCTION tempK tK = tC + 273.15 
est appelée par exemple par : tF = 9*tC/5 + 32
END SUBROUTINE convert
Programme appelant

tC_amb = 20.
tK_amb = tempK ( tC_amb ) est appelé par exemple par :

Prog. appelant
PRINT *, ’’Temp. ambiante :’’ , & tC_amb = 15.
tK_amb, ’’ Kelvin.’’ CALL convert (tC_amb, tK_amb, tF_amb)
PRINT *, ’’La glace fond a ’’ , & PRINT *, ’’Temp. ambiante :’’ , &
tempK ( 0. ) , ’’ Kelvin.’’ tK_amb, ’’K ou’’ , tF_amb, ’’°F. ’’
A l’appel, les valeurs des paramètres d’entrée A l’appel, les valeurs des paramètres d’entrée
( INTENT(IN) ) sont transmises à la fonction. ( INTENT(IN) ) sont transmises au sous-prog :
1er appel : tC_amb (valeur 20.) → tC, 2nd : 0. → tC tC_amb (valeur 15.) → tC
A l’issue de l’appel, « tempK ( a ) » est remplacée A l’issue de l’appel, les valeurs de sortie ( INTENT(OUT) )
par la valeur de tempK calculée dans la fonction sont transmises au programme appelant :
pour tC = a. tK → tK_amb et tF → tF_amb
7c – Attribut INTENT des
paramètres d’appel
Deux types de variables sont déclarées dans les procédures :
- les variables et constantes locales déclarées de manière normale
- les variables de la liste d’appel ⇒ attribut INTENT
INTENT (...) Vocation Contraintes
IN Paramètre d’entrée ●
Doit posséder une valeur à l’appel

Ne peut être modifié dans la procédure

Peut être une constante à l’appel
OUT Paramètre de sortie ●
Doit être initialisé dans la procédure

Ne peut pas être une constante à l’appel
INOUT Paramètre ●
Doit posséder une valeur à l’appel
d’entrée-sortie ●
Doit être modifié dans la procédure

Ne peut pas être une constante à l’appel
Exemple SUBROUTINE normalise ( v ) REAL, DIMENSION (3) :: v
REAL, DIMENSION ( : ), INTENT ( INOUT ) :: v Prog. appelant
REAL   :: norme_v  ! variable locale v = (/ 1.5, 2., 2.5 /)
norme_v = SQRT( SUM ( v**2 ) )  CALL normalise ( v )
v = v / norme_v
END SUBROUTINE normalise
PRINT *, ’’ v / ||v|| : ’’ , v
8 – Module

mod_prog.f90 prog.f90
MODULE temperature USE nom_module PROGRAM conversion
IMPLICIT NONE rend les variables, USE temperature
  ! Déclaration de variables types et procédures IMPLICIT NONE
  du module
disponibles pour le PRINT *, tempK (...)
! Déclaration de types
programme CALL convert (…)
principal.
CONTAINS END PROGRAM conversion
  ! Procédures
REAL FUNCTION tempK (…)

Les variables déclarées dans une procédure
ne sont pas visibles en dehors de la procédure.
………….. ●
Les variables déclarées dans le programme principal
END FUNCTION tempK ne sont pas visibles dans le module.

Seules les variables déclarées avant CONTAINS
sont visibles dans le programme grâce à USE.
SUBROUTINE convert (…)
………….. Compilation : attention aux dépendances
END SUBROUTINE convert
END MODULE temperature d’ abord les fichiers des modules, ensuite ceux qui les utilisent.
Bibliographie

● Programmer en Fortran 90 : guide complet, Claude Delannoy, éditeur Eyrolles

● Les spécificités du Fortran 90, Michel Dubusset, Jean Vignes, éditeur : Technip

● Manuel complet du langage Fortran 90 et Fortran 95, Patrice Lignelet, éditeur :


Masson

● Cours de l'IDRIS
http://www.idris.fr/media/formations/fortran/idris_fortran_base_cours.pdf

● Cours de Fortran 90/95/2003 (Jacques Lefrère, UPMC)


http://wwwens.aero.jussieu.fr/lefrere/master/mni/mni/f90+c/polyf90/polyf90.pdf

Vous aimerez peut-être aussi