///|
/// Piecewise-constant cell averages integrate a discontinuity even inside a cell.
pub fn Gas::shock_tube(
self : Gas,
mesh : Mesh,
left : Primitive,
right : Primitive,
interface_at : Double,
) -> Array[Conserved] raise GasError {
if !finite(interface_at) ||
interface_at < mesh.left ||
interface_at > mesh.right {
raise Invalid("interface must lie within mesh")
}
let ul = self.conserved(left)
let ur = self.conserved(right)
let states = []
for i in 0.. Array[Primitive] raise GasError {
let result = []
for i in 0.. Array[Conserved] raise GasError {
Array::make(mesh.cells, self.conserved(state))
}
///|
/// A periodic smooth entropy wave: constant pressure and velocity, varying density.
/// Integral cell averages use analytic averaging of the sinusoid.
pub fn Gas::entropy_wave(
self : Gas,
mesh : Mesh,
mean_density : Double,
amplitude : Double,
velocity : Double,
pressure : Double,
phase : Double,
) -> Array[Conserved] raise GasError {
let base = Primitive::new(mean_density, velocity, pressure)
ignore(self.conserved(base))
if !finite(amplitude) || amplitude.abs() >= mean_density || !finite(phase) {
raise Invalid("wave amplitude must be finite and smaller than mean density")
}
let k = 2.0 * @math.PI / (mesh.right - mesh.left)
let result = []
for i in 0.. (Primitive, Primitive) {
match self {
Sod =>
(
{ rho: 1.0, velocity: 0.0, pressure: 1.0, },
{ rho: 0.125, velocity: 0.0, pressure: 0.1, },
)
Lax =>
(
{ rho: 0.445, velocity: 0.698, pressure: 3.528, },
{ rho: 0.5, velocity: 0.0, pressure: 0.571, },
)
Contact =>
(
{ rho: 1.0, velocity: 0.5, pressure: 1.0, },
{ rho: 0.5, velocity: 0.5, pressure: 1.0, },
)
}
}
///|
pub extend TubeCase with @debug.Debug::{to_repr}
///|
pub extend TubeCase with Eq::{equal, not_equal}