75 lines
2.7 KiB
Python
75 lines
2.7 KiB
Python
# tests/test_riemann.py
|
|
import numpy as np
|
|
from riemann import hll_flux
|
|
|
|
|
|
GAMMA = 1.4
|
|
|
|
|
|
def _to_conservative(rho, u, P, gamma):
|
|
"""(rho, u, P) -> [rho, rho*u, rho*E] where E = e + u^2/2."""
|
|
return np.array([
|
|
rho,
|
|
rho * u,
|
|
P / (gamma - 1) + 0.5 * rho * u ** 2,
|
|
])
|
|
|
|
|
|
def _physical_flux(W, gamma):
|
|
"""F(W) = [rho*u, rho*u^2 + P, u*(rho*E + P)]."""
|
|
rho = W[0]
|
|
u = W[1] / rho
|
|
E = W[2]
|
|
P = (gamma - 1) * (E - 0.5 * rho * u ** 2)
|
|
return np.array([rho * u, rho * u ** 2 + P, u * (E + P)])
|
|
|
|
|
|
def test_hll_identical_states_returns_physical_flux():
|
|
"""
|
|
When W_L == W_R, HLL must return the exact physical flux F(W)
|
|
with zero numerical dissipation (the (W_R - W_L) term vanishes).
|
|
"""
|
|
W = _to_conservative(rho=1.2, u=50.0, P=2.5e5, gamma=GAMMA)
|
|
F = hll_flux(W, W, GAMMA)
|
|
expected = _physical_flux(W, GAMMA)
|
|
assert np.allclose(F, expected, rtol=1e-12), f"F={F}, expected={expected}"
|
|
|
|
|
|
def test_hll_equal_pressure_equal_energy_gives_exact_pressure_flux():
|
|
"""
|
|
Two stationary states (u=0) with same P but different rho:
|
|
- Both have the same energy density E = P/(gamma-1), so the HLL
|
|
(W_R - W_L)[2] term vanishes -> exact zero energy flux.
|
|
- F_L[1] = F_R[1] = P, and W_L[1] = W_R[1] = 0, so the momentum
|
|
flux is exactly P.
|
|
- The mass flux is NOT exactly zero for HLL (the density jump
|
|
triggers the (W_R - W_L)[0] dissipation term) — this is a known
|
|
HLL limitation for stationary contact discontinuities. We do
|
|
not assert on F[0] here.
|
|
"""
|
|
W_L = _to_conservative(rho=10.0, u=0.0, P=1e5, gamma=GAMMA)
|
|
W_R = _to_conservative(rho=1.0, u=0.0, P=1e5, gamma=GAMMA)
|
|
F = hll_flux(W_L, W_R, GAMMA)
|
|
assert abs(F[1] - 1e5) < 1e-6, f"momentum flux should equal P=1e5, got {F[1]}"
|
|
assert abs(F[2]) < 1e-8, f"energy flux should be exactly 0, got {F[2]}"
|
|
|
|
|
|
def test_hll_sod_shock_tube_directional_fluxes_all_positive():
|
|
"""
|
|
Classical Sod initial values:
|
|
left: (rho, u, P) = (1.0, 0, 1.0)
|
|
right: (rho, u, P) = (0.125, 0, 0.1)
|
|
The pressure gradient drives flow from left to right, so the
|
|
HLL flux at the interface should have all three components
|
|
strictly positive:
|
|
F[0] > 0 : mass flux rightward
|
|
F[1] > 0 : momentum flux rightward
|
|
F[2] > 0 : energy flux rightward
|
|
"""
|
|
W_L = _to_conservative(rho=1.0, u=0.0, P=1.0, gamma=GAMMA)
|
|
W_R = _to_conservative(rho=0.125, u=0.0, P=0.1, gamma=GAMMA)
|
|
F = hll_flux(W_L, W_R, GAMMA)
|
|
assert F[0] > 0, f"expected positive mass flux, got {F[0]}"
|
|
assert F[1] > 0, f"expected positive momentum flux, got {F[1]}"
|
|
assert F[2] > 0, f"expected positive energy flux, got {F[2]}"
|