Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                

Explicite PDF

Télécharger au format docx, pdf ou txt
Télécharger au format docx, pdf ou txt
Vous êtes sur la page 1sur 12

MP2 Licence Creative Commons 1

Équation de diffusion : méthode des différences finies

1. Introduction
Ce document montre comment résoudre numériquement l’équation de diffusion en géométrie
unidirectionnelle, par la méthode des différences finies avec un schéma explicite.
Ce document est une copie du notebook
numerique/diffusion/diffusion-explicite.ipynb

2. Définition du problème
On considère l’équation de diffusion (par exemple diffusion thermique) pour un problème
unidirectionnel. La fonction T (x, t) obéit à l’équation aux dérivées partielles suivante :
∂T ∂2T
=D 2
∂t ∂x (1)
La résolution se fait pour x [a, b]. La condition initiale est supposée donnée par la fonc-

tion T (x, 0) pour x [a, b]. On considère le cas où les conditions limites en x = a et x = b

consistent à imposer les valeurs de T aux bornes :

T (a, t) = Ta, ∀t ≥ 0
T (b, t) = Tb, ∀t ≥ 0

3. Variables réduites
Pour faire la résolution numérique de l’équation de diffusion, il est intéressant d’introduire des
variables réduites, c’est-à-dire des variables sans dimensions. Posons tout d’abord

J x−a
x = b−a
xJ est une abscisse sans dimensions, appartenant à l’intervalle [0, 1]. On a :

∂T ∂T ∂xJ ∂T 1
= =
∂x ∂xJ ∂x ∂xJ b −a
∂2T ∂2T 1
=
∂x 2
∂x (b − a)2
J2

Soit le temps τ défini par :


(b a)2
τ= −
D
Introduisons le temps sans dimension :
t
tJ =
τ
MP2 Licence Creative Commons 2

On a :

∂T ∂T ∂tJ ∂T 1
= =
∂t ∂t ∂t J
∂tJ τ
En reportant ces expressions des dérivées partielles dans l’équation de diffusion, on obtient
l’équation de diffusion exprimée avec les variables sans dimensions xJ et tJ, pour la fonction
T (xJ, tJ) :

∂T ∂2T
=
∂tJ
∂xJ2
La condition initiale est donnée par la fonction T (xJ, 0) pour xJ ∈[0, 1]. Les conditions limites
s’écrivent :

T (0, tJ) = Ta, ∀tJ ≥ 0


T (1, tJ) = Tb, ∀tJ ≥ 0

4. Différences finies
L’équation de diffusion est :

∂T ∂2T
=D 2 (2)
∂t ∂x
Si les variables x et t sont les variables sans dimensions xJ et tJ définies ci-dessus, on posera
D = 1.
On doit commencer par discrétiser les variables x et t. La discrétisation de x consiste à poser :

b−a
∆x = N − 1
xn = a + n∆x pour n = 0, 1, . . . N − 1

∆x est le pas d’espace.


La discrétisation du temps consiste à poser :

tk = k∆t pour k = 0, 1, 2, . . .
∆t est le pas de
temps.
L’indice n est donc un nombre entier (compris entre 0 et N−1) représentant la variable
d’espace alors que k est un nombre entier positif ou nul représentant le temps.
Une résolution numérique de l’équation de diffusion consiste à rechercher une
approximation de T (xn, tk) pour tout n compris entre
− 0 et N 1 et pour k = 0, 1, . . .. Notons Tn,k
cette approximation.
Considérons le développement de Taylor par rapport à la variable t :

