embedded3 loads: the control-volume route between no-slip z walls carries the walls' shear (control_volume_force_with_walls); the DFG driver uses it
CI / Test (macos-latest) (push) Blocked by required conditions
CI / Test (ubuntu-latest) (push) Blocked by required conditions
CI / Build (macos-latest) (push) Waiting to run
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
Documentation / Build API Documentation (push) Failing after 4s
CI / Format Check (push) Failing after 14s
CI / Build CPU-Only (Explicit) (push) Failing after 4s
Documentation / Build User Guide (push) Successful in 3s
CI / Clippy Check (push) Failing after 1m1s
CI / Build (ubuntu-latest) (push) Failing after 1m56s
Performance Benchmarks / Run Benchmarks (push) Successful in 2m17s

Co-Authored-By: Claude Fable 5.1 <[email protected]>
This commit is contained in:
Omar Sobh
2026-09-17 17:27:19 -05:00
co-authored by Claude Fable 5.1
parent 4fecb3098c
commit 32546b1222
2 changed files with 34 additions and 1 deletions
@@ -252,6 +252,23 @@ impl Mask {
/// `F = Σ_outer (σ·n ρ u (u·n)) A d/dt ∫ ρ u dV + ∫ f dV`.
#[allow(clippy::too_many_arguments)]
pub fn control_volume_force(
&self,
f: &Field,
dt: f64,
rho: f64,
mu: f64,
source: Option<&dyn Fn(f64, f64, f64) -> (f64, f64, f64)>,
bx: (usize, usize, usize, usize, usize, usize),
) -> [f64; 3] {
self.control_volume_force_with_walls(f, dt, rho, mu, source, bx, false)
}
/// Route B on a box spanning the whole z range between NO-SLIP z walls
/// (`no_slip_z`): the walls' shear on the fluid inside the box (against
/// a wall at rest) is an outer-face stress and enters the balance;
/// without it (slip or periodic sides) the z faces carry nothing.
#[allow(clippy::too_many_arguments)]
pub fn control_volume_force_with_walls(
&self,
f: &Field,
dt: f64,
@@ -259,6 +276,7 @@ impl Mask {
mu: f64,
source: Option<&dyn Fn(f64, f64, f64) -> (f64, f64, f64)>,
(i0, i1, j0, j1, k0, k1): (usize, usize, usize, usize, usize, usize),
no_slip_z: bool,
) -> [f64; 3] {
let g = self.grid();
let (nx, ny, nz, dx, dy, dz) = (g.nx, g.ny, g.nz, g.dx, g.dy, g.dz);
@@ -341,6 +359,20 @@ impl Mask {
// z faces on the domain's z sides: no momentum flux and no shear on
// a slip wall, and the two faces cancel on a periodic pair — skipped.
let full_span = k0 == 0 && k1 == nz;
if full_span && no_slip_z {
let a = dx * dy;
for j in j0..j1 {
for i in i0..i1 {
for k in [0, nz - 1] {
if !self.is_fluid_cell(g.cell(k, j, i)) {
continue;
}
force[0] -= mu * uc(k, j, i) / (0.5 * dz) * a;
force[1] -= mu * vc(k, j, i) / (0.5 * dz) * a;
}
}
}
}
for j in (j0..j1).filter(|_| !full_span) {
for i in i0..i1 {
for (k, sign) in [(k1, 1.0), (k0, -1.0)] {
@@ -129,7 +129,8 @@ fn dfg_3d_2z_on_the_device() {
0,
nz,
);
let fcv = mask.control_volume_force(&field, dt, RHO, RHO * NU, None, bx);
let fcv =
mask.control_volume_force_with_walls(&field, dt, RHO, RHO * NU, None, bx, true);
let zc = 0.5 * H;
let p_front = mask
.pressure_at(&field.p, CX - 0.5 * D, CY, zc)