embedded3 item 11: moving bodies (end-of-step mask, fresh-cell refill, space-time cut cell: step-averaged apertures, GCL wall flux, Reynolds-transport momentum), the 3D fresh-cell falsifier (plate / circle / stadium, wall + control-volume routes) and the Lipschitz sweep; ghost wall reproduces the 2D falsifier to the digit; cut wall 5–14× smoother on the circle, gates not met (fresh cell's first step); wall.rs split (impose.rs)
CI / Build (macos-latest) (push) Waiting to run
CI / Test (macos-latest) (push) Blocked by required conditions
CI / Test (ubuntu-latest) (push) Blocked by required conditions
CI / Python Bindings (maturin) (macos-latest) (push) Blocked by required conditions
CI / Python Bindings (maturin) (ubuntu-latest) (push) Blocked by required conditions
CI / WASM Build + Size Check (push) Blocked by required conditions
CI / Distributed Training Tests (push) Blocked by required conditions
CI / CI Success (push) Blocked by required conditions
CI / Clippy Check (push) Failing after 3s
CI / Build (ubuntu-latest) (push) Failing after 4s
CI / Format Check (push) Failing after 4s
Performance Benchmarks / Run Benchmarks (push) Failing after 5s
Documentation / Build User Guide (push) Successful in 6s
CI / Build CPU-Only (Explicit) (push) Failing after 1m6s
Documentation / Build API Documentation (push) Failing after 1m9s
CI / Build (macos-latest) (push) Waiting to run
CI / Test (macos-latest) (push) Blocked by required conditions
CI / Test (ubuntu-latest) (push) Blocked by required conditions
CI / Python Bindings (maturin) (macos-latest) (push) Blocked by required conditions
CI / Python Bindings (maturin) (ubuntu-latest) (push) Blocked by required conditions
CI / WASM Build + Size Check (push) Blocked by required conditions
CI / Distributed Training Tests (push) Blocked by required conditions
CI / CI Success (push) Blocked by required conditions
CI / Clippy Check (push) Failing after 3s
CI / Build (ubuntu-latest) (push) Failing after 4s
CI / Format Check (push) Failing after 4s
Performance Benchmarks / Run Benchmarks (push) Failing after 5s
Documentation / Build User Guide (push) Successful in 6s
CI / Build CPU-Only (Explicit) (push) Failing after 1m6s
Documentation / Build API Documentation (push) Failing after 1m9s
Co-Authored-By: Claude Fable 5.1 <[email protected]>
This commit is contained in:
co-authored by
Claude Fable 5.1
parent
0e4c97ed24
commit
5b1621e6ad
@@ -188,9 +188,34 @@ impl Mask {
|
||||
anchor,
|
||||
fluid_cells,
|
||||
cut: Some(cut),
|
||||
step_apertures: None,
|
||||
step_open: None,
|
||||
})
|
||||
}
|
||||
|
||||
/// Set the step-averaged apertures and the space-time classification
|
||||
/// from the previous mask's geometry.
|
||||
pub fn set_step_apertures(&mut self, old: &Mask) {
|
||||
let (Some(cut), Some(old_cut)) = (self.cut.as_ref(), old.cut.as_ref()) else {
|
||||
return;
|
||||
};
|
||||
let avg = |a: &[f64], b: &[f64]| -> Vec<f64> {
|
||||
a.iter().zip(b).map(|(x, y)| 0.5 * (x + y)).collect()
|
||||
};
|
||||
let au = avg(&cut.a_u, &old_cut.a_u);
|
||||
let av = avg(&cut.a_v, &old_cut.a_v);
|
||||
let aw = avg(&cut.a_w, &old_cut.a_w);
|
||||
let open = |a: &[f64]| -> Vec<bool> { a.iter().map(|&x| x > 0.0).collect() };
|
||||
let active = self
|
||||
.cell_fluid
|
||||
.iter()
|
||||
.zip(&old.cell_fluid)
|
||||
.map(|(&n, &o)| n || o)
|
||||
.collect();
|
||||
self.step_open = Some((open(&au), open(&av), open(&aw), active));
|
||||
self.step_apertures = Some((au, av, aw));
|
||||
}
|
||||
|
||||
pub(super) fn lattice(&self) -> Lattice {
|
||||
Lattice {
|
||||
g: self.grid,
|
||||
@@ -319,6 +344,51 @@ impl Mask {
|
||||
(table, correction)
|
||||
}
|
||||
|
||||
/// The moving rigid body's wall fluxes by the discrete geometric
|
||||
/// conservation law: `(V_c^{n+1} − V_c^n)/dt` per active cell (a dying
|
||||
/// cell's remaining volume leaves through its step-averaged apertures),
|
||||
/// the net (the cut geometry's closure defect) redistributed over the
|
||||
/// wall cells by wall area.
|
||||
pub fn gcl_flux_table(&self, old: &Mask, dt: f64) -> (Vec<f64>, f64) {
|
||||
let mut table = vec![0.0; self.grid.cells()];
|
||||
let (Some(cut), Some(old_cut)) = (self.cut.as_ref(), old.cut.as_ref()) else {
|
||||
return (table, 0.0);
|
||||
};
|
||||
let g = self.grid;
|
||||
let dv = g.dx * g.dy * g.dz;
|
||||
let (mut net, mut area) = (0.0, 0.0);
|
||||
for (idx, entry) in table.iter_mut().enumerate() {
|
||||
if !self.cell_active(idx) {
|
||||
continue;
|
||||
}
|
||||
*entry = (cut.vol[idx] - old_cut.vol[idx]) * dv / dt;
|
||||
net += *entry;
|
||||
let w = cut.wall[idx];
|
||||
area += (w[0] * w[0] + w[1] * w[1] + w[2] * w[2]).sqrt();
|
||||
}
|
||||
if std::env::var_os("RTX_E3_DEBUG").is_some() {
|
||||
let dead = (0..table.len())
|
||||
.filter(|&i| !self.cell_fluid[i] && old.cell_fluid[i])
|
||||
.count();
|
||||
let fresh = (0..table.len())
|
||||
.filter(|&i| self.cell_fluid[i] && !old.cell_fluid[i])
|
||||
.count();
|
||||
let (vn, vn1): (f64, f64) = (old_cut.vol.iter().sum(), cut.vol.iter().sum());
|
||||
eprintln!(
|
||||
" gcl: dead {dead} fresh {fresh} net {net:.3e} area {area:.3e} ΣV old {vn:.6} new {vn1:.6} (Δ {:.3e})",
|
||||
vn1 - vn
|
||||
);
|
||||
}
|
||||
let correction = if area > 0.0 { net / area } else { 0.0 };
|
||||
if correction != 0.0 {
|
||||
for (idx, w) in cut.wall.iter().enumerate() {
|
||||
let a = (w[0] * w[0] + w[1] * w[1] + w[2] * w[2]).sqrt();
|
||||
table[idx] -= correction * a;
|
||||
}
|
||||
}
|
||||
(table, correction)
|
||||
}
|
||||
|
||||
/// The volume flux of the surface velocity through a cell's wall into
|
||||
/// the body, `U_b·W_c`, uncorrected. Zero without a cut geometry.
|
||||
pub fn wall_flux(&self, body: &Body, idx: usize, t: f64) -> f64 {
|
||||
@@ -348,14 +418,27 @@ impl Mask {
|
||||
/// shear `Σ_f μ A_w (u_f − U_b)/d_f` over the unknown faces. `None`
|
||||
/// without a cut geometry.
|
||||
pub fn cut_wall_force(&self, body: &Body, f: &Field, mu: f64, t: f64) -> Option<[f64; 3]> {
|
||||
let (p, s) = self.cut_wall_force_parts(body, f, mu, t)?;
|
||||
Some([p[0] + s[0], p[1] + s[1], p[2] + s[2]])
|
||||
}
|
||||
|
||||
/// The cut-cell load route split into its pressure and shear parts.
|
||||
pub fn cut_wall_force_parts(
|
||||
&self,
|
||||
body: &Body,
|
||||
f: &Field,
|
||||
mu: f64,
|
||||
t: f64,
|
||||
) -> Option<([f64; 3], [f64; 3])> {
|
||||
let cut = self.cut.as_ref()?;
|
||||
let g = self.grid;
|
||||
let (nx, ny, nz) = (g.nx, g.ny, g.nz);
|
||||
let mut pressure = [0.0; 3];
|
||||
let mut force = [0.0; 3];
|
||||
for (idx, w) in cut.wall.iter().enumerate() {
|
||||
if self.cell_fluid[idx] {
|
||||
for c in 0..3 {
|
||||
force[c] += f.p[idx] * w[c];
|
||||
pressure[c] += f.p[idx] * w[c];
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -395,6 +478,6 @@ impl Mask {
|
||||
}
|
||||
}
|
||||
}
|
||||
Some(force)
|
||||
Some((pressure, force))
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user