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