embedded3 S2-5: the cut wall sat ½(1−α)h inside the body — cross diffusion over the open-part centroid spacing (RTX_E3_DIFFUSION_CENTROID; host + e3_cut.cu, shift tables, point-implicit excess); flat-wall effective-position instrument; DFG 2D-1 ladder tests (device + host); knobs tried and refuted along the way (oblique distance, axis exchange, centroid pressure gradient)
Documentation / Build API Documentation (push) Failing after 4s
Documentation / Build User Guide (push) Successful in 4s
CI / Clippy Check (push) Failing after 2m24s
CI / Build CPU-Only (Explicit) (push) Failing after 3s
CI / Format Check (push) Failing after 11s
CI / Build (ubuntu-latest) (push) Failing after 1m58s
Performance Benchmarks / Run Benchmarks (push) Successful in 2m44s
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
Documentation / Build API Documentation (push) Failing after 4s
Documentation / Build User Guide (push) Successful in 4s
CI / Clippy Check (push) Failing after 2m24s
CI / Build CPU-Only (Explicit) (push) Failing after 3s
CI / Format Check (push) Failing after 11s
CI / Build (ubuntu-latest) (push) Failing after 1m58s
Performance Benchmarks / Run Benchmarks (push) Successful in 2m44s
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:
co-authored by
Claude Fable 5.1
parent
4c3e58fa27
commit
fdfb6da769
@@ -210,6 +210,11 @@ impl Mask {
|
||||
scheme: crate::solvers::incompressible::ConvectionScheme::Upwind,
|
||||
density: 1.0,
|
||||
wall_order: 1,
|
||||
wall_distance_oblique: false,
|
||||
wall_exchange_axis: false,
|
||||
grad_weights: None,
|
||||
diffusion_centroid: false,
|
||||
face_shifts: None,
|
||||
};
|
||||
mask.compute_merging(None);
|
||||
Ok(mask)
|
||||
@@ -307,6 +312,94 @@ impl Mask {
|
||||
self.compute_merging(Some(old));
|
||||
}
|
||||
|
||||
/// The shift of a face's open-part centroid from the face centre:
|
||||
/// `½h(1 − α)` along the wall normal's in-plane part, away from the
|
||||
/// body (zero for a full face or without the centroid diffusion). Read
|
||||
/// from the tables of [`Self::compute_face_shifts`].
|
||||
pub(super) fn face_shift(&self, c: usize, p: [i64; 3]) -> [f64; 3] {
|
||||
let (Some(t), Some(f)) = (self.face_shifts.as_ref(), self.lattice().face(c, p)) else {
|
||||
return [0.0; 3];
|
||||
};
|
||||
[t[c][3 * f], t[c][3 * f + 1], t[c][3 * f + 2]]
|
||||
}
|
||||
|
||||
/// The per-face shift tables (three components interleaved).
|
||||
#[must_use]
|
||||
pub fn face_shift_tables(&self) -> Option<&[Vec<f64>; 3]> {
|
||||
self.face_shifts.as_ref()
|
||||
}
|
||||
|
||||
/// Build the open-part centroid shifts of every cut face (S2-5).
|
||||
pub fn compute_face_shifts(&mut self) {
|
||||
let g = self.grid;
|
||||
let h = [g.dx, g.dy, g.dz];
|
||||
let lat = self.lattice();
|
||||
let sizes = [g.n_ufaces(), g.n_vfaces(), g.n_wfaces()];
|
||||
let mut tables = [
|
||||
vec![0.0; 3 * sizes[0]],
|
||||
vec![0.0; 3 * sizes[1]],
|
||||
vec![0.0; 3 * sizes[2]],
|
||||
];
|
||||
for c in 0..3 {
|
||||
let (ni, nj, nk) = (
|
||||
g.nx + usize::from(c == 0),
|
||||
g.ny + usize::from(c == 1),
|
||||
g.nz + usize::from(c == 2),
|
||||
);
|
||||
for k in 0..nk {
|
||||
for j in 0..nj {
|
||||
for i in 0..ni {
|
||||
let p = [i as i64, j as i64, k as i64];
|
||||
let Some(f) = lat.face(c, p) else { continue };
|
||||
let Some(alpha) = self.aperture(c, p) else {
|
||||
continue;
|
||||
};
|
||||
if alpha <= 0.0 || alpha >= 1.0 {
|
||||
continue;
|
||||
}
|
||||
// Interior faces only (a control volume needs both cells).
|
||||
let on_side = p[c] == 0 || p[c] as usize == [g.nx, g.ny, g.nz][c];
|
||||
if on_side && !(c == 2 && self.periodic_z) {
|
||||
continue;
|
||||
}
|
||||
let cv = self.cv_geometry(c, p);
|
||||
let mut n = cv.wall;
|
||||
n[c] = 0.0;
|
||||
let a = (n[0] * n[0] + n[1] * n[1] + n[2] * n[2]).sqrt();
|
||||
if a == 0.0 {
|
||||
continue;
|
||||
}
|
||||
for d in 0..3 {
|
||||
// `wall` points into the body: the open part lies the other way.
|
||||
tables[c][3 * f + d] = -0.5 * h[d] * (1.0 - alpha) * n[d] / a;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
self.face_shifts = Some(tables);
|
||||
}
|
||||
|
||||
/// The distance over which a fluid face exchanges momentum with a solid
|
||||
/// neighbour face along `d`: the full spacing, or (S2-5) the axis
|
||||
/// distance from the open part's centroid to the wall, `min(h, d_f/|n_d|)`.
|
||||
pub(super) fn exchange_delta(&self, cv: &CvGeometry, d: usize) -> f64 {
|
||||
let h = [self.grid.dx, self.grid.dy, self.grid.dz][d];
|
||||
if !self.wall_exchange_axis {
|
||||
return h;
|
||||
}
|
||||
let a_w =
|
||||
(cv.wall[0] * cv.wall[0] + cv.wall[1] * cv.wall[1] + cv.wall[2] * cv.wall[2]).sqrt();
|
||||
if a_w == 0.0 {
|
||||
return h;
|
||||
}
|
||||
let n_d = cv.wall[d].abs() / a_w;
|
||||
if n_d < 1e-12 {
|
||||
return h;
|
||||
}
|
||||
(cv.distance / n_d).min(h)
|
||||
}
|
||||
|
||||
/// The wall-gradient coefficients of the unknown face of component
|
||||
/// `c` at `p` with control volume `cv`: `u'(0) = c_1 (u_f − U_b) + c_2
|
||||
/// (u_n − U_b)` with `u_n` the face returned (one lattice step away
|
||||
@@ -420,7 +513,21 @@ impl Mask {
|
||||
_ => cut.d_w[f],
|
||||
}
|
||||
});
|
||||
let distance = (phi_face + 0.5 * h[c] * (1.0 - alpha)).max(DISTANCE_FLOOR * h_min);
|
||||
// The open part's centroid sits ½h(1 − α) from the face centre IN THE
|
||||
// FACE PLANE: its wall distance gains that times the wall normal's
|
||||
// in-plane part (1 for a wall parallel to the face normal).
|
||||
let n_t = if self.wall_distance_oblique {
|
||||
let a_w = (wall[0] * wall[0] + wall[1] * wall[1] + wall[2] * wall[2]).sqrt();
|
||||
if a_w > 0.0 {
|
||||
let n_c = wall[c] / a_w;
|
||||
(1.0 - n_c * n_c).max(0.0).sqrt()
|
||||
} else {
|
||||
1.0
|
||||
}
|
||||
} else {
|
||||
1.0
|
||||
};
|
||||
let distance = (phi_face + 0.5 * h[c] * (1.0 - alpha) * n_t).max(DISTANCE_FLOOR * h_min);
|
||||
CvGeometry {
|
||||
alpha,
|
||||
ap,
|
||||
@@ -670,6 +777,10 @@ impl Mask {
|
||||
}
|
||||
}
|
||||
}
|
||||
let gw = self.gradient_weight_force(&f.p, Some((k0, k1)));
|
||||
for c in 0..3 {
|
||||
pressure[c] += gw[c];
|
||||
}
|
||||
let lat = self.lattice();
|
||||
let values: [&[f64]; 3] = [&f.u, &f.v, &f.w];
|
||||
let w_range = if self.periodic_z { 0..nz } else { 1..nz };
|
||||
|
||||
Reference in New Issue
Block a user