Vous êtes sur la page 1sur 30

Licence 2ème année

Physique et Physique Chimie


4TPY303U

TD Méthodes numériques

Automne 2022

Enseignants : R ODOLPHE B OISGARD, D ENIS D UMORA , N ICOLAS FARES , J ÉRÔME G AUDIN , E MMANUEL
D ’H UMIÈRES , L IONEL T RUFLANDIER
Version originale du document : R ODOLPHE B OISGARD (2013)
TABLE DES MATIÈRES

I Travaux Dirigés 3

1 Premiers pas 5
A Découverte de l’environnement . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
A.1 Le mode « console » . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
A.2 Premiers scripts . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
B Tracé de courbes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10

2 Boucles et structures conditionnelles 14


A Rappels . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14
A.1 Les boucles . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14
A.2 Les structures conditionnelles . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15
B Applications . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16
B.1 Structures conditionnelles . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16
B.2 Les boucles . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16
B.3 Boucles, tests et fonction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17

3 Traitement des données 18


A Préparation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18
B Ajustements . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19
B.1 Méthode des moindres carrés . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19
C Création « manuelle » d’un fichier de données . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20

4 Équations différentielles 23
A Équation différentielle du premier ordre . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23
A.1 Principe : la méthode d’Euler . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23
A.2 La fonction odeint de scipy . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24
B Système du 1er ordre . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25
B.1 Système proie-prédateur . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25
B.2 Cinétique chimique . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26
C Systèmes du second ordre . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27

2
Première partie

Travaux Dirigés

3
I NTRODUCTION

Les TDs de Python de ce module de S3 ont lieu, suivant les groupes sur les machines du CRPhy au premier
étage du bâtiment A1 (PC/Linux, Python 3.x) ou sur les machines de l’espace Lavoisier (Mac/Mac OS X, Python
2.7). Python 3.x n’étant pas l’héritier direct de python 2.7, mais plutôt une évolution parallèle des différences
existent entre les deux langages. En effet, le projet d’écrire une version 3 de Python a démarré en 2008 alors que la
version courante était Python 2.5. L’idée de départ était de proposer une version plus cohérente du langage avec
la conséquence de rendre Python 3 non rétrocompatible avec python 2.x...
Au vu des millions de ligne de code à réécrire pour produire Python 3, l’exercice a pris un certain temps pen-
dant lequel Python 2 a continué à évoluer. Python 3.0 est donc sorti à peu près en même temps que Python 2.6.
Ce dernier a intégré un module __future__ chargé de préfigurer dans Python 2.x les principaux changements
apportés par Python 3.x.
Au cours des années suivantes les deux Pythons ont continué à évoluer en parallèle et une version 2.7 de
Python 2 est apparue pendant que des versions 3.1, 3.2, 3.3, 3.4, 3.5, 3.6, 3.7 et maintenant (en 2020) 3.8 se sont
succédées afin d’inclure de plus en plus de modules originellement écrits en Python 2 dans Python 3.
Depuis le 1er Janvier 2020, Python 2.7 n’est plus supporté, actant ainsi l’arrivée à maturité de Python 3.
Il est donc conseillé à tout nouvel utilisateur de Python d’installer Python 3 (3.8 actuellement)... et à tout
ancien utilisateur d’envisager sérieusement la migration de ses codes Python 2 vers Python 3.
Les différences entre Python 2 et Python 3 qui seront rencontrées dans ce cours sont assez minimes. Elles
feront l’objet d’un exemple clairement identifié pour chaque version.
Quand il ne sera pas explicitement fait mention de la version de Python, le code sera rédigé en utilisant la
syntaxe Python 3. Généralement, dans ce cas, le code s’avèrera aussi compatible avec Python 2.

4
TD 1
P REMIERS PAS

A Découverte de l’environnement
A.1 Le mode « console »
Python est un langage « dit » interprété, l’interface de développement va donc donner accès à une console
dans laquelle les commandes python tapées par l’utilisateur sont immédiatement interprétées. Nous utiliserons
la console pour faire des essais mais nous ne privilégieront pas cette approche pour la programmation. Un des
objectifs du module numérique est de pouvoir construire des programmes complets.
Deux types de consoles sont accessibles sur l’IDE Spyder (c’est aussi vrai pour d’autres IDE),
Console Classique reconnaissable à son prompt (ou invite de commande) python à 3 chevrons >>>.
Console IPython reconnaissable à son prompt (ou invite de commande) Ipython donnant le numéro d’ins-
truction entre crochets [1].
La console permet à la fois un accès direct à l’interpréteur, elle sera aussi comme nous le verrons plus tard l’endroit
où apparaissent les messages liés à l’exécution des programmes.

Remarque préliminaire : le symbole ␣ dans les portions de code signifie qu’on a introduit une espace 1

Exercice no 1 Opération de base


Console Classique
1. Taper quelques opérations élémentaires : addition >>> 5+4 , soustraction >>> 5-14, multiplication >>>
3*8. Ces opérations fonctionnent avec des entiers on vient de le voir, avec des réels bien sûr
>>> 3.5*3.14
10.99
>>> 1.6e-19*6.6e-34
1.056e-52

mais aussi avec les nombres complexes


>>> (1+3j)*(3+2j)
(-3+11j)
>>> (1+3j)/(3+2j)
(0.6923076923076924+0.5384615384615385j)

Confortable, non ?
2. Problème de la division Attention ce « problème » n’existe qu’en python 2.7, donc ceux qui sont sous
python 3 ne sont pas concernés. Taper dans la console : >>> 2/3. Comparer avec >>> 2./3.
Pour éviter cet inconvénient il suffit d’introduire la ligne : from␣__future__␣import␣division

1. en typographie espace est un mot féminin !

5
6 TD 1. PREMIERS PAS

3. Affectation dans des variables. On veut calculer le nombre complexe, résultat de la formule :

x = a + j b2

avec a = 3, b = 6.5 et afficher le résultat. Tapez les lignes suivantes dans la console
>>> a = 3
>>> b = 6.5
>>> x = a+1j*(b**2)
>>> print x
(3+42.25j)
>>> print "x =",x
x = (3+42.25j)
>>> type(a), type(b),type(x)
(<type ’int’>, <type ’float’>, <type ’complex’>)

4. On notera à cette occasion que l’opérateur « puissance » s’écrit : ** et que la fonction type() permet
d’afficher le type de la variable ainsi définie.
Console IPython sous Spyder
1. Taper quelques opérations élémentaires : addition In [1]: 5+4 , soustraction In [2]: 5-14, multipli-
cation In [3]: 3*8. Ces opérations fonctionnent avec des entiers on vient de le voir, avec des réels bien
sûr
In [1]: 3.5*3.14
Out [1]:10.99
In [2]: 1.6e-19*6.6e-34
Out [2]:1.056e-52

mais aussi avec les nombres complexes


In [3]: (1+3j)*(3+2j)
Out [3]:(-3+11j)
In [4]: (1+3j)/(3+2j)
Out [4]:(0.6923076923076924+0.5384615384615385j)

Confortable, non ?
2. Affectation dans des variables. On veut calculer le nombre complexe, résultat de la formule :

x = a + j b2

