Table des matières Python

Équation de diffusion à une dimension

1. Équation de diffusion

Soit une fonction u(x,t) représentant la température dans un problème de diffusion thermique, ou la concentration pour un problème de diffusion de particules. L'équation de diffusion est :

ut=D2ux2+s(x,t)

D est le coefficient de diffusion et s(x,t) représente une source, par exemple une source thermique provenant d'un phénomène de dissipation.

On cherche une solution numérique de cette équation pour une fonction s(x,t) donnée, sur l'intervalle [0,1], à partir de l'instant t=0. La condition initiale est u(x,0). Sur les bords (x=0 et x=1) la condition limite est soit de type Dirichlet :

u(0,t)=U0

soit de type Neumann (dérivée imposée) :

ux(0,t)=J0

2. Méthode des différences finies

2.a. Définitions

Soit N le nombre de points dans l'intervalle [0,1]. On définit le pas de x par

Δx=1N-1

On définit aussi le pas du temps Δt . La discrétisation de u(x,t) est définie par :

Ujn=u(jΔx,nΔt)

j est un indice variant de 0 à N-1 et n un indice positif ou nul représentant le temps.

discretisation.svgFigure pleine page

La discrétisation du terme de source est

Sjn=u(jΔx,nΔt)

On pose

α=DΔt(Δx)2

2.b. Schéma explicite

Pour discrétiser l'équation de diffusion, on peut écrire la différence finie en utilisant les instants n et n+1 pour la dérivée temporelle, et la différence finie à l'instant n pour la dérivée spatiale :

Ujn+1-UjnΔt=DUj+1n-2Ujn+Uj-1n(Δx)2+Sjn

Avec ce schéma, on peut calculer les Ujn+1 à l'instant n+1 connaissant tous les Ujn à l'instant n, de manière explicite. Ce schéma est précis au premier ordre ([1]). Comme montré plus loin, sa stabilité n'est assurée que si le critère suivant est vérifié :

DΔt(Δx)212

En pratique, cela peut imposer un pas de temps trop petit.

L'implémentation de cette méthode est immédiate. Voici un exemple :

import numpy
from matplotlib.pyplot import *

N=100
x=numpy.linspace(0,1,N)
dx=x[1]-x[0]
dx2=dx**2
U=numpy.zeros(N)
laplacien=numpy.zeros(N)
dt = 3e-5
U[0]=1
U[N-1]=0
D=1.0
for i in range(1000):
    for k in range(1,N-1):
        laplacien[k] = (U[k+1]-2*U[k]+U[k-1])/dx2
    for k in range(1,N-1):
        U[k] += dt*D*laplacien[k]

figure()
plot(x,U)
xlabel("x")
ylabel("U")
grid()

alpha=D*dt/dx2

                
print(alpha)
--> 0.29402999999999996
figAfigA.pdf

Le nombre de points N et l'intervalle de temps sont choisis assez petits pour satisfaire la condition de stabilité. Pour ces valeurs, l'atteinte du régime stationnaire est très longue (en temps de calcul) car l'intervalle de temps Δt est trop petit. Si on augmente cet intervalle, on sort de la condition de stabilité :


N=100
x=numpy.linspace(0,1,N)
dx=x[1]-x[0]
dx2=dx**2
U=numpy.zeros(N)
laplacien=numpy.zeros(N)
dt = 6e-5
U[0]=1
U[N-1]=0
D=1.0
for i in range(1000):
    for k in range(1,N-1):
        laplacien[k] = (U[k+1]-2*U[k]+U[k-1])/dx2
    for k in range(1,N-1):
        U[k] += dt*D*laplacien[k]

figure()
plot(x,U)
xlabel("x")
ylabel("U")
grid()

alpha=D*dt/dx2

                
print(alpha)
--> 0.58805999999999992
figBfigB.pdf

2.c. Schéma implicite de Crank-Nicolson

La dérivée seconde spatiale est discrétisée en écrivant la moyenne de la différence finie évaluée à l'instant n et de celle évaluée à l'instant n+1 :

Ujn+1-UjnΔt=D2(Uj+1n+1-2Ujn+1+Uj-1n+1)+(Uj+1n-2Ujn+Uj-1n)(Δx)2+Sjn

Ce schéma est précis au second ordre. Contrairement au schéma explicite, il est stable sans condition. En revanche, les Ujn+1 à l'instant n+1 sont donnés de manière implicite. Il faut donc à chaque instant n+1 résoudre le système à N équations suivant :

