///|
/// Cell average or integrated flux: density, momentum and total energy.
#derive(Debug, Eq, ToJson, FromJson)
pub(all) struct Conserved {
mass : Double
momentum : Double
energy : Double
}
///|
pub fn Conserved::zero() -> Conserved {
{ mass: 0.0, momentum: 0.0, energy: 0.0, }
}
///|
pub fn Conserved::plus(self : Conserved, other : Conserved) -> Conserved {
{
mass: self.mass + other.mass,
momentum: self.momentum + other.momentum,
energy: self.energy + other.energy,
}
}
///|
pub fn Conserved::minus(self : Conserved, other : Conserved) -> Conserved {
self.plus(other.scaled(-1.0))
}
///|
pub fn Conserved::scaled(self : Conserved, factor : Double) -> Conserved {
{
mass: self.mass * factor,
momentum: self.momentum * factor,
energy: self.energy * factor,
}
}
///|
pub fn Conserved::max_abs(self : Conserved) -> Double {
self.mass.abs().max(self.momentum.abs()).max(self.energy.abs())
}
///|
pub fn Gas::conserved(self : Gas, q : Primitive) -> Conserved raise GasError {
q.validate()
let u = {
mass: q.rho,
momentum: q.rho * q.velocity,
energy: q.pressure / (self.gamma - 1.0) +
0.5 * q.rho * q.velocity * q.velocity,
}
if !finite(u.mass) || !finite(u.momentum) || !finite(u.energy) {
raise Numerical("conservative conversion overflow")
}
u
}
///|
pub fn Gas::primitive(self : Gas, u : Conserved) -> Primitive raise GasError {
if !finite(u.mass) ||
!finite(u.momentum) ||
!finite(u.energy) ||
u.mass <= 0.0 {
raise Invalid("nonfinite conserved state or nonpositive mass")
}
let velocity = u.momentum / u.mass
let pressure = (self.gamma - 1.0) * (u.energy - 0.5 * u.momentum * velocity)
Primitive::new(u.mass, velocity, pressure)
}
///|
pub fn Gas::physical_flux(
self : Gas,
q : Primitive,
) -> Conserved raise GasError {
let u = self.conserved(q)
let f = {
mass: u.momentum,
momentum: u.momentum * q.velocity + q.pressure,
energy: (u.energy + q.pressure) * q.velocity,
}
if !finite(f.mass) || !finite(f.momentum) || !finite(f.energy) {
raise Numerical("flux overflow")
}
f
}
///|
pub fn Gas::max_speed(self : Gas, q : Primitive) -> Double raise GasError {
let speed = q.velocity.abs() + self.sound_speed(q)
if !finite(speed) {
raise Numerical("characteristic speed overflow")
}
speed
}
///|
pub extend Conserved with @debug.Debug::{to_repr}
///|
pub extend Conserved with Eq::{equal, not_equal}
///|
pub extend Conserved with ToJson::{to_json}
///|
pub extend Conserved with @json.FromJson::{from_json}