avec a = 3, b = 6.5 et afficher le résultat. Tapez les lignes suivantes dans la console
In [1]: a = 3
In [2]: b = 6.5
In [3]: x = a+1j*(b**2)
In [4]: print x (ou In [4]: print(x) en python 3)
Out [4]: (3+42.25j)
In [5]: print "x =",x (ou In [5]: print("x =",x))
Out [5]: x = (3+42.25j)
In [6]: type(a), type(b),type(x)
Out [6]: (<type ’int’>, <type ’float’>, <type ’complex’>)

On ne distinguera pas les deux environnements par la suite. La syntaxe utilisée dans le fascicule sera celle de
python 3

Exercice no 2 Les bibliothèques


1. Essayer de calculer le sinus de 0.1 radian en tapant dans la console sin(0.1). Qu’obtenez-vous ?
2. Solution : faire appel à la bibliothèque mathématique numpy :
A. DÉCOUVERTE DE L’ENVIRONNEMENT 7

(a) Première méthode, on appelle la bibliothèque par son nom puis on va chercher la fonction (ici la fonc-
tion sinus) :
>>> import numpy
>>> numpy.sin(0.1)
0.099833416646828155

(b) Deuxième méthode, on donne un surnom (ou alias) la bibliothèque pour alléger l’écriture :
>>> import numpy as np
>>> np.sin(0.1)
0.099833416646828155

On a choisi ici arbitrairement le surnom « np » mais « toto » pourrait tout aussi bien faire l’affaire.
(c) Troisième méthode, on importe directement la fonction recherchée de façon à enrichir le langage py-
thon initialement très limité :
>>> from numpy import sin
>>> sin(0.1)
0.099833416646828155

(d) Quatrième et dernière méthode (dite du « paresseux »), on importe toutes les fonctions de la biblio-
thèque en une seule fois
>>> from numpy import *
>>> sin(0.1), cos(2), log(4)
(0.099833416646828155, -0.41614683654714241, 1.3862943611198906)

Inconvénients :
 si la bibliothèque est volumineuse cela augmente quelque peu la durée d’exécution et la mémoire
est inutilement surchargée
 il peut y avoir conflit entre deux bibliothèques utilisant des fonctions différentes qui ont le même
nom (ça arrive !)
Tout bon programmeur un tant soit peu sérieux devrait donc éviter cette dernière méthode...
Avantage :
 c’est tellement plus confortable...
Dans le cadre du cours Python :
 on proscrira cette quatrième méthode, l’importation des modules se fera exclusivement en utilisant l’une
des trois premières méthodes. La quatrième méthode d’importation n’est donnée que dans un but de
compréhension de codes déjà rédigés qui l’utiliseraient.

Remarque : À présent vous pouvez jeter votre calculatrice !

A.2 Premiers scripts


Exercice no 3 Premier programme
Le mode console ne gardant pas trace (à long terme) des lignes de code, il est préférable d’écrire des scripts
(programmes) qui regroupent les différentes lignes de code. On peut alors lancer en une seule fois l’ensemble des
opérations demandées.
1. Créer tout d’abord dans l’IDE un fichier modèle contenant les lignes suivantes :
Python 2.7
#!␣/usr/bin/env␣python
#␣-*-␣coding:␣utf-8␣-*-
"""
Commentaires
"""
8 TD 1. PREMIERS PAS

from␣__future__␣import␣division
import␣numpy␣as␣np
import␣scipy␣as␣sc
import␣matplotlib.pyplot␣as␣plt

Python 3
#!␣/usr/bin/env␣python
#␣-*-␣coding:␣utf-8␣-*-
"""
Commentaires
"""
import␣numpy␣as␣np
import␣scipy␣as␣sc
import␣matplotlib.pyplot␣as␣plt

La seconde bibliothèque (pyplot) nous sera utile par la suite pour les représentations graphiques.
Vous ferez appel à ce programme modèle pour tout nouveau script python afin de vous épargner la mé-
morisation de ces lignes de code. Néanmoins vous placerez dans la zone « commentaires » un descriptif
concis mais explicite de ce que votre programme est sensé réaliser.
2. Créer alors un programme (lance_balle.py par exemple) calculant la position d’une balle lancée vers
le haut avec une vitesse initiale de 15 m.s−1 dans le champ de pesanteur terrestre à partir de son point de
lancé après : t = 1 s, t = 2 s et t = 5 s. On rappelle que l’équation horaire pour cette situation s’écrit

1
z = − g t 2 + v0 t
2

Exercice no 4 Listes et tableaux

Quelques rappels : On définit une liste à l’aide de la syntaxe suivante :


>>> L1 = [1,20,3.14,1+3j]
>>> L2 = [2.5,"toto",L1]
>>> type(L1),type(L2)
(<type ’list’>, <type ’list’>)

une liste peut donc être un ensemble de nombre (entier, réel ou complexe) ou bien une liste de n’importe quel
objet python : nombre, chaîne de caractères ou même d’autres listes 2 .
Un tableau (array) est, dans la bibliothèque numpy (la bibliothèque de base sur laquelle s’appuient les biblio-
thèques scipy et pyplot), une liste de nombres un peu particulière que l’on définira de la façon suivante :
>>> A = np.array([1,4,3.14])
>>> L = [5,pi/2]
>>> B = np.array(L)
>>> print (A,L,B)
[ 1. 4. 3.14] [5, 1.5707963267948966] [ 5. 1.57079633]
>>> type(A),type(L),type(B)
(<type ’numpy.ndarray’>, <type ’list’>, <type ’numpy.ndarray’>)

Attention cependant les 2 types sont différents et l’opérateur « + » ne produit pas le même effet comme on peut
le tester sur l’exemple suivant :
>>> L1 = [3,6,2]
>>> L2 = [8,14,4]
>>> L = L1+L2
>>> print (L)
[3, 6, 2, 8, 14, 4]
>>> A1 = np.array(L1)
>>> A2 = np.array(L2)

2. une chaîne de caractères est d’ailleurs une liste de caractères


A. DÉCOUVERTE DE L’ENVIRONNEMENT 9

>>> A = A1+A2
>>> print (A)
[11 20 6]

L’opérateur « + » réalise la concaténation des listes tandis qu’il agit comme l’addition vectorielle sur les tableaux.

Création de listes et de tableaux : À l’aide d’une boucle while, écrire un programme


(construction_tableau_boucle.py par exemple) permettant de construire un tableau dont le premier élément
est x min = 2, le dernier est x max = 12 et dont les éléments sont équidistants de leurs plus proches voisins de h = 0.4.
Indication : la fonction append(A,2) rajoute l’élément ’2’ au tableau A.
En réalité il existe des fonctions permettant de générer facilement (et rapidement) :
 des listes : fonction range()
>>> L = range(4,15,3)
>>> print (L)
[4, 7, 10, 13]

"En python 3, pour des raisons d’efficacité la nature de range(4,15,3) a été modifiée, la liste n’est plus
générée à l’appel de la fonction range mais au fur et à mesure (techniquement range() est désormais une
classe).
>>> L = range(4,15,3)
>>> print (L)
range(4,15,3)

Le comportement est en revanche inchangé.


