TP 4 Rendu
TP 4 Rendu
TP 4 Rendu
Question 1
Calculons la solution du problème d'évolution suivant:
u2
∂t u + u∂x ( ) = 0, x ∈ [−1, 2], t ∈ [0, T ]
2
u(−1, t) = 1, t ∈ [0, T ]
u(x, 0) = u0 (x), x ∈ [−1, 2]
⎧1 si x < 0
u0 (x) = ⎨1 − x si 0 ≤ x ≤ 1
⎩
0 si x > 1
∂u ∂u ∂2u
+u =ν 2
∂t ∂x ∂x
Lorsque le terme de diffusion est nul, comme dans notre cas, ν = 0, on obtient une équation
de Burger sans viscosité.
∂u ∂u
+u =0 (forme advective)
∂t ∂x
Il s'agit d'un prototype de l'équation de conservation pouvant développer des discontinuités
(ondes de choc). Nous nous intéressons dans ce TP à sa forme conservatrice:
∂u 1 ∂u2
+ =0 (forme conservatrice)
∂t 2 ∂x
L'équation de Burger sans viscosité est plus généralement une équation hyperbolique non
linéaire du premier ordre.
La solution de l'équation peut être construite par la méthode des caractéristiques. Les
équations caractéristiques sont données par:
dx du
= u et =0
dt dt
L'intégration de la deuxième équation nous permet de voir que u est constante le long de la
courbe caractéristique et que ces dernières sont des lignes droites.
u=c et x = ut + x0
où x0 est le point sur l'axe x du plan (x, t) à partir duquel la courbe caractéristique part.
Sachant que sur tout l'axe des abscisses, u est connue dès la condition initiale, et reste
invariante au fur et à mesure que l'on se déplace le long de la courbe caractéristique, on peut
écrire: u = c = u0 (x0 ) sur chaque courbe caractéristique.
La famille de trajectoires caractéristiques paramétrées par x0 est donnée par:
x = u0 (x0 )t + x0
Donc:
⎧1 si x < t
x′ (t) = ⎨1 − x0 si t ≤ x ≤ 1
⎩
0 si x > 1
Or,
⎧1 si x < t
u(x, t) = ⎨1 − x0 si 0 ≤ x ≤ 1
⎩
0 si x > 1
Pour 0 ≤x≤1,
1−x
u(x, t) = 1 − x0 = 1 − (x − u(x, t)t) = 1 − x + u(x, t)t ⟹ u(x, t) =
1−t
Finalement,
⎧1 si x < t
u(x, t) = ⎨ 1−x si t ≤ x ≤ 1
⎩
1−t
0 si x > 1
Il s'agit d'une relation implicite qui détermine la solution de l'équation à condition que les
courbes caractéristiques ne se coupent pas.
En fonction de la condition initiale, si elles se croisent, alors il n'existe pas de solution unique,
il y a formation d'une onde de choc. Le temps de rupture ( breaking time tb ) avant qu'une
onde de choc puisse se former est donné par:
−1
tb = inf
x∈R u′0 (x)
On a :
⎧0 si x < 0
u′0 (x) = ⎨−1 si 0 ≤ x ≤ 1
⎩
0 si x > 1
Donc, tb = 1.
La solution obtenue précédemment par la méthode des caractéristiques est donc valable
pour t ≤ tb .
Afin d'établir une solution pour t > tb , il faut permettre les discontinuités de u. Cependant en
élargissant la classe des solutions, l'unicité de la solution n'est pls garantie.
Les relations de Rankine-Hugoniot permettent d'imposer des conditions de choc reliant les
sauts de u à travers la discontinuité.
∂u ∂f (u)
+ =0
∂t ∂x
la vitesse de propagation d'un choc est donné par l'équation suivante:
Δf
s=
Δu
u2L u2
1 2 − 2R uL +uR
dans notre cas, f (u) = 2 u ainsi s= 2
uL −uR = 2
où uL et uR sont les valeurs de u à gauche et à droite de la discontinuité.
u0 (x0 ) convient comme solution, pour y < 1 on a comme valeur uL = 1 et pour y > 1 on
a uR = 0. On obtient après intégration de l'équation de discontinuité : u0 (t) = 12 (1 + t).
Pour t <1:
⎧1 si x ≤ t
u(x, t) = ⎨ 1−x si t < x < 1
⎩
1−t
0 si x ≤ 1
et pour t ≥1:
u(x, t) = {
1 si x ≤ t+1
2
0 si x > t+1
2
Question 2
Dans un le fichier main.rs , nous définissons une fonction fluxnum qui calcule le flux
numérique pour le schéma de Rusanov, elle prend deux arguments uL et uR qui sont les
valeurs de u à gauche et à droite de la discontinuité.
ρ2L + ρ2R λ
f (ρL , ρR ) = − (ρR − ρL ) ˋ λ = max(∣f ′ (ρL )∣, ∣f ′ (ρR )∣)
ou
2 2
u2
On a f (u) = 2 et f ′ (u) = u donc :
1 2 1
f (ρL , ρR ) = (ρL + ρ2R ) − max(∣ρL ∣, ∣ρR ∣)(ρR − ρL )
4 2
fn fluxnum(ul: f64, ur: f64) -> f64 {
let abs = f64::abs;
let max = f64::max;
let lambda= max(abs(ul), abs(ur));
0.25*(ul*ul+ur*ur)-0.5*lambda*(ur-ul)
}
On definit ensuite une fonction sol_num qui calcule la solution numérique pour le schéma de
Rusanov.
fn sol_num(nx:usize, xmin:f64, xmax:f64, cfl:f64, vmax:f64, tmax:f64, mut t:f64 )-> Vec<f6
Elle prend en argument nx qui est le nombre de points de discrétisation, xmin et xmax qui
sont les bornes de l'intervalle, cfl qui est la condition CFL, vmax qui est la vitesse
maximale, tmax qui est le temps final et t qui est le temps courant.
Le calcul de la solution numérique se fait ensuite dans une boucle while qui s'arrête lorsque
le temps courant t est supérieur au temps final tmax .
while t<tmax {
for i in 1..nx {
// schéma de Rusanov
unp1[i] += -dt/h*(fluxnum(un[i],un[i+1]) - fluxnum(un[i-1],un[i]));
}
t+=dt;
// conditions aux limites
unp1[0] = sol_exacte(xmin, t);
unp1[nx] = sol_exacte(xmax, t);
// mise à jour de un
un=unp1.clone();
}
Les conditions aux limites sont imposées grâce à la fonction sol_exacte qui retourne la
solution exacte pour un temps t et une position x .
Pour ce faire dans le main.rs , nous initialisons les paramètres de notre simulation.
let nx_tab: Vec<usize> = vec![50, 100, 1000, 10000];
Afin de pouvoir tracer plusieurs graphes sur la même fenêtre, nous utilisons la bibliothèque
gnuplot .
// Création de la fenêtre
let mut fig = Figure::new();
// Création des axes
let mut ax = fig.axes2d();
// Titre de la fenêtre
ax.set_title("Solution numérique et exacte pour différentes valeurs de nx", &[]);
let color = ["light-blue", "dark-green", "blue", "pink"];
for i in 0..nx_tab.len() {
// Tracé des graphes pour chaque valeur de nx
ax.lines(&xi_tab[i], &un_tab[i], &[Caption(&format!("nx={}", nx_tab[i])), Color(co
}
// Tracé de la solution exacte
ax.lines(&xi_tab[3], &uex, &[Caption("Solution exacte"), Color("red")]);
fig.show();
Question 3
Le code est similaire à celui du schéma de Rusanov, la seule différence réside dans la
fonction sol_num . On modifie l'expression de unp1 dans la boucle while comme suit:
while t<tmax {
for i in 1..nx {
// schéma differences finies
unp1[i] += -dt/h*un[i-1]*(un[i]-un[i-1]);
}
t+=dt;
unp1[0] = sol_exacte(xmin, t);
unp1[nx] = sol_exacte(xmax, t);
un=unp1.clone();
}
return un;
Question 4
Nous souhaitons dans cette question résoudre le problème d'évolution suivant:
où ρ ∈ [0, ρ0 ] est la densité de véhicules et ρ0 (x) est la densité maximale de véhicules sur la
route. ρ = ρ0 correspond à une congestion totale de la route et ρ = 0 correspond à une
route vide.
= 1 km. La densité et la
Afin de simuler ce trafic, on considère une route de longueur L
vitesse maximales sont respectivement ρ0 = 200 véhicules/km et v0 = 130 km/h.
f (ρ) = ρv0 (1 − )
ρ
ρ0
On initialise dans le main également les éléments suivants en plus des variables déjà
définies:
// le temps maximal de simulation
let tmaxmax = 5./60.;
// le pas de temps maximal auquel on observe l'évolution de la densité
let dtmax = 0.2/60.;
Nous pouvons créer une boucle while qui va itérer sur le pas de temps maximal tmaxmax . A
chaque itération, on va résoudre le problème d'évolution avec le schéma de Rusanov et on va
tracer la densité de véhicules en fonction de la position sur la route. On va également calculer
la vitesse maximale sur la route et on va l'afficher à chaque itération.
while tmax < tmaxmax {
while t < tmax {
// calcul de la vitesse maximale
let mut vmax = 0.;
for i in 0..nx as usize + 1 {
let v= f_prime(un[i]);
if v > vmax {
vmax = v;
}
}
let dt = dx / vmax;
for i in 1..nx as usize {
// schéma de Rusanov
unp1[i] = un[i] - dt / dx * (flux_num_traffic(un[i], un[i+1]) - flux_num_t
}
unp1[0] = 0.;
unp1[nx] = 0.;
for i in 0..nx as usize + 1 {
un[i] = unp1[i];
}
t += dt;
}
plot1d(&xi, &uinit, &un);
tmax += dtmax;
}