embedded3 S2-7b instruments: the quadratic / full-cells-only pressure probe (Mask::pressure_at_quadratic[_from]) and the DFG 2D-1 test's RTX_E3_DFG_DP_PROBE line; the manufactured sphere's pressure-error read by cell class + six signed wall-point reads, RTX_E3_MMS_SCHEME=tvd, the cut_cell_pressure_ladder and sphere_operator_probe tests (defaults untouched; MMS gates green)
CI / Format Check (push) Failing after 4s
Performance Benchmarks / Run Benchmarks (push) Failing after 5s
CI / Clippy Check (push) Failing after 4s
CI / Build (ubuntu-latest) (push) Failing after 4s
Documentation / Build User Guide (push) Successful in 7s
CI / Build CPU-Only (Explicit) (push) Failing after 58s
Documentation / Build API Documentation (push) Failing after 1m0s
CI / Build (macos-latest) (push) Canceled after 0s
CI / Test (macos-latest) (push) Canceled after 0s
CI / Test (ubuntu-latest) (push) Canceled after 0s
CI / Python Bindings (maturin) (macos-latest) (push) Canceled after 0s
CI / Python Bindings (maturin) (ubuntu-latest) (push) Canceled after 0s
CI / WASM Build + Size Check (push) Canceled after 0s
CI / Distributed Training Tests (push) Canceled after 0s
CI / CI Success (push) Canceled after 0s

Co-Authored-By: Claude Fable 5.1 <[email protected]>
This commit is contained in:
Omar Sobh
2026-09-20 07:34:40 -05:00
co-authored by Claude Fable 5.1
parent 44ecc164f1
commit c430510802
4 changed files with 421 additions and 2 deletions
@@ -124,6 +124,87 @@ impl Mask {
linear_fit(&pts, (x, y, z))
}
/// S2-7b: pressure at a point by a QUADRATIC least-squares fit (six
/// coefficients in the plane) through the fluid, unmerged cells whose
/// centres lie within `radius` of the point on the plane nearest `z`;
/// `None` with fewer than eight cells or a singular normal matrix.
pub fn pressure_at_quadratic(&self, p: &[f64], x: f64, y: f64, z: f64, radius: f64) -> Option<f64> {
self.pressure_at_quadratic_from(p, x, y, z, radius, false)
}
/// The quadratic fit through FULL fluid cells only (`full_only`): the
/// cut cells' pressures left out of the read (S2-7b's discriminator).
pub fn pressure_at_quadratic_from(
&self,
p: &[f64],
x: f64,
y: f64,
z: f64,
radius: f64,
full_only: bool,
) -> Option<f64> {
let g = self.grid();
let (nx, ny, nz, dx, dy, dz) = (g.nx, g.ny, g.nz, g.dx, g.dy, g.dz);
let k = ((z / dz - 0.5).round().max(0.0) as usize).min(nz - 1);
let usable = |idx: usize| {
self.is_fluid_cell(idx)
&& self.master(idx).is_none()
&& (!full_only || self.vol(idx) >= 1.0 - 1e-9)
};
let (ri, rj) = ((radius / dx).ceil() as i64 + 1, (radius / dy).ceil() as i64 + 1);
let (ic, jc) = ((x / dx - 0.5).round() as i64, (y / dy - 0.5).round() as i64);
// Rows: [1, ξ, η, ξ², ξη, η²] with ξ, η in units of h about the point.
let mut ata = [[0.0f64; 6]; 6];
let mut atb = [0.0f64; 6];
let mut count = 0;
for j in (jc - rj).max(0)..=(jc + rj).min(ny as i64 - 1) {
for i in (ic - ri).max(0)..=(ic + ri).min(nx as i64 - 1) {
let idx = g.cell(k, j as usize, i as usize);
if !usable(idx) {
continue;
}
let (xi, eta) = (((i as f64 + 0.5) * dx - x) / dx, ((j as f64 + 0.5) * dy - y) / dy);
if (xi * dx).powi(2) + (eta * dy).powi(2) > radius * radius {
continue;
}
let row = [1.0, xi, eta, xi * xi, xi * eta, eta * eta];
for a in 0..6 {
for b in 0..6 {
ata[a][b] += row[a] * row[b];
}
atb[a] += row[a] * p[idx];
}
count += 1;
}
}
if count < 8 {
return None;
}
// Gaussian elimination with partial pivoting; the value at the point
// is the constant coefficient.
let mut m = [[0.0f64; 7]; 6];
for a in 0..6 {
m[a][..6].copy_from_slice(&ata[a]);
m[a][6] = atb[a];
}
for c in 0..6 {
let piv = (c..6).max_by(|&a, &b| m[a][c].abs().partial_cmp(&m[b][c].abs()).unwrap())?;
if m[piv][c].abs() < 1e-12 * count as f64 {
return None;
}
m.swap(c, piv);
for r in 0..6 {
if r != c {
let f = m[r][c] / m[c][c];
for cc in c..7 {
m[r][cc] -= f * m[c][cc];
}
}
}
}
Some(m[0][6] / m[0][0])
}
/// Velocity at a point: trilinear over a component's nodes when all are
/// fluid faces, else the fit through the fluid ones and the point's own
/// boundary intercept with its surface velocity.