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