Afin d’afficher l’objet range() comme le ferait Python 2, il va falloir transformer le range() en liste python
>>> L = range(4,15,3)
>>> print (list(L))
[4, 7, 10, 13]

 des tableaux : fonctions arange() et linspace()


>>> A1 = np.arange(2,3,0.2)
>>> print (A1)
[ 2. 2.2 2.4 2.6 2.8]
>>> A2 = np.linspace(0,10,6)
>>> print (A2)
[ 0. 2. 4. 6. 8. 10.]

 affichage des éléments d’un tableau 1D


>>> x = np.linspace(2,12,6)
>>> print (x)
[ 2. 4. 6. 8. 10. 12.]
>>> print (x[0], x[3])
2.0 8.0
>>> print (x[3:])
[ 8. 10. 12.]
>>> print (x[:3])
[ 2. 4. 6.]
>>> print (x[:])
[ 2. 4. 6. 8. 10. 12.]

 affichage des éléments d’un tableau 2D


>>> MM = np.array([[1, 2, 3] , [10, 11, 12] , [20, 21, 22]])
>>> print (MM[0,0])
1
>>> print (MM[2,0])
20
>>> print (MM[0,2])
10 TD 1. PREMIERS PAS

3
>>> print (MM[0,:]) # ligne "zéro"
[1 2 3]
>>> print (MM[:,1]) # colonne "un"
[ 2 11 21]

Matrices et vecteurs Les tableaux numpy.array permettent d’effectuer de nombreuses opérations sur les
éléments qui les composent et sur leur structure (redimensionnement, découpage, ...), il est assez aisé de com-
prendre qu’à partir des tableaux numpy, on va pouvoir dériver des objets de type matrice et vecteur. Ces objets
apparaissent notés entre double crochets.

>>> a = np.array([1,2,3])
>>> print("a est un tableau à 1 dimension:",a)
a est un tableau : [1 2 3]
>>> m = np.mat(a)
>>> print("m est une matrice à 1 dimension (vecteur ligne):",m)
m est une matrice : [[1 2 3]]

 Matrice créée à partir d’un tableau à deux dimensions



>>> a2D = np.array([ [1,2,3],[ 4,5,6 ],[7,8,9]])
>>> print("a2D est un tableau à 2 dimension:",a2D)
a2D est un tableau à 2 dimension: [[1 2 3]
[4 5 6]
[7 8 9]]
>>> m2D = np.mat(a2D)
>>> print("m2D est une matrice à 2 dimensions:",m2D)
m2D est une matrice à 2 dimensions: [[1 2 3]
[4 5 6]
[7 8 9]]

 Création directe de matrice et vecteur


>>> a=np.mat(’[1. 2 3 ; 4 5 6; 7 8 9]’)
>>> print("a est une matrice 3x3\n", a)
a est une matrice 3x3
[[1. 2. 3.]
[4. 5. 6.]
[7. 8. 9.]]
>>> b=np.mat(’[10 11 12]’)
>>> print("b est un vecteur ligne\n", b)
b est un vecteur ligne
[[10 11 12]]
>>> c=np.mat(’[13 ; 14 ; 15]’)
>>> print("c est un vecteur colonne\n", c)
c est un vecteur colonne
[[13] [14] [15]]

Les matrices apparaissent comme des tableaux exclusivement bi-dimensionnels, il faut noter la syntaxe
particulière pour leur déclaration.
Remarque : Toutes les opérations s’appliquant aux matrices s’appliquant également aux tableaux dans un
cadre plus général (déterminant, inversion, transposition, diagonalisation, recherche de valeurs propres et
vecteurs propres....), le type matrice n’est pas nécessairement très utile et peut être aisément remplacé par
un objet de type array.

B Tracé de courbes
Exercice no 5 Premiers plots
B. TRACÉ DE COURBES 11

1. Utiliser les tableaux pour créer un programme de base permettant le tracé de courbes (on fait appel aux
fonctions plot() et show() de la bibliothèque matplotlib) :

Listing 1.1 – Code écrit pour python 2.7 (pour nous IDE Spyder)
#!/usr/bin/env␣python
#␣-*-␣coding:␣utf-8␣-*-
"""
Programme␣minimal␣de␣tracé␣d’une␣fonction
Python␣2.7
"""

from␣__future__␣import␣division
import␣numpy␣as␣np
import␣matplotlib.pyplot␣as␣plt
x␣=␣np.linspace(0,␣10,␣400)
y␣=␣np.sin(x)*np.exp(-x/5)
plt.plot(x,y,␣label=ur"fonction␣$\sin(x)*\exp(-x/5)$")
plt.legend()
plt.show()

Listing 1.2 – Code écrit pour python 3.x (pour nous IDE Pyzo)
#!/usr/bin/env␣python
#␣-*-␣coding:␣utf-8␣-*-
"""
Programme␣minimal␣de␣tracé␣d’une␣fonction
Python␣3.x
"""

import␣numpy␣as␣np
import␣matplotlib.pyplot␣as␣plt
x␣=␣np.linspace(0,␣10,␣400)
y␣=␣np.sin(x)*np.exp(-x/5)
plt.plot(x,y,␣label="fonction␣$\sin(x)*\exp(-x/5)$")
plt.legend()
plt.show()

"On notera les légères différences entre les codes écrits pour python 2.7 et python 3
 On a déjà vu la différence dans l’écriture de la commande print() pour laquelles la mise entre
parenthèses des arguments est obligatoire en python 3.
 La ligne from __future__ import division est inutile en python 3 puisque la division est par dé-
faut considérée comme réelle.
 Le modifieur de chaine de caractère r ( qui apparaît ur"fonction $\sin(x)*\exp(-x/5)$") n’existe
pas en Python 3, l’interprétation des symboles mathématiques à la LATEXse fait par défaut.
 Le modifieur de chaine de caractère u ( qui apparaît ur"fonction $\sin(x)*\exp(-x/5)$") pour le
codage des caractère Unicode (caractères accentuées par exemple) est inutile en Python 3. Contrai-
rement à r, le modifieur u ne génère pas d’erreur d’interprétation en Python 3.

Dans les deux cas la courbe obtenue est la même


12 TD 1. PREMIERS PAS

2. Prenons l’exemple d’une molécule diatomique. L’énergie potentielle qui traduit l’interaction entre les deux
atomes est souvent modélisée par une fonction analytique appelée « potentiel de Morse » dont voici l’ex-
pression en fonction de la distance interatomique R :
£ ¤2
V (R) = D e 1 − exp(−β(R − R eq ))

Les paramètres R eq , D e et β définissent respectivement :

(i) la distance interatomique à l’équilibre,


(ii) la profondeur du puits de potentiel (égal à la différence d’énergie entre la situation à l’équilibre R = R eq ,
et la situation dissociée R = +∞) et
(iii) la « largeur » du puits (voir figure (1.1)).

 Reproduire la courbe de Morse pour la cas de la molécule Cl2 (R eq = 0.198 nm, D e = 243 kJ.mol−1 , β =
20.0 nm−1 ).

 Tracer sur la figure précédente les courbes représentant le potentiel de Morse des molécules F2 et I 2 carac-
térisées par les paramètres suivants :
— F2 : (R eq = 0.142 nm, D e = 150 kJ.mol−1 , β = 23.9 nm−1 )
— I2 : (R eq = 0.267 nm, D e = 148 kJ.mol−1 , β = 15.0 nm−1 )

