Correction TP 2

Transcription

Correction TP 2
Correction TP 2
Script de la fonction Runge Kutta
function [X]=runge_kutta(t0,tf,p,X0,meth)
select meth
case "Euler" then
s=1;a=0;b=1;c=0;
case "Point-Milieu" then
s=2;a=[0 0;1/2 0];b=[0 1];c=[0 1/2];
case "Heun" then
s=2;a=[0 0;2/3 0];b=[1/4 3/4];c=[0 2/3];
case "RK4" then
s=4;a=[0 0 0 0;1/2 0 0 0; 0 1/2 0 0;0 0 1 0];b=[1/6 1/3 1/3 1/6];c=[0 1/2 1/2 1];
else
error("méthode (meth) inconnue");
end
//initialisation
n=size(X0,2);
dt=(t0-tf)/p;
X=zeros(p+1,n);
X(1,:)=X0;
tk=t0;
K=zeros(s,n);
for k=1:p,
//boucle en temps
for i=1:s,
ti=tk+c(i)*dt; Xi=X(k,:);
for j=1:i-1,
Xi=Xi+a(i,j)*dt*K(j,:);
end,
K(i,:)=F(Xi,ti);
end,
X(k+1,:)=X(k,:)+dt*b*K;
tk=tk+dt;
end,
endfunction
Script de la résolution d’une EDO par une méthode de Runge Kutta
function Y=F(X,t)
omg2=1;alpha=0;
Y=[X(2) -omg2*X(1)+2*alpha*X(2)]; //cas du pendule linéaire + armotissement
endfunction
function X=solex(t0,tf,p,X0) //solution du pendule linéaire
dt=(tf-t0)/p;
T=(t0:dt:tf)’;
T=T-t0;
omg=1.;alpha=0;
gam=sqrt(omg*omg-alpha*alpha);
S=sin(gam*T);C=cos(gam*T);
E=exp(-alpha*T);
a=X0(2)/(gam-alpha);
b=-alpha*X0(1)+gam*a;
c=alpha*a+gam*X0(1);
X=[E.*(a*S+X0(1)*C) E.*(b*C-c*C)];
endfunction
4
t0=0.;
tf=20*%pi;
X0=[%pi/2 0];
p=400;
meth="RK4";
//temps initial
//temps final
//paramètre
//nb points de discrétisation
//méthode RK
X=runge_kutta(t0,tf,p,X0,meth);
//appel de la méthode RK
//diagramme de phase
figure("BackgroundColor",[1 1 1],"figure_name","Méthode "+ meth);
subplot(121);
title("Diagramme de phase");
square(-1,-1,1,1)
plot(X(:,1),X(:,2),"k");
//Evolution temporelle
subplot(122);
title("Evolution temporelle");
dt=(tf-t0)/p;
T=t0:dt:tf;
plot(T,X(:,1),"r");
set(gca(),"auto_clear","off")
S=solex(t0,tf,p,X0);
plot(T,S(:,1),"k");
hl=legend([’sol. approchée’ ’sol. exacte’]);
hl.legend_location="in_upper_left";
hl.background=-2;
Les essais numériques ont été réalisés avec l’équation du pendule linéarisées (ω = 1, α = 1) sur l’intervalle de temps
[0, 20π] discrétisé avec 400 points.
La méthode d’Euler donne de très mauvais résultats (solution exponentiellement croissante). En fait elle converge
mais il faut utiliser un très grand nombre de points de discrétisation. Ainsi pour obtenir la qualité de la méthode
RK4, il faudrait mettre au moins 4004 points (RK4 est une méthode d’ordre 4 et Euler est seulement d’ordre 1)!
Méthode d’Euler
5
Méthode de Heun
Méthode du point milieu
Méthode RK4
Fonction F pour le pendule non linéaire
function Y=F(X,t)
omg2=1;alpha=0;
Y=[X(2) -omg2*X(1)+2*alpha*X(2)]; //cas du pendule linéaire + armotissement
endfunction
6
L’effet de la non linéarité dans le cas du pendule non linéaire s’observe sur le diagramme de phase où l’orbite n’est
plus circulaire mais demeure périodique (aux erreurs d’approximation près).
Pendule non linéaire avec la méthode RK4
Courbe d’erreurs C 0 en échelle logarithmique
figure("BackgroundColor",[1 1 1],"figure_name","Courbes d’’erreur");
set(gca(),"auto_clear","off")
for q=1:200,
N(q)=20+q*10;
X=runge_kutta(t0,tf,N(q),X0,"Euler");
E=X-solex(t0,tf,N(q),X0);
es(q)=norm(E(:,1),%inf);
end,
plot2d("ll",(tf-t0)./N,es,1); //plot en échelle log-log
for q=1:200,
N(q)=20+q*10;
X=runge_kutta(t0,tf,N(q),X0,’Heun’);
E=X-solex(t0,tf,N(q),X0);
es(q)=norm(E(:,1),%inf);
end,
plot2d("ll",(tf-t0)./N,es,2); //plot en échelle log-log
for q=1:200,
N(q)=20+q*10;
X=runge_kutta(t0,tf,N(q),X0,’RK4’);
E=X-solex(t0,tf,N(q),X0);
es(q)=norm(E(:,1),%inf);
end,
plot2d("ll",(tf-t0)./N,es,3); //plot en échelle log-log
title("courbe d’’erreurs $\L^\infty$")
hl=legend([’Euler’ ’Heun’ ’RK4’]);
hl.legend_location="in_upper_left";
hl.background=-2;
7
Utilisation de la fonction Scilab : ode
function Y=g(t,X),
omg2=1;alpha=0;
Y=[X(2) -omg2*X(1)+2*alpha*X(2)];
endfunction
t=0:%pi/100:20*%pi;
X=ode(X0,t0,t,g); //nombreux paramètres possibles dans ode (prédicteur-correcteur Adams par défaut)
//diagramme de phase
figure("BackgroundColor",[1 1 1],"figure_name","Scilab ode");
subplot(121);
title("Diagramme de phase");
square(-1,-1,1,1)
plot(X(1:2:$),X(2:2:$),"k");
//Evolution temporelle
subplot(122);
title("Evolution temporelle");
plot(t,X(1:2:$),"k");
8