-α2Uj-1n+1+(1+α)Ujn+1-α2Uj+1n+1=α2Uj-1n+(1-α)Ujn+α2Uj+1n+ΔtSjn

Ce système est tridiagonal. On l'écrit sous la forme :

Aj,j-1Uj-1n+1+Aj,jUjn+1+Aj,j+1Uj+1n+1=Rj

À chaque étape, on calcule la matrice colonne R et on résout le système AUn+1=R . Pour j=0 et j=N-1, l'équation est obtenue par la condition limite.

On peut aussi écrire le membre de droite sous la forme :

Rj=Bj,j-1Uj-1n+Bj,jUj,n+Bj,j+1Uj+1n+Cj

ce qui donne la forme matricielle

AUn+1=BUn+C

2.d. Analyse de stabilité de von Neumann

L'analyse de stabilité de von Neumann ([2][3]) consiste à ignorer les conditions limites et le terme de source, et à rechercher une solution de la forme suivante :

Ujn=σnexp(iβj)

Il s'agit d'une solution dont la variation spatiale est sinusoïdale, avec un nombre d'onde β. Toute solution de l'équation de diffusion sans source et sans condition limite doit tendre vers une valeur uniformément nulle au temps infini. La méthode numérique utilisée est donc stable si |σ|<1 quelque soit la valeur de β.

En reportant cette solution dans le schéma explicite, on obtient :

σ=1+2α(cosβ-1)

La valeur absolue maximale de σ est obtenue pour cos(β)=-1. On en déduit la condition de stabilité : α<1/2 .

Pour le schéma de Crank-Nicolson, on obtient :

σ=1-α(1-cosβ)1+α(1-cosβ)

|σ| est inférieur à 1, donc le schéma est inconditionnellement stable.

2.e. Discrétisation des conditions limites

La discrétisation de la condition de Dirichlet (en x=0) est immédiate :

U0n=U0

On pose donc pour la première équation du système précédent :

A0,-1=0,A0,0=1,A0,1=0,R0=U0

De même pour une condition limite de Dirichlet en x=1 on pose

AN-1,N-2=0,AN-1,N-1=1,AN-1,N=0,RN-1=U1

Une condition limite de Neumann en x=0 peut s'écrire :

U1n+1-U0n+1=ΔxJ0

ce qui donne

A0,-1=0,A0,0=-1,A0,1=1,R0=ΔxJ0

Cependant, cette discrétisation de la condition de Neumann est du premier ordre, alors que le schéma de Crank-Nicolson est du second ordre. Pour éviter une perte de précision due aux bords, il est préférable de partir d'une discrétisation du second ordre ([1]) :

U1n+1-U-1n+1=2ΔxJ0

Un point fictif d'indice -1 a été introduit. Pour ne pas avoir d'inconnue en trop, on écrit le schéma de Crank-Nicolson au point d'indice 0 tout en éliminant le point fictif avec la condition ci-dessus ([1]). On obtient ainsi :

(1+α)U0n+1-αU1n+1=(1-α)U0n+αU1n-2αΔxJ0+ΔtS0n

On obtient de la même manière la condition limite de Neumann en x=1 :

-αUN-2n+1+(1+α)UN-1n+1=αUN-2n+(1-α)UN-1n+2αΔx J1+ΔtSN-1n

2.f. Milieux de coefficients de diffusion différents

On suppose que le coefficient de diffusion n'est plus uniforme mais constant par morceaux. Exemple : diffusion thermique entre deux plaques de matériaux différents. Soit une frontière entre deux parties située entre les indices j et j+1, les coefficients de diffusion de part et d'autre étant D1 et D2. Pour j-1 et j+1, on écrira le schéma de Crank-Nicolson ci-dessus. En revanche, sur le point à gauche de la frontière (indice j), on écrit une condition d'égalité des flux :

D1Ux(x-)=D2Ux(x+)

qui se traduit par

D1(Ujn+1-Uj-1n+1)=D2(Uj+1n+1-Ujn+1)

et conduit aux coefficients suivants

Aj,j-1=-D1,Aj,j=D1+D2,Aj,j+1=-D1,Rj=0

2.g. Convection latérale

Un problème de transfert thermique dans une barre comporte un flux de convection latéral, qui conduit à l'équation différentielle suivante :

Tt=D2Tx2+s-C(T-Te)

