Commit Graph
22 Commits
Author SHA1 Message Date
ClaudeandClaude Opus 5.5 c397e08565 BlockLayout2D: explicit selected block origins with hole owners
build(..., origins=None|[(y0, x0), ...]) stores only grid-aligned selected
blocks (unique, strictly row-major, no silent reordering). Cells of absent
blocks own layout.hole (= nblocks*L, one past the last block cell) so an
unguarded index fails rather than wrapping like -1; layout.owned is the
dense mask. Halo pairs never read holes, to_blocked ignores hole values,
to_dense returns NaN there, map_cut_links rejects receivers, solid
neighbors or q<.5 donors in absent blocks, blocked_link_tables stores
owned flags only. origins=None or every origin reproduces the regular
layout exactly. Storage only: no CUDA or stepper changes.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-16 03:09:15 +00:00
ClaudeandClaude Opus 5.5 bf0adda45f Test: jet ownership is set membership, not row adjacency
Synthetic rows: one jet over non-contiguous rows of one body is accepted;
the same rows with a second body id are rejected (Grok case 2).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-16 02:41:15 +00:00
ClaudeandClaude Opus 5.5 64d54ab23e Jets: one jet may drive links of only one body
surface_link_velocity (the shared host check used by CurvedLinkSoA,
ObjectManager sync, prepare_fine_boundary and FixedPatchStepper) now
rejects a jet whose selected cut links carry more than one body id, at
any amplitude, before uploads. Identity is the scene-wide body id of the
physical cut-link list, so one body spanning storage blocks stays valid.
No body selector; empty-selection semantics unchanged.

