rtx-cfd 3D Stage 1 item 4: three_d::{FlowField3D, piso_host::Piso3Solver} — the 2D embedded predictor/projection transcribed with the z terms appended (u/v/w predictors, six sides incl. periodic z, TVD, the apertured-ready projection on PoissonProblem3D); gates 4/5/6 HELD: MMS + Poiseuille marches value-identical to the 2D embedded solver (multigrid) over 200 steps at nz=1; 3D MMS orders 0.88 upwind / 1.61 TVD, div 1e-9; Beltrami orders 1.08/1.25 with face-averaged data (box compatible to 1e-12); Poiseuille |u−û| ≤ 2e-10, |v|,|w| ≤ 4e-10, p spread ≤ 5e-8 at nz 1 and periodic nz 4
CI / Build (macos-latest) (push) Waiting to run
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
CI / Format Check (push) Failing after 5s
CI / Clippy Check (push) Failing after 4s
CI / Build (ubuntu-latest) (push) Failing after 4s
Performance Benchmarks / Run Benchmarks (push) Failing after 5s
Documentation / Build User Guide (push) Successful in 9s
CI / Build CPU-Only (Explicit) (push) Failing after 1m36s
Documentation / Build API Documentation (push) Failing after 1m41s

Co-Authored-By: Claude Fable 5.1 <[email protected]>
This commit is contained in:
Omar Sobh
2026-09-17 11:31:30 -05:00
co-authored by Claude Fable 5.1
parent 2f476a38d5
commit 616d2a3394
6 changed files with 2326 additions and 0 deletions
@@ -0,0 +1,98 @@
//! The 3D staggered field: u on `(nx + 1) × ny × nz` faces, v on
//! `nx × (ny + 1) × nz`, w on `nx × ny × (nz + 1)`, p on the cells; flat
//! storage (see [`super::Grid3`] for the index conventions).
use super::Grid3;
#[derive(Debug, Clone)]
pub struct FlowField3D {
pub grid: Grid3,
pub u: Vec<f64>,
pub v: Vec<f64>,
pub w: Vec<f64>,
pub p: Vec<f64>,
pub u_old: Vec<f64>,
pub v_old: Vec<f64>,
pub w_old: Vec<f64>,
pub u_star: Vec<f64>,
pub v_star: Vec<f64>,
pub w_star: Vec<f64>,
pub p_prime: Vec<f64>,
/// The continuity source of the projection.
pub sp: Vec<f64>,
}
impl FlowField3D {
#[must_use]
pub fn new(grid: Grid3) -> Self {
let nu = (grid.nx + 1) * grid.ny * grid.nz;
let nv = grid.nx * (grid.ny + 1) * grid.nz;
let nw = grid.nx * grid.ny * (grid.nz + 1);
let nc = grid.cells();
Self {
grid,
u: vec![0.0; nu],
v: vec![0.0; nv],
w: vec![0.0; nw],
p: vec![0.0; nc],
u_old: vec![0.0; nu],
v_old: vec![0.0; nv],
w_old: vec![0.0; nw],
u_star: vec![0.0; nu],
v_star: vec![0.0; nv],
w_star: vec![0.0; nw],
p_prime: vec![0.0; nc],
sp: vec![0.0; nc],
}
}
pub fn update_old_values(&mut self) {
self.u_old.copy_from_slice(&self.u);
self.v_old.copy_from_slice(&self.v);
self.w_old.copy_from_slice(&self.w);
}
pub fn copy_to_starred(&mut self) {
self.u_star.copy_from_slice(&self.u);
self.v_star.copy_from_slice(&self.v);
self.w_star.copy_from_slice(&self.w);
}
/// `max |∇·u|` over the cells (per unit volume).
#[must_use]
pub fn max_divergence(&self) -> f64 {
let g = self.grid;
let mut worst = 0.0_f64;
for k in 0..g.nz {
for j in 0..g.ny {
for i in 0..g.nx {
let div = (self.u[g.uface(k, j, i + 1)] - self.u[g.uface(k, j, i)]) / g.dx
+ (self.v[g.vface(k, j + 1, i)] - self.v[g.vface(k, j, i)]) / g.dy
+ (self.w[g.wface(k + 1, j, i)] - self.w[g.wface(k, j, i)]) / g.dz;
worst = worst.max(div.abs());
}
}
}
worst
}
/// Kinetic energy `½ Σ (u² + v² + w²) dV` over the cells (face values
/// averaged to the cell).
#[must_use]
pub fn kinetic_energy(&self, rho: f64) -> f64 {
let g = self.grid;
let dv = g.dx * g.dy * g.dz;
let mut e = 0.0;
for k in 0..g.nz {
for j in 0..g.ny {
for i in 0..g.nx {
let uc = 0.5 * (self.u[g.uface(k, j, i)] + self.u[g.uface(k, j, i + 1)]);
let vc = 0.5 * (self.v[g.vface(k, j, i)] + self.v[g.vface(k, j + 1, i)]);
let wc = 0.5 * (self.w[g.wface(k, j, i)] + self.w[g.wface(k + 1, j, i)]);
e += 0.5 * rho * (uc * uc + vc * vc + wc * wc) * dv;
}
}
}
e
}
}
@@ -7,8 +7,15 @@
//!
//! Layout: cells are `(k, j, i)` row-major, `cell = (k * ny + j) * nx + i`.
pub mod flow_field;
pub mod piso_host;
pub mod poisson;
pub use flow_field::FlowField3D;
pub use piso_host::{
Boundaries3, Fluid3, Piso3Parameters, Piso3Result, Piso3Solver, SideBoundary3,
};
/// A uniform Cartesian grid.
#[derive(Debug, Clone, Copy, PartialEq)]
pub struct Grid3 {
File diff suppressed because it is too large Load Diff