UNIVERSITE SULTAN MY SLIMANE Année Universitaire 2019-2020
Faculté Polydisciplinaire Master Physique Moderne /S1
Béni Mellal
TP n◦ 1 : Algorithmique & Programmation
Exercice 1 : Saisie, calcul, affichage
1. Saisissez avec un éditeur de texte et sauvegardez dans un fichier de suffixe approprié le
code source suivant :
! Titre de mon programme en fortran
program calcul
implicit none
integer :: x, y, z, t, u
real :: a, b
! Mon premier commentaire
write(*, *) ”Entrez un nombre entier:”
read(*, *) x
! Mon deuxieme
! commentaire
write(*, *) ”Entrez un deuxieme entier”
read(*, *) y
z = x * y ! 3ieme commentaire
t=x/y u = mod(x,y)
write(*, *) x, ” * ”, y, ” = ”, z, &
” t = ”, t , ” u = ”, u
! decrire la suite
write(*,*) ”saisir deux reels ”
read (*,*) a, b
c=a/b
write(*,*) ”a=”, a, ” b=”, b, ” c=”, c
write(*,*) ”fin”
end program calcul
2. Compiler ce code source en examinant attentivement les messages du compilateur. Corriger
pas à pas les erreurs dans l’ordre des lignes du code. Que fait le programme ?
Exercice 2 : Constante de Stefan
1. Compiler et exécuter le programme domaine.f90, qui affichent les limites du domaine des
valeurs positives représentables:
program real 32 range
! domaine des reels sur 32 bits
implicit none
write(*,*) ” valeur positive max ”, HUGE(1.)
write(*,*) ” valeur positive min ”, TINY(1.)
end program real 32 range
2. On souhaite calculer la constante de Stefan σ qui intervient dans l’expression de l’émittance
totale du corps noir :
2π 5 k 4
MB = πB = σT 4 où σ = .
15 c2 h3
1
h constante de Planck h = 6.626 × 10−34 J s
k constante de Boltzmann k = 1.380 × 10−23 JK −1
c vitesse de la lumière c = 3.000 × 108 m s−1
On doit obtenir σ = 5.67 × 10−8 W m−2 K −4 .
• Écrire un programme stefan.f90 qui évalue naı̈vement la constante de Stefan en
flottants sur 32 bits. On prendra pour simplifer π = 3.141593.
• Expliquer pourquoi on n’obtient pas la valeur attendue.
• Reformuler l’expression de σ en cherchant à limiter le domaine des valeurs intermédiaires
à calculer.
• Exploiter la nouvelle formulation.
• Reprendre la première partie de l’exercice en travaillant avec des flottants sur 64 bits
(double precision en fortran). Expliquer le comportement en affichant les limites du
domaine des sous-types flottants sur 64 bits.
Exercice 3 : Fonctions avec retour sans effet de bord
• Éditer le fichier suivant, produit.f90 en fortran 90. À chaque question, prendre soin de
faire une copie en incrémentant le nom de façon à conserver toutes les versions.
module m prod !=> nom du fichier .mod
implicit none
contains ! procédures de module
function prod(x, y)
integer :: prod
integer, intent(in) :: x, y
integer :: z ! locale
z=x*y
prod = z ! valeur de retour
return ! sans valeur
end function prod
end module m prod
program produit
use m prod ! relit m [Link]
! ce qui rend visible l’interface
integer :: a1, b1, a2, b2
integer :: p
write(*,*) ”Saisir 4 entiers a1,b1,a2,b2”
read(*,*) a1, b1, a2, b2
! deux appels dans une expression
p = prod(a1, b1) + prod(a2, b2)
write(*,*) ”a1*b1 + a2*b2 = ”, p
end program produit
1. Ce programme fait appel à une fonction prod qui ne modifie pas ses arguments et rend une
valeur à l’appelant. Compiler le fichier, observer les fichiers créés. Tester ce programme.
Modifier la fonction prod pour qu’elle n’utilise plus de variable locale z et tester.
2. Déclarer la variable p en tant que réel real en fortran dans le programme principal. Ex-
pliquer les comportements à la compilation et à l’exécution.
2
3. En conservant p réel dans chaque langage, déclarer les variables a1, b1, a2 et b2 en tant
que réels dans le programme principal. Expliquer les comportements à la compilation et
à l’exécution.
4. Modifier la fonction prod de manière à ce que le programme se compile sans avertissement
lorsque a1, b1, a2 et b2 sont déclarés réels dans le programme principal. Tester de nouveau.
Exercice 4 : Diffusion de particules (devoir)
Soit un ensemble de n part particules se déplaçant dans un espace unidimensionnel. Toutes
les particules se trouvent initialement en x = 0. À chaque pas de temps, chaque particule i va
effectuer un déplacement dxi d’une valeur aléatoire uniformément répartie entre -1 et +1. La
position xi des n part particules à un instant donné est stockée dans un tableau 1D nommé x.
On ne conserve donc pas les trajectoires des particules, mais seulement leurs positions finales.
1. Fichier diffus1.f90 ou diffus1.c :
Rédiger et tester un programme principal diffusion1.f90 ou diffusion1.c qui demande
le nombre de particules n part à simuler et le nombre de pas de temps n step à effectuer,
puis affiche les valeurs saisies. Il crée (déclare ou alloue) ensuite le tableau x de réels (float
en C et REAL en fortran) des n part positions.
2. Fichier diffus2.f90 ou diffus2.c :
Créer une procédure init qui initialise toutes les positions à zéro. Elle respectera l’interface
ou le prototype suivant :
en fortran :
subroutine init(x)
real, dimension(:), intent(?) :: x (remplacer le ?)
end subroutine init
en C :
void init(int n part, float * x); si allocation dynamique
Sur le même modèle, créer une procédure affiche qui imprime toutes les positions sur
une seule ligne. Tester l’initialisation et l’affichage depuis le programme principal pour 6
particules.
3. Fichier diffus3.f90 ou diffus3.c :
Créer une procédure move de même interface que init et qui, pour chaque particule i
effectue un déplacement dxi d’une valeur aléatoire uniformément répartie entre -1 et +1.
Les tirages feront appel à une procédure intrinsèque dont la syntaxe et la nature dépendent
du langage choisi :
• En Fortran, un seul appel au sous-programme intrinsèque random number avec
un argument de type tableau de réels qui fournit des réels pseudo-aléatoires distribués
uniformément dans l’intervalle [0, 1[, que l’on ramènera dans l’intervalle [-1, 1].
• En C, une suite d’appels à la fonction rand qui rend un entier distribué uni-
formément dans l’intervalle [0, RAND MAX] ; on le convertira en type float pour
éviter les dépassements de capacité avant de le ramener dans l’intervalle [-1, 1].
Afficher les positions après ce pas de temps dans le cas de n part=6 particules. Exécuter
de nouveau avec 100 particules pour contrôler qu’on parcourt l’intervalle [-1, 1].
4. Fichier diffus4.f90 ou diffus4.c
Compléter le programme pour lancer un nombre quelconque n step de pas de temps. Tester
en affichant les positions à chaque pas pour 6 particules et 10 pas. Reprendre avec 100 pas
en n’affichant que les positions finales.
3
5. Fichier diffus5.f90 ou diffus5.c
Écrire une fonction moy qui calcule la moyenne des positions des n part particules à un
instant donné. Écrire de même une fonction var qui calcule leur variance (elle appellera
moy) à un instant donné. On donne l’interface et les prototypes communs de moy et var:
en fortran :
real function moy(x)
real, dimension(:), intent(?) :: x
end function moy
en C :
float moy(int n part, float * x);
Afficher la moyenne et la variance des positions de n part=1000 particules au bout de
n step=500 pas de temps. Comparer aux valeurs théoriques. La variance théorique au
bout de n step pas est n step/3.
6. Fichier diffus6.f90 ou diffus6.c On étudie maintenant l’évolution de la variance en
fonction du temps. Créer un tableau 1D de n step réels (float en C et REAL en fortran)
nommé vars et y stocker la variance des positions à chaque pas de temps. Introduire
dans votre code la procédure ecritvar fournie. Appeler cette procédure qui écrit sur
deux colonnes dans un fichier [Link] le numéro du pas et la variance. Une fois le fichier
[Link] créé, lancer la commande
[Link] (il faudra saisir ensuite votre nom sans accent ni espace)
qui produit, au format postscript, le fichier [Link], graphique de la variance. Afficher ce
graphique avec par exemple la commande okular [Link]& pour contrôler. Puis l’imprimer
avec la commande :
lpr [Link]
7. Fichier diffus7.f90 ou diffus7.c
Écrire une fonction nsup qui compte le nombre de particules situées à une distance
supérieure (en valeur absolue) à un seuil dist de l’origine. Elle respectera l’interface ou le
prototype suivants :
en fortran :
integer function nsup(x, dist)
real, dimension(:), intent(?) :: x
real, intent(?) :: dist
end function nsup
en C :
int nsup(int n part, float * x, float dist);
Afficher le nombre de particules situées à une distance |x| > 8 sur un total de n part=1000
particules au bout de n step=100 pas.