overset mesh: the flat-tip outline (P5-3 option B) — cylinder_flag_outline_deformed_tip / cylinder_flag_patch_deformed{,_from}_tip take the tip's corner radius (t = the recorded semicircle, bit for bit; smaller = the benchmark's flat face between corner arcs sampled at the wall spacing, point count fixed across the deformation, the tip's corners kept off the hull source); pins: corner t reproduces the recorded outline, the 2.5 mm outline has the exact area excess with no collapsed spacing, the O-grid builds straight and at ± 80 mm cold and warm at ny 41/62; harness knob RTX_FSI2O_TIP_CORNER (default 0.01) on the cold and warm builds, printed in both headers; pinned-toolchain fmt on touched crates
Performance Benchmarks / Run Benchmarks (push) Failing after 10s
CI / Format Check (push) Failing after 10s
CI / Build (ubuntu-latest) (push) Failing after 10s
CI / Clippy Check (push) Failing after 10s
Documentation / Build User Guide (push) Successful in 9s
CI / Build CPU-Only (Explicit) (push) Failing after 1m13s
Documentation / Build API Documentation (push) Failing after 2m25s
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]>
Claude-Session: https://claude.ai/code/session_01LzcjQX7tvgn87CQCyg9Cfr
This commit is contained in:
Omar Sobh
2026-09-13 22:22:08 -05:00
co-authored by Claude Fable 5.1
parent 7224521309
commit 415c32ab04
12 changed files with 519 additions and 71 deletions
@@ -13,7 +13,7 @@ use std::sync::{Arc, RwLock};
use nalgebra::Vector3;
use rtx_cfd::mesh::PatchSide;
use rtx_cfd::mesh::patch_gen::cylinder_flag_patch_deformed;
use rtx_cfd::mesh::patch_gen::cylinder_flag_patch_deformed_tip;
use rtx_cfd::solvers::incompressible::{
AleBoundaries, ConvectionScheme, CurvilinearParameters, CurvilinearPisoSolver,
EmbeddedParameters, EmbeddedPisoSolver, FlowField, MgPrecision, NormalDiffusion, OversetField,
@@ -45,6 +45,17 @@ fn patch_offset_h() -> f64 {
.unwrap_or(6.0)
}
/// The tip's corner radius (`RTX_FSI2O_TIP_CORNER`, metres; the recorded
/// outline is the full semicircle, corner = t = 0.01): P5-3 option B — the
/// benchmark's flat tip with rounded corners (2.5 mm) against the
/// semicircle, gated on the lift phase and the per-period amplitude.
pub fn tip_corner() -> f64 {
std::env::var("RTX_FSI2O_TIP_CORNER")
.ok()
.and_then(|v| v.parse().ok())
.unwrap_or(FLAG_T)
}
/// The outline's fillet radius (`RTX_FSI2O_FILLET`, metres; 5 mm = t/2 in
/// every recorded run, so the tip is a full half-round and the root
/// carries 5 mm fillets — the reference's flag is a sharp rectangle).
@@ -292,7 +303,7 @@ impl OversetFluid {
}
});
let (cold_mesh, _) = cylinder_flag_patch_deformed(
let (cold_mesh, _) = cylinder_flag_patch_deformed_tip(
CYL_CENTRE,
CYL_R,
FLAG_T,
@@ -304,6 +315,7 @@ impl OversetFluid {
patch_rows(),
patch_stretch(),
sweeps,
tip_corner(),
)?;
// With the warm-started regeneration (`RTX_FSI2O_WARM_SWEEPS`), the
// march starts on the converged fixed point of the warm build's
@@ -314,7 +326,7 @@ impl OversetFluid {
.unwrap_or(0);
let start_mesh = if warm_sweeps > 0 {
let t0 = std::time::Instant::now();
let (m, (it, last)) = rtx_cfd::mesh::patch_gen::cylinder_flag_patch_deformed_from(
let (m, (it, last)) = rtx_cfd::mesh::patch_gen::cylinder_flag_patch_deformed_from_tip(
Some(&cold_mesh),
CYL_CENTRE,
CYL_R,
@@ -327,6 +339,7 @@ impl OversetFluid {
patch_rows(),
patch_stretch(),
20_000,
tip_corner(),
)?;
println!(
" warm base: {it} sweep+respace iterations (last move {last:.1e}) in {:.1} s; {warm_sweeps} per regeneration",
@@ -788,7 +801,7 @@ impl OversetFluid {
/// The patch around the interface `d`.
pub fn patch_for(&self, d: &[f64]) -> CfdResult<rtx_cfd::mesh::PatchMesh> {
let start = std::time::Instant::now();
let (mesh, _) = rtx_cfd::mesh::patch_gen::cylinder_flag_patch_deformed_from(
let (mesh, _) = rtx_cfd::mesh::patch_gen::cylinder_flag_patch_deformed_from_tip(
if self.warm_sweeps > 0 {
self.warm_base.as_ref()
} else {
@@ -809,6 +822,7 @@ impl OversetFluid {
} else {
self.sweeps
},
tip_corner(),
)?;
self.regen_count.set(self.regen_count.get() + 1);
self.regen_seconds
@@ -100,7 +100,7 @@ pub fn run_march_overset(case: BenchmarkCase, config: &OversetMarchConfig) -> Ov
// Every setting the acceptance rule reads, printed once: P5-3 lost a
// day to a floor of 2e-4 against the overnight marches' 1e-6.
println!(
" coupling: {} (reuse {}, ω0 {}, c1 {}), floor {:.1e}, rtol {:.1e}, stall accept {:.1e}, max subit {}, predictor {}, s = {}, patch offset {} h × {} rows, patch convection {:?}, bg convection {:?}, patch stretch {}, fillet {} m",
" coupling: {} (reuse {}, ω0 {}, c1 {}), floor {:.1e}, rtol {:.1e}, stall accept {:.1e}, max subit {}, predictor {}, s = {}, patch offset {} h × {} rows, patch convection {:?}, bg convection {:?}, patch stretch {}, fillet {} m, tip corner {} m",
cfg.coupler,
cfg.reuse,
cfg.initial_relaxation,
@@ -117,6 +117,7 @@ pub fn run_march_overset(case: BenchmarkCase, config: &OversetMarchConfig) -> Ov
super::overset::bg_convection(),
super::overset::patch_stretch(),
super::overset::fillet(),
super::overset::tip_corner(),
);
// Phase 1: rigid flag to t_release (`RTX_FSI2O_LOAD=dir` replaces the