où le coefficient C (inverse d'un temps) caractérise l'intensité de la convection et Te est la température extérieure.

On pose β=CΔt. Le schéma de Crank-Nicolson correspondant à cette équation est :

Ujn+1-Ujn=α2((Uj+1n+1-2Ujn+1+Uj-1n+1)+(Uj+1n-2Ujn+Uj-1n))+Sjn+β2(2Ue-Ujn+1-Ujn)

c'est-à-dire :

-α2Uj-1n+1+(1+α+β2)Ujn+1-α2Uj+1n+1=α2Uj-1n+(1-α-β2)Ujn+α2Uj+1n+ΔtSjn+βUe

3. Résolution du système tridiagonal

Les matrices A et B étant tridiagonales, une implémentation efficace doit stocker seulement les trois diagonales, dans trois tableaux différents. On écrit donc le schéma de Crank-Nicolson sous la forme :

ajUj-1n+1+bjUjn+1+cjUj+1n+1=djUj-1n+ejUjn+fjUj+1n+sjn

Les coefficients du schéma sont ainsi stockés dans des tableaux à N éléments a,b,c,d,e,f,s. On remarque toutefois que les éléments a0, cN-1, d0 et fN-1 ne sont pas utilisés.

Le système tridiagonal à résoudre à chaque pas de temps est :

ajUj-1+bjUj+cjUj+1=Rj

où l'indice du temps a été omis pour alléger la notation. Le second membre du système se calcule de la manière suivante :

R0=e0U0+f0U1+s0Rj=djUj-1+ejUj+fjUj+1+sjpour1jN-2RN-1=dN-1UN-2+eN-1UN-1+sN-1

Le système tridiagonal s'écrit :

(b0c0a1b1c1a2b2c2aN-1bN-1)(U0U1U2UN-1)=(R0R1R2RN-1)(1)

La méthode d'élimination de Gauss-Jordan permet de résoudre ce système de la manière suivante.

Les deux premières équations sont :

b0U0+c0U1=R0a1U0+b1U1+c1U2=R1

b0 est égal à 1 ou -1 suivant le type de condition limite. On divise la première équation par ce coefficient, ce qui conduit à poser :

β0=b0γ0=c0β0x0=R0β0

La première élimination consiste à retrancher l'équation obtenue multipliée par a1 à la seconde :

(b1-a1γ0)U1+c1U2=R1-a1x0

On pose alors :

β1=b1-a1γ0γ1=c1β1x1=R1-a1x0β1

On construit par récurrence la suite suivante :

βk=bk-akγk-1(2)γk=ckβk(3)xk=Rk-akxk-1βk(4)

Considérons la kième équation réduite et la suivante :

Uk+γkUk+1=xkak+1Uk+bk+1Uk+1+ck+1Uk+2=Rk+1

La réduction de cette dernière équation est :

(bk+1-ak+1γk)Uk+1+ck+1Uk+2=Rk+1-ak+1xk

ce qui justifie la relation de récurrence définie plus haut.

Pour finir, voyons les deux dernières équations :

UN-2+γN-2UN-1=xN-2aN-1UN-2+bN-1UN-1=RN-1

La dernière équation réduite donne :

(bN-1-aN-1γN-2)UN-1=RN-1-aN-2xN-2

c'est-à-dire :

UN-1=xN-1

Il reste à calculer les Uk en partant du dernier par la relation :

Uk=xk-γkUk+1(5)

Les coefficients des diagonales sont stockés dans trois tableaux (à N éléments) a,b et c dès que les conditions limites et les pas sont fixés. Les tableaux β et γ (relations 1 et 2) sont calculés par récurrence avant le départ de la boucle d'itération. À chaque pas de l'itération (à chaque instant), on calcule par récurrence la suite xk (relation 3) pour k variant de 0 à N-1, et enfin la suite Uk (relation 4) pour k variant de N-1 à 0. En pratique, dans cette dernière boucle, on écrit directement dans le tableau utilisé pour stocker les Uj,n .

Références
[1]  J.W. Thomas,  Numerical partial differential equations,  (Springer-Verlag, 2010)
[2]  J.H. Ferziger, M. Peric,  Computational methods for fluid dynamics,  (Springer, 2002)
[3]  R.H. Pletcher, J.C. Tannehill, D.A. Anderson,  Computational Fluid Mechanics and Heat Transfer,  (CRC Press, 2013)
Creative Commons LicenseTextes et figures sont mis à disposition sous contrat Creative Commons.