embedded3 A1-b: the tiled momentum volume as a host prototype (RTX_E3_MOMENTUM_VOLUME=tiled; pressure force, source and inertia on ½(V−+V+)hA; default off; the device refuses it) — REFUTED on the oblique instrument (level moves, the h-independent remainder and the near-wall pressure residual do not)
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
Performance Benchmarks / Run Benchmarks (push) Failing after 5s
Documentation / Build User Guide (push) Successful in 7s
CI / Build CPU-Only (Explicit) (push) Failing after 1m9s
Documentation / Build API Documentation (push) Failing after 1m12s
CI / Build (macos-latest) (push) Waiting to run
CI / Clippy Check (push) Failing after 4s
CI / Build (ubuntu-latest) (push) Failing after 4s
CI / Format Check (push) Failing after 5s

Co-Authored-By: Claude Fable 5.1 <[email protected]>
This commit is contained in:
Omar Sobh
2026-09-19 20:38:29 -05:00
co-authored by Claude Fable 5.1
parent b126915759
commit 0cf9d20afb
3 changed files with 31 additions and 5 deletions
@@ -344,8 +344,20 @@ impl Solver {
let p_plus = lat.cell(cell_plus).map_or(0.0, |ci| field.p[ci]); let p_plus = lat.cell(cell_plus).map_or(0.0, |ci| field.p[ci]);
let p_minus = lat.cell(cell_minus).map_or(0.0, |ci| field.p[ci]); let p_minus = lat.cell(cell_minus).map_or(0.0, |ci| field.p[ci]);
let idx_f = lat.face(c, p).expect("the face"); let idx_f = lat.face(c, p).expect("the face");
let pressure = -(p_plus - p_minus) * cv.alpha * area[c] * mask.grad_weight(c, idx_f); // A1-b: the control volume the pressure force, the source and the
let v_u = cv.alpha * h[c] * area[c]; // inertia act on — the aperture prism (default) or the tiled
// half-cells `½(V_ + V_+)` the convective / diffusive sides use.
let 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))
};
let alpha_p = if self.params.momentum_volume_tiled {
cell_mean()
} else {
cv.alpha
};
let pressure = -(p_plus - p_minus) * alpha_p * area[c] * mask.grad_weight(c, idx_f);
let v_u = alpha_p * h[c] * area[c];
let source = self.momentum_source.as_ref().map_or(0.0, |f| { let source = self.momentum_source.as_ref().map_or(0.0, |f| {
let s = f(x[0], x[1], x[2], t_old); let s = f(x[0], x[1], x[2], t_old);
[s.0, s.1, s.2][c] * v_u [s.0, s.1, s.2][c] * v_u
@@ -361,9 +373,9 @@ impl Solver {
let shear = mu * a_w * c1; let shear = mu * a_w * c1;
// The explicit part of the quadratic wall gradient (order 2). // The explicit part of the quadratic wall gradient (order 2).
let shear_explicit = nb.map_or(0.0, |f| mu * a_w * c2 * (old[c][f] - ub)); let shear_explicit = nb.map_or(0.0, |f| mu * a_w * c2 * (old[c][f] - ub));
let fraction = if self.params.momentum_volume_cell_mean { let fraction = if self.params.momentum_volume_cell_mean || self.params.momentum_volume_tiled
let vol = |q: [i64; 3]| lat.cell(q).map_or(cv.alpha, |ci| mask.vol(ci)); {
0.5 * (vol(cell_minus) + vol(cell_plus)) cell_mean()
} else { } else {
cv.alpha cv.alpha
}; };
@@ -169,6 +169,10 @@ impl DeviceStep {
!solver.params.pressure_centroid, !solver.params.pressure_centroid,
"the centroid pressure gradient (S2-5) is a host prototype: the device kernels do not carry it" "the centroid pressure gradient (S2-5) is a host prototype: the device kernels do not carry it"
); );
assert!(
!solver.params.momentum_volume_tiled,
"the tiled momentum volume (A1-b) is a host prototype: the device kernels do not carry it"
);
let rt = runtime(); let rt = runtime();
let nu = (grid.nx + 1) * grid.ny * grid.nz; let nu = (grid.nx + 1) * grid.ny * grid.nz;
let nv = grid.nx * (grid.ny + 1) * grid.nz; let nv = grid.nx * (grid.ny + 1) * grid.nz;
@@ -139,6 +139,14 @@ pub struct Parameters {
/// correction and the predictor's pressure force. The device path /// correction and the predictor's pressure force. The device path
/// refuses it. `RTX_E3_PRESSURE_CENTROID=1`. /// refuses it. `RTX_E3_PRESSURE_CENTROID=1`.
pub pressure_centroid: bool, pub pressure_centroid: bool,
/// HOST PROTOTYPE (A1-b, 2026-09-19): the pressure force, the momentum
/// source and the inertia of a face's control volume taken on the
/// TILED volume `½(V_ + V_+) h A` (the cell means the convective and
/// diffusive sides already use) instead of the aperture prism
/// `α h A`. On an oblique cut the two differ by O(1) in the cut
/// layer — the sharpened S2-7 hypothesis. The device path refuses it.
/// `RTX_E3_MOMENTUM_VOLUME=tiled`.
pub momentum_volume_tiled: bool,
/// S2-5: the cross-direction diffusion between two faces over the /// S2-5: the cross-direction diffusion between two faces over the
/// distance between their OPEN-PART CENTROIDS (a cut face's velocity /// distance between their OPEN-PART CENTROIDS (a cut face's velocity
/// is its open part's mean, ½h(1 α) off the face centre along the /// is its open part's mean, ½h(1 α) off the face centre along the
@@ -181,6 +189,8 @@ impl Default for Parameters {
.is_ok_and(|v| v == "off"), .is_ok_and(|v| v == "off"),
wall_exchange_axis: std::env::var("RTX_E3_WALL_EXCHANGE").is_ok_and(|v| v == "axis"), wall_exchange_axis: std::env::var("RTX_E3_WALL_EXCHANGE").is_ok_and(|v| v == "axis"),
pressure_centroid: std::env::var("RTX_E3_PRESSURE_CENTROID").is_ok_and(|v| v == "1"), pressure_centroid: std::env::var("RTX_E3_PRESSURE_CENTROID").is_ok_and(|v| v == "1"),
momentum_volume_tiled: std::env::var("RTX_E3_MOMENTUM_VOLUME")
.is_ok_and(|v| v == "tiled"),
// ON by default since S2-5 (`=0` reproduces the records before it). // ON by default since S2-5 (`=0` reproduces the records before it).
diffusion_centroid: std::env::var("RTX_E3_DIFFUSION_CENTROID") diffusion_centroid: std::env::var("RTX_E3_DIFFUSION_CENTROID")
.map_or(true, |v| v != "0"), .map_or(true, |v| v != "0"),