docs: moving circles — current status and user guide, BC capability, stage-1 evidence

docs/moving_bodies.md gains a current status/user-guide section; the staged
contract below it is kept unchanged as the design record.
configs/CONFIG.md states the single dense outer-boundary package.
docs/validation/moving_bodies_stage1.md summarizes the Dütsch and VIV
evidence with SHAs and binding limitations. One stale source comment fixed
(comment only).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Claude
2026-10-30 16:10:32 +00:00
co-authored by Claude Opus 5.5
parent fb507aa1f2
commit 307468b671
4 changed files with 117 additions and 13 deletions
+56 -12
View File
@@ -1,17 +1,61 @@
# Moving circles on the uniform dense grid — S0 DRAFT contract
# Moving circles on the uniform dense grid
Status: **DRAFT, not frozen** for the force RHS, kernels and physical
acceptance. Host-only S1 (state, validation, guards; no kernels) is on branch
`claude/moving-bodies-s1`; positive-step runs with a moving body are rejected
until S2. When S2 lifts that guard, `run(n > 1)` with a pending target must
raise `ValueError` before mutation (4a), and `run(0)` must not upload a motion
record or consume the pending target. Base: main
`b2034f87e03656c5f67ab88562a70d6c338b9918`. Scope approved by Frank (via TRON,
thread C0C78UFKGRM/1793335557.460509): uniform-grid prescribed translation and
single-cylinder free transverse VIV. Out of scope: refinement/blocked path,
pinball assembly, EsoPull, shifted storage, D3Q19, DynamisLab, manuscript.
## Status and user guide (current)
Items marked **OPEN** are undecided; items marked **CANDIDATE** are proposals.
Development-stage feature, integrated from the reviewed slices S1–S3a
(production code identical to `653fd997`). Physical evidence and its limits:
`docs/validation/moving_bodies_stage1.md`. The force used as a structural RHS
is a declared stage choice, not an established result.
*What it does.* Translating circles (with optional spin) on the dense
double-buffer D2Q9 path: per-step cut links from an FP64 geometry record
(M2 `MovingCircleLinks`), reclassification and refill of covered/uncovered
cells (M1 `MovingCircleCells`), moving-wall Bouzidi with wall velocity
`u + omega x r`, and separate per-body diagnostics.
*API.*
- `Simulation.add_body("circle", centre, radius,
translation=Translation(offset_box, max_speed))` before `initialize()`;
`offset_box = (x_min, x_max, y_min, y_max)` in lattice cells around the
base centre (must contain 0), `0 < max_speed ≤ .5`.
- `set_body(id, offset=(dx, dy), vx=..., vy=..., omega=...)` sets a pending
target (validated against the applied offset: box, Euclidean step ≤ .5
cell, speed, no sliding hold); `vx`/`vy` are the interval wall velocity.
- `run(1)` advances a pending target and commits it only after the step
synchronizes with `no_donor == 0`; `run(n > 1)` with a pending target
raises; without a target `run(n)` holds the geometry (spin allowed).
Direct `LBMStepper.step` refuses while a target is pending.
- `moving_diagnostics()` returns per body the columns of
`MovingTables.DIAG` (CME, Wen term, link mass, cover/uncover momentum and
mass, eq_only, no_donor, crossings) accumulated since obs were zeroed;
`obs`/`read_force` keep their contract (CME on the body).
- `get_flags()` reads device flags back when moving circles exist.
*Supported:* dense double buffer, D2Q9, FP32 unshifted, SRT/MRT, circles,
spin. *Rejected before mutation:* EsoPull, ddf shifting, D3Q19, refinement /
blocked steppers, Jets or surface actuation on a moving circle,
`sync_bodies` and checkpoints while a moving circle exists, swept bands that
touch the domain edge, other bodies, sensors or force regions.
*Failure lifecycle.* Device-side failures (upload, step, sync, no_donor)
mark the Simulation failed; later run/step/sync/checkpoint calls and direct
stepper calls refuse until `close()`.
*Known limitations.* No mass correction at curved walls (static or moving);
cover/uncover and Wen terms are diagnostics, not a selected force law; the
host loop costs a fixed per-step synchronization (≈ 1 ms/step measured on a
7.2 M-cell grid, run(1) class); outer boundaries are the single dense
channel package (see `configs/CONFIG.md`).
## Design record (staged contract, kept as written)
The sections below are the contract the slices were reviewed against
(S0 → S3a). They are kept unchanged for provenance; where they say "draft",
"proposed" or "until S2/S3", the status above supersedes them.
Original scope (Frank via TRON, thread C0C78UFKGRM/1793335557.460509):
uniform-grid prescribed translation and single-cylinder free transverse VIV;
base main `b2034f87e03656c5f67ab88562a70d6c338b9918`.
## 1. Working standards
+46
View File
@@ -0,0 +1,46 @@
# Moving circles — stage-1 evidence (development level)
Owner criterion (Yanqi via TRON): prescribed motion and one free VIV case both
"reasonably close" to a predeclared reference = development-stage success.
This is practical closeness, not a formal validation claim. Every number
below is from Astra's receipts as posted in Slack C0C78UFKGRM thread
1793335557.460509; raw outputs stay on Horsea under `/tmp/celeris-results-*`
and the Mac evidence directory (not in git).
## Code
- Production: `src/` identical to `653fd997` (slices S1 `983020b6`,
S2a `b920a303`, S3a `653fd997`). CPU suites and GPU hold/crossing gates
passed on those slices (G0a/G0b population-bitwise; X1 crossing ledger).
- Research drivers: `research/duetsch_re100_kc5/` (`dd37883d`, capture
`a0aea3b9`) and `research/viv_re150/` (`fb507aa1`), run as committed.
## Prescribed in-line oscillation (Dütsch et al. 1998, Re 100, KC 5)
- Protocol: `docs/validation/duetsch_re100_kc5_protocol.md`.
- Frozen settling gate (.002 F_ref waveform): **FAILED** and kept on record:
D40 domain stage (20/40/60 D, 11.25 T) and the 60 D duration diagnostic
(31.25 T, 0/28 pairs; last waveform drift .00613 F_ref).
- Unscored late-cycle CME fits c_d ≈ 2.02–2.05, c_i ≈ 1.46–1.48 vs the
paper's computed (2.09, 1.45); fields clean and symmetric (owner view).
The owner accepts ~0.61 % cycle drift at D40 for this stage; the gate is
not re-scored.
- Fig. 8 LDA profiles: qualitative only (no digitized ordinates).
## Free transverse VIV (Kolahdouz §4.1.1 setup, Qin §4.5 target)
- Predeclaration: `docs/validation/leontini_viv_predeclare.md` (agreed at
`1abfe954`); run at `fb507aa1`, single case, D = 40, 75 D × 60 D.
- Result: status `scored`, 336,384 steps (t U/D = 336.4); A_max = .5464 D vs
.520 D (+5.1 %, inside the declared ±10 % band); mean half peak-to-peak
.5448 D; f/f_n = .955; block drifts .78/.29/.18 %, last-five spreads
.15/.11/.10 %; finite, no_donor = 0, no seed; 337.7 s, ~1.0 ms/step.
## Limitations (binding)
- One resolution (D40) per case; no grid or time convergence.
- Structural RHS = CME + Wen is a theory-motivated stage choice; CME-only
and node-impulse variants were not run as RHS; no force law is validated.
- Boundary mismatches: NEQ outlet with backflow clamp vs traction outlet;
finite box; the strict Dütsch settling failure is unexplained.
- No mass correction at curved walls; ~1 ms/step host-coupled overhead.