Corrigé
Transcription
Corrigé
L2-maths Cours Informatique appliquée aux mathématiques TP5. Equations différentielles, initiation aux schémas numériques . Corrigé Il est important de commenter les résultats. Nous nous proposons de résoudre le problème de Cauchy pour l’équation différentielle u̇ = f (u), (1) c’est-à-dire trouver une fonction u(t) qui vérifie (??) sur un intervalle (0, T ), avec une condition initiale u(0) = u0 , et ce par plusieurs moyens. Programmation 1 (Schéma d’Euler Explicite). On se donne des points t0 = 0 < t1 < . . . < tN = T , espacés de h, et on définit une suite par un+1 − un = f (un ) h 1. Ecrire une fonction function [t,u]=Euler(f,T0,Tfinal,u0,N); % EULER solves the differential equation du/dt=f(t,u) with forward Euler % function [t,u]=Euler(f,T0,Tfinal,u0,N) solves the % first order ordinary differential equation du/dt=f(t,u) using % the forward Euler method. f is a string containing the function % name of the right hand side, the simulation runs from starting time % T0 to the final time Tfinal, starting with the initial value u0 % doing N steps. dt=(Tfinal-T0)/N; u(1)=u0; t=T0; for i=1:N, u(i+1)=u(i)+dt*feval(f,t,u(i)); t=t+dt; end; t=(T0:dt:Tfinal)’; u=u’; 2. L’appliquer à f (u) = u sur l’intervalle [0, 1] pour N = 10 avec u0 = 1. f=@(t,u) u; T=1; u0=1; N=10; [t,u]=Euler(f,0,T,u0,N); 3. Tracer sur le même graphique la solution exacte U et la solution du schéma u, définie sur les points de grille. Calculer l’erreur maximale e = max|U(ti ) − ui |. U=exp(t); plot(t,u,’b’,t,U,’r’) legend(’Solution exacte’,’Solution approchee par Euler’) 2.8 Solution exacte Solution approchee par Euler 2.6 2.4 2.2 2 1.8 1.6 1.4 1.2 1 0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1 On constate que les deux courbes sont assez proches, mais que la distance entre ui et U(ti ) augmente avec i. On calcule maintenant l’erreur e=max(abs(U-u)); Matlab fournit le résultat e=0.1245 4. Reproduire les calculs pour N = 10, 20, 40. Calculer les erreurs e1 , e2 , e3 . On a déjà e(1) = 1245. On écrit maintenant [t,u]=Euler(f,0,T,u0,20); e(2)=max(abs(exp(t)-u)); [t,u]=Euler(f,0,T,u0,40); e(3)=max(abs(exp(t)-u)); On trouve e = [0.1245 0.0650 0.0332], qu’on peut mettre dans un tableau N erreur 10 20 40 0.1245 0.0650 0.0332 On remarque déjà qu’en passant de la première à la deuxième colonne, N est multiplié par 2, et l’erreur divisée par environ 2, de même en passant de la deuxième à la troisième colonne. Représenter ces quantités sur un graphique en échelle log-log. NN=[10 20 40] figure(2) loglog(NN,e,’b’,NN,1./NN,’b--’) legend(’Euler explicite’,’pente -1’) xlabel(’N’) ylabel(’erreur’) print -depsc TP5_Fig2.eps 0 10 −1.8 Euler explicite Euler explicite Fonction N−1 Fonction N−1 −2 −2.2 −2.4 log(erreur) erreur −2.6 −1 10 −2.8 −3 −3.2 −3.4 −3.6 −2 10 −3.8 2.2 1 10 N 2.4 2.6 2.8 3 log(N) 3.2 3.4 3.6 3.8 La fonction loglog de matlab trace l’erreur en fonction de N en échelle logarithmique (en base 10), c’est-à-dire les axes N et e sont gradués en progression des puissances de 10. Si vous tracez log(e) en fonction de log(N) (logaritmes néperiens ou naturels, figure de droite), vous aurez une échelle linéaire sur les axes. Dans les deux cas la fonction N 7→ N α est représentée par une droite de pente α. Donc si nous traçons l’erreur en fonction de N, et la courbe N 7→ N −1 , en échelle loglog, et qu’elles sont presque parallèles, on en déduit que log(e(N)) ∼ − log(N) + k, ou encore e(N) ∼ CN −1 . Programmation 2 (Schéma de Runge). 1. On introduit le script function [t,u]=Runge(f,T0,Tfinal,u0,n); % RUNGE solves the differential equation du/dt=f(t,u) using Runge’s method % function [t,u]=Runge(f,T0,Tfinal,u0,n) solves the system of % first order ordinary differential equations du/dt=f(t,u) using % Runge’s 2nd order method. f is a string containing the function % name of the right hand side, the simulation runs from starting time % T0 to the final time Tfinal, starting with the initial value u0 % doing n steps of integration. dt=(Tfinal-T0)/n; u(:,1)=u0; t=T0; for i=1:n, Y1=u(:,i); Y2=u(:,i)+dt/2*feval(f,t,Y1); u(:,i+1)=u(:,i)+dt*feval(f,t+dt/2,Y2); t=t+dt; end; t=(T0:dt:Tfinal)’; u=u’; A quelle discrétisation de l’équation différentielle correspond-il ? Ce script correspond au schéma de Runge h h yn+1 = yn + hf (tn , yn + hf (tn + , yn + f (tn , yn ))) 2 2 2. L’appliquer à f (u) = −u sur l’intervalle [0, 1] pour N = 10. function r=f(t,u) r=-u T=1; u0=1; N=10; [t,ur]=Runge(’f’,0,T,u0,N); 3. Tracer sur le même graphique la solution exacte U et la solution du schéma ur, définie sur les points de grille. 1 Solution exacte Solution approchee par Runge 0.9 0.8 0.7 0.6 0.5 0.4 0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1 Les deux courbes sont pratiquement indiscernables. L’erreur maximale er = max|U(ti ) − uri | est égale à 6.6154e − 04. 4. Reproduire les calculs pour N = 10, 20, 40. Calculer les erreurs er1 , er2 , er3 . On peut aussi réaliser le tableau N erreur Euler erreur Runge 10 20 40 0.1245 0.0650 0.0332 −3 −3 0.661510 0.159210 0.039010−3 On remarque deux choses : premièrement l’erreur est beaucoup plus petite que pour Euler, deuxièmement lorsque l’on multiplie N par 2, l’erreur est divisée par environ 4. Sur un graphique en échelle log-log (pour la même fonction f (t, u) = −u), nous représentons l’erreur er pour Runge et e pour Euler. −1 10 Euler explicite Fonction N−1 Runge Fonction N−2 −2 erreur 10 −3 10 −4 10 −5 10 1 10 N On constate bien que le schéma de Runge est d’ordre 2 Exercice 1 (Résolution exacte). 1. La solution du Problème de Cauchy (2) u̇ = u(1 − u), avec u(0) = 1 2 est U= et 1 + et 2. Calculer des solutions approchées par les schémas de Euler et Runge. On remplace, dans le script f, r=-u par r=u.*(1-u) T=1; u0=1/2; N=10; [t,ur]=Runge(’f’,0,T,u0,N); [t,ue]=Euler(’f’,0,T,u0,N); U=exp(t)./(1+exp(t)); plot(t,ue,’b’,t,ur,’m’,t,U,’r’) legend(’Solution approchee par Euler’,’Solution approchee par Runge’,... ’Solution exacte’) print -depsc TP5_Fig5.eps er=max(abs(U-ur));e=max(abs(U-ue)); On trouve e = 0.0023 et er = 2.1705e − 05 0.75 Solution approchee par Euler Solution approchee par Runge Solution exacte 0.7 0.65 0.6 0.55 0.5 0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1 Programmation 3 (Schéma d’Euler implicite). 1. On considère maintenant l’équation linéaire f (u) = −20u, sur l’intervalle de temps [0, 1], avec 10 points. Tracer sur le même schéma la solution approchée calculée avec le schéma de Euler explicite, et la solution exacte. 1 1 100 Solution exacte Solution approchee par Euler, N100 Solution exacte Solution approchee par Euler, N=10 Solution exacte Solution approchee par Euler, N=5 0.8 0.9 0.6 0.8 0.4 0.7 0.2 0.6 0 0.5 −0.2 0.4 −0.4 0.3 −0.6 0.2 −0.8 0.1 50 0 −50 −100 −150 −200 −250 0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1 −1 0 0.1 0.2 N =5 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1 N = 10 0 0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 N = 100 La solution exacte avec condition initiale 1 est égale à exp(−20t). Pour de petites valeurs de N, la solution approchée oscille et prend de grandes valeurs, qui diminuent quand N augmente, et la situation redevient normale lorsque N devient grand. C’est un problème de stabilité . 2. On introduit le schéma de Euler implicite un+1 − un = f (un+1 ) h Ecrire le script matlab permettant de réaliser ce schéma pour f (u) = −20u. Dans ce cas le schéma se réécrit un+1 = ui(1)=1; h=T/N; [t,u]=Euler(f,0,T,u0,N); for i=1:N ui(i+1)=ui(i)/(1+20*h) end 1 un , 1 + 20 ∗ h u0 = 1. 0.9 1 1 1 Solution exacte Euler explicite Euler implicite 0.8 0.6 0.8 0.4 0.7 0.2 0.6 0 0.5 −0.2 0.4 −0.4 0.3 −0.6 0.2 −0.8 0.1 −1 0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 Solution exacte Euler explicite Euler implicite 0.9 1 0 0 0.1 0.2 0.3 N = 10 0.4 0.5 0.6 0.7 0.8 0.9 1 N = 100 La stabilité est rétablie pour les petites valeurs de N . 3. Comment proposez-vous d’utiliser ce schéma pour une fonction f non linéaire du type de celle rencontrée dans l’exercice précédent. Pour calculer un+1 il faut résoudre l’équation en z f (z) − z − un = 0. h n , Pour cela on peut utiliser l’algorithme de Newton pour la fonction F (z) = f (z)− z−u h 1 ′ ′ dont la dérivée est F (z) = f (z) − h . Donc on calcule une suite zp par z0 = un , zp+1 n f (zp ) − zp −u h = . f ′ (zp ) − h1 Puisque l’on a choisi z0 = un comme donnée initiale de l’algorithme de Newton on peut espérer que l’algorithme peut converger assez vite, et donc n’utiliser que quelques itérations de Newton (cf cours de Licence 3). code monTP5.m % TP5 Corrige clear all close all % Schema d Euler f=@(t,u) u; T=1; u0=1; N=10; [t,u]=Euler(f,0,T,u0,N); U=exp(t); plot(t,U,’r’,t,u,’b’) legend(’Solution exacte’,’Solution approchee par Euler’) print -depsc TP5_Fig1.eps % e=max(abs(U-u)); % [t,u]=Euler(f,0,T,u0,20); e(2)=max(abs(exp(t)-u)); [t,u]=Euler(f,0,T,u0,40); e(3)=max(abs(exp(t)-u)); e NN=[10 20 40] figure(2) loglog(NN,e,’b’,NN,1./NN,’b--’) legend(’Euler explicite’,’Fonction N^{-1}’) xlabel(’N’) ylabel(’erreur’) print -depsc TP5_Fig2.eps figure(3) plot(log(NN),log(e),’b’,log(NN),log(1./NN),’b--’) legend(’Euler explicite’,’Fonction N^{-1}’) xlabel(’log(N)’) ylabel(’log(erreur)’) print -depsc TP5_Fig2_log.eps clear all; close all; T=1; u0=1; N=10; f=@(t,u) -u; [t,ur]=Runge(f,0,T,u0,N); [t,ue]=Euler(f,0,T,u0,N); U=exp(-t); plot(t,U,’r’,t,ur,’b’) legend(’Solution exacte’,’Solution approchee par Runge’) print -depsc TP5_Fig3.eps % er=max(abs(U-ur));e=max(abs(U-ue)); N=20; [t,ur]=Runge(f,0,T,u0,N); [t,ue]=Euler(f,0,T,u0,N); U=exp(-t); er(2)=max(abs(U-ur));e(2)=max(abs(U-ue)); N=40; [t,ur]=Runge(f,0,T,u0,N); [t,ue]=Euler(f,0,T,u0,N); U=exp(-t); er(3)=max(abs(U-ur));e(3)=max(abs(U-ue)); figure(4) NN=[10 20 40] loglog(NN,e,’b’,NN,1./NN,’b--’,NN,er,’m’,NN,1./NN.^2,’m--’) legend(’Euler explicite’,’Fonction N^{-1}’,’Runge’,’Fonction N^{-2}’) xlabel(’N’) ylabel(’erreur’) print -depsc TP5_Fig4.eps clear all; close all; % Maintenant comparaison des algorithmes pour % f(u)=u(1-u) (on utilise ’fun’) T=1; u0=1/2; N=10; [t,ur]=Runge(’fun’,0,T,u0,N); [t,ue]=Euler(’fun’,0,T,u0,N); U=exp(t)./(1+exp(t)); plot(t,ue,’b’,t,ur,’m’,t,U,’r’) legend(’Solution approchee par Euler’,’Solution approchee par Runge’,’Solution exacte’) print -depsc TP5_Fig5.eps er=max(abs(U-ur));e=max(abs(U-ue)); % maintenant EUler implicite clear all close all f=@(t,u)-20*u; T=1; u0=1; N=5; [t,u]=Euler(f,0,T,u0,N); U=exp(-20*t); plot(t,U,’r’,t,u,’b’) legend(’Solution exacte’,’Solution approchee par Euler, N=5’) print -depsc TP5_Fig6.eps pause N=10; [t,u]=Euler(f,0,T,u0,N); U=exp(-20*t); plot(t,U,’r’,t,u,’b’) legend(’Solution exacte’,’Solution approchee par Euler, N=10’) print -depsc TP5_Fig7.eps pause N=100 [t,u]=Euler(f,0,T,u0,N); U=exp(-20*t); plot(t,U,’r’,t,u,’b’) legend(’Solution exacte’,’Solution approchee par Euler, N100’) print -depsc TP5_Fig8.eps N=10; ui(1)=1; h=T/N; [t,u]=Euler(f,0,T,u0,N); for i=1:N ui(i+1)=ui(i)/(1+20*h) end % Euler implicite U=exp(-20*t); plot(t,U,’r’,t,u,’b’,t,ui,’m’) legend(’Solution exacte’,’Euler explicite’,’Euler implicite’) print -depsc TP5_Fig7a.eps pause N=100;ui(1)=1; h=T/N; [t,u]=Euler(f,0,T,u0,N); for i=1:N ui(i+1)=ui(i)/(1+20*h) end % Euler implicite U=exp(-20*t); plot(t,U,’r’,t,u,’b’,t,ui,’m’) legend(’Solution exacte’,’Euler explicite’,’Euler implicite’) print -depsc TP5_Fig8a.eps function r=fun(t,u) r=u.*(1-u); end