use crate::moment::{
Moments2d, Moments3d, moments_d2q9, moments_d3q27, reconstruct_d2q9, reconstruct_d3q27,
};
#[derive(Debug, Clone, Copy, Default)]
pub struct Residual {
pub rho: f64,
pub u: f64,
pub s: f64,
}
impl Residual {
pub fn max(&self) -> f64 {
self.rho.max(self.u).max(self.s)
}
pub fn within(&self, tol: f64) -> bool {
self.max() <= tol
}
}
pub fn round_trip_d2q9(m: &Moments2d) -> Residual {
let back = moments_d2q9(&reconstruct_d2q9(m));
Residual {
rho: (back.rho - m.rho).abs(),
u: (0..2)
.map(|i| (back.u[i] - m.u[i]).abs())
.fold(0.0, f64::max),
s: (0..3)
.map(|i| (back.s[i] - m.s[i]).abs())
.fold(0.0, f64::max),
}
}
pub fn round_trip_d3q27(m: &Moments3d) -> Residual {
let back = moments_d3q27(&reconstruct_d3q27(m));
Residual {
rho: (back.rho - m.rho).abs(),
u: (0..3)
.map(|i| (back.u[i] - m.u[i]).abs())
.fold(0.0, f64::max),
s: (0..6)
.map(|i| (back.s[i] - m.s[i]).abs())
.fold(0.0, f64::max),
}
}
pub fn sample_states_2d() -> Vec<Moments2d> {
let mut v = Vec::new();
for &rho in &[1.0f64, 0.85, 1.2] {
for &(ux, uy) in &[(0.0, 0.0), (0.05, -0.03), (-0.08, 0.06), (0.1, 0.1)] {
for &k in &[0.0f64, 1e-4, 1e-3, 5e-3] {
v.push(Moments2d {
rho,
u: [ux, uy],
s: [ux * ux + k, uy * uy - 0.6 * k, ux * uy + 0.5 * k],
});
}
}
}
v
}
pub fn sample_states_3d() -> Vec<Moments3d> {
let mut v = Vec::new();
for &rho in &[1.0f64, 0.9, 1.15] {
for &(ux, uy, uz) in &[
(0.0, 0.0, 0.0),
(0.05, -0.03, 0.02),
(-0.07, 0.04, -0.06),
(0.09, 0.09, -0.09),
] {
for &k in &[0.0f64, 1e-4, 1e-3, 5e-3] {
v.push(Moments3d {
rho,
u: [ux, uy, uz],
s: [
ux * ux + k,
uy * uy - 0.6 * k,
uz * uz - 0.4 * k,
ux * uy + 0.5 * k,
ux * uz - 0.2 * k,
uy * uz + 0.3 * k,
],
});
}
}
}
v
}