Files
rustytorch/crates/specialized/rtx-cfd/tests/embedded3_density_scaling.rs
T
Omar SobhandClaude Fable 5.1 f6add276c0
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 / Build (macos-latest) (push) Waiting to run
CI / Test (macos-latest) (push) Blocked by required conditions
CI / Build CPU-Only (Explicit) (push) Failing after 3s
Documentation / Build API Documentation (push) Failing after 4s
CI / Build (ubuntu-latest) (push) Failing after 4s
Documentation / Build User Guide (push) Successful in 4s
CI / Format Check (push) Failing after 10s
CI / Clippy Check (push) Failing after 35s
Performance Benchmarks / Run Benchmarks (push) Successful in 1m32s
embedded3: cut predictor convection carries ρ (host + e3_cut.cu; density-scaling pin); operator load route includes the wall exchange (exchange.rs); reconstructed_parts, probe aperture floor knob; dfg_split diagnostic test
Co-Authored-By: Claude Fable 5.1 <[email protected]>
2026-09-18 03:59:57 -05:00

102 lines
3.1 KiB
Rust
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
//! Density-scaling pin for the cut-cell predictor (host): the same flow at
//! `ρ` and `1000 ρ` with `μ` scaled alike is the same velocity field and a
//! pressure scaled by 1000 — every term of the momentum equation carries
//! `ρ` (the convection term used to be a bare volume flux times velocity,
//! which starved every ρ = 1000 cut-cell run of convection).
use rtx_cfd::solvers::incompressible::ConvectionScheme;
use rtx_cfd::solvers::incompressible::embedded3::{
Body, Boundaries, Field, Fluid, Grid, Parameters, Side, Solver, WallScheme,
};
fn run(rho: f64, moving: bool) -> Field {
let n = 16;
let h = 1.0 / n as f64;
let g = Grid::cubic(2 * n, n, n, h);
let nu = 1e-2;
let mut solver = Solver::new(
Fluid {
density: rho,
viscosity: rho * nu,
reference_velocity: 1.0,
reference_length: 0.3,
},
Parameters {
corrector_steps: 2,
tolerance: 1e-11,
convection_scheme: ConvectionScheme::TvdVanAlbada,
wall_scheme: WallScheme::CutCell,
boundaries: Boundaries {
x1: Side::PressureOutlet,
..Boundaries::default()
},
max_surface_speed: if moving { Some(0.5) } else { None },
..Parameters::default()
},
);
solver.set_boundary_velocity(|x, _, _, _| {
if x <= 0.0 {
(1.0, 0.0, 0.0)
} else {
(0.0, 0.0, 0.0)
}
});
let xc = move |t: f64| 0.7 + if moving { 0.1 * (3.0 * t).sin() } else { 0.0 };
let body = Body::from_sdf(move |x, y, z, t| {
((x - xc(t)).powi(2) + (y - 0.5_f64).powi(2) + (z - 0.5_f64).powi(2)).sqrt() - 0.15
})
.with_surface_velocity(move |_, _, _, t| {
(if moving { 0.3 * (3.0 * t).cos() } else { 0.0 }, 0.0, 0.0)
});
if moving {
solver.set_moving_body(body);
} else {
solver.set_body(body);
}
let mut field = Field::new(g);
for k in 0..n {
for j in 0..n {
for i in 0..=2 * n {
field.u[g.uface(k, j, i)] = 1.0;
}
}
}
solver.initialize(&mut field);
let dt = 0.2 * h;
for _ in 0..40 {
solver.advance(&mut field, dt);
}
field
}
fn compare(moving: bool) {
let a = run(1.0, moving);
let b = run(1000.0, moving);
let max = |x: &[f64], y: &[f64], s: f64| {
x.iter()
.zip(y)
.map(|(p, q)| (p - q / s).abs())
.fold(0.0, f64::max)
};
let du = max(&a.u, &b.u, 1.0)
.max(max(&a.v, &b.v, 1.0))
.max(max(&a.w, &b.w, 1.0));
let dp = max(&a.p, &b.p, 1000.0);
let pscale = a.p.iter().fold(0.0f64, |m, p| m.max(p.abs()));
println!(" moving {moving}: max |Δu| {du:.3e}, max |Δp/1000| {dp:.3e} (p scale {pscale:.3e})");
assert!(du < 1e-9, "velocity is not density-invariant: {du:.3e}");
assert!(
dp < 1e-9 * pscale.max(1.0),
"pressure does not scale with density: {dp:.3e}"
);
}
#[test]
fn cut_cell_flow_is_density_invariant_at_rest() {
compare(false);
}
#[test]
fn cut_cell_flow_is_density_invariant_moving() {
compare(true);
}