Prérequis : Chapitre 1 — Équations d'Euler (système hyperbolique, variables conservatives et primitives), Chapitre 2 — Problème de Riemann (structure des ondes, solutions faibles).
Les deux premiers chapitres ont établi le cadre physique : les équations d'Euler 1D forment un système hyperbolique de lois de conservation, et le problème de Riemann en est la brique élémentaire. Nous savons caractériser analytiquement les ondes (détentes, contacts, chocs) qui naissent d'une discontinuité initiale.
Le passage au calcul numérique pose une question fondamentale : comment transformer l'EDP continue
en un algorithme évaluable par un ordinateur, tout en respectant la structure physique du problème — en particulier la conservativité et la capacité à capturer les discontinuités ?
La méthode des volumes finis répond à cette question en partant de la forme intégrale des lois de conservation. Contrairement aux différences finies qui discrétisent directement les dérivées, les volumes finis discrétisent les bilans de flux à travers les frontières de cellules. Cette approche est intrinsèquement conservative : ce qui sort d'une cellule entre dans la voisine.
Ce chapitre construit la méthode étape par étape, depuis la formulation intégrale exacte jusqu'à l'algorithme complet implémenté dans le code.
On subdivise le domaine
Intégrons l'équation d'Euler sur la cellule
Le second terme se simplifie exactement par le théorème fondamental de l'analyse :
On définit la moyenne de cellule :
En divisant l'équation intégrée par
Point essentiel : cette équation est exacte. Aucune approximation n'a été faite. L'évolution de la moyenne de cellule est entièrement déterminée par les flux physiques aux interfaces. La difficulté est que nous ne connaissons pas la valeur ponctuelle
À l'interface
où
C'est ici que le problème de Riemann du chapitre 2 intervient : chaque interface est vue comme un mini-problème de Riemann entre l'état gauche
Un flux numérique doit satisfaire trois propriétés fondamentales :
-
Consistance : si les deux états sont identiques, le flux numérique redonne le flux physique :
$$\hat{\mathbf{F}}(\mathbf{U}, \mathbf{U}) = \mathbf{F}(\mathbf{U})$$ -
Conservativité : le flux
$\hat{\mathbf{F}}_{i+1/2}$ est unique à chaque interface. Ce qui sort de la cellule$i$ par sa frontière droite est exactement ce qui entre dans la cellule$i+1$ par sa frontière gauche. Le théorème de Lax-Wendroff garantit que si un schéma conservatif converge, il converge vers une solution faible des équations de conservation. Sans conservativité, un schéma peut converger vers une solution qui ne respecte pas les relations de saut (Rankine-Hugoniot). -
Continuité Lipschitz :
$\hat{\mathbf{F}}$ est Lipschitz-continue par rapport à ses arguments, ce qui assure la stabilité du schéma.
Les chapitres 4 détailleront les flux numériques implémentés dans le code : Rusanov, HLL, HLLC, Roe, Godunov (solveur exact), ainsi que les schémas centrés (Lax-Friedrichs, Lax-Wendroff, JST). Chacun réalise un compromis différent entre précision, coût de calcul et robustesse.
En remplaçant les flux exacts par les flux numériques, on obtient la semi-discrétisation :
C'est un système d'EDO (équations différentielles ordinaires) : la variable continue est le temps
Le système d'EDO est de la forme :
où
Le pas de temps est contraint par la condition CFL (Courant-Friedrichs-Lewy) :
où
Au premier ordre, on prend simplement :
Chaque cellule est représentée par une valeur constante égale à sa moyenne. Cette reconstruction est stable mais très diffusive : les discontinuités sont étalées sur de nombreuses cellules.
Pour améliorer la précision, on reconstruit les valeurs aux interfaces à partir des moyennes de cellule voisines. L'idée est d'utiliser un polynôme interpolant les moyennes sur un stencil (groupe de cellules voisines) pour estimer
Par exemple :
- MUSCL (ordre 2) : reconstruction linéaire avec limiteur de pente pour éviter les oscillations (chapitre 5).
- ENO (ordre 2) : sélection adaptative du stencil le plus régulier.
- WENO (ordres 3 et 5) : combinaison pondérée de plusieurs stencils, avec des poids qui s'adaptent à la régularité locale de la solution.
Convention importante : toutes les reconstructions sont effectuées sur les variables primitives
L'ordre spatial du schéma global est déterminé par l'ordre de la reconstruction (à condition que l'intégrateur temporel soit d'ordre au moins égal). Une reconstruction d'ordre
Un schéma de volumes finis d'ordre élevé se décompose en deux briques indépendantes :
-
Reconstruction : à partir des moyennes de cellule, estimer les états
$\mathbf{U}_L$ et$\mathbf{U}_R$ aux interfaces. -
Flux numérique : à partir de
$\mathbf{U}_L$ et $\mathbf{U}R$, calculer le flux $\hat{\mathbf{F}}{i+1/2}$.
Ces deux briques sont interchangeables : on peut combiner n'importe quelle reconstruction (constante, MUSCL, ENO, WENO3, WENO5) avec n'importe quel solveur de Riemann (Rusanov, HLL, HLLC, Roe, Godunov). Cela donne une grande variété de schémas à partir d'un petit nombre de composants.
Dans le code, cette composition est réalisée par la classe abstraite NumericalScheme (fichier euler1d/schemes/base.py). L'algorithme est le suivant :
-
compute_fluxes(U, gas, dx, dt)est appelé avec le tableau étendu (cellules intérieures + fantômes). - Par défaut (ordre 1), il extrait $\mathbf{U}L = \mathbf{U}{:, i}$ et $\mathbf{U}R = \mathbf{U}{:, i+1}$ (reconstruction constante).
- Il appelle
compute_riemann_flux(UL, UR, gas, dx, dt)pour calculer le flux. - Les schémas d'ordre élevé surchargent
compute_fluxespour insérer leur reconstruction avant l'appel au flux.
Les schémas Lax-Friedrichs, Lax-Wendroff et JST ne se décomposent pas en « reconstruction + solveur de Riemann ». Ce sont des schémas centrés qui calculent le flux directement à partir des valeurs de cellule, sans résoudre de problème de Riemann local. Ils ne sont pas composables avec les reconstructions d'ordre élevé.
En particulier, Lax-Wendroff inclut sa propre intégration temporelle (propriété time_integral_included = True), ce qui force l'utilisation de RK1 (un seul étage).
Au bord du domaine, le stencil du schéma s'étend au-delà des cellules intérieures. Par exemple, pour calculer le flux
La solution est d'ajouter des cellules fantômes de chaque côté du domaine, remplies selon les conditions aux limites. Le tableau de variables conservatives passe de la forme
Le nombre
| Reconstruction | Ordre | |
|---|---|---|
| Constante (ordre 1) | 1 | 1 |
| MUSCL, ENO2 | 2 | 2 |
| WENO3 | 3 | 2 |
| WENO5 | 5 | 3 |
Trois types sont implémentés dans euler1d/boundary.py :
Les cellules fantômes copient la cellule intérieure la plus proche :
Physiquement, cela simule un domaine ouvert : les ondes sortent librement sans réflexion. C'est la condition par défaut pour les problèmes de Riemann (tube de Sod, test de Lax, etc.).
Les cellules fantômes copient la cellule intérieure symétrique avec inversion de la quantité de mouvement :
Physiquement, cela impose une vitesse nulle à la paroi (
Les cellules fantômes à gauche copient les cellules intérieures de droite, et vice versa :
Physiquement, le domaine se « referme » sur lui-même : ce qui sort à droite réapparaît à gauche. C'est la condition appropriée pour les cas tests lisses (onde entropique, onde acoustique) où la solution est périodique.
Tous les schémas sont accessibles par un nom unique suivant la convention "reconstruction-flux". Par exemple :
"hllc": flux HLLC seul (reconstruction constante, ordre 1)"muscl-hllc": reconstruction MUSCL + flux HLLC (ordre 2)"weno5-roe": reconstruction WENO5 + flux Roe (ordre 5)
Les flux composables avec les reconstructions sont : Rusanov, HLL, HLLC, Roe, Godunov (5 flux). Combinés avec les 6 reconstructions (MUSCL, ENO2, WENO3, WENOZ3, WENO5, WENOZ5), ils produisent 30 schémas d'ordre élevé.
Les schémas non composables (Lax-Friedrichs, Lax-Wendroff, JST) ne fonctionnent qu'en ordre 1 (ou avec leur propre méthode interne). Ils sont enregistrés directement dans le registre.
Au total, le registre propose 38 schémas : 8 autonomes + 30 combinaisons.
La fonction get_scheme(name, **kwargs) du module euler1d/schemes/__init__.py est le point d'entrée unique pour instancier un schéma. Elle accepte le nom en minuscules et, pour les schémas MUSCL, un argument optionnel limiter (par défaut "van-leer").
from euler1d.schemes import get_scheme
# Ordre 1
scheme = get_scheme("hllc")
# Ordre 2 avec limiteur
scheme = get_scheme("muscl-hllc", limiter="superbee")
# Ordre 5
scheme = get_scheme("weno5-hllc")Le code correspondant à ce chapitre se trouve dans trois fichiers :
-
euler1d/boundary.py: conditions aux limites par cellules fantômes (§3.6). La fonctionapply_boundary_conditionsétend le tableau$(3, N)$ en$(3, N + 2 \cdot n_{\text{ghost}})$ . -
euler1d/schemes/base.py: classe abstraiteNumericalScheme(§3.5). Définit l'interface de composition reconstruction + flux, avec les propriétésorder,n_ghost,time_integral_included,default_time_integrator. -
euler1d/schemes/__init__.py: registre de schémas (§3.7). La fonctionget_scheme(name)instancie n'importe quel schéma par son nom, etavailable_schemes()retourne la liste complète.
- [Toro, 2009] E.F. Toro, Riemann Solvers and Numerical Methods for Fluid Dynamics, 3e éd., Springer. Chapitre 6 : « The Method of Godunov for Non-linear Systems ».
- [LeVeque, 2002] R.J. LeVeque, Finite Volume Methods for Hyperbolic Problems, Cambridge University Press. Chapitre 4 : « Finite Volume Methods ».