T (xn ∂T
, + ∆t) = T , )+ (xn , )∆t + O((∆t)2)
tk (xn tk ∂t tk
MP2 Licence Creative Commons 3
2 2
La notation O((∆t) ) désigne un terme dont la valeur absolue est inférieure à K(∆t) si ∆t
est assez petit (où K est une constante).
MP2 Licence Creative Commons 4

On déduit de cette relation :


∂T (x , t
T (xn, tk + ∆t) − T (xn, tk)
n k) = + O(∆t)
∂t ∆t
Il s’en suit qu’une approximation de la dérivée partielle par rapport au temps est donnée par :
∂T Tn,k+1 − Tn,k
(xn , ) ≈ ∆t
∂t tk
et que l’erreur de cette approximation (erreur de troncature) est O(∆t). On sait donc que, si ∆t
est assez petit, il existe une constante K telle que l’erreur de troncature est inférieure à
K∆t (en valeur absolue).
Dans cette expression, la dérivée est remplacée par une différence finie.
Afin d’obtenir une différence finie pour la dérivée seconde par rapport à x, considérons les
développements de Taylor suivants :

∂T ∂2T
(∆x)2 ∂ 3T (∆x)3 4
+ O((∆x) )
T (xn + ∆x, tk) = T (xn, tk) + (xn, tk)∆x + 2
(xn, tk) + 3
(xn, tk) 6
∂x
∂T ∂x
∂2T 22
(∆x) ∂x
∂ 3T (∆x)3 4
+ O((∆x) )
T (xn − ∆x, tk) = T (xn, tk) − (xn, tk)∆x + (xn, tk) − (xn, tk) 6
∂x ∂x2 2 ∂x3
La somme de ces deux relations conduit à :

∂2T
T (xn + ∆x, tk) − 2T (xn, tk) + T (xn − ∆x, tk) 2
(xn, tk) = + O((∆x) )
∂x2 (∆x)2
Une expression de la dérivée seconde sous forme de différence finie est donc :
∂2T
Tn+1,k − 2Tn,k + Tn−1,k
2
(xn, tk) ≈
∂x (∆x)2
L’erreur de troncature de cette approximation est O((∆x)2).
On dispose ainsi d’une expression approchée de chaque dérivée partielle sous la forme d’une
différence finie, que l’on reporte dans l’équation de diffusion :
Tn,k+1 − Tn,k Tn+1,k − 2Tn,k + Tn−1,k
=D (3)
∆t (∆x)2
MP2 Licence Creative Commons 5

5. Schéma numérique explicite


Un schéma numérique est une relation qui permet de calculer les valeurs de Tn,k en partant de
k = 0 (instant t = 0).
La relation (3) fournit immédiatement un moyen de calculer les Tn,k+1 (pour n = 0, . . . N −

1) explicitement si les Tn,k sont connus :


D∆t
Tn,k+1 = Tn,k + (Tn+1,k − 2Tn,k + Tn−1,k)
(∆x)2
Soit le coefficient sans dimensions :
D∆t
α= (4)
(∆x)2
Le schéma explicite s’écrit :

Tn,k+1 = Tn,k + α(Tn+1,k − 2Tn,k + Tn−1,k) (5)

Cette relation de récurrence est valable pour tout k ≥0 et pour n = 1, 2, . . . N 1.


La condition initiale consiste en la donnée de Tn,0 pour n = 0, 1, . . . N −1. Les deux
conditions limites sont :

T0,k = Ta, ∀k ≥ 0
TN−1,k = Tb, ∀k ≥ 0

Le schéma explicite et les conditions limites permettent de calculer Tn,1 pour n = 0, 1, · · ·N


1, puis Tn,2, etc.
Le schéma explicite est stable à condition que :
1
α< (6)
2
Pour un pas d’espace ∆x donné, le pas de temps devra donc vérifier :
(∆x)2
∆t <
2D
MP2 Licence Creative Commons 6

6. Implémentation

import numpy as np
from matplotlib.pyplot import *
rcParams[’figure.figsize’] = [13, 6]

Les Tn,k (instant k donné) sont stockés dans un tableau à N éléments (n = 0, 1, . . . N−1).
L’itération consiste à calculer le tableau des Tn,k+1 (instant k + 1) à partir du tableau des
Tn,k et à appliquer les conditions limites. Il est nécessaire de créer un nouveau tableau pour
faire ce calcul. La fonction iteration effectue ce calcul et renvoie le nouveau tableau.

def iteration(T,N,alpha,Ta,Tb):
# tableau contenant T(n,k) pour n=0,1,.. N-1
# N : taille du tableau
# alpha
# Ta,Tb : températures aux frontières
T1 = np.zeros(N)
T1[0] = Ta
T1[N-1] =
Tb
for n in range(1,N-1):
T1[n] = T[n] +alpha*(T[n+1]-2*T[n]+T[n-1])
return T1

Il n’est pas nécessaire de garder en mémoire les Tn,k pour tout k. La fonction calcul
effectue les itérations pour t variant de ti à tf . La variable t n’apparaît pas explicitement dans
ce calcul mais elle pourrait apparaître dans un problème où les conditions limites seraient
variables. La fonction renvoie l’instant final (qui peut être différent de tf ), le tableau des Tn,k
pour cet instant et le nombre d’itérations.

def
calcul(T,N,ti,tf,delta_t,alpha,Ta,Tb)
: t = ti
niter = 0
while t<tf:
T = iteration(T,N,alpha,Ta,Tb)
t += delta_t
niter += 1
return (t,T,niter)

Voici un exemple où x ∈ [0, 1] désigne xJ (abscisse sans dimension) et t désigne tJ (temps sans
dimensions). La condition initiale est T (x, 0) = 0 pour x ∈[0, 1]. Les conditions limites sont
T (0, t) = 1 et T (1, t) = 0.
Le choix de ∆x dépend de la pente maximale de la fonction x → T (x, t) sur l’intervalle
[0, 1]. Plus cette pente maximale est grande, plus ∆x doit être petit. Dans le problème de
diffusion étudié ici, la pente est très forte au voisinage de x = 0 pour les instants petits. Le pas
de temps est choisi à 90 % de sa valeur maximale. Essayons avec N = 210 :
MP2 Licence Creative Commons 7

N=2**10
delta_x = 1/(N-1)
x = np.arange(N)*delta_x
T = np.zeros(N)
Ta = 1
Tb = 0
D = 1
delta_t_max = delta_x**2/(2*D) # valeur maximale pour garantir la
stabilité delta_t = 0.9*delta_t_max
alpha = D*delta_t/delta_x**2

Faisons un premier calcul de l’instant tJ = 0 à tJ = 10−4 puis traçons la courbe de xJ →


T (xJ, tJ) :

(t1,T1,niter1) = calcul(T,N,0,1e-4,delta_t,alpha,Ta,Tb)

figure()
plot(x,T1)
xlabel("x’")
ylabel(’T’)
grid()
xlim(0,1)

Voici le pas de temps qui a été utilisé pour ce calcul et le nombre d’itérations

print((delta_t,niter1))
--> (4.2999286211848885e-07, 233)

L’évolution du profil de température est rapide lorsque t est petit puis devient de plus en plus
lente.
Nous cherchons à présent à calculer l’évolution de tJ = 10−4 à tJ = 10−3. Si ∆x reste
inchangé, la valeur de ∆t ne peut pas être augmentée car elle a été choisie à 90 % de la limite
de stabilité. Or l’intervalle de temps du calcul de tJ = 10−4 à tJ = 10−3 est environ 10 fois plus
grand que le précédent. Il y aura donc 10 fois plus de calculs.
MP2 Licence Creative Commons 8

(t2,T2,niter2) = calcul(T1,N,1e-4,1e-3,delta_t,alpha,Ta,Tb)

figure()
plot(x,T2)
xlabel("x’")
ylabel(’T’)
grid()
xlim(0,1)

print(niter2)
--> 2094

Le temps de calcul est encore acceptable. L’étape suivante consiste à calculer de tJ = 10−3
à tJ = 10−2. Si on ne change pas ∆x, le nombre d’itérations sera 10 fois plus grand que le
précédent. On remarque que la pente maximale de la courbe est plus faible que pour tJ =
10−4. Il devrait donc être possible d’augmenter ∆x afin d’augmenter ∆t, donc de réduire le
nombre d’itérations. Nous avons défini N comme une puissance de 2. Il est donc facile de
réduire la valeur de N en le divisant pas 4, ce qui aura pour effet de réduire le nombre
d’itérations d’un facteur 16.

N_1 = N//4
T2_1 = T2[0::4]
x_1 = x[0::4]
figure()
plot(x_1,T2_1)
xlabel("x’")
ylabel(’T’)
grid()
xlim(0,1)
MP2 Licence Creative Commons 9

Comme on le voit sur cette figure, l’augmentation de ∆x est sans conséquence sur la
bonne représentation de la fonction xJ → T (xJ, tJ). Calculons les nouveaux paramètres du
calcul :

delta_x_1 = 1/(N_1-1)
delta_t_max_1 = delta_x_1**2/(2*D) # valeur maximale pour garantir la stabilité
delta_t_1 = 0.9*delta_t_max_1
alpha_1 = D*delta_t_1/delta_x_1**2

Voici le calcul de tJ = 10−3 à tJ = 10−2 :

(t3,T3_1,niter3) = calcul(T2_1,N_1,1e-3,1e-2,delta_t_1,alpha_1,Ta,Tb)
figure()
plot(x_1,T3_1)
xlabel("x’")
ylabel(’T’)
grid()
xlim(0,1)

print(niter3)
--> 1301
MP2 Licence Creative Commons 10

Pour le calcul de tJ = 10−2 à tJ = 10−1, on peut garder le même ∆x car le nombre


d’itérations sera encore acceptable (10 fois plus que le précédent).

(t4,T4_1,niter4) = calcul(T3_1,N_1,1e-2,1e-1,delta_t_1,alpha_1,Ta,Tb)

figure()
plot(x_1,T4_1)
xlabel("x’")
ylabel(’T’)
grid()
xlim(0,1)

print(niter4)
--> 13005

Le régime stationnaire n’est pas encore atteint. Il faut encore calculer de tJ = 10−1 à tJ =
1, ce qui demanderait 10 fois plus d’itérations si on ne change pas ∆x. Il est donc
judicieux de procéder à nouveau à une division de N d’un facteur 4 :

N_2 = N_1//4
T4_2 = T4_1[0::4]
x_2 = x_1[0::4]
figure()
plot(x_2,T4_2)
xlabel("x’")
ylabel(’T’)
grid()
xlim(0,1)
MP2 Licence Creative Commons 11

delta_x_2 = 1/(N_2-1)
delta_t_max_2 = delta_x_2**2/(2*D) # valeur maximale pour garantir la stabilité
delta_t_2 = 0.9*delta_t_max_2
alpha_2 = D*delta_t_2/delta_x_2**2
(t5,T5_2,niter5) = calcul(T4_2,N_2,1e-1,1,delta_t_2,alpha_2,Ta,Tb)

figure()
plot(x_2,T5_2)
xlabel("x’")
ylabel(’T’)
grid()
xlim(0,1)

print(niter5)
--> 7939

Le régime stationnaire est bien atteint à tJ = 1 (un examen plus détaillé montre qu’il est
atteint pratiquement pour tJ = 0,2). On voit ici l’intérêt d’avoir défini des variables xJ et tJ
sans dimensions. Le temps tJ qu’il faut pour atteindre le régime stationnaire est de l’ordre de
1. La durée réelle correspondante est τ .
Pour finir, on trace les courbes de xJ → T (xJ, tJ) obtenues pour les différents instants :
MP2 Licence Creative Commons 12

figure() plot(x,T1,label="t’=
%0.2g"%t1) plot(x,T2,label="t’=
%0.2g"%t2) plot(x_1,T3_1,label="t’=
%0.2g"%t3) plot(x_1,T4_1,label="t’=
%0.2g"%t4) plot(x_2,T5_2,label="t’=
%0.2g"%t5) xlabel("x’")
ylabel(’T’)
grid()
xlim(0,1)
legend(loc=’upper right’)

Vous aimerez peut-être aussi