Quelques indications :
 le nom des axes est fixé grâce aux fonctions xlabel() et ylabel()
 le titre est indiqué à l’aide de la fonction title()
 les marqueurs de ligne sont donnés par : ’o’ pour les cercles, ’s’ pour les carrés (square), ’v’ pour les
triangles pointe vers le bas et ’^’ pour les triangles pointes vers le haut
 on peut fixer le domaine de représentation graphique à l’aide de la fonction axis([xmin,xmax,ymin,ymax
]).
B. TRACÉ DE COURBES 13

F IGURE 1.1 – Potentiel de Morse pour la molécule de Cl2


TD 2
B OUCLES ET STRUCTURES CONDITIONNELLES

Comme tout langage de programmation Python possède des structures de boucles et des structures condi-
tionnelles. Après un rapide survol de ces différentes structures, on traitera sur 3 exemples portant sur le domaine
de la spectroscopie.

A Rappels
A.1 Les boucles
Elles permettent d’effectuer de façon itérative une suite d’instructions dont la fin est programmée par un test
conditionnel. On a ainsi formellement
Faire (pour un itérateur prenant ces valeurs dans une liste) la suite d’instructions suivantes

A.1.1 Boucle for


Une réalisation possible en python est d’itérer dans une liste un paramètre, la boucle se terminant automa-
tique sur le dernier élément.
for n in liste:
# suite d’instructions

" : on prendra garde de ne pas oublier les 2 points à la fin de liste for et d’indenter TOUTES les instructions
contenues dans la boucle.
Par exemple si on a la liste liste_particules = ["proton","neutron","quark","boson de Higgs"] on peut
afficher les différents éléments de cette liste à l’aide de la boucle for suivante :
for particule in liste_particules:
print particule

qui affichera
proton
neutron
quark
boson de Higgs

On peut ainsi facilement itérer sur des entiers en créant une liste d’entiers à l’aide de la fonction range(). Par
exemple
for n in range(4):
print n**3

imprime les cubes des 4 premiers entiers (0 inclus et 4 exclu)

14
A. RAPPELS 15

0
1
8
27

A.1.2 Boucle while


Une autre façon de réaliser une boucle en python est de réitérer une séquence d’instructions tant qu’une
condition reste vraie. On sort alors de la boucle dès que la condition est fausse.
while (condition logique):
# suite d’instructions

On peut de cette manière écrire la suite des cubes des 4 premiers entiers comme vu plus haut
n = 0 # initalisation du compteur
while (n<4):
print n**3
n = n+1

A.2 Les structures conditionnelles


C’est le second type de structure très important qui permet à un programme de réagir différemment en fonc-
tion d’un (ou plusieurs) test(s) logiques(s).

A.2.1 Structure if de base


Formellement on aura la structure suivante :
si (condition logique est vraie) faire
suite d’instruction 1
sinon
suite d’instruction 2

En python cela donne


if (condition logique):
# suite d’instruction 1
else: (optionnel)
# suite d’instruction 2

" : comme dans le cas des structure de boucles on n’oubliera pas les 2 points à la fin de la ligne du if ET du
else, ainsi que l’indentation (impérative) de TOUTES les instructions répondant à la condition logique.
Exemple : on veut savoir si un corps est un conducteur ou non. On pourra écrire le code suivant :
rho = 22e-9 # résistivité de l’or en Ohm.m
if (rho < 1.e-6):
print u"ce corps est un conducteur"
else:
print u"ce corps n’est pas un conducteur"

A.2.2 Structure if complète


Dans le cas où plusieurs éventualités sont possibles on pourra utiliser la structure suivante :
if (condition logique 1):
# suite d’instruction 1
elif (condition logique 2):
# suite d’instruction 2
16 TD 2. BOUCLES ET STRUCTURES CONDITIONNELLES

elif (condition logique 3):


# suite d’instruction 3
(...etc)
else:
# suite d’instruction N

Si on reprend le cas de la résistivité d’un corps, on peut répondre à la question plus précise : s’agit-il d’un conduc-
teur, d’un semi-conducteur ou d’un isolant
rho = 2.5e-4 # résistivité intrinsèque du silicium en Ohm.m
if (rho < 1.e-6):
print u"ce corps est un conducteur"
elif (rho > 1.e-6 and rho < 1.e10):
print u"ce corps est un semi-conducteur"
else:
print u"ce corps est un isolant"

B Applications
B.1 Structures conditionnelles
Exercice no 6 Ondes électromagnétiques
On demande de réaliser un petit programme qui, après introduction de la longueur d’onde λ en nanomètre
d’une onde électromagnétique, permette à la demande de l’opérateur d’avoir ou bien la fréquence de l’onde cor-
respondante (en Hz ou MHz), ou bien le nombre d’onde σ = 1/λ ou enfin l’énergie du photon correspondant
E = hc/λ.
Le programme aura donc la structure suivante :
1. Entrer la longueur d’onde en nanomètre et la convertir en mètre
2. A la demande de l’opérateur entrer un caractère et choisir entre la fréquence "f", le nombre d’onde "s" et
l’énergie "e".

(a) si "f" demander à l’opérateur de choisir "h" (pour Hz) ou "mh" (pour MHz) et afficher le résultat dans
l’unité choisie.
(b) si "s" demander à l’opérateur de choisir "m" (pour m−1 ) ou "cm" (pour cm−1 ) et afficher le résultat dans
l’unité choisie.
(c) si "e" demander à l’opérateur de choisir "j" (pour Joule) ou "ev" (pour électron-volt) et afficher le
résultat dans l’unité choisie.

Indications :
 la fonction raw_input() permet de rentrer de façon interactive une chaîne de caractère
 la fonction float() convertit une chaîne de caractère en nombre (si cela a un sens bien sûr !)
 attention lambda est un mot réservé du langage python.
 on donne les valeurs numériques des constantes physiques :
— c = 3, 00.108 m.s−1 vitesse de la lumière dans le vide
— h = 6, 67.10−34 J.s−1 constante de Planck
— q e = 1.60.10−19 C charge élémentaire

B.2 Les boucles


Exercice no 7 Atome d’hydrogène
En 1913 Bohr dans son modèle atomique de l’atome d’hydrogène propose une quantification du moment
cinétique qui conduit à la quantification des niveaux d’énergie donnée par la formule

mq e4 1
En = −
8ϵ20 h 2 n 2
B. APPLICATIONS 17

où m est la masse de l’électron, q e sa charge, ϵ0 la permittivité du vide, h la constante de Planck et n un entier


strictement positif.
1. En déduire que la longueur d’onde λn,p d’une onde électromagnétique correspondant à la transition entre
le niveau p et le niveau n (avec p > n) s’écrit
µ ¶
1 1 1
= RH 2 − 2
λn,p n p

2. Écrire un programme qui donne toutes les longueurs possibles (en nanomètre) pour des transitions issues
du niveau p = 7.
On donne :
 m = 9, 109 10−31 kg
 h = 6, 626 10−34 J.s−1
 ϵ0 = 8, 854 10−12 F.m−1
 c = 2, 9979 108 m.s−1
 q e = 1, 602 10−19 C

