Résolution d`équations différentielles avec odeint cas de l`oscillateur

publicité
IPT_ PCSI utilisation de odeint : oscillateur harmonique et trajectoires de satellites
Résolution d'équations différentielles avec odeint
cas de l'oscillateur harmonique
cas des trajectoires de satellites
Dans ce TP, on désire
•
Se familiariser avec la commande scipy.integrate.odeint pour résoudre de façon numérique des équations
différentielles.
•
Tracer les courbes intégrales et les portraits de phase d’une équation différentielle.
•
Simuler la trajectoire d’un satellite soumis à la force gravitationnelle d’un seul corps, avec ou sans frottements.
•
Simuler la trajectoire d’un satellite soumis à la force gravitationnelle de deux corps.
•
Calculer les paramètres de l’orbite dans le cas d’un seul corps, et tracer les courbes de l’énergie efficace.
Modules à charger
import numpy as np
from scipy.integrate import odeint
import matplotlib.pyplot as plt
voir polycopiés pour l’utilisation de matplotlib et de numpy.
1)
Exemples de résolution d’équations différentielles avec odeint
On résout de façon numérique, donc de façon approximative, des équations différentielles du premier ordre,
exclusivement de la forme
 x’(t) = f (x(t), t)

 x(t0) connu
où la fonction x(t) peut-être éventuellement vectorielle. Sous des hypothèses raisonnables, on dispose d’un théorème de
Cauchy qui garantit l’existence et l’unicité d’une solution sur un intervalle de temps le plus grand possible (sur pour
les EDL).
On se donne un vecteur t = (t0 , t1, ... , tn) qui donne l’échantillon de temps sur lequel on veut résoudre le problème de
Cauchy. Partant de x0 = x(t0) qui est imposé, on calcule de proche en proche des approximations x1 , x2 , ... xn de x(t1),
x(t2), ... , x(tn).
1.1 Syntaxe
odeint( f , x0 , t) où t est l’échantillon de temps sous forme de liste ou de tableau numpy et où x0 = x(t0) est la valeur de x
à l’instant initial de l’échantillon. La fonction odeint retourne le tableau numpy contenant les valeurs calculées pour x
aux points de l’échantillon de temps. On se sert de ce tableau pour tracer les courbes demandées.
1.2 Exemple d'équation scalaire d'ordre 1
On veut résoudre le problème de Cauchy x’ = 2x + 1 , x(0) = 1 sur l’intervalle [0, 2]. Ici, f (x, t) = 2x + 1.
>>>
Construire à l’aide de np.linspace une subdivision T de [0, 2] comportant disons, 20 valeurs.
Définir la fonction f puis utiliser odeint( f , 1 , T).
Récupérer le résultat sous forme d’un vecteur X. Tracer la courbe intégrale à l’aide plt.plot(T, X).
Faire varier le nombre de points et discuter la qualité du tracé en fonction du nombre de points.
1.3 Exemple d'équation scalaire d'ordre 2
On veut résoudre sur [0,10], le problème de Cauchy x" + x = 0 , x(0) = 1, x’(0) = − 1.
Pour se ramener à une équation du premier ordre, il faut passer d’une inconnue scalaire x(t) à une inconnue vectorielle,
en l’occurrence X(t) = (x(t) , x’(t)). Il est plus commode de présenter les calculs sous forme matricielle :
x'(t) 
1
x'(t)
= f (X(t), t) et X0 = X(t0) = X(0) =  
X ’(t) = x"(t) = 
− x(t)
−1
on pose donc f (X, t) = (x1 , − x0) si X est le couple (x0, x1).
- page 1 -
IPT_ PCSI utilisation de odeint : oscillateur harmonique et trajectoires de satellites
En Python, cela devient :
def f(x, t):
|
return [x[1], − x[0]]
T = np.linspace(0,10,100)
X = odeint(f, [1,− 1], T)
plt.plot(T, X[ : , 0]) # courbe x(t)
plt.show()
pour la définition de la fonction f, on peut aussi écrire :
def f(y, t):
|
(x, dx) = y
|
return [dx, − x]
Bien comprendre qu’ici, le vecteur X retourné par odeint est un tableau à deux colonnes qui contient à la fois les valeurs
de x et celles de x’. Avec X[ :,0], on extrait la première colonne, donc les valeurs de x sur l’échantillon de temps T.
>>>
Dessiner le portrait de phase (x(t) , x'(t)) en utilisant la commande plt.plot(X[ : , 0] , X[ : , 1]) .
1.4 Oscillateur harmonique : cas du ressort
>>>
Sur le même modèle, écrire une fonction oscill_harm(ω, a, b, N, x0, v0, g) qui résout l'équation (mouvement d'une
particule à l'extrémité d'un ressort)
x" + ω2x = g
sur l'intervalle [a,b] avec N points dans l'échantillon de temps et avec comme conditions initiales x(0) = x0, x'(0) = v0.
La fonction tracera les courbes suivantes :
• t # x(t) sur [a, b]
.
• t # (x(t) , x (t) ) le portrait de phase
.
• t # Em(t) où Em(t) = 1/2x 2 + 1/2 ω2 x2 qui représente l'énergie mécanique (divisée par la masse) et qui est censée
être constante lorsque g = 0.
1.5 Pendule non linéarisé
..
L'équation est θ + ω2 sin(θ) = 0.
.
L'énergie mécanique (divisée par la masse) est donnée par E = 1/2 θ 2 + ω2 (1 − cos(θ)).
>>>
Ecrire une fonction oscill_harm_non_lin(ω, a, b, N, x0, v0) qui trace les mêmes courbes que précédemment.
Observer le changement d'allure du portrait de phase lorsque x0 = 0 et que v0 devient > 2ω.
2)
Trajectoires de satellites soumis à l'attraction de un ou plusieurs astres
On propose donc d'étudier le mouvement d'un satellite autour d'un astre, connaissant sa position et sa vitesse initiales.
Conventions
M désigne la masse de l'astre et m celle du satellite, considérée comme négligeable devant M
L'origine O du repère est le centre de l'astre qu'on considère comme immobile
La relation fondamentale de la dynamique s'écrit
t
t
f =mγ =−
GmM →
r
r3
t
t
→
→
où f est la force à laquelle le satellite est soumis, γ son accélération et r le vecteur polaire OM , M(t) étant la
position du satellite à l'instant t.
On suppose que GM = 1 (quitte à changer les unités de longueurs et de temps). Avec ces nouvelles unités, on a donc
- page 2 -
IPT_ PCSI utilisation de odeint : oscillateur harmonique et trajectoires de satellites
t
f =−m
t
2.1 Implémentation de l’équation γ = −
t
1→
1→
r , c'est à dire γ = − 3 r
r3
r
1→
r
r3
t
Comme γ (t) = (x"(t), y"(t)), on a affaire à un système différentiel du second ordre où l’inconnue est le vecteur (x(t) , y(t)).
Il faut le transformer en un système du premier ordre en augmentant la dimension.
Pour cela, on pose Y(t) = (x(t), x'(t), y(t), y'(t))). On a alors,
x'(t)
x'(t)
 x"(t) 
