rtx-cfd: overset A-P3 — the falsifier plate on the overset (FAILS the registered gates by one order less than the staircase); wall force; composite pressure-level pin; Schwarz stall detection
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 / 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 / Format Check (push) Canceled after 0s
CI / Clippy Check (push) Canceled after 0s
CI / Build (macos-latest) (push) Canceled after 0s
CI / Build (ubuntu-latest) (push) Canceled after 0s
CI / Test (macos-latest) (push) Canceled after 0s
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 / 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 / Format Check (push) Canceled after 0s
CI / Clippy Check (push) Canceled after 0s
CI / Build (macos-latest) (push) Canceled after 0s
CI / Build (ubuntu-latest) (push) Canceled after 0s
CI / Test (macos-latest) (push) Canceled after 0s
patch_gen::{stadium, graded_fractions}: the falsifier plate as a stadium O-grid
(semicircular ends r = half-thickness; 16 cells per end arc, straights graded
0.30 h -> h at 1.15, offset 6 h, 12 rows stretched 4x; 148x12 cells, every ray
a normal, worst non-orthogonality 4 deg). CurvilinearPisoSolver::surface_force
(+ PatchLoad): F = sum(-p_f S_f + mu (grad u + grad u^T)_f . S_f) on the wall
faces with the wall cell's LSQ gradients (wall Dirichlet in the velocity fit);
HELD on the phantom circle against the exact stress integral: 1.3e-2 / 6.3e-3 /
3.6e-3 at n = 32/64/128 (orders 1.05 / 0.81), 22x the staircase's accuracy.
OversetPisoSolver: the composite p' level pinned to zero mean over the active
cells every round (the coupled problem is pure Neumann; the temporal warm start
handed each step's level to the next — background pressure 1e7 growing 5e4 per
step on the falsifier; an unpinned level also inflated the relative Schwarz
stop); stall detection (no progress over three rounds = the inner solvers'
noise floor; 6560 of 150k steps burned the 20-round cap at n = 64, a 7.5 h
n = 128 march); schwarz_stalled in the result.
tests/overset_falsifier.rs (records; RTX_OVERSET_FALSIFIER_STRICT asserts the
registered gates, _LADDER runs dt/2 and dt/4, _TRACE the top-12 spike steps):
max spike 594 / 981 / 1720 N/m at dt / dt/2 / dt/4 (staircase 6490 / 12600 /
25600), rms spike 61-89 (810), far probe 502-1509 (7900), KE injection 0.16-0.21
J/m per event on the common cell set (2.6) — every large spike a ~104-cell
full-row reclassification; exponent -0.77 (-1.0). The registered 5% gate (8.75
N/m) is missed 68x: the overset's own reclassification impulse is the finding
(omni-cortex overset_metal_campaign.md §5.10); P3b = locate per cell, then the
fringe flux balance. tests/patch_stadium.rs, curvilinear_loads.rs,
overset_common::plate_patch.
Co-Authored-By: Claude Fable 5.1 <[email protected]>
Claude-Session: https://claude.ai/code/session_01X2GmJXeQ2njUecEKiJZ1G2
This commit is contained in:
co-authored by
Claude Fable 5.1
parent
afd1bff6ee
commit
e2edff9b1d
@@ -148,3 +148,98 @@ pub fn channel_varying_skew(
|
||||
}
|
||||
PatchMesh::from_nodes(nx, ny, x, y, periodic_x.then_some([lx, 0.0]))
|
||||
}
|
||||
|
||||
/// Spacings along a straight of `length` that grow geometrically from `d0`
|
||||
/// at both ends (ratio `ratio`) to at most `d1` in the middle, symmetric;
|
||||
/// returns the cumulative fractions `0 ..= 1`. The count adapts to the
|
||||
/// length.
|
||||
pub fn graded_fractions(length: f64, d0: f64, d1: f64, ratio: f64) -> Vec<f64> {
|
||||
// One end's graded run, until the spacing reaches d1 or half the length.
|
||||
let mut run = Vec::new();
|
||||
let mut d = d0;
|
||||
let mut acc = 0.0;
|
||||
while d < d1 && acc + d < 0.5 * length {
|
||||
run.push(d);
|
||||
acc += d;
|
||||
d *= ratio;
|
||||
}
|
||||
let middle = length - 2.0 * acc;
|
||||
let n_mid = ((middle / d1).round() as usize).max(1);
|
||||
let d_mid = middle / n_mid as f64;
|
||||
let mut spacings = run.clone();
|
||||
spacings.extend(std::iter::repeat_n(d_mid, n_mid));
|
||||
spacings.extend(run.iter().rev());
|
||||
let total: f64 = spacings.iter().sum();
|
||||
let mut fr = Vec::with_capacity(spacings.len() + 1);
|
||||
let mut s = 0.0;
|
||||
fr.push(0.0);
|
||||
for w in &spacings {
|
||||
s += w;
|
||||
fr.push(s / total);
|
||||
}
|
||||
let last = fr.len() - 1;
|
||||
fr[last] = 1.0;
|
||||
fr
|
||||
}
|
||||
|
||||
/// An O-grid around a STADIUM (a rectangle of half-length `hx` and
|
||||
/// half-thickness `r` with semicircular ends of radius `r`, the plate of
|
||||
/// the fresh-cell falsifier rounded at its ends) centred at `centre`: the
|
||||
/// inner ring is the stadium, the outer ring its normal offset by
|
||||
/// `offset`, so every ray is a normal (orthogonal cells). Along the body
|
||||
/// the straights are graded from the arc spacing `d0 = π r / k_arc` at the
|
||||
/// tangent points to `d_straight` in the middle (ratio `grade`); each end
|
||||
/// arc carries `k_arc` cells. Across, `nn` cells with the geometric
|
||||
/// `stretch` (wall spacing = `offset · (g − 1)/(g^nn − 1)`). `s` runs
|
||||
/// CLOCKWISE (the right-handed frame `PatchMesh` needs), starting at the
|
||||
/// top-left tangent point. Periodic.
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
pub fn stadium(
|
||||
centre: [f64; 2],
|
||||
hx: f64,
|
||||
r: f64,
|
||||
offset: f64,
|
||||
k_arc: usize,
|
||||
d_straight: f64,
|
||||
grade: f64,
|
||||
nn: usize,
|
||||
stretch: f64,
|
||||
) -> CfdResult<PatchMesh> {
|
||||
let a = hx - r; // half-length of the straights
|
||||
let d0 = PI * r / k_arc as f64;
|
||||
let straight = graded_fractions(2.0 * a, d0, d_straight, grade);
|
||||
let mut inner = Vec::new();
|
||||
let mut outer = Vec::new();
|
||||
let mut push = |p: [f64; 2], n: [f64; 2]| {
|
||||
inner.push([centre[0] + p[0], centre[1] + p[1]]);
|
||||
outer.push([
|
||||
centre[0] + p[0] + offset * n[0],
|
||||
centre[1] + p[1] + offset * n[1],
|
||||
]);
|
||||
};
|
||||
// Top straight, left → right (clockwise around the body).
|
||||
for &f in &straight[..straight.len() - 1] {
|
||||
push([-a + f * 2.0 * a, r], [0.0, 1.0]);
|
||||
}
|
||||
// Right arc, from +90° down to −90° (exclusive of both ends' duplicates
|
||||
// handled by the straights: include angles strictly between).
|
||||
for k in 0..k_arc {
|
||||
let th = PI / 2.0 - PI * k as f64 / k_arc as f64;
|
||||
let (s, c) = th.sin_cos();
|
||||
push([a + r * c, r * s], [c, s]);
|
||||
}
|
||||
// Bottom straight, right → left.
|
||||
for &f in &straight[..straight.len() - 1] {
|
||||
push([a - f * 2.0 * a, -r], [0.0, -1.0]);
|
||||
}
|
||||
// Left arc, from −90° down to −270°.
|
||||
for k in 0..k_arc {
|
||||
let th = -PI / 2.0 - PI * k as f64 / k_arc as f64;
|
||||
let (s, c) = th.sin_cos();
|
||||
push([-a + r * c, r * s], [c, s]);
|
||||
}
|
||||
// Close the ring: the last point repeats the first.
|
||||
inner.push(inner[0]);
|
||||
outer.push(outer[0]);
|
||||
transfinite(&inner, &outer, nn, stretch, Some([0.0, 0.0]))
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user