B.3 Boucles, tests et fonction


On se propose d’enrichir le programme précédent en combinant l’utilisation de boucles for, de test if et
d’une fonction définie localement.

Exercice no 8 Domaine spectral


Les spectroscopistes classent les raies suivant le niveau d’arrivée des transitions considérées : séries spectrales
de Lyman (n = 1), Balmer (n = 2), Paschen (n = 3), Brackett (n = 4), Pfund (n = 5) et Humphreys (n = 6).
Reprendre l’exercice précédent et introduire les modifications suivantes :
1. Afficher le nom et le nombre de la série spectrale (état du niveau d’arrivée)
2. Définir une fonction test_interval(x) qui reçoit en argument la longueur d’onde en nanomètre et qui
renvoie une chaîne de caractères indiquant à quel domaine spectral (IR, Visible ou IR) appartient cette
onde
3. En utilisant cette fonction, indiquer le domaine spectral correspondant à chaque transition et exprimer les
caractéristiques du rayonnement électromagnétique en cm−1 dans le domaine infrarouge (IR), en nano-
mètre dans le visible et en électron-volt dans l’ultra-violet (UV).
On donne :
 UV : 10 nm–390 nm
 visible : 390 nm–750 nm
 IR : 750 nm– 0, 1 mm
Extrait en sortie du programme (cas de la série de Lyman) :
spectre de Lyman
n = 1 , p = 2
energie = 10.2 eV (UV)
n = 1 , p = 3
energie = 12.1 eV (UV)
n = 1 , p = 4
energie = 12.8 eV (UV)
n = 1 , p = 5
energie = 13.1 eV (UV)
n = 1 , p = 6
energie = 13.2 eV (UV)
n = 1 , p = 7
energie = 13.3 eV (UV)
TD 3
T RAITEMENT DES DONNÉES

Depuis Galilée les sciences physiques se caractérisent par la confrontation entre une compréhension d’un
phénomène reposant sur un modèle mathématique et des données issues de l’expérience. Tout scientifique est
donc confronté un jour ou l’autre à la récupération de données expérimentales et à leur traitement afin de tester
la pertinence d’un modèle théorique.
Dans une première partie, on se propose de récupérer des données que l’on a stockées dans un fichier. Après
extraction de ces données, on effectue un affichage graphique de celles-ci.
La seconde partie consiste a appliquer un traitement mathématique (méthode des moindres carrés) afin d’ex-
traire les paramètres d’ajustement correspondant à une modélisation du phénomène physique étudié (ici une
simple régression linéaire).
Enfin dans une dernière partie on propose de montrer comment fabriquer un fichier de données directement
exploitable en python.

A Préparation
Exercice no 9 Récupération et affichage
Récupérez sur l’ENT le fichier dataMalus.dat qui contient les données d’une expérience visant à vérifier la
loi de Malus. Cette expérience consiste à vérifier qu’une lumière polarisée rectilignement traversant un analy-
seur faisant un angle α avec la polarisation initiale produit une intensité lumineuse proportionnelle au cosinus
de l’angle α. Dans l’expérience une photodiode fournit en sortie de l’analyseur, une tension U proportionnelle à
l’intensité lumineuse. Les données sont représentées dans le fichier sous la forme de deux colonnes correspon-
dant aux angles α et aux tensions U correspondantes. Une ligne d’en-tête permet d’identifier à quelle grandeur
physique se rapporte chaque colonne ainsi que les unités utilisées.

alpha (en degré) U (en mV)


0 422.2
10 416.5
20 394.2
30 344.8
40 280.1
50 208.8
60 137.0
70 75.5
80 30.1
90 9

TABLE 3.1 – Données expérimentales correspondant à la vérification de la loi de Malus

Pré-traitement des données

18
B. AJUSTEMENTS 19

1. Écrire un programme qui récupère les données du fichier dataMalus.dat, les convertit en réels (float),
puis les stocke dans des tableaux (array) qu’on pourra noter U et alpha , d’après le modèle suivant :
f = open("monFichierData.dat", ’r’)
f.readline() # on saute la première ligne si nécessaire (en-tête)
# itération sur le nombre de lignes
for ligne in f:
mots = ligne.split() # découpe la ligne en "mots"
x = float(mots[0]) # conversion du type "text" en type "float"
y = float(mots[1])

2. Tracer avec la fonction plot, le graphe U = f cos2 α (cf. figure 3.1a). On prendra soin de convertir les degrés
¡ ¢

en radians.
3. Rajouter un décalage systématique α0 sur les angles. Combien faut-il prendre pour que les données semblent
« bien alignées » ? Comment appelle-t-on ce type d’erreurs ?
4. Reprendre le tracé des données en rajoutant des barres d’erreurs (5% sur la mesure plus une erreur de
10 mV due au calibre) à l’aide de la fonction de matplotlib : errorbar, dont voici la syntaxe errorbar(x,
y, yer, fmt=’o’) (cf. figure 3.1b)

450 tension diode en fonction de l'intensité lumineuse 500 tension diode en fonction de l'intensité lumineuse

400
400
350
300 300
250
U en mV

U en mV

200
200
150 100
100
0
50
00.0 0.2 0.4 0.6 0.8 1.0 1000.0 0.2 0.4 0.6 0.8 1.0
cos2 α ou Intensité cos2 α ou Intensité

(a) Tracé simple (b) Tracé avec barres d’erreurs

F IGURE 3.1 – Tracé des données expérimentales du fichier dataMalus.dat

B Ajustements
On veut dans cette partie obtenir les paramètres d’une formule d’ajustement sur les données numériques (fit
en anglais) ; ajustement linéaire dans un premier temps, puis non-linéaire dans une seconde étape.

B.1 Méthode des moindres carrés


