Table des matières Scilab

Méthode d'Euler implicite

1. Définition et stabilité

La méthode d'Euler est présentée dans Méthode d'Euler explicite. On reprend ici les mêmes notations. La méthode d'Euler implicite consiste à chercher la valeur approchée à l'instant tn+1 avec la relation suivante :

yn+1=yn+hf(tn+1,yn+1)(1)

Cette méthode consiste donc à prendre la dérivée à la fin de l'intervalle [tn,tn+1] au lieu de la prendre au début.

La valeur yn+1 est obtenue par résolution d'une équation. Dans le cas d'un système différentiel, le nombre d'équation à résoudre est égal aux nombres de fonctions inconnues.

Pour étudier la stabilité, on considère l'équation linéaire suivante :

dydt=qy(t)(2)

Pour la condition initiale y(0)=1, la solution est :

y(t)=exp(qt)(3)

Pour cette équation, la méthode d'Euler implicite s'écrit :

yn+1=yn+hqyn+1(4)

Les valeurs approchées obtenues par cette méthode sont donc :

yn=y0(1-hq)n(5)

On pose z=hq. Le domaine de stabilité est défini comme le domaine du plan complexe où la suite précédente est bornée, c'est-à-dire :

|1-z|1(6)

Le domaine de stabilité est donc tout le plan complexe à l'exclusion du disque de centre z=1 et de rayon 1. Le demi espace Re(z)<0 est donc entièrement dans le domaine de stabilité. Si la partie réelle de q est négative, la solution approchée à toujours le même comportement que la solution exacte, c'est-à-dire qu'elle tend vers 0 lorsque t tend vers l'infini.

2. Itération de Newton-Raphson

L'équation (1) est linéaire pour les systèmes différentiels linéaires. Dans le cas général, il faut résoudre un système d'équations algébriques non linéaires. Celui peut être résolu par la méthode de Newton-Raphson décrite ci-dessous.

Pour préciser les calculs à effectuer, nous écrivons explicitement les équations différentielles. Soit P le nombre d'équations. L'équation différentielle k est :

dykdt=fk(t,y1(t),,yi(t),,yP(t))(7)

L'indice désignant la fonction inconnue est donc en exposant. La méthode d'Euler implicite s'écrit alors, pour 1kP :

yn+1k=ynk+hfk(tn+1,yn+11,,yn+1i,,yn+1P)(8)

Posons

Gk(yn+11,,yn+1i,,yn+1P)=ynk+hfk(tn+1,yn+11,,yn+1i,,yn+1P)-yn+1k(9)

Le système à résoudre pour déterminer les yn+1k s'écrit alors :

Gk(yn+11,,yn+1i,,yn+1P)=0(10)

Soit Yn+1 la matrice colonne contenant les yn+1k . Une première estimation de Yn+1 est donnée par Yn. Pour simplifier la notation, on note Y cette estimation. La méthode de Newton-Raphson consiste à considérer le développement de Taylor à l'ordre 1 suivant :

Gk(Y+δY)=Gk(Y)+j=1PGkyjδyj(11)

L'estimation suivante est donnée par Y'=Y+δY avec :

j=1PGkyjδyj=-Gk(Y)(12)

Il faut donc résoudre un système linéaire pour calculer les δY . Soit J le jacobien du système différentiel évalué en Y, c'est-à-dire la matrice carrée PxP définie par :

Jij=fiyj(Y)(13)

Le système à résoudre s'écrit sous forme matricielle :

(hJ-Id)δY=-G(14)

Ce système est résolu avec la décomposition LU puis Y' est calculé. Si |δY| est supérieure à une tolérance, l'itération est reprise.

3. Programmation avec Scilab

Pour tester le fonctionnement, on considère l'équation différentielle de l'oscillateur harmonique, qui se met sous la forme d'un système différentiel du premier ordre :

dy1dt=y2(15)dy2dt=-4π2y1(16)

Le système différentiel est défini par une fonction :

function [dy]=oscillateur(t,y),
 dy(1)=y(2),
 dy(2)=-4*%pi^2*y(1),
endfunction
   

Rappelons tout d'abord les fonctions réalisant la méthode d'Euler explicite :

function [y]=pasEuler(systeme,ne,h,t,yn),
   dy = systeme(t,yn);
   for e=1:ne,
    y(e) = yn(e)+h*dy(e)
   end;
endfunction

function [mt,my]=euler(yi,T,N,systeme,ne),
   h = T/N;
   my = zeros(ne,N+1);
   mt = zeros(1,N+1);
   my(:,1)=yi;
   mt(1)=0;
   for k=1:N,
    my(:,k+1)=pasEuler(systeme,ne,h,mt(k),my(:,k));
    mt(k+1) = mt(k)+h;
   end;
