On s’intèresse au problème de Cauchy \(
\begin{cases}
y'(t)=\sin(y(t))-2z(t)e^{y(t)},\\
z'(t)=z(t)\Big(z(t)e^{y(t)}-\cos(y(t))\Big),\\
y(0)=\frac{1}{2},\\
z(0)=\frac{1}{4},
\end{cases}
\qquad
t\in[0,30]
\)
Q1 [1 point] Notons \(E(y,z) = z\sin(y)-z^2e^y\) et \(\mathcal{E}(t)=E(y(t),z(t))\). Montrer que \(\mathcal{E}\) est un invariant.
On remarque que \(\frac{\partial E}{\partial y}(y(t),z(t))=-z'(t)\) et \(\frac{\partial E}{\partial z}(y(t),z(t))=y'(t)\). On a alors \(
\mathcal{E}'(t)=
\frac{d }{dt}E(y(t),z(t))=
\frac{\partial E}{\partial y}y'(t)+\frac{\partial E}{\partial z}z'(t)=
-z'(t)y'(t)+y'(t)z'(t)=0.
\) Donc \(\mathcal{E}(t)=\mathcal{E}(0)=0\).
Q2 [2 points] Calculer la solution approchée obtenue avec le schéma d’Euler Explicite avec \(N=100\). Dans trois repères différents afficher
dans le premier repère \(t\mapsto y(t)\) et \(t\mapsto z(t)\) dans le même,
dans le deuxième repère \(y\mapsto z(y)\),
dans le troisième repère \(t\mapsto\mathcal{E}(t)\).
from scipy.integrate import odeintuu,ww = odeint(pphi,yy0,tt,tfirst=True).THH_num = Ham(uu,ww)plt.figure(figsize=(18,5))affichage(tt,uu,ww,HH_num,"scipy.odeint")
2 Exercice 2 [8 points] : étude d’un schéma multipas
On notera \(\varphi_k\stackrel{\text{déf}}{=}\varphi(t_k,u_k)\). Considérons la méthode multipas \(
u_{n+1}=\frac{4}{3}u_n-\frac{1}{3}u_{n-1}+h\frac{2}{3}\varphi_{n+1}
\)
Q2 [1 points] Étudier la zéro-stabilité.
Le schéma est de la forme \(
u_{n+1} = a_0u_n+a_1u_{n-1}+h\left(b_0\varphi_n+b_1\varphi_{n-1}\right)+hb_{-1}\varphi_{n+1}.
\) On a
\(p=1\): c’est un méthode à \(q=p+1=2\) pas;
\(a_0=\frac{4}{3}\) et \(a_1=-\frac{1}{3}\),
\(b_0=0\) et \(b_1=0\),
\(b_{-1}=\frac{2}{3}\neq0\) (\(\implies\) la méthode est implicite).
Le premier polynôme caractéristique est \(
\varrho(r)=
%r^{p+1}-\sum_{j=0}^p a_jr^{p-j}=
r^2-a_0r-a_1=
r^2-\frac{4}{3}r+\frac{1}{3}
=(r-1)\left(r-\frac{1}{3}\right).
\)
Les racines sont \(
r_0=1,\quad r_{1}=\frac{1}{3}.
\) La méthode est donc zéro-stable car \(
\begin{cases}
|r_j|\le1 \quad\text{pour tout }j=0,\dots,p
\\
\text{ multiplicité de $r_j$ > }1 \implies |r_j|<1
\end{cases}
\)
Q2 [3 points] La méthode est elle consistente? Est elle convergente? Si oui, étudier théoriquement l’ordre de convergence.
On a prouvé que la méthode est zéro-stable. Ainsi, si elle est consistante, alors elle est convergente.
Pour que la méthode soit consistante il faut que \(\xi(0)=\xi(1)=1\). De plus, pour que la méthode soit d’ordre \(\omega\), il faut que \(\xi(i)=1\) pour tout \(i\le\omega\).
De plus, \(\omega\) vérifie la première barrière de Dahlquist : le schéma étant implicite à \(q=2\) (pair) pas consistante et zéro-stable, \(\omega=q+2\le4\).
En calculant \(\xi\) on trouve que la méthode est d’ordre 2:
No artists with labels found to put in legend. Note that artists whose label start with an underscore are ignored when legend() is called with no argument.
3 Exercice 3 [8 points] : étude d’un schéma RK
Considérons le schéma dont la matrice de Butcher est donnée ci-dessous: \(
\begin{array}{c|ccc}
0 & 0 & 0 & 0 \\
\eta & \eta & 0 & 0\\
\sigma & 0 & \sigma & 0\\
\hline
& 1-\gamma & 0 & \gamma
\end{array}
\)
Dans le sujet de cet exercice, il y a un paramètre \(\eta\). Pour le fixer, remplacez mon nom et prénom par les vôtres et vous obtiendrez la valeur pour ce paramètre dans tout l’exercice.
Code
%reset -f%matplotlib inlinefrom IPython.display import display, Mathimport sympy sympy.init_printing()# =======================================================nom ="Faccanoni"prenom ="Gloria"# =======================================================L =list(range(2,5))idx =sum([ord(c) for c in nom+prenom])%len(L)print("Paramètre de l'exercice ")display(Math(f"\\eta = {</span>sympy<span class="sc">.</span>latex(sympy.Rational(<span class="dv">1</span>,L[idx]))<span class="sc">}"))
Paramètre de l'exercice
\(\displaystyle \eta = \frac{1}{3}\)
Q1 [3 points] Pour quelles valeurs des paramètres \(\sigma\) et \(\gamma\) le schéma est d’ordre 2? Et d’ordre 3?
Soit \(\omega\) l’ordre de la méthode.
C’est un schéma explicite à \(3\) étages (\(s=3\)) donc \(\omega\le s=3\).
Il est consistant (i.e. d’ordre 1) pour tout \(\sigma\) et tout \(\gamma\).
Les conditions pour être d’ordre 2 et 3 sont rappelées ci-dessous. On trouve que :
il est d’ordre 2 ssi \(\sigma\gamma=\frac{1}{2}\),
il est d’ordre 3 ssi, de plus, \(\sigma^2\gamma=\frac{1}{3}\) et \(\sigma\gamma\eta=\frac{1}{6}\); autrement dit, ssi \(\sigma\gamma=\frac{1}{2}\), \(\sigma=\frac{2}{3}\) et \(\eta=\frac{1}{3}\).
Conclusion : il est au moins d’ordre 2 ssi \(\sigma\gamma=\frac{1}{2}\), et d’ordre 3 ssi \(\sigma=\frac{2}{3}\), \(\gamma=\frac{3}{4}\) et \(\eta=\frac{1}{3}\).
Ci-dessous la vérification avec sympy.
Code
import numpy as npimport matplotlib.pyplot as pltfrom scipy.optimize import fsolveimport sympy sympy.init_printing()sigma = sympy.Symbol(r"\sigma")gamma = sympy.Symbol(r"\gamma")# =======================================================eta = sympy.Rational(1,3)# eta = sympy.Symbol(r"\eta")# =======================================================from IPython.display import display, Math, Markdown# prlat = lambda *args : display(Math(''.join( sympy.latex(arg) for arg in args )))def ordre_RK(s, A=None, b=None, c=None): j = sympy.symbols('j')if A isNone: A = sympy.MatrixSymbol('a', s, s)else: A = sympy.Matrix(A)if c isNone: c = sympy.symbols(f'c_0:{</span>s<span class="sc">}') if b isNone: b = sympy.symbols(f'b_0:{</span>s<span class="sc">}') display(Markdown("**Matrice de Butcher**")) matrice_Butcher(s, A, b, c) display(Markdown(f"**On a {</span>s<span class="op">+</span><span class="dv">1</span><span class="sc">} conditions pour avoir consistance = pour être d'ordre 1**")) ordre_1(s, A, b, c, j) display(Markdown("**On doit ajouter 1 condition pour être d'ordre 2**")) ordre_2(s, A, b, c, j) display(Markdown("**On doit ajouter 2 conditions pour être d'ordre 3**")) ordre_3(s, A, b, c, j) # display(Markdown("**On doit ajouter 4 conditions pour être d'ordre 4**"))# ordre_4(s, A, b, c, j)returnNonedef matrice_Butcher(s, A, b, c): But = sympy.Matrix(A) But = But.col_insert(0, sympy.Matrix(c)) last = [sympy.Symbol(" ")] last.extend(b) But = But.row_insert(s,sympy.Matrix(last).T) display(Math(sympy.latex(sympy.Matrix(But))))returnNonedef ordre_1(s, A, b, c, j): texte ="\sum_{j=1}^s b_j ="+f"{</span><span class="bu">sum</span>(b)<span class="sc">.</span>simplify()<span class="sc">}" texte +=r"\text{ doit être égale à }1" display(Math(texte))for i inrange(s): somma = sympy.summation(A[i,j],(j,0,s-1)).simplify() texte =r'\sum_{j=1}^s a_{'</span><span class="op">+</span><span class="bu">str</span>(i)<span class="op">+</span><span class="vs">r'j}='+ sympy.latex( somma ) texte +=r"\text{ doit être égale à }"+sympy.latex(c[i]) display(Math( texte ))returnNonedef ordre_2(s, A, b, c, j): texte ='\sum_{j=1}^s b_j c_j='+sympy.latex(sum([b[i]*c[i] for i inrange(s)]).simplify()) texte +=r"\text{ doit être égale à }\frac{1}{2}" display(Math(texte))returnNonedef ordre_3(s, A, b, c, j): texte ='\sum_{j=1}^s b_j c_j^2=' texte += sympy.latex( sum([b[i]*c[i]**2for i inrange(s)]).simplify() ) texte +=r"\text{ doit être égale à }\frac{1}{3}" display(Math(texte)) texte =r'\sum_{i,j=1}^s b_i a_{ij} c_j=' somma =sum([b[i]*A[i,j]*c[j] for j inrange(s) for i inrange(s)]).simplify() texte = texte + sympy.latex(somma) texte +=r"\text{ doit être égale à }\frac{1}{6}" display(Math(texte))returnNonedef ordre_4(s, A, b, c, j): texte ='\sum_{j=1}^s b_j c_j^3=' texte += sympy.latex( sum([b[i]*c[i]**3for i inrange(s)]).simplify() ) texte +=r"\text{ doit être égale à }\frac{1}{4}" display(Math(texte)) texte =r'\sum_{i,j=1}^s b_i c_i a_{ij} c_j=' somma =sum([b[i]*c[i]*A[i,j]*c[j] for j inrange(s) for i inrange(s)]).simplify() texte = texte + sympy.latex(somma) texte +=r"\text{ doit être égale à }\frac{1}{8}" display(Math(texte)) texte =r'\sum_{i,j=1}^s b_i a_{ij} c_j^2=' somma =sum([b[i]*A[i,j]*c[j]**2for j inrange(s) for i inrange(s)]).simplify() texte = texte + sympy.latex(somma) texte +=r"\text{ doit être égale à }\frac{1}{12}" display(Math(texte)) texte =r'\sum_{i,j,k=1}^s b_i a_{ij} a_{jk} c_k=' somma =sum([b[i]*A[i,j]*A[j,k]*c[k] for k inrange(s) for j inrange(s) for i inrange(s)]).simplify() texte = texte + sympy.latex(somma) texte +=r"\text{ doit être égale à }\frac{1}{24}" display(Math(texte))returnNone# APPLICATION A NOTRE CASc = [0,eta,sigma]b = [1-gamma,0,gamma]A = [[0,0,0],[eta,0,0],[0,sigma,0]]s =len(c)display(Markdown(f"La méthode de Runge-Kutta est à {</span>s<span class="sc">} étages"))ordre_RK(s,A,b,c)
On a 4 conditions pour avoir consistance = pour être d’ordre 1
\(\displaystyle \sum_{j=1}^s b_j =1\text{ doit être égale à }1\)
\(\displaystyle \sum_{j=1}^s a_{0j}=0\text{ doit être égale à }0\)
\(\displaystyle \sum_{j=1}^s a_{1j}=\frac{1}{3}\text{ doit être égale à }\frac{1}{3}\)
\(\displaystyle \sum_{j=1}^s a_{2j}=\sigma\text{ doit être égale à }\sigma\)
On doit ajouter 1 condition pour être d’ordre 2
\(\displaystyle \sum_{j=1}^s b_j c_j=\gamma \sigma\text{ doit être égale à }\frac{1}{2}\)
On doit ajouter 2 conditions pour être d’ordre 3
\(\displaystyle \sum_{j=1}^s b_j c_j^2=\gamma \sigma^{2}\text{ doit être égale à }\frac{1}{3}\)
\(\displaystyle \sum_{i,j=1}^s b_i a_{ij} c_j=\sigma {b}_{2} {c}_{1} + \frac{{b}_{1} {c}_{0}}{3}\text{ doit être égale à }\frac{1}{6}\)
Q2 [3 points] Étudier empiriquement l’ordre de convergence sur le problème de Cauchy \(
\begin{cases}
y'(t)=\left(\cos(2\pi t)-4t^2\right)y(t), & t\in[0;5]\\
y(0)=4
\end{cases}\) On affichera les courbes de convergence pour un schéma d’ordre 1 (à vous de donner un choix de \(\sigma\) et \(\gamma\) pour obtenir un tel schéma) et pour un schéma d’ordre 2 (ou 3 si possible).
💭 ne pas confondre sympy.cos ou sympy.pi … (du module sympy pour le calcul de la solution exacte) et np.cos ou np.pi … (du module numpy pour le calcul numérique).
Q3 [2 points] Étudier théoriquement la A-stabilité du schéma d’ordre maximal (dans la correction ci-dessous \(\eta=\frac{1}{3}\) et donc l’ordre maximal est 3).
La méthode appliquée à l’EDO \(y'(t)=-\beta y(t)\) avec \(\beta>0\) s’écrit: \(\begin{cases}
u_0 = y_0 \\
K_1 = -\beta u_n\\
K_2 = -\beta \left(u_n+\frac{h}{3}K_1\right)\leadsto K_2=\left(1-\frac{\beta h}{3}\right)K_1\\
K_3 = -\beta \left(u_n+\frac{2h}{3}K_2\right)\leadsto K_3=\left(1-\frac{2\beta h}{3}\left(1-\frac{\beta h}{3}\right)\right)K_1\\
u_{n+1} = u_n + \frac{h}{4}\left(K_1+4K_3\right) & n=0,1,\dots N-1
\end{cases}
\) L’étude ci-dessous montre que le schéma est A-stable ssi \(h<\frac{\vartheta}{\beta}\) avec \(\vartheta\approx2.7\).
Code
%reset -f%matplotlib inlineimport numpy as npimport matplotlib.pyplot as pltfrom scipy.optimize import fsolveimport sympy sympy.init_printing()from IPython.display import display, Math, Markdown# prlat = lambda *args : display(Math(''.join( sympy.latex(arg) for arg in args )))sympy.var('u_n, h, β, K1, K2, sigma, gamma, eta') g =lambda y : -β*yK1 = g(u_n)K2 = g(u_n+h*eta*K1)K3 = g(u_n+h*sigma*K2)RHS = u_n+h*((1-gamma)*K1+gamma*K3)RHS = RHS.factor()texte ='u_{n+1}='+ sympy.latex(RHS)display(Math(texte))display(Markdown(r"Notons $x=hβ>0$. On trouve donc"))x = sympy.Symbol('x',positive=True)RHS = RHS.subs(h*β,x).simplify()texte ='u_{n+1}='+ sympy.latex(RHS)display(Math(texte)) texte =r"La méthode est A-stable ssi $|q(x)|<1$ avec $q(x)=\dfrac{u_{n+1</span><span class="sc">}}{u_n}="texte += sympy.latex(RHS/u_n) +"$"display(Markdown(texte)) # ======== On remplace les paramètres par les valeurs optimales ==========RHS = RHS.subs(gamma,sympy.Rational(4,3)).subs(sigma,sympy.Rational(2,3)).subs(eta,sympy.Rational(1,3)).simplify()q = sympy.apart(RHS/u_n)# ======================================================================texte =r"Dans le cas optimal on a $\sigma=\dfrac{2}{3}$ et $\gamma=\dfrac{4}{3}$ ainsi \(q(x)=\dfrac{u_{n+1</span><span class="sc">}}{u_n}="texte += sympy.latex(RHS/u_n) +"\)"display(Markdown(texte)) display(Markdown(r"Étudions la fonction $q(x)$ pour $x>0$:"))sympy.solve( [ -1<RHS/u_n , RHS/u_n<1 ] )display(Markdown(f"$q(0)={</span>q<span class="sc">.</span>subs(x,<span class="dv">0</span>)<span class="sc">}$"))ell = sympy.Limit(q,x,sympy.oo)display(Math(f"{</span>sympy<span class="sc">.</span>latex(ell)<span class="sc">}={</span>sympy<span class="sc">.</span>latex(ell.doit())<span class="sc">}"))dq = sympy.diff(q,x).simplify()display(Markdown(f"$\displaystyle q'(x)={</span>sympy<span class="sc">.</span>latex(dq)<span class="sc">}$"))sol=sympy.solveset(dq,domain=sympy.S.Reals)display(Markdown(f"$q'(x)<0$ pour tout $x>0$ et l'on a"))sol = sympy.solveset(q+1,domain=sympy.S.Reals)texte =r"q(x)=-1 \iff x= "+ sympy.latex(sol) +r"\approx"+ sympy.latex(sol.evalf()) display( Math( texte ) )# p1 = sympy.plot(q,(x,0,5),ylim=(-2,2),xlabel=r'$x$',ylabel=r'$q(x)$',show=False,grid=True)# p2 = sympy.plot(1,(x,0,5),ylim=(-2,2),show=False,line_color='r')# p3 = sympy.plot(-1,(x,0,5),ylim=(-2,2),show=False,line_color='r')# p1.extend(p2)# p1.extend(p3)# p1.show()plt.figure(figsize=(12,6))q = sympy.lambdify(x,RHS/u_n,'numpy')xx = np.linspace(0,5,100)plt.plot(xx,q(xx),label=r'$q(x)$')plt.hlines(1,0,5,'r')plt.hlines(-1,0,5,'r')plt.axis([0,5,-2,2])plt.grid();
La méthode est A-stable ssi \(|q(x)|<1\) avec \(q(x)=\dfrac{u_{n+1}}{u_n}=- \eta \gamma \sigma x^{3} + \gamma \sigma x^{2} - x + 1\)
Dans le cas optimal on a \(\sigma=\dfrac{2}{3}\) et \(\gamma=\dfrac{4}{3}\) ainsi \(q(x)=\dfrac{u_{n+1}}{u_n}=- \frac{8 x^{3}}{27} + \frac{8 x^{2}}{9} - x + 1\)