Le principe de cette méthode consiste à déterminer la « meilleure droite » y (x) passant par les points expé-
rimentaux y i en minimisant la distance de cette droite Ax + B aux différents points mesurés y i . Pour cela on
construit la fonction
N y − (Ax + B ) 2
£ ¤
2 i i
χ (A, B ) =
X
i =1 σ2i
où σi correspond à l’incertitude de mesure associée à la variable y i . On posera par la suite σi = σ constante.
∂χ2 ∂χ2
On minimise cette distance en posant d χ = 0 qui conduit à la relation ∂A = ∂B = 0.
On obtient (faites le calcul !) le système linéaire en A et B
(
AΣx i2 + B Σx i = Σx i y i
AΣx i + B N = Σy i
20 TD 3. TRAITEMENT DES DONNÉES

Ce qui donne

N Σx i y i − Σx i Σy i Σy i Σx i2 − Σx i Σx i y i
A= et B =
∆ ∆

avec ∆ = N Σx i2 − (Σx i )2 .
On suppose que tous les points y i sont soumis à la même loi de distribution dont on estime l’écart type à l’aide
de l’expression
1 X N £ ¤2
σ2y = y i − (Ax i + B )
N − 2 i =1

et en utilisant la formule de propagation des erreurs, on en déduit l’incertitude sur A et B


sP
x i2
r
N
σ A = σy et σB = σ y
∆ ∆

Exercice no 10 Programme « maison »


Traiter les données en appliquant les formules précédentes de la méthode des moindres carrés. Calculer A, B ,
σ A et σB et comparer avec les valeurs « exactes » qui nous ont permis de construire les données de la simulation.

Exercice no 11 Programme scipy


À l’aide de la fonction curve_fit de la bibliothèque scipy.optimize on peut traiter directement les données en
définissant la fonction fonc(x, a, b) à ajuster. On récupère les paramètres A et B optimisés de la façon suivante :
def fonc(x, a, b):
return a*x+b

popt, pcov = curve_fit(fonc, P, T)


[A, B] = popt

sigma_A = np.sqrt(pcov[0, 0])


sigma_B = np.sqrt(pcov[1, 1])

où popt est un vecteur qui renvoie les paramètres optimisés de la fonction et pcov est une matrice dont les
éléments diagonaux correspondent aux écarts type aux carrés (variances) de chacun des paramètres. Comparer
avec les résultats de votre programme précédent.

C Création « manuelle » d’un fichier de données


Exercice no 12 fabrication du fichier dataMalus.dat
On suppose dans cet exercice que vous avez noté dans votre cahier de manip les valeurs des angles et des
tension ainsi qu’indiqué dans le tableau 3.1. Rentrez ces valeur dans un fichier tableur sous LibreOffice (ou Ope-
nOffice).
Les fichiers de tableur sont par défaut sauvegardés dans un format propriétaire qui permet, outre le stockage
des données numériques de conserver les mises en forme des cellules, les formules et d’autres « extras » qui ne
sont pas à proprement parler utiles pour l’exploitation par un programme python.
Le format de données le plus adapté à la lecture par un programme python est le format CSV (pour Coma
Seperated Variable), format texte pour lequel chaque « champ » (élément d’une colonne) du fichier tableur est
séparé du suivant par un signe de ponctuation (une virgule « , » (coma) dans le format standard).
Cependant, les tableurs gèrent la francisation qui se manifeste en particulier par le fait que le séparateur dé-
cimal est la virgule et non le point comme en notation anglo-saxonne. Les fichiers CSV francisés ne peuvent donc
pas accepter la virgule comme séparateur de champ sous peine de confondre point décimal et séparateur de co-
lonne. Le séparateur par défaut est alors souvent le point-virgule « ; », mais il est généralement possible de choisir
un autre séparateur comme l’espace « » ou le caractère de tabulation « → | ». On a donc par exemple :
C. CRÉATION « MANUELLE » D’UN FICHIER DE DONNÉES 21

A B 1,2 2,5
1 1, 2 2, 5 1,4 3,25
2 1, 4 3, 25 ⇒ 1,44 4,56
3 1, 44 4, 56

Fichier Excel ou OpenOffice Fichier CSV (séparateur espace)

Le fichier CSV créé n’est pas directement lisible par un code python puisque les réels ne seront pas recon-
nus comme tels. Afin de rendre le fichier exploitable, il faut transformer toutes les virgules décimales en points
décimaux. Cet exercice de conversion de format est malheureusement très fréquent lorsqu’on passe d’un envi-
ronnement logiciel à un autre.

Méthode manuelle Effectuer les opérations suivantes :


 sauver le fichier avec l’extension .csv,
 cocher l’option « Éditer les paramètres du filtre »,
 choisir l’option {Tab} ou {Espace} comme séparateur de champ et sauver sous le nom dataMalus.csv,
 ouvrir le fichier dataMalus.csv dans un éditeur de texte (par exemple Notepad++ sous Windows, gedit
sous Linux, TextEdit sous Mac) et remplacer les séparateurs décimaux virgules par des points (le faire avec
l’option Rechercher/Remplacer en une seule fois et pas à la main un par un !). Le sauver sous le nom
dataMalus.dat.
Vous pouvez alors traiter vos données comme indiqué au début du TD.

Méthode automatique avec Python Les fichiers issus de tableurs et sauvegardés au format CSV sont comme
nous l’avons vu des fichiers textes (on peut les ouvrir avec Notepad++ sous Windows, gedit sous Linux, TextEdit
sous Mac).

Fichier CSV
Fichier Excel ou OpenOffice (séparateur ; et réels francisés)

Il est donc possible de les lire directement en Python.


Il faudra cependant veiller à séparer correctement chaque colonne et surtout à convertir la virgule décimale
en point décimal avant la transformation des données lues en réels.
Le code de convertion ressemble donc à ce qui suit.
f = open("monFichierData.csv", ’r’)
f.readline() # on saute la première ligne si nécessaire (en-tête)
# itération sur le nombre de lignes
for ligne in f:
mots = ligne.split(";") # découpe la ligne en "mots" en utilisant le séparateur ; pour
les colonnes
x = mots[0]
y = mots[1].replace(",",".") # on remplace dans la variable texte mots[1] les virgules ","
par des points "."
x = float(x) # conversion du type "text" en type "float"
y = float(y)
22 TD 3. TRAITEMENT DES DONNÉES

Téléchargez sur l’ENT le fichier dataMalus.csv. Ecrire le code Python qui lit le fichier et convertit chaque
colonne en nombre du type de ceux sur lesquels on a travaillé au début du TP. Afin de comprendre le rôle de
chaque ligne, on imprimera à l’écran le contenu de chaque colonne à chaque étape de la transformation.
TD 4
É QUATIONS DIFFÉRENTIELLES

A Équation différentielle du premier ordre


A.1 Principe : la méthode d’Euler
Exercice no 13 Décroissance radioactive
La population d’un corps radioactif évolue suivant la loi de désintégration
dN
= −αN
dt
où N est le nombre d’atomes à l’instant t et α le taux de décroissance caractéristique du corps considéré. On
prendra dans la suite comme valeur numérique le nombre d’atomes initial N0 =1000 et le taux de décroissance
α = 3 s−1 .
1. Rappeler brièvement la solution analytique de cette équation.
2. Résoudre cette équation par la méthode d’Euler dont on rappelle ici le principe pour une équation du type
dy ¡ ¢
= F y, t
dt
On découpe l’intervalle [0, t ] en N sous-intervalles de longueur h appelé pas d’intégration, on note t n = nh
l’instant après n itérations et y n = y (t n ) la fonction recherchée y (t ) à cet instant. On a alors la relation de
récurrence
¡ ¢
y n+1 = y n + h F y n , t n
3. Construire en python deux tableaux l’un contenant les t n et l’autre les Nn . Comparer alors sur un même
graphique la solution analytique N (t ) avec la solution numérique pour différentes valeurs du pas h. Conclure.
4. Améliorer votre code en définissant une fonction euler(func, Yini, x_tab): implémentant l’algorithme
d’Euler dans lequel vous passerez en argument la fonction F , les conditions initiales et le tableau des temps
sur lequel vous effectuez l’intégration. Vous appellerez cette procédure euler() d’après le modèle suivant :
def F(y, t):
return -alpha*y

# Initialisations
alpha = 3
Nini = 1e3
tini = 0
tfin = 2
Npt = 30
t_tab = np.linspace(tini, tfin, Npt)
CI = Nini

N = euler(F, CI, t_tab)


plt.plot(t_tab, N, ’o’, label="solution numerique")

23
24 TD 4. ÉQUATIONS DIFFÉRENTIELLES

1.8 Évolution temporelle de la vitesse de chute d'une bille

1.6
1.4
1.2

vitesse en m/s 1.0


0.8
0.6
0.4
solution numérique
0.2 solution exacte
0.00.0 0.2 0.4 0.6 0.8 1.0
temps en seconde

F IGURE 4.1 – Vitesse d’une bille chutant dans un milieu visqueux

A.2 La fonction odeint de scipy

Voici la solution du problème précédent en faisant appel à la fonction odeint de scipy.

import numpy as np
import matplotlib.pyplot as plt
from scipy.integrate import odeint

def F(y, t):


res = -alpha*y
return res

# Initialisations
alpha = 3
yini = 1
tini = 0
tfin = 2
Npt = 20 # nombre de points sur l’axe des temps
t_tab = np.linspace(tini, tfin, Npt)
CI = np.array([yini]) #condition initiale
y = odeint(F, CI, t_tab)
plt.plot(t_tab, y, ’o’, label="solution numérique")

# comparaison avec la solution exacte


yexact = yini*np.exp(-alpha*t_tab)
plt.plot(t_tab, yexact, ’-r’, label="solution exacte")
plt.legend()
plt.show()

Exercice no 14 Chute d’une bille dans la glycérine


En vous inspirant du programme précédent tracer l’évolution temporelle de la vitesse de chute d’une bille
métallique de rayon r = 0.4 mm et de masse m = 2 g dans de la glycérine de viscosité η = 1.5 Pa.s. On prendra
g = 9.8 m.s−2 pour l’accélération de la pesanteur et on rappelle que la force de frottement visqueuse sur une sphère
de rayon r obéit à la loi de Stokes : F = −6πηr v.
B. SYSTÈME DU 1ER ORDRE 25

B Système du 1er ordre


B.1 Système proie-prédateur
On cherche à présent à résoudre numériquement un système d’équations différentielles du premier ordre
en prenant comme exemple le système d’équations dit de Lotka-Volterra ou équations du modèle d’interaction
proies-prédateurs.

Exercice no 15 Modèle proies-prédateurs


Ce modèle proposé par le physicien italien Vito Volterra à la fin de la première guerre mondiale cherche à
décrire l’évolution des populations de sardines et de requins en mer Adriatique. Son but était en particulier d’ex-
pliquer pourquoi les quantités de sardines pêchées après l’interruption due à la guerre n’étaient plus aussi impor-
tantes que précédemment et pourquoi à la reprise de la pêche la proportion observée de requins avait augmenté.
Si on note S la population de sardines et R celle des requins, le modèle conduit au système suivant
(
dS
dt = aS −bSR
dR
dt = −c R + d S R

1. Interpréter chaque terme du système a S, −b S R, −c R et d S R en vous inspirant de vos connaissances en


cinétique chimique.
2. On pose par la suite b = d = 1 ce qui est toujours possible en renormalisant les populations.
Résoudre numériquement à l’aide de la fonction odeint ce système d’équations.
(a) En définissant les « vecteurs » suivants (tableaux en python) :
· ¸ · ¸
s a s −b sr
Y = et F =
r −c r + d s r

on obtient alors l’équation formelle


dY
= F (Y , t )
dt
(b) Définir une fonction (au sens de python def F(Y,t) avec comme arguments le tableau Y et le temps t)
dans laquelle
 on décompactera le tableau Y en deux sous-tableaux [s,r] = Y,
— on construira ensuite les éléments du tableau F
F1 = a*s-b*s*r
F2 = -c*r + d*s*r

— qui renverra enfin le tableau return [F1,F2]


 Utiliser cette fonction F comme argument de la fonction odeint de scipy vu à l’exercice précédent.
On définira bien sûr au préalable le tableau t des instants où l’on veut évaluer S (t ) et R (t ) à l’aide
de la fonction linspace. Néanmoins comme il s’agit ici d’un système d’équations et non d’une
équation unique, le tableau retourné par la fonction odeint est un tableau (ici à 2 dimensions) que
l’on récupèrera de la façon suivante :
Z = odeint(F, CI, t)
sn = Z[:, 0]
rn = Z[:, 1]

où les deux points (:) signifient que l’on récupère tous les éléments de ce tableau pour l’indice
correspondant.
(c) Tracé S (t ) et R (t ) en prenant comme conditions initiales S (0) = s 0 = 2 et R (0) = r 0 = 0.1 et pour para-
mètres a = 0.5 et c = 1.
Explorez le comportement des solutions en modifiant (un peu) les paramètres a et c.
26 TD 4. ÉQUATIONS DIFFÉRENTIELLES

3.0 Modèle proies-prédateurs


sardines
requins
2.5

2.0

Population S(t) et R(t)


1.5

1.0

0.5

0.00 10 20 30 40 50
temps

F IGURE 4.2 – Exemple d’évolution des populations de sardines et de requins pour les paramètres a = 0.5 et c = 1

B.2 Cinétique chimique


On s’intéresse à présent à un système d’équations différentielles du premier ordre dans un contexte de ciné-
tique chimique. Il s’agit d’une cinétique consécutive mettant en jeu trois espèces chimiques A, B et C.

k1 k2
A ⇌ B ⇌ C
k −1 k −2

B.2.1 Solution approchée


Nous allons faire les hypothèses suivantes :
 Nous commençons avec une solution pure de l’espèce A. Donc au temps t = 0, [A] = [A]0 = 1, [B ] = [B ]0 = 0
et [C ] = [C ]0 = 0.
 La réaction C → B peut être négligée car on ne s’intéresse qu’au tout début de la réaction, avant une for-
mation importante de l’espèce C .
 k2 ≫ k1 et donc l’espèce B disparait aussi vite qu’elle est formée. Par conséquent, nous pouvons aussi
négliger la réaction B → A.
Ces hypothèses nous mènent au modèle simplifié,

k1 k2
A B C
→ →
Nous pouvons alors exprimer les lois de vitesse qui conduisent au système différentiel suivant :

d [A]
= −k 1 [A]
dt
d [B ]
= k 1 [A] − k 2 [B ]
dt
d [C ]
= k 2 [B ]
dt
La résolution de ces équations donne les relations suivantes :

[A] = [A]0 exp(−k 1 t )


k1 ¡ ¢
[B ] = [A]0 exp(−k 1 t ) − exp(−k 2 t )
k2 − k1
k1 ¡
½ ¾
¢
[C ] [A]0 [B ] [A]
= − − = [A] 0 1 − exp(−k 1 t ) − exp(−k 1 t ) − exp(−k 2 t )
k2 − k1
C. SYSTÈMES DU SECOND ORDRE 27

³ ´
1 k2
On remarque également que la quantité [B ] passe par un maximum à : t m = k 2 −k 1 ln k1

Exercice no 16 Étude graphique


Tracer le graphique contenant les trois courbes [A], [B ], et [C ] (avec des symboles différents) en fonction du
temps en prenant soin de choisir les valeurs de k 1 et k 2 de telle sorte que k 2 ≫ k 1 . On calculera les concentrations
jusqu’à t = 3t m .

B.2.2 Solution exacte

Dans cette seconde partie du TD on se propose de résoudre le problème de cinétique chimique précédent
sans faire d’approximations et/ou d’hypothèses particulières. Il s’agit d’une résolution exacte par un traitement
numérique des équations.
Les conditions initiales sur les concentrations des trois espèces sont identiques au cas précédent (i.e. [A] =
[A]0 = 1, [B ] = [B ]0 = 0 et [C ] = [C ]0 = 0).
Soit le système différentiel :

d [A]
= k −1 [B ] − k 1 [A]
dt
d [B ]
= k 1 [A] − k 2 [B ] − k −1 [B ] + k −2 [C ]
dt
= k 1 [A] − (k 2 + k −1 )[B ] + k −2 [C ]
d [C ]
= k 2 [B ] − k −2 [C ]
dt

Exercice no 17 Solution numérique complète


Résoudre ce système d’équations avec la fonction odeint évoquée au paragraphe précédent.
1. Calculer les concentrations jusqu’à t = 3t m et tracer le graphique contenant les trois courbes [A], [B ], et [C ]
en fonction du temps.
2. Tester la validité des approximations faites dans la première partie en confrontant les résultats obtenus
précédemment avec ceux obtenus par une méthode de résolution numérique.
On pourra également se placer dans un cas (choix spécifique des constantes de vitesse) où l’évolution de
l’espèce [B ] est brutale pour mettre en évidence l’importance du choix de pas de temps.

C Systèmes du second ordre


En transformant une équation différentielle du second ordre (ou plus) en un système d’équations différen-
tielles du premier ordre on va pouvoir réutiliser les procédures employées plus haut et ainsi résoudre numérique
des équations différentielles d’ordre quelconque. Nous étudierons ici plus particulièrement la résolution d’équa-
tions différentielles du second ordre en mécanique qui par l’utilisation des lois de Newton en constitue un do-
maine d’application privilégié.

Exercice no 18 Mouvement unidirectionnel dans un champ de pesanteur


On lance dans un champ de pesanteur supposé uniforme un objet de masse m vers le haut avec une vitesse
initiale v 0 = 5 m.s−1 .
1. Retrouver (rapidement) que l’équation différentielle à laquelle obéit la cote z (t ) de l’objet s’écrit en prenant
un axe Oz orienté vers le haut
d 2z
= −g
dt2
Donner l’expression de la solution analytique de cette équation en fonction des conditions initiales z (t = 0) =
0 et dd zt (t = 0) = v 0
28 TD 4. ÉQUATIONS DIFFÉRENTIELLES

10 Chute d'une bille dans g uniforme 10 Chute d'une bille dans g uniforme avec frottement
solution numérique solution numérique
solution exacte 0 solution exacte
5 sans frottement
10
20
0
30
z (en m)

z (en m)
40
5
50

10 60
70
150.0 0.5 1.0 1.5 2.0 2.5 3.0 800 1 2 3 4 5
t (en s) t (en s)

(a) Comparaison analytique-numérique (b) Chute avec frottement visqueux

F IGURE 4.3 – Trajectoire dans un champ de pesanteur uniforme

2. Cette équation différentielle du deuxième ordre peut s’écrire comme un système d’équations différentielles
du premier ordre (
dz
dt = v
dv
dt = −g
Comme vu plus haut on définit les « vecteurs » suivants (tableaux en python) :
· ¸ · ¸
z v
Y = et F =
v −g
et on obtient l’équation formelle
dY
= F (Y , t )
dt
(a) Définir une fonction (au sens de python def F(Y,t) avec comme arguments le tableau Y et le temps t)
dans laquelle
 on décompactera le tableau Y en deux sous-tableaux [z,v] = Y,
 on construira ensuite les éléments du tableau F
F1 = v
F2 = -g

 et qui renverra enfin le tableau return [F1,F2]


(b) Utiliser cette fonction F comme argument de la fonction odeint de scipy vu au TD précédent. On
définira bien sûr au préalable le tableau t des instants où l’on veut évaluer z (t ) à l’aide de la fonction
linspace. Néanmoins comme il s’agit ici d’un système d’équations et non d’une équation unique, le
tableau retourné par la fonction odeint est un tableau (ici à 2 dimensions) que l’on récupèrera de la
façon suivante :
Z = odeint(F, CI, t)
z = Z[:, 0]
v = Z[:, 1]

où les deux points (:) signifient que l’on récupère tous les éléments de ce tableau pour l’indice corres-
pondant.
(c) Tracer la solution numérique sous forme de points dans un plot superposé à la solution analytique
comme indiqué sur la figure (4.3a)
3. Reprendre le problème en ajoutant un frottement visqueux Fv = −αv dans le bilan des forces. On prendra
par exemple α = 0.5 kg.s−1 et on tracera sur le même graphe la solution numérique, la solution analytique
sans frottement et la solution analytique exacte avec frottement visqueux (à calculer !) comme indiqué sur
la figure (4.3b)
C. SYSTÈMES DU SECOND ORDRE 29

Pendule (petits angles)


0.10 solution numérique
solution harmonique
0.05

θ (en rd.s−1 )
0.00

0.05

0.10
0 1 2 3 4 5
t (en s)
Pendule (grands angles)
1.0 solution numérique
solution harmonique
0.5
θ (en rd.s−1 )

0.0

0.5

1.0
0 1 2 3 4 5
t (en s)

F IGURE 4.4 – Comparaison de la solution numérique de l’équation du pendule avec son approximation harmonique

Exercice no 19 Pendules
On considère un pendule simple c’est-à-dire un objet de masse m suffisamment petit pour être considéré
comme ponctuel que l’on accroche à un fil inextensible, de masse négligeable et de longueur L à un point fixe O.
1. Retrouver (par exemple à partir du théorème du moment cinétique) que l’angle θ que fait le pendule avec
la verticale obéit à l’équation différentielle

d 2θ
+ ω20 sin θ = 0
dt2
g
avec ω20 = L où g est l’accélération de la pesanteur. On a bien entendu négligé ici les frottements.
2. Résoudre numérique cette équation en suivant la méthode développée dans l’exercice précédent : trans-
formation de l’équation différentielle du second ordre en un système différentiel du premier ordre, puis
utilisation de la fonction odeint de scipy. On comparera cette solution numérique avec la solution har-
monique de l’équation numérique aux petits angles pour lesquels on peut utiliser l’approximation sin θ ≃ θ
(cf. figure 4.4).
3. On se place à présent dans le régime harmonique mais on rajoute une force de frottements visqueux.

(a) Montrer que l’équation différentielle s’écrit alors

θ̈ + 2λθ̇ + ω20 θ = 0

(b) Vérifier numériquement que l’on a bien les 3 régimes : pseudo-périodique si λ < ω0 , critique si λ = ω0
et sur-amorti si λ > ω0 (cf. figure 4.5)
30 TD 4. ÉQUATIONS DIFFÉRENTIELLES

Pendule avec frottements


0.10 solution pseudo-périodique
solution critique
solution sur-amorti
0.05
θ (en rd.s−1 )

0.00

0.05

0.10
0 1 2 3 4 5
t (en s)

F IGURE 4.5 – Les 3 régimes d’amortissement pour un oscillateur harmonique soumis à des frottements visqueux

Vous aimerez peut-être aussi