endfunction
   

Pour la méthode implicite, on doit aussi définir le jacobien :

function [J]=jacobienOscillateur(t,y),
   J(1,1) = 0; J(1,2)=1;
   J(2,1)=-4*%pi^2; J(2,2)=0;
endfunction   
   

La fonction suivante effectue le calcul de yn+1 à partir de yn :

function [y]=pasEulerImplicite(systeme,jacobien,Id,P,h,t,yn,tol),
   stop = 0; it=0; maxit=100;
   y = yn;
   t1 = t+h;
   while stop==0,
    it = it+1;
    dy = systeme(t1,y);
    G = yn+h*dy-y;
    [deltaY,ker] = linsolve(h*jacobien(t1,y)-Id,G);
    y = y+deltaY;
    if it>maxit then stop=1; end;
    stop = 1;
    for k=1:P,
     if abs(deltaY(k))>tol then stop=0; end;
    end;
   end;
endfunction
   

La fonction suivante effectue le calcul complet, avec une condition initiale (instant 0) définie dans une matrice colonne.

function [mt,my]=eulerImplicite(yi,T,N,systeme,jacobien,P,tol),
   Id = eye(P,P);
   h = T/N;
   my = zeros(P,N+1); 
   mt = zeros(1,N+1);
   my(:,1)=yi;
   mt(1)=0;
   for k=1:N,
    my(:,k+1)=pasEulerImplicite(systeme,jacobien,Id,P,h,mt(k),my(:,k),tol);
    mt(k+1) = mt(k)+h;
   end;
endfunction
   

Voyons le fonctionnement avec le système défini plus haut :

yi=[1;0];
P=2;
N=5000;
T=20;
tol=1e-5;
[mt,my] = eulerImplicite(yi,T,N,oscillateur,jacobienOscillateur,P,tol);
   
figA=scf();
plot2d(mt,my(1,:));
xtitle('','t','y(1)');
   
figA.pngfigA.pdf

La solution exacte est une sinusoïde d'amplitude 1. Comme prévu par l'étude de stabilité, l'amplitude d'oscillation décroît alors qu'elle augmente avec la méthode d'Euler explicite. En réduisant le pas d'un facteur 2, on réduit l'erreur du même facteur (méthode d'ordre 1) :

yi=[1;0];
N=10000;
[mt,my] = eulerImplicite(yi,T,N,oscillateur,jacobienOscillateur,P,tol);
   
figB=scf();
plot2d(mt,my(1,:));
xtitle('','t','y(1)');
   
figB.pngfigB.pdf

Bien entendu, la méthode d'Euler est en pratique inutilisable en raison du coût très élevé en calcul pour obtenir une erreur faible. On voit néanmoins sur cet exemple une propriété vérifiée ausi sur des méthodes d'ordre plus élevé : l'application de la méthode à un système conservatif revient à introduire une dissipation dans le système. Voyons ce qu'il en est pour un système dissipatif, l'oscillateur amorti. Le calcul est aussi conduit avec la méthode d'Euler explicite.

function [dy]=amorti(t,y),
 dy(1)=y(2),
 dy(2)=-4*%pi^2*y(1)-0.1*y(2),
endfunction

function [J]=jacobienAmorti(t,y),
 J(1,1)=0; J(1,2)=1;
 J(2,1)=-4*%pi^2; J(2,2)=-0.1;
endfunction

P=2;
N=10000;
T=40;
tol=1e-5;
[mt,my] = eulerImplicite(yi,T,N,amorti,jacobienAmorti,P,tol);
function y=f(t),
 y=exp(-0.05*t)*(cos(2*%pi*t)+0.05/(2*%pi)*sin(2*%pi*t))
endfunction
[mt1,my1] = euler(yi,T,N,amorti,P);
   
figC=scf();
plot2d(mt,my(1,:),style=color('red'));
plot2d(mt1,my1(1,:),style=color('blue'))
fplot2d(mt,f)
xtitle('','t','y(1)');
   
figC.pngfigC.pdf

Pour comparaison, la solution exacte est tracée (en noir) et la solution obtenue par la méthode d'Euler explicite (en bleu). Sur cet exemple de système dissipatif, la méthode d'Euler implicite conduit à une erreur plus faible que la méthode explicite, et surtout à un comportement beaucoup plus réaliste.

Creative Commons LicenseTextes et figures sont mis à disposition sous contrat Creative Commons.