Tests: two bodies under one jet rejected (amplitude 2e-3 and 0) on the
Simulation/manager path and on the fine path; separate jets on separate
bodies accepted on both; one fine body crossing 2x2 block seams accepted.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-16 02:39:58 +00:00
ClaudeandClaude Opus 5.5 f1e03423f3 Action upload: keep 2D slot fallback for ObjectManager(cfg=None)
19bd308 computed slot = 3*self.cfg.dim unconditionally, so a default
manager without cfg raised even when empty. Use the existing fallback
(cfg.dim if cfg else 2). Regression for empty and one-body managers.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-15 09:03:11 +00:00
ClaudeandClaude Opus 5.5 e67799812e Jet review tests: rotated tube, exact edge rule, synthetic flat wall
Test-only. Rotated 30-degree tube: lateral .999 in, 1.001 out, along -0.1
and 4.1 out, Parallel(30 deg) gives the axis unit vector. Separate
axis-aligned exact-edge check: |s| = 1 excluded, Tube along 0/length and
Sector r_min/r_max included. Synthetic hit sampling on a flat face x=10
(no non-circle geometry or kernel coverage): spatial selection |y| <= 1
and off-centre radial vectors from (5, 0) rather than the face normal.
Re-written from Grok's stated cases; the original text was clipped.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-15 09:02:05 +00:00
ClaudeandClaude Opus 5.5 19bd3088ef Gate action upload on Jet stationarity; document setter device-error handling
ObjectManager._upload_action_async is the single entry for every action
path (setters, direct edits of the public action array, run()). It now
also rejects nonzero vx/vy/omega slots of Jet-driven bodies via
validate_jet_motion, before any device copy. Regression: each motion
slot edited directly is rejected with no device write; zero motion
uploads. Simulation.set_jet_amplitude documents that a device error
requires close/recreate, as for other CUDA exceptions.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-15 08:58:17 +00:00
ClaudeandClaude Opus 5.5 508d412e43 Add Grok's Jet review tests (5-link sector oracle, axis wrap)
Taken from Grok's inline patch (Slack ts 1792052057.423679); the selector
fix in that patch was already applied in b1cd555. The rotated-tube and
non-circle-wall cases were clipped in transit and are not included.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-15 08:42:51 +00:00
ClaudeandClaude Opus 5.5 038a759ff1 Jets: one shared assignment check for dense and fine levels
Move surface_link_velocity (pure host code) from lbm/curved_links.py to
body/jets.py, re-exported by curved_links, so refinement.py can reuse it
without importing PyCUDA. prepare_fine_boundary now runs the same
assignment validation as the steppers when jets are given, rejecting
jet-vs-SurfaceActuation overlap (root's C(12.25,12.25) R2.15 case) as
well as empty/overlapping jets. Test the overlap and a disjoint pair.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-15 08:35:12 +00:00
ClaudeandClaude Opus 5.5 f7753be0e4 Jets: enforce stationary rule at ObjectManager.set_body_state too
Move the Jet motion check into ObjectManager.validate_jet_motion (uses the
synced field's cut-link jet_id) and call it from both Simulation.set_body
and the direct ObjectManager.set_body_state entry, before any state or
action change. Test both entries, vx too, and that action is untouched.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-15 08:32:29 +00:00
ClaudeandClaude Opus 5.5 62c525e735 Jets: freeze origins, guard set_body, fine-boundary hit helper
Sector/Tube/Radial store origin as a validated float 2-tuple, so caller
lists/arrays cannot change a registered definition. Simulation.set_body
rejects nonzero motion for bodies with Jet-driven links once initialized
(before initialize the sync-time stationary check applies).
prepare_fine_boundary accepts jets in the same coarse cell-edge frame as
fine objects, records read-only FP64 edge-frame hits (FineBoundary2D
.curved_hits, default None) and rejects empty or overlapping selections
before CUDA. FixedPatchStepper wiring is not included.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-15 08:27:35 +00:00
ClaudeandClaude Opus 5.5 da8bfb0d4a Jets: explicit cell-edge/node frame conversion, same-physical-hit test
Replace fine_hits_to_physical with fine_hits_to_edge_frame (patch
cell-edge frame, coarse centers at I+1/2, as FixedPatchStepper uses) and
edge_to_node_frame (Simulation integer-node frame, shift -1/2). Test one
physical circle through both frames: fine hits converted to node frame
lie on the Simulation circle and one node-frame Jet selects the same arc
on coarse and fine links; relabelling without conversion is detected.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-15 08:23:28 +00:00
ClaudeandClaude Opus 5.5 b1cd555b0f Jet review fixes: frozen Jet, validated amplitude replacement, test selector
Jet is a frozen dataclass; with_amplitude returns a validated copy, so
region/field/profile cannot drift from the cached per-link shapes and
amplitude cannot bypass validation. CurvedLinkSoA.set_jet_amplitude and
Simulation.set_jet_amplitude replace the Jet (Simulation also updates the
registered list so later geometry syncs keep the amplitude). Reject
non-finite hits; document edge rule (|s|<1 exclusive, radial/along
bounds inclusive). Fix the clipped-q test selector to receiver (9,5)
dir 8, as in test_surface_actuation.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-15 08:18:29 +00:00
ClaudeandClaude Opus 5.5 932702f779 Wire Jets through ObjectManager and Simulation
ObjectManager.jets holds scene-level Jets. build_compact_lists_for
collects true FP64 hits (SimObject.get_curved_list hits_out) row-aligned
with the cut-link columns; BodySyncPlan carries them as curved_hits, and
sync_to_gpu / apply_sync_plan / the pre-sync check pass jets+hits to
assign_surface. Jets require D2Q9/FP32/unshifted/double_buffer and may
only drive links of stationary bodies. Simulation.add_jet (before
initialize) and set_jet_amplitude (velocity column re-upload only);
save_checkpoint refuses scenes with jets. Fine-path wiring not included.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-15 08:15:22 +00:00
ClaudeandClaude Opus 5.5 611a64c54a Add body-independent Jet: true-hit spatial selection, fields, profiles
Jet(region, field, profile, amplitude) with Sector/Tube regions,
Radial/Parallel fields and uniform/parabolic/quartic profiles. Selection
uses true FP64 hit points over all scene cut links, no body association.
Overlap between jets or with a SurfaceActuation aperture is rejected.
CurvedLinkSoA caches unit-amplitude shapes; set_jet_amplitude rewrites
and re-uploads only the surface-velocity column. SurfaceActuation.as_jet
is the legacy adapter (equivalence measured in tests). Kernel and SoA
geometry columns unchanged. Manager/Simulation/fine-path wiring pending.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-15 08:10:31 +00:00
Frank14f 99c86e441c Integrate grok/wall-transfer-validation for bounded validation 2026-10-15 10:53:20 +08:00
Grok 103f144404 Relax coarse wall transfer guard to reconstructed rows only
Rows 2 and ny-3 are ordinary bulk cells that explosion only reads as
donors; only rows 0/1 and ny-2/ny-1 are dropped or reconstructed after
coalescence. Matches the existing y0>=4, y1<=ny-4 slot_reservoir contract.
Adds margin-4 acceptance and margin-3 rejection for a central circle.
2026-10-15 10:40:39 +08:00
ClaudeandClaude Opus 5.5 118635aebd Reject non-integral, bool and out-of-range block-layout indices
One _index helper guards block_cell (block, y, x), slot (block_cell, q)
and map_cut_links (fluid_idx, dir) before addressing; previously e.g.
block_cell(-1, 0, 0) returned -49 and fractional values were truncated.
Adds focused rejection tests and Astra's one-block seam reproducer
(build(4,8,4,8), receiver (2,0), dir 2 -> west-halo slot 90).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-15 02:39:15 +00:00
ClaudeandClaude Opus 5.5 2a68d7e7c7 Fix periodic-seam cut-link addressing in map_cut_links
Source (write) and reverse-donor addresses are now the receiver's local
core address +/- (ey*local_nx + ex), i.e. the window image the next local
pull reads. block_cell preferred the in-window core image on a one-block
periodic axis, so BFL wrote a copy the pull never reads. Physical
neighbors are still formed only to reject non-periodic exteriors.
block_cell semantics unchanged; docstring notes the image ambiguity.
Adds an end-to-end synthetic seam test (x=0/x=nx-1/corner wraps) on
one-block-x, one-block-y and 1x1 periodic layouts.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-15 02:38:13 +00:00
ClaudeandClaude Opus 5.5 2aadffe183 Add receiver-local static cut-link mapping to BlockLayout2D
Each physical link belongs once to the block owning its fluid receiver
core; the reflected source population is written into that block's own
core/halo copy (no halo copy between BFL and pull). Rejects repeated
links and repeated local writers; one row per link so force counts once.
Documents stale remote solid-core slots vs unique core ownership, and
that the 4-cell refinement halo is separate. Static geometry only.
Tests: address equivalence incl. cross-block q<.5 donors, and static
BFL+pull bit-equal to the dense operator on fluid cells.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-15 02:33:00 +00:00
ClaudeandClaude Opus 5.5 a64af5bece Add CPU BlockLayout2D: core ownership, halo pairs, blocked packing
Fixed-size 2D blocks, block-contiguous Q-major storage, explicit per-axis
periodicity; non-periodic exterior halo cells stay unpaired (NaN).
Provides owner/halo tables for a later periodic GPU consumer. Cut-link
mapping deliberately omitted until the BFL write policy is settled.
Tests: ownership, pair invariants, pack round trip, tagged pull vs dense.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-15 02:30:40 +00:00
Frank14f cdbb9c42f6 Add jet, surface and fixed-patch tests and runnable examples 2026-10-15 10:13:49 +08:00
Frank14fandCursor 987566c0e6 feat(body): runtime body add/remove, unified action/obs, FRC_REGION flag
- Add runtime body topology sync (add_body/remove_body + sync_bodies)
  with recompile, DDF patch (feq + BFS inward fill), and commit.
- Unify action/obs flow: set_body/set_force are now host-only;
  run() auto-uploads action and downloads obs via CUDA stream.
- Add read_body(id) -> BodyTelemetry and read_bodies() for DRL loops.
- Add FRC_REGION flag (0x0800) for force_region cells.
- Extract equilibrium helpers (lbm/equilibrium.py) and DDF patch module
  (body/ddf_patch.py).
- Merge recompile / _runtime_recompile into single _recompile().
- Add n_objects to checkpoint; validate on load.
- Add test suite: 40 unit + 19 integration tests (59 total).
- Add conftest.py and docs/tests_overview.md for test documentation.
- Update README.md and CONFIG.md for new API.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-20 18:17:07 +08:00