diff --git a/docs/moving_bodies.md b/docs/moving_bodies.md index 9923f00..4af8c90 100644 --- a/docs/moving_bodies.md +++ b/docs/moving_bodies.md @@ -82,12 +82,21 @@ fluid pull from a solid slot of a moving body is BFL-written. ## 4. State, masks and authority -- Host `ObjectState` is the single authority for `offset = (dx, dy)`, - `velocity = (vx, vy)` and `omega`. Velocity is supplied, never differenced - from offsets. -- Per body a small device **motion record** `{c^{n-1}, c^n, u^n}` is uploaded - with the action buffer; action-slot meaning is not overloaded. (CANDIDATE - layout; OPEN.) +- Host `ObjectState` is the single authority for one displacement + `offset = (dx, dy)` relative to the immutable base centre, plus + `velocity = (vx, vy)` and `omega`. Centres are always derived + (`c = base + offset`), never stored as independent state. Velocity is + supplied, never differenced from offsets. +- `c^{n-1}` is derived from the last *committed* offset, `c^n` from the + offset being applied. Per body a small device **motion record** + `{c^{n-1}, c^n, u^n}` is uploaded with the action buffer; action-slot meaning + is not overloaded. (CANDIDATE layout; OPEN.) +- Fail-closed commit: an enqueued upload is not a completed one. The new + offset becomes the committed offset only after the stream synchronization + that follows the upload and the step group succeeds. Any upload or later + synchronization failure leaves host and device motion state unknown: the + simulation is marked unusable (existing `_require_usable` lifecycle), and + no API may report a host/device match afterwards. - Membership is never read from a flag that M1 is overwriting. The host verifies at `add_body` that every swept-band cell has base flag FLUID, so the band's base state is known without reading `flag_gpu`. @@ -97,7 +106,9 @@ fluid pull from a solid slot of a moving body is BFL-written. ## 5. Refill of fresh cells (CANDIDATE) - Stored time level: everything in `ddf` at M1 is post-collision `G^{n-1}`; the - refill writes all 9 slots at that same level. + refill writes all 9 slots at that same level, so every slot of a fresh cell + that the following pull or a q < 1/2 link may read is defined. Donor values + are read at the same level `G^{n-1}` (old-fluid cells, untouched by M1). - `G = f_eq(rho_bar, u_w(x)) + G_neq(x_d)` where `rho_bar` = mean density of valid neighbours and `x_d` = the valid neighbour best aligned with the outward normal `(x - c^n)/|x - c^n|`; `G_neq(x_d) = G(x_d) - f_eq(rho(x_d), u(x_d))`. @@ -146,6 +157,12 @@ switch cancels with the switching momentum. Whether `sum u_w dm` approximates impulse, per crossing cycle). Momentum conservation is also distinct from Galilean invariance, which G4 tests. +External reference note: waLBerla's covered/refill momentum switches +(`conserveMomentumWhenMapping`, `conserveMomentumWhenRestoring`) default to +false (Astra), so their existence does not establish which combination its +validation cases use. A bookkeeping identity alone does not select the +physical force either. + Accumulators (separate, per body, per step window; all reported raw): `link_cme`, `link_wen_correction` (= `sum u_w dm`), `node_cover`, `node_uncover`, plus counters of crossings and refill fallbacks, so force @@ -182,8 +199,11 @@ mass), `zeta = c/c_crit = 0.01`, `U* = U/(f_N D)` with `f_N` the natural frequency in fluid assuming an inviscid added-mass term; the paper also reports frequencies normalised by the in-vacuo value. Our runner derives `k` from that in-fluid `f_N` (added-mass coefficient as stated in the paper) and -never from the vacuum formula; `c_crit` definition to be confirmed (OPEN). Stability/convergence is gated by a halved-time-step run, not -assumed from the mass ratio. +never from the vacuum formula; `c_crit` convention and the original +comparison data are still OPEN. Stability/convergence is gated by fluid +time/space refinement of the coupled run, not assumed from the mass ratio; +structural sub-stepping does not substitute for fluid-coupling time +refinement. ## 9. Gates (map; tolerances OPEN, declared before runs) @@ -196,7 +216,32 @@ KC 5 in-line (needs 2-component offset) · G6 Leontini free transverse VIV (m* = 10, ζ = 0.01, Re = 200, definitions pending) · G7 time-level contract frozen before the oscillator. -## 10. Remaining decisions +Candidate pre-run engineering tolerances (Astra; for discussion, not +literature limits or measured outcomes; norms, averaging window, convergence +protocol and physical reference uncertainty must be fixed before adoption, and +none may be weakened after seeing runs): +normalised momentum-ledger residual FP32 ≤ 5e-6 (FP64 oracle ≤ 2e-13); +10-cycle relative mass drift ≤ 1e-4; prescribed-motion grid study D = 40/80/160 +with final-step amplitude change ≤ 2 % and phase ≤ 2°; enlarged domain +amplitude change ≤ 1 %; matched-frame force RMS ≤ 2 % and improving with +refinement; VIV refinement amplitude ≤ 2 %, frequency ≤ 1 %, five consecutive +cycle amplitudes within 1 %. + +## 10. Proposed minimal S1 scope (host only; held until cross-review) + +- `add_body` moving-circle declaration: base centre, declared offset box + (x/y), speed bound; swept-band computation and band-placement validation. +- `set_body(offset=..., velocity=..., omega=...)` validation before mutation + (section 7) and the fail-closed commit of section 4. +- Motion-record host layout and upload path; exclusion of moving bodies from + the packed `CurvedBoundaryKernel` links (stationary packing unchanged). +- Explicit rejections for unsupported modes. +- Host tests (Astra runs them): rejection-before-mutation, band geometry, + derived centres, fail-closed behaviour under an injected upload/sync + failure, stationary packing byte-identical. No kernels, no GPU runs, no + y-only VIV oscillator (S4), no force RHS. + +## 11. Remaining decisions Structural RHS (section 6); motion-record layout; refill details; coupling scheme; benchmark definitions and digitized reference data; tolerances;