From c4a29b557de0ffaf811d475deaa10842167b7a7a Mon Sep 17 00:00:00 2001 From: Omar Sobh Date: Wed, 23 Sep 2026 12:02:49 -0500 Subject: [PATCH] =?UTF-8?q?embedded3=20flag=20wake:=20RTX=5FE3=5FFLAG=5FCY?= =?UTF-8?q?L=5FSPAN=3Dflag=20=E2=80=94=20the=20cylinder=20cut=20to=20the?= =?UTF-8?q?=20flag's=20span=20with=20the=20flag's=20rounded=20edges=20(the?= =?UTF-8?q?=20whole=20body=20finite=20in=20the=20wider=20ducts);=20wall=20?= =?UTF-8?q?to=20wall=20by=20default,=20slab=20gate=20byte-identical?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Fable 5.1 --- .../rtx-cfd/tests/embedded3_flag_wake.rs | 22 ++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/crates/specialized/rtx-cfd/tests/embedded3_flag_wake.rs b/crates/specialized/rtx-cfd/tests/embedded3_flag_wake.rs index 0b22ca9..a8dba59 100644 --- a/crates/specialized/rtx-cfd/tests/embedded3_flag_wake.rs +++ b/crates/specialized/rtx-cfd/tests/embedded3_flag_wake.rs @@ -256,6 +256,21 @@ fn flag_3d(x: f64, y: f64, z: f64, t: f64, r: f64) -> (f64, (f64, f64)) { (outside + q1.max(q2).min(0.0) - r, v) } +/// The finite cylinder: the 2D circle cut to `span` in z with the same +/// rounded edges as the flag (`RTX_E3_FLAG_CYL_SPAN=flag`, 2026-09-23: the +/// whole body a finite object in the wider ducts); wall to wall otherwise. +fn cylinder_3d(d2: f64, z: f64, r: f64) -> f64 { + let span = flag_span(); + if span >= duct_depth() || !std::env::var("RTX_E3_FLAG_CYL_SPAN").is_ok_and(|v| v == "flag") { + return d2; + } + let zc = 0.5 * duct_depth(); + let q1 = d2 + r; + let q2 = (z - zc).abs() - 0.5 * span + r; + let outside = (q1.max(0.0).powi(2) + q2.max(0.0).powi(2)).sqrt(); + outside + q1.max(q2).min(0.0) - r +} + fn inflow(y: f64, z: f64) -> f64 { let (hd, d) = (duct_height(), duct_depth()); 16.0 * U_M * y * z * (hd - y) * (d - z) / (hd * hd * d * d) @@ -355,11 +370,11 @@ fn flag_wake_on_the_device() { let cyl = move |x: f64, y: f64| ((x - CX).powi(2) + (y - cy).powi(2)).sqrt() - R_CYL; let r_fillet = root_fillet(); let body = Body::from_sdf(move |x, y, z, t| { - fillet_union(cyl(x, y), flag_3d(x, y, z, t, r_edge).0, r_fillet) + fillet_union(cylinder_3d(cyl(x, y), z, r_edge), flag_3d(x, y, z, t, r_edge).0, r_fillet) }) .with_surface_velocity(move |x, y, z, t| { let (df, (vx, vy)) = flag_3d(x, y, z, t, r_edge); - if df <= cyl(x, y) { + if df <= cylinder_3d(cyl(x, y), z, r_edge) { (vx, vy, 0.0) } else { (0.0, 0.0, 0.0) @@ -378,8 +393,9 @@ fn flag_wake_on_the_device() { } solver.initialize(&mut field); println!( - " flag wake ny {ny} (span {}; duct {:.2} × {:.2} m, inflow {}, z sides {}; root fillet {:.4} m, tip inset {:.4} m): {nx}×{ny_grid}×{nz} = {} cells, h {h:.4e}, dt {dt:.3e}, {periods} periods = {t_end:.3} s, {} steps", + " flag wake ny {ny} (span {}, cylinder {}; duct {:.2} × {:.2} m, inflow {}, z sides {}; root fillet {:.4} m, tip inset {:.4} m): {nx}×{ny_grid}×{nz} = {} cells, h {h:.4e}, dt {dt:.3e}, {periods} periods = {t_end:.3} s, {} steps", flag_span(), + if std::env::var("RTX_E3_FLAG_CYL_SPAN").is_ok_and(|v| v == "flag") { "cut to the span" } else { "wall to wall" }, duct_height(), duct_depth(), if slab_nz > 0 || inflow_2d { "2d" } else { "3d" },