Telechargé par Fouad Nafis

Calcul Scientifique

publicité
Filière : MP
Classes : MP3 et MP4 - Équations différentielles
CPGE LOK Meknès
Octobre 2019
Équations différentielles
3
Introduction
Les équations différentielles ordinaires (EDO) apparaissent très souvent dans la modélisation de la physique
et des sciences de l’ingénieur. Trouver la solution d’une EDO ou d’un système d’EDO est ainsi un problème
courant, souvent difficile ou impossible à résoudre de facon analytique. Il est alors nécessaire de recourir à des
méthodes numériques pour résoudre ces équations différentielles.
La méthode d’Euler est une procédure numérique qui permet de résoudre de façon approximative des équations
différentielles ordinaires du premier ordre avec condition initiale. Elle a le mérite d’être simple à comprendre et
à programmer.
3.1
Contexte
Dans le début de cette partie, on considérera l’exemple suivant :
(
3.2
y 0 = 2ty 2 sur [0,2]
y(0) = 0.2
Principe
On considère une équation différentielle du type y’=F(t,y) où F est une fonction à deux variables.
Soit y une solution de l’équation différentielle. Pour h petit, on peut écrire : y 0 (t) = y(t+h)−y(t)
h
Dans le cas de l’exemple, on a F(t,y) = .............. et donc y(t+h) = ......................
Pour i ∈ [0, n] on pose ti = ......................................, le n-ième point de la subdivision ainsi créée
3.3
Méthode
On cherche à représenter sur l’intervalle [a, b] la solution approchée de l’équation y’=F(t,y) telle que y(a)=c.
La méthode consiste à construire une suite de points (tn , yn ) ∈ IN approchant les points réels de la courbe de
la solution f.
• On souhaite obtenir une approximation de y(ti ) pour tout entier i entre 0 et n.
On a au départ y(a)=c. On a donc un premier point de coordonnées (t0,y0).
On approche y(t1) par le nombre y1 avec la formule : y(t1 ) = y(t0 ) + hy 0 (t0 ) = y0 + hF (t0 , y0 ). On a alors un
deuxième point de coordonnées (t1 , y1 )...etc
A l’étape i (i ∈ [1,n-1]), on a donc : ti+1 =................. et yi+1 =.........................
3.4
Application à la main
Effectuer à la main la résolution approchée de l’équation y 0 = 2ty 2 sur [0,2] avec y(0) = 0.2 pour n = 4
Tracer la courbe obtenue.
5
3.5
Implémentation en langage Python
1 def Euler_ordre_1_explicite(F,a,b,n,y0):
2
y=y0
3
Y=[y]
4
t=a
5
T=[t]
6
h=(b-a)/n
7
for i in range(n):
8
y=y+h*F(t,y)
9
t=t+h
10
Y.append(y)
11
T.append(t)
12
return T,Y
6
4
4.1
Méthode Euler implicite
Introduction
Dans l’approximation par la méthode Euler explicite, on dit que la surface des rectangles formés entre les instants ti et ti+1 est calculée en utilisant la méthode du rectangle gauche.
Dans la méthode Euler implicite, on utilise la méthode du rectangle droit, ce qui nous donne :
y(ti+1 ) = y(ti ) + h ∗ F (ti+1 , y(ti+1 ))
Le problème de cette équation est qu’elle met en oeuvre, en seconde membre une fonction du membre y(ti+1 )
qu’on cherche à calculer. Ceci nous ramène à la résolution d’une équation de la forme f (x) = 0 qu’on déjà vu
quelques méthodes de résolution
4.2
Implémentation en langage Python
1 from scipy.optimize import fsolve
2 def Euler_ordre_1_implicite(F,a,b,n,y0):
3
y,t=y0,a
4
Y,T=[y],[t]
5
h=(b-a)/n
6
for i in range(1,n+1):
7
y=fsolve(lambda y:Y[i-1]+h*F(T[i],y)-y,0.01)
8
t=t+h
9
Y.append(y)
10
T.append(t)
11
return T,Y
5
5.1
Méthode de Heun
Principe
Pour tenter d’améliorer l’éficacité de la méthode d’Euler, on peut envisager d’améliorer l’approximation de
départ : y(ti+1 ) = yi + hF (ti , yi ) par : y(ti+1 ) = y(ti ) + h2 (F (ti , yi ) + F (ti+1 , yi+1 )) qui est implicite au sens où
elle fait intervenir la valeur de yi+1 qu’on cherche à approcher, en remplaçant dans cette formule, le terme yi+1
par l’approximation de départ : y(ti+1 ) = yi + hF (ti , yi ) on obtient la formule explicite :
y(ti+1 ) = yi + h ∗ F (ti + (h/2), yi + (h/2) ∗ F (ti , yi ))
Cette approximation est appelée : approximation par la méthode de Heun
5.2
Implémentation en langage Python
1 def Heun_ordre_1(F,a,b,n,y0):
2
y,t=y0,a
3
Y,T=[y],[t]
4
h=(b-a)/n
5
for i in range(1,n+1):
6
y=y+h*F(t+(h/2),y+(h/2)*F(t,y))
7
t=t+h
8
Y.append(y)
9
T.append(t)
10
return T,Y
7
6
Méthode de Runge-Kutta4 (RK4)
6.1
Principe
Les méthodes de Runge-Kutta sont des méthodes d’analyse numérique d’approximation de solutions d’équations
différentielles. Elles ont été nommées ainsi en l’honneur des mathématiciens Carl Runge et Martin Wilhelm
Kutta lesquels élaborèrent la méthode en 1901.
Ces méthodes reposent sur le principe de l’itération, c’est-à-dire qu’une première estimation de la solution est
utilisée pour calculer une seconde estimation, plus précise, et ainsi de suite.
Dans cette méthode, on calcul les termes suivants :
a = F (ti , yi )
b = F (ti + h2 , yi + a2 )
c = F (ti + h2 , yi + 2b )
d = F (ti + h, yi + c)
et on approxime la valeur de yi+1 par la formule : yi+1 = a+2∗b+2∗c+d
6
6.2
Implémentation en langage Python
1 def RK4_ordre_1(F,a,b,n,y0):
2
y,t=y0,a
3
Y,T=[y],[t]
4
h=(b-a)/n
5
for i in range(1,n+1):
6
a=h*F(t,y)
7
b=h*F(t+h/2,y+a/2)
8
c=h*F(t+h/2,y+b/2)
9
d=h*F(t+h,y+c)
10
y=y+(1/6)*(a+2*b+2*c+d)
11
t=t+h
12
Y.append(y)
13
T.append(t)
14
return T,Y
7
Méthode odeint
La méthode odeint du module scipy.integrate implémente la démarche Euler pour la résolution des équation
différentielles d’ordre 1 (Problème de Cauchy)
Elle prend en argument la fonction F, la condition initiale y0 et une liste de temps commençant à t0 . Par
exemple, pour résoudre y 0 = y sur [0, 1] avec y(0) = 1. On pourra écrire le script suivant :
1
2
3
4
5
6
7
8
9
8
from scipy.integrate import odeint
import numpy as np
import matplotlib.pyplot as plt
def F(y,t):
return y
temps = np.linspace(0, 1, 10)
Y = odeint(F, 1, temps)
plt.plot(temps,Y)
plt.show()
Simulation
Comparer les méthode illustrées dans les sections précédentes pour résoudre les EDO suivantes :
(
y 0(x) + y(x) =cos(x)
1.
=3
y(0)
La solution algébrique est donnée par la formule :
y(x) = 21 (cos(x) + sin(x) + 5e−x )
8
(
2.
y 0(x) =xy 2 (x)
y(0) =2
De même on peut observer que : y(x) =
2
1 x2
−
Corrige´ de l’equation
1
´
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
import numpy as np
import scipy.integrate as sp
from scipy.optimize import fsolve
import matplotlib.pyplot as plt
def Euler_ordre1_explicit(F,a,b,y0,n):
y,t,Y,T,h=y0,a,[y0],[a],(b-a)/n
for i in range(n):
y=y+h*F(t,y)
t=t+h
Y.append(y)
T.append(t)
return T,Y
def Heun(F,a,b,y0,n):
y,t,Y,T,h=y0,a,[y0],[a],(b-a)/n
for i in range(n):
x=y+(h/2)*F(t,y)
y=y+h*F(t+(h/2), x)
t=t+h
Y.append(y)
T.append(t)
return T,Y
def RK4(F,a,b,y0,n):
y,t,Y,T,h=y0,a,[y0],[a],(b-a)/n
for i in range(n):
x1=h*F(t,y)
x2=h*F(t+h/2,y+x1/2)
x3=h*F(t+h/2,y+x2/2)
x4=h*F(t+h,y+x3)
y=y+(1/6)*(x1+2*x2+2*x3+x4)
t=t+h
Y.append(y)
T.append(t)
return T,Y
def F(t,y):
return -y+np.cos(t)
def SolExacte(T):
Y=[]
for x in T:
Y.append( 0.5*(np.cos(x)+np.sin(x)+5*np.exp(-x)))
return Y
T1,Y1=Euler_ordre1_explicit(F,0,1,3,50)
T2,Y2=Heun(F,0,1,3,50)
T3,Y3=RK4(F,0,1,3,50)
Y4=sp.odeint(F,3,T1)
Y5=SolExacte(T1)
plt.plot(T1,Y1,’b-.’,label=’Euler␣explicite’)
plt.plot(T1,Y5,’g-s’,label=’Solution␣exacte’)
plt.plot(T1,Y2,’y-h’,label=’Heun’)
plt.plot(T1,Y3,’ro’,label=’RK4’)
plt.plot(T1,Y3,’c-x’,label=’odeint’)
plt.grid()
plt.legend()
plt.show()
9
Résultats
1. sous forme d’un tableau des calculs effectués (10 premières itérations)
2. sous forme graphique
Remarques
- Après avoir obtenu le graphique avec le code ci-haut, augmenter le zoom pour pouvoir comparer la
performance des méthodes utilisées
- Ces comparaisons sont très nettes dans le tableau des calculs obtenus
3. après un zoom sur le graphique de départ
10
9
Équations différentielles de 2nd Ordre
9.1
Principe
On considère une équation différentielle du type y 00 = F (t, y, y 0) où F est une fonction à 3 variables. Soit y une
solution de cette équation différentielle.
+
Pour un nombre réel h petit, on a y 0 (t) ' y(t h)h y (t) soit y(t + h) ' y(t) + hF (t, y(t), y0 (t))
0
0
(t+h) y (t)
Pour h petit, on a y 00 (t) ' y
soit y 0 (t) ' y 0 (t) + hF (t, y(t), y0 (t))
h
Exemple
Soit l’équation différentielle y 00 + y0 y = t2 4sin(t) sur [0, 4] avec y(0) = 1 et y 0(0) = 2
−
−
−
−
1. Exprimer F en fonction de t, yety0
2. Donner la valeur y1 , y2 , y10 et y20
3. Donner à l’étape i l’expression de ti+1, yi+1 et y 0i+1
9.2
9.2.1
En bref
Méthode Euler d’ordre 1
11
9.2.2
9.3
Méthode Euler d’ordre 2
Exercices pratiques
Exercice 01 (Extrait du CCINP Épreuve de Physique - Filière MP 2019)
La position instantanée r(t) de l’électron dans le repère défini sur la figure vérifie une équation différentielle
dont la difficulté de résolution dépend de la modélisation physique choisie.
Pour résoudre des équations différentielles complexes, on peut utiliser une méthode numérique. Pour
illustrer cette méthode de résolution, on considère que r(t) obéit à l’équation différentielle :
d2r
dt2
ω2 = 0
+ 2λ dr
dt + 0
Avec λ et ω20 des constantes positives non nulles.
12
L’objectif est d’obtenir une représentation graphique de la fonction r(t), la plus proche possible de la
réalité. On utilise une méthode numérique simple (connue sous le nom de méthode d’Euler explicite)
que l’on programme en langage PYTHON.
Dans ce langage :
- la fonction np.arange(N) renvoie une liste de nombres entiers compris entre 0 et N–1, de type array
.
- la fonction np.zeros(N) renvoie une liste de N valeurs toutes nulles, de type array .
Pour des raisons de commodité, les valeurs numériques utilisées ne correspondent pas à la réalité physique
; les valeurs obtenues pour r(t) seront donc arbitraires (en revanche la forme de la courbe est réaliste).
Le programme est le suivant :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
import numpy as np
from matplotlib import pyplot as plt
T=150
omega = 1.4
lamda = 0.03
def euler(N,x0,v0):
x = x0
v = v0
h = T/N
a = -2*lamda*v-omega*omega*x
tab_1 = np.zeros(N)
tab_2 = np.zeros(N)
for i in range(N):
(x,v,a)=(x+v*h,v+a*h,-2*lamda*v-omega*omega*x)
tab_1[i] = x
tab_2[i] = v
return tab_1
def temps(N):
h=T/N
t = np.arange(N)*h
return t
plt.figure (’graphique’)
plt.plot(temps(15000),euler(15000,0,1),’b’)
plt.title("représentation␣graphique␣de␣r␣en␣fonction␣de␣t")
plt.xlabel("t")
14
31 plt.ylabel("r")
32 plt.grid()
33 plt.show()
L’exécution de ce programme permet d’obtenir la courbe r(t) (les échelles sont arbitraires).
Q14 Décrire, en détaillant les étapes, comment l’algorithme utilisé permet, connaissant les valeurs de la
, de calculer ces mêmes valeurs à une date notée
fonction r(tn ) et de sa dérivée dr
dt (tn ) à une date tn
tn+1 . Quelle approximation est faite ?
Q15 Afin de tester la fonction euler, nous exécutons l’instruction euler(3,0,1) . Que retourne cette
instruction ?
Q16 Les lignes 16 à 19 contiennent une boucle itérative dans laquelle la commande for est utilisée.
Modifier ces lignes de façon à utiliser la commande while en créant une boucle conditionnelle. La partie de programme écrite avec la boucle while doit produire exactement les mêmes
résultats que la portion de code qu’elle remplace.
Afin de tester la méthode d’Euler, on rajoute les lignes de code suivantes, qui permettent de tracer la
courbe donnant la solution exacte de la solution de l’équation différentielle. Le programme modifié
est donné ci-après (à partir de la ligne 27).
Les lignes 1 à 26 ne sont pas modifiées.
27 omega = à compléter (voir Q17)
28 def vraie(N,v0):
29
x=0
30
v=v0
h=T/N
31
32
tab_3=temps(N)
33
for i in range (N):
tab_3[i]=np.sin(np.sqrt(omega*omega-lamda*lamda)*h*i)*np.exp
34
(-lamda*h*i)*v/(np.sqrt(omega*omega-lamda*lamda))
35
return tab_3
36
37 plt.figure (’graphique’)
38 plt.plot(temps(15000),vraie(15000,1),’b’)
39 plt.title("représentation␣graphique␣de␣r␣en␣fonction␣de␣t")
40 plt.xlabel("t")
41 plt.ylabel("r")
42 plt.grid()
43 plt.show()
L’exécution de ce programme donne la courbe r(t ) ci-dessous (les échelles sont arbitraires) :
Q17 En exploitant la courbe, déterminer la valeur de la variable omega masquée à la ligne 27.
Q18 La méthode d’Euler donne-t-elle une solution satisfaisante ?
15
Téléchargement