embedded3: study knobs — aperture_substeps (space-time sub-sampling), momentum_volume_cell_mean, RTX_E3_MERGE_FRACTION; all default off (refuted as the fresh-row residual's source)
CI / Test (ubuntu-latest) (push) Blocked by required conditions
CI / Python Bindings (maturin) (macos-latest) (push) Blocked by required conditions
CI / Build (macos-latest) (push) Waiting to run
CI / Test (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 / Build (ubuntu-latest) (push) Failing after 4s
Documentation / Build User Guide (push) Successful in 4s
CI / Build CPU-Only (Explicit) (push) Failing after 3s
Documentation / Build API Documentation (push) Failing after 4s
CI / Format Check (push) Failing after 14s
CI / Clippy Check (push) Failing after 48s
Performance Benchmarks / Run Benchmarks (push) Successful in 1m52s

Co-Authored-By: Claude Fable 5.1 <[email protected]>
This commit is contained in:
Omar Sobh
2026-09-17 21:38:46 -05:00
co-authored by Claude Fable 5.1
parent 33de5d0080
commit c713bbbbb2
5 changed files with 87 additions and 9 deletions
@@ -213,7 +213,13 @@ impl Solver {
let a_w =
(cv.wall[0] * cv.wall[0] + cv.wall[1] * cv.wall[1] + cv.wall[2] * cv.wall[2]).sqrt();
let shear = mu * a_w / cv.distance;
let v_eff = cv.alpha.max(INERTIA_FLOOR) * h[c] * area[c];
let fraction = if self.params.momentum_volume_cell_mean {
let vol = |q: [i64; 3]| lat.cell(q).map_or(cv.alpha, |ci| mask.vol(ci));
0.5 * (vol(cell_minus) + vol(cell_plus))
} else {
cv.alpha
};
let v_eff = fraction.max(INERTIA_FLOOR) * h[c] * area[c];
let inertia = rho * v_eff / dt;
(inertia * u0 - conv + diff + pressure + source + shear * ub) / (inertia + shear)
}
@@ -12,6 +12,7 @@ mod projection;
use super::Grid;
use super::body::Body;
use super::cut::CutGeometry;
use super::field::Field;
use super::poisson::{PcgCache, Problem, solve_pcg_cached};
use super::wall::{FaceKind, Mask, WallScheme};
@@ -79,6 +80,16 @@ pub struct Parameters {
/// (identical results; the far corners keep their sign). `None` =
/// every corner every step.
pub max_surface_speed: Option<f64>,
/// Intermediate geometries per step for the space-time apertures
/// (0 = the trapezoid of the two end points).
pub aperture_substeps: usize,
/// The cut predictor's momentum volume per unit `h A`: the face's own
/// aperture (the registered design, `false`) or the mean fluid
/// fraction of the two cells the face separates (`true`: the control
/// volume's actual fluid content — a fresh face then carries the
/// inertia of the fluid half of its volume instead of a tenth of a
/// cell against O(1) fluxes).
pub momentum_volume_cell_mean: bool,
}
impl Default for Parameters {
@@ -93,6 +104,8 @@ impl Default for Parameters {
inner_stop_factor: 1e-2,
wall_scheme: WallScheme::GhostBinary,
max_surface_speed: None,
aperture_substeps: 0,
momentum_volume_cell_mean: false,
}
}
}
@@ -502,7 +515,32 @@ impl Solver {
let mut new_mask = self.build_mask(body, field.grid, t_new, dt);
if let Some(old_mask) = &self.mask {
fresh_cells = refill_fresh_cells(old_mask, &new_mask, field);
new_mask.set_step_apertures(old_mask);
let n_in = self.params.aperture_substeps;
if n_in == 0 {
new_mask.set_step_apertures(old_mask);
} else {
// The intermediate geometries, each within the band of the
// previous one.
let g = field.grid;
let h = g.dx.min(g.dy).min(g.dz);
let t_old = t_new - dt;
let mut inner: Vec<CutGeometry> = Vec::with_capacity(n_in);
for m in 1..=n_in {
let tm = t_old + dt * m as f64 / (n_in + 1) as f64;
let prev: Option<(&CutGeometry, f64, f64)> = match (
self.params.max_surface_speed,
inner.last().or(old_mask.cut()),
) {
(Some(speed), Some(c)) => {
Some((c, 3.0 * h, speed * dt / (n_in + 1) as f64))
}
_ => None,
};
inner.push(CutGeometry::build_from(body, g, tm, prev));
}
let refs: Vec<&CutGeometry> = inner.iter().collect();
new_mask.set_step_apertures_with(old_mask, &refs);
}
}
new_mask.impose_from(
body,