Y'(t) = 
y'(t) 
 y"(t) 
 − x(t)
 (x(t) + y(t) )
 y(t)y(t)
 − (x(t) + y(t) )
2
=
2
2 3/2
2 3/2

 = f (Y(t), t)


x0
,
Y0
 vx 
= Y(t ) = 
y 
 vy 
0
0
0
0
En Python, on définira donc (observer et comprendre la syntaxe),
def f(z, t):
|
(x, dx, y, dy) = z
|
return [dx , − 1/(x**2 + y**2)**(3/2)*x , dy , − 1/(x**2 + y**2)**(3/2)*y]
odeint retournera le tableau Y avec 4 colonnes, la première fournissant les valeurs de x(t), la troisième celles de y(t).
2.2 Trajectoire du satellite soumis à l’attraction d’un seul corps
>>>
Ecrire une fonction orbite(ini, T, f) où ini est une liste de la forme [x0, vx0, y0, vy0] fixant les conditions initiales à
l’instant 0, T la durée d’observation et f la fonction qu'on vient de définir.
La fonction devra tracer successivement,
• La trajectoire du satellite (le portrait de phase) : (x(t), y(t)) , t ∈ [0,T]
• La courbe de la fonction t # x(t) : (t, x(t)) , t ∈ [0,T]
• La courbe de la fonction t # y(t) : (t, y(t)) , t ∈ [0,T]
On testera la fonction avec les jeux de données suivants :
ini = [2, − 0.2 , 0 , 0.4] , ini = [2,− 0,5, 0, 1] et un exemple où le vecteur vitesse initial est dirigé vers l’astre.
Deviner la nature de la trajectoire.
2.3 Avec une force de frottement
>>>
t
Rajouter un frottement : le satellite est donc soumis à une force supplémentaire proportionnelle à la vitesse − k V . On
prendra k/m = 0.05.
Modifier la fonction f donnée en 2.1 et écrire une fonction orbite_amortie(ini, T, f) sur le modèle de orbite(ini, T, f).
Observer et commenter l’effet du frottement sur le mouvement.
2.4 Trajectoire avec deux astres
>>>
On rajoute un deuxième astre S situé en position (1,0) avec GMs = 0.5. Le satellite est alors soumis à l’attraction des
deux astres. On ne sait pas résoudre explicitement les équations du mouvement (problème des 3 corps) ni même garantir
la stabilité de l’orbite.
→
Modifier la fonction f en rajoutant le terme dû au deuxième astre − 1/MS3 SM .
Procéder ensuite comme pour orbite(ini, T, f).
On pourra tester avec le jeu de données ini = [2,0,0,0.25] et T = 20, 30, ... (adapter la durée) et ini = [2,0,-0.5,1].
- page 3 -
IPT_ PCSI utilisation de odeint : oscillateur harmonique et trajectoires de satellites
2.5 Influence d'une perturbation sur les conditions initiales
>>>
Ecrire une fonction orbite_pertubee(ini,T, f, epsilon). On modifie le vecteur ini par une perturbation aléatoire dont
l’ampleur est contrôlée par le paramètre epsilon. On dessine sur un même graphique, l’orbite correspondant au vecteur
ini et celle correspondant au vecteur pertubé.
On pourra utiliser la commande np.random.rand(n) qui retourne un vecteur de n nombres aléatoires entre 0 et 1.
Observer la stabilité de la trajectoire.
Dans le même veine, superposer un échantillon de trajectoire avec le même point (x0, y0) de départ mais en faisant
varier la direction du vecteur vitesse (mais avec le même module), ou bien en faisant varier le module de la vitesse (sans
changer la direction), etc ...
>>>
Pour les deux astres, écrire une fonction orbite_pertubee2(ini,T, f, epsilon) sur le même modèle que celle écrite avec un
seul astre.
Observer, commenter la stabilité des trajectoires.
3)
Calcul des paramètres de la trajectoire et diagramme de l'énergie
3.1 Si le satellite est soumis uniquement à l’attraction de l’astre, la trajectoire est une conique : ellipse, parabole ou
hyperbole, l’astre occupant un des foyers.
La fonction suivante prend en argument la position initiale du satellite M0 et son vecteur vitesse initial V0 et calcule les
paramètres de l'orbite :
1 def param_orbite(M0,V0):
2 |
>>>
3 |
zM, zV = M0[0] + M0[1]*1.j , V0[0] + V0[1]*1.j # affixes de la position et de la vitesse
→
a0 = np.angle(zV/zM) # angle entre OM0 et vecteur V0"
4 |
r0 = abs(M0) # norme euclidienne du point M0
5 |
v0 = np.abs(zV)
6 |
C = r0*v0*np.sin(a0) # mC = moment cinetique
7 |
em = 0.5*v0**2 − 1/r0 # energie mécanique/m
8 |
a = abs(− 1/(2*em)) # distance centre-sommets sur l'axe focal pour une ellipse ou une hyperbole
9 |
p = C**2 # paramètre de la conique
10 |
if em > 0: # hyperbole
11 |
|
12 |
elif em < 0:# ellipse
13 |
|
14 |
else: # em =0 parabole
15 |
e=1
16 |
c = a*e # distance focale
17 |
b = np.sqrt(a*p) # ou bien b = asqrt(|e**2-1|)
18 |
return([C,em,p,e,a,b,c])
e = np.sqrt(1 + p/a)
e = np.sqrt(1 − p/a)
3.2 En s’aidant de la fonction param_orbite, écrire une fonction courbe_energie(ini) qui trace sur un même diagramme
C2
1
la courbe de l’énergie effective Eff /m = 0.5 2 −
et celle de l’énergie mécanique Em et qui affiche la nature de la
r
r
conique et l’état du satellite (état lié ou état de diffusion). Observer le résultat pour les deux jeux de données de (2.2).
- page 4 -
Téléchargement