Académique Documents
Professionnel Documents
Culture Documents
Nous allons nous baser sur la méthode des caractéristiques pour résoudre cette équation aux
dérivées partielles.
On cherche une fonction
u : (x, t) ∈ R × R+ ↦ u(x, t) ∈ R
qui satisfait :
Nous cherchons ainsi une courbe caractéristique ∑ = (x(t), t) le long de laquelle notre
équation aux dérivées partielles du 1er ordre se réduit à une équation différentielle ordinaire.
Ainsi, toute solution de (1) est constante le long de ∑.
∂u ′ ∂u
On pose u(x(t), t) = 0 et dx
dt = c1 (c1 une constante réelle) donc ∂x x (t) + ∂t × 1 = 0.
Nous distinguons alors deux cas possibles pour définir la solution exacte:
u(x, t) = u0 (x − ct) = 0
et le second cas lorsque xc < 0:
x x
u(x, t) = g(t0 ) = g(t − ) = exp( − t)
c c
On a:
∥u(⋅, t)∥2 = ∥u0 ∥2
et on cherche une solution approchée qu'on notera un n
i tel que: ui ≃ u(i∆x, n∆t).
+∞
On a: ∥u∥l2 (Z) = en (u) = h ∑i=0 ∣uni ∣2 .
On a:
un+1 − uni ∂u
i
≃ (xi , tn )
∆t ∂t
et
uni+1 − uni−1 ∂u
≃ (xi , tn )
2∆x ∂x
Ainsi:
∂u u(xi+1 , tn ) − u(xi−1 , tn )
(xi , tn ) = + O(∆x2 )
∂x 2∆x
uni − uni−1 u(xi , tn ) − u(xi−1 , tn ) ∂u
= = (xi , tn ) + O(∆t)
∆t ∆t ∂x
On obtient le schéma numérique décentré suivant:
un+1 − uni uni − uni−1 c∆t n
i
+c = 0 ⟹ un+1
i = u n
i − (ui − uni−1 )
∆t ∆x ∆x
k k
∑ cm un+1
j+m = ∑ dm unj+m
m=−k m=−k
k k
∑ cm Fv n+1 iξm△x
(ξ)e = ∑ dm Fv n (ξ)eiξm△x
m=−k m=−k
Ainsi
c∆t
Fv n+ (ξ) = (1 − c (1 − exp(−iξ∆x))Fv n (ξ)
∆x
Le critère de Von Neumann nécessaire et suffisant pour la stabilité en norme L2 (Z) d'un
schéma à deux niveaux est :
Le coefficient d'amplification pour ce schéma décentré à gauche est donc g(ξ; ∆x, ∆t) =
(1 − ∆x (1
c c∆t − cos(ξ∆x)).
∆x )(1 − cos(ξ∆x)).
c∆t
si c∆t
∆x ≤ 1 donc supξ∈R ∣g(ξ; ∆x, ∆t)∣ = 1,
si c∆t
∆x > 1 donc supξ∈R ∣g(ξ; ∆x, ∆t)∣ = 1 − 2 c∆t
∆x (1 − ∆x ).
c∆t
c∆x n c∆t n
un+1 = ui−1 + (1 − )u
i
∆t ∆x i
Sous cette forme le schéma décentré à gauche est une combinaison convexe si la condition
C.F.L (0 ≤ ∣c∣∆t ≤ ∆x) est satisfaite. Il vérifie le principe du maximum discret, ce dernier a
pour conséquence un contrôle des oscillations numériques.
On dit qu'un schéma est précis d'ordre p en x et précis d'ordre q en t si l'erreur de troncature
est de l'ordre O((∆x)p + (∆t)q ).
∣c∣ ∂2u
ErrT = (−∆x + ∣c∣∆t) 2 + O((∆x)2 + (∆t)2 )
2 ∂x
Donc, le schéma est précis d'ordre 1 seulement ainsi il converge.
La fonction sol_exacte(x: f64, t: f64) est appelée dans le main() qui permet de
calculer la solution numérique de l'équation du transport.
La première étape est l'initialisation des variables nx , length , tmax , c , h , cfl , dt qui
correspondent respectivement au nombre de points de discrétisation, la longueur de la barre,
le temps final, la vitesse de propagation, la taille d'un pas de discrétisation, le nombre de
Courant, et le pas de temps.
La boucle suivante :
for i in 0..nx + 1 {
unow_d[i] = sol_exacte(xi[i], 0.);
}
permet d'initialiser la solution numérique au temps n avec la solution exacte au temps n=0.
(car nous voulons dans la boucle while calculer la solution numérique au temps n+1 à partir de
la solution numérique au temps n)
Tant que le paramètre temps t est inférieur au temps final tmax , on calcule la solution
numérique au temps n+1 à partir de la solution numérique au temps n et parallèlement la
solution exacte au temps n+1 à partir de la solution exacte au temps n.
Un exemple de résultat obtenu avec le programme Rust pour les paramètres suivants:
nx = 1000
length = 1.0
tmax = 0.5
c = 1.0
cfl = 0.5
dt = length / nx = 0.0005
Pour vérifier que le schéma est instable lorsque la condition de cfl n’est pas vérifiée, on
peut mettre cfl = 1.5 au lieu de cfl = 0.5 dans le programme Rust.
On crée dans un premier temps un vecteur nx_tab qui contiendra les valeurs de nx pour
lesquelles on veut calculer la norme L1 et L2.
let nx_array = [10, 20, 50, 100, 200, 500, 1000, 2000, 5000];
let abs: Vec<f64> = [1., 2. , 3., 4., 5., 6., 7., 8., 9.].to_vec();
Ensuite, dans une boucle qui parcourt tous les éléments du tableau nx_array on calcule
u_ex et unow_d pour chaque nombre de points de discrétisation. On calcule ensuite la
norme L1 et L2 de u_ex et unow_d et on les stocke dans les vecteurs dédiés.
( abs est un vecteur qui permet de tracer le graphe, il contient les abscisses.)
On appelle ensuite la fonction plot1d qui prend en paramètre les vecteurs temp et
normel1_tab et normel2_tab et qui trace le graphe de la norme L1 et L2 en fonction du
nombre de points de discrétisation nx .
Le programme est sensiblement le même que pour le schéma décentré nous ajoutons dans le
while la boucle for suivante qui va cette fois jusqu'à nx au lieu de nx+1 :
for i in 1..nx {
unext_c[i] = unow_c[i] - c * dt / (2. * h) * (unow_c[i + 1] - unow_c[i - 1]);
uex[i]=sol_exacte(xi[i],t,c);
}
Dans le while qui parcourt tous les points de discrétisation nx on souhaite calculer unext_l
et unow_l .
On ajoute donc la boucle for suivante, elle va de 1 à nx (car on a besoin de calculer
unow_l[i + 1] ):
for i in 1..nx {
unext_l[i] = unow_l[i] - c * dt / (2. * h) * (unow_l[i + 1] - unow_l[i - 1])
+ c * c * dt * dt / (2. * h * h) * (unow_l[i + 1] - 2. * unow_[i] + unow_l[i - 1]);
uex[i] = sol_exacte(xi[i], t, c);
}
△t △t2 2 n
un+1
i = uni − n n
c(ui+1 − ui−1 ) + 2
c (ui+1 − 2uni + uni−1 )
2△x 2△x
△t △t2 2
g(ξ, △x, △t) = 1 − c sin(ξ△x) + 2
c (cos(ξ△x) − 1)2
2△x 2△x
On rappelle que le critère de Von Neumann nécessaire et suffisant pour la stabilité en norme
L2 (Z) d'un schéma à deux niveaux est :
△t
Et si c △x < 1, on a : supξ∈R ∣g(ξ, △x, △t)∣ = 1.
△t
On en conclut donc que le schéma de Lax-Wendrof est stable en norme L2 (Z) si c △x < 1.
On trace la solution exacte et la solution approchée pour deux conditions CFL différentes
( nx=100 et tmax=0.5 ):
△t
Pour c △x = 0.5 nous avons :
△t
et pour c △x = 1.5 nous avons :
△t
On constate que pour c △x = 0.5, la solution approchée est stable, en revanche pour l'autre
C.F.L. elle diverge. Ceci conforte notre analyse théorique.
À présent pour vérifier numériquement que le schéma n'est pas stable en norme L∞ on crée
une fonction norme_linf . Cette fonction prend en paramètres uex et unow_l qui sont les
vecteurs de la solution exacte et de la solution approchée. Elle renvoie la norme L∞ de la
différence entre ces deux vecteurs.
fn linf_norm(uex: &[f64], unow_l: &[f64]) -> f64 {
let mut m = 0.;
for i in 0..uex.len() {
let err = (uex[i] - unow_l[i]).abs();
if err > m {
m = err;
}
}
m
}
On utilise le même procédé que pour les deux normes L1 et L2 pour récupérer les valeurs de
la norme L∞ pour différentes valeurs de nx .
△t
Pour c △x = 0.5 nous avons :
△t
Pour c △x = 1. nous avons :
△t
Pour c △x = 1.5 nous avons :
On observe que peu importe la condition C.F.L utilisée, la norme L∞ de la différence entre la
solution exacte et la solution approchée diverge. Ceci confirme que le schéma de Lax-
Wendrof n'est pas stable en norme L∞ .