P5-3 instruments: per-region wall loads on saved instants (top / bottom / tip arc / fillets+cylinder — drag, lift, normal-traction mean/min/max; RTX_FSI2O_AUDIT_FACES, RTX_FSI2O_AUDIT_ONLY) and the patch-thickness knobs (RTX_FSI2O_PATCH_OFFSET / _PATCH_ROWS, RTX_OVERSET_PATCH_OFFSET / _PATCH_ROWS; save tags carry the offset) — the overlap band sat at a fixed number of cells (6 h) and moved inward in metres with refinement
CI / Build (macos-latest) (push) Failing after 9s
Documentation / Build API Documentation (push) Canceled after 0s
Documentation / Build User Guide (push) Canceled after 0s
Performance Benchmarks / Run Benchmarks (push) Canceled after 0s
CI / Format Check (push) Canceled after 0s
CI / Clippy Check (push) Canceled after 0s
CI / Build (ubuntu-latest) (push) Canceled after 0s
CI / Test (macos-latest) (push) Canceled after 0s
CI / Test (ubuntu-latest) (push) Canceled after 0s
CI / Build CPU-Only (Explicit) (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
CI / Build (macos-latest) (push) Failing after 9s
Documentation / Build API Documentation (push) Canceled after 0s
Documentation / Build User Guide (push) Canceled after 0s
Performance Benchmarks / Run Benchmarks (push) Canceled after 0s
CI / Format Check (push) Canceled after 0s
CI / Clippy Check (push) Canceled after 0s
CI / Build (ubuntu-latest) (push) Canceled after 0s
CI / Test (macos-latest) (push) Canceled after 0s
CI / Test (ubuntu-latest) (push) Canceled after 0s
CI / Build CPU-Only (Explicit) (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]> Claude-Session: https://claude.ai/code/session_0116sg1Qz1gMv9hdcKP1XUam
This commit is contained in:
co-authored by
Claude Fable 5.1
parent
2c1143076e
commit
3e019d1491
@@ -34,6 +34,37 @@ const FILLET: f64 = 0.5 * 0.41 / 41.0;
|
||||
const PATCH_ROWS: usize = 12;
|
||||
const PATCH_STRETCH: f64 = 4.0;
|
||||
|
||||
/// The patch's thickness in units of h (`RTX_FSI2O_PATCH_OFFSET`, 6).
|
||||
/// At the default the overlap band sits a fixed NUMBER of cells from the
|
||||
/// wall and moves inward in metres with refinement (ny 41 / 62 / 82 →
|
||||
/// 60 / 40 / 30 mm); P5-3 holds it in metres across the ladder instead.
|
||||
fn patch_offset_h() -> f64 {
|
||||
std::env::var("RTX_FSI2O_PATCH_OFFSET")
|
||||
.ok()
|
||||
.and_then(|v| v.parse().ok())
|
||||
.unwrap_or(6.0)
|
||||
}
|
||||
|
||||
/// The patch's across-rows (`RTX_FSI2O_PATCH_ROWS`, 12; scale it with the
|
||||
/// offset to keep the wall spacing).
|
||||
fn patch_rows() -> usize {
|
||||
std::env::var("RTX_FSI2O_PATCH_ROWS")
|
||||
.ok()
|
||||
.and_then(|v| v.parse().ok())
|
||||
.unwrap_or(PATCH_ROWS)
|
||||
}
|
||||
|
||||
/// The save tag: `fsi2o_ny{ny}`, plus `_off{offset}` off the default
|
||||
/// patch thickness so a thicker patch never loads the default's state.
|
||||
fn save_tag(ny: usize) -> String {
|
||||
let offset = patch_offset_h();
|
||||
if (offset - 6.0).abs() < 1e-12 {
|
||||
format!("fsi2o_ny{ny}")
|
||||
} else {
|
||||
format!("fsi2o_ny{ny}_off{offset}")
|
||||
}
|
||||
}
|
||||
|
||||
/// The deforming wall as the patch sees it: the wetted polygon (the
|
||||
/// `Interface` walk, anchors included) and the velocity at each vertex.
|
||||
#[derive(Debug, Clone, Default)]
|
||||
@@ -221,8 +252,8 @@ impl OversetFluid {
|
||||
FLAG_X1,
|
||||
h,
|
||||
FILLET,
|
||||
6.0 * h,
|
||||
PATCH_ROWS,
|
||||
patch_offset_h() * h,
|
||||
patch_rows(),
|
||||
PATCH_STRETCH,
|
||||
sweeps,
|
||||
)?;
|
||||
@@ -244,8 +275,8 @@ impl OversetFluid {
|
||||
FLAG_X1,
|
||||
h,
|
||||
FILLET,
|
||||
6.0 * h,
|
||||
PATCH_ROWS,
|
||||
patch_offset_h() * h,
|
||||
patch_rows(),
|
||||
PATCH_STRETCH,
|
||||
20_000,
|
||||
)?;
|
||||
@@ -359,7 +390,7 @@ impl OversetFluid {
|
||||
pub fn save(&self, dir: &str) -> CfdResult<()> {
|
||||
let dir = std::path::Path::new(dir);
|
||||
std::fs::create_dir_all(dir).expect("save dir");
|
||||
let tag = format!("fsi2o_ny{}", self.ny);
|
||||
let tag = save_tag(self.ny);
|
||||
self.field
|
||||
.background
|
||||
.save(&dir.join(format!("bg_{tag}.bin")))?;
|
||||
@@ -390,7 +421,7 @@ impl OversetFluid {
|
||||
/// (the deformed mesh), its vectors, the time and the interface `d`
|
||||
/// (`dir/inst_<tag>_<step>/`).
|
||||
pub fn save_instant(&self, dir: &str, step: usize, d: &[f64], ddot: &[f64]) -> CfdResult<()> {
|
||||
let tag = format!("fsi2o_ny{}", self.ny);
|
||||
let tag = save_tag(self.ny);
|
||||
let dir = std::path::Path::new(dir).join(format!("inst_{tag}_{step:06}"));
|
||||
std::fs::create_dir_all(&dir).expect("instant dir");
|
||||
self.field.background.save(&dir.join("bg.bin"))?;
|
||||
@@ -496,6 +527,110 @@ impl OversetFluid {
|
||||
Ok((fluid, d, t))
|
||||
}
|
||||
|
||||
/// The wall load by REGION at the current state (P5-3): for the top
|
||||
/// face, the bottom face, the tip arc, and the fillets + cylinder —
|
||||
/// `(name, faces, length, drag, lift, mean t_n, min t_n, max t_n)`
|
||||
/// with `t_n` the normal traction (≈ −p at the wall), and the patch's
|
||||
/// pressure level.
|
||||
pub fn wall_regions(
|
||||
&self,
|
||||
d: &[f64],
|
||||
) -> (
|
||||
Vec<(&'static str, usize, f64, f64, f64, f64, f64, f64)>,
|
||||
f64,
|
||||
) {
|
||||
let e = self.interface.edges(d);
|
||||
let tip_mid = [
|
||||
0.5 * (e.tip[0][0] + e.tip[e.tip.len() - 1][0]),
|
||||
0.5 * (e.tip[0][1] + e.tip[e.tip.len() - 1][1]),
|
||||
];
|
||||
let nearest = |pts: &[[f64; 2]], q: [f64; 2]| -> f64 {
|
||||
pts.iter()
|
||||
.map(|p| (p[0] - q[0]).powi(2) + (p[1] - q[1]).powi(2))
|
||||
.fold(f64::INFINITY, f64::min)
|
||||
};
|
||||
let mut acc: Vec<(&'static str, usize, f64, f64, f64, f64, f64, f64)> = vec![
|
||||
(
|
||||
"top",
|
||||
0,
|
||||
0.0,
|
||||
0.0,
|
||||
0.0,
|
||||
0.0,
|
||||
f64::INFINITY,
|
||||
f64::NEG_INFINITY,
|
||||
),
|
||||
(
|
||||
"bottom",
|
||||
0,
|
||||
0.0,
|
||||
0.0,
|
||||
0.0,
|
||||
0.0,
|
||||
f64::INFINITY,
|
||||
f64::NEG_INFINITY,
|
||||
),
|
||||
(
|
||||
"tip arc",
|
||||
0,
|
||||
0.0,
|
||||
0.0,
|
||||
0.0,
|
||||
0.0,
|
||||
f64::INFINITY,
|
||||
f64::NEG_INFINITY,
|
||||
),
|
||||
(
|
||||
"fillets+cyl",
|
||||
0,
|
||||
0.0,
|
||||
0.0,
|
||||
0.0,
|
||||
0.0,
|
||||
f64::INFINITY,
|
||||
f64::NEG_INFINITY,
|
||||
),
|
||||
];
|
||||
for (centre, normal, len, traction) in self.solver.patch().wall_tractions(
|
||||
&self.field.patch,
|
||||
PatchSide::Inner,
|
||||
self.solver.time(),
|
||||
) {
|
||||
let on_cyl =
|
||||
((centre[0] - CYL_CENTRE[0]).powi(2) + (centre[1] - CYL_CENTRE[1]).powi(2)).sqrt()
|
||||
< CYL_R + 1.5 * FILLET;
|
||||
let near_tip = ((centre[0] - tip_mid[0]).powi(2) + (centre[1] - tip_mid[1]).powi(2))
|
||||
.sqrt()
|
||||
< 2.5 * FLAG_T;
|
||||
let k = if on_cyl {
|
||||
3
|
||||
} else if near_tip {
|
||||
2
|
||||
} else if nearest(&e.top, centre) <= nearest(&e.bottom, centre) {
|
||||
0
|
||||
} else {
|
||||
1
|
||||
};
|
||||
let tn = traction[0] * normal[0] + traction[1] * normal[1];
|
||||
let r = &mut acc[k];
|
||||
r.1 += 1;
|
||||
r.2 += len;
|
||||
r.3 += traction[0] * len;
|
||||
r.4 += traction[1] * len;
|
||||
r.5 += tn * len;
|
||||
r.6 = r.6.min(tn);
|
||||
r.7 = r.7.max(tn);
|
||||
}
|
||||
for r in &mut acc {
|
||||
if r.2 > 0.0 {
|
||||
r.5 /= r.2;
|
||||
}
|
||||
}
|
||||
let p = &self.field.patch.p;
|
||||
let level = p.iter().sum::<f64>() / p.len().max(1) as f64;
|
||||
(acc, level)
|
||||
}
|
||||
|
||||
/// The solver-metric momentum chain at the current state (§5.11's
|
||||
/// instrument on the moving patch): the solved-face pin, the ring, the
|
||||
/// box in the solver's flux form, the patch's balance, the wall.
|
||||
@@ -568,7 +703,7 @@ impl OversetFluid {
|
||||
/// returns its time.
|
||||
pub fn load(&mut self, dir: &str) -> CfdResult<f64> {
|
||||
let dir = std::path::Path::new(dir);
|
||||
let tag = format!("fsi2o_ny{}", self.ny);
|
||||
let tag = save_tag(self.ny);
|
||||
self.field.background = FlowField::load(&dir.join(format!("bg_{tag}.bin")))?;
|
||||
let read = |name: &str| -> Vec<f64> {
|
||||
let bytes = std::fs::read(dir.join(format!("patch_{tag}_{name}.bin")))
|
||||
@@ -611,8 +746,8 @@ impl OversetFluid {
|
||||
FLAG_X1,
|
||||
self.h,
|
||||
FILLET,
|
||||
6.0 * self.h,
|
||||
PATCH_ROWS,
|
||||
patch_offset_h() * self.h,
|
||||
patch_rows(),
|
||||
PATCH_STRETCH,
|
||||
if self.warm_sweeps > 0 && self.warm_base.is_some() {
|
||||
self.warm_sweeps
|
||||
|
||||
Reference in New Issue
Block a user