Compare commits

..
Author SHA1 Message Date
ClaudeandClaude Opus 5.5 9660894a1b docs: checkpoint save/load scope and read_surface_exchange wording
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-20 13:38:30 +00:00
ClaudeandClaude Opus 5.5 ba3772e3b8 docs: record cut-link ownership and read_surface_exchange changes from 87c3a31
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-20 13:29:44 +00:00
CodexandFrank14f b4692e6ec4 test: select single-case resolution and compact refinement 2026-10-19 23:55:26 +08:00
CodexandFrank14f 5731c5171b test: add optional public macro CV observations 2026-10-19 22:43:22 +08:00
CodexandFrank14f 05de02ee60 test: parameterize matched public MRT Jet diagnostics 2026-10-19 22:43:22 +08:00
CodexandFrank14f 87c3a3165e fix: validate passive boundary ownership and expose Jet exchange 2026-10-19 22:43:22 +08:00
Codex eec4677db1 test: add explicit projected-port LES source profile 2026-10-18 16:13:30 -07:00
Codex 2cf9853952 test: prepare matched projected pair Taylor-Green repeat 2026-10-18 15:38:04 -07:00
Codex 1aa8110ec8 test: add bounded projected pair CUDA qualification gate 2026-10-18 15:04:51 -07:00
Codex a135252ae7 feat: add experimental projected explosion per refinement pair 2026-10-18 14:54:17 -07:00
Codex ed9d8c937d docs: correct refinement topology and diagnostics scope 2026-10-18 13:13:53 -07:00
Codex fc0e544c0a Merge reviewed LES normalization into bounded 2D dev scope 2026-10-18 08:19:23 -07:00
Codex 95cb6d2b9f fix: integrate reviewed LES normalization with explicit dev flow pins 2026-10-18 07:58:41 -07:00
TRON 53fad76759 test: cover TRT restart and actual-rate refinement phase
Integrate reviewed test changes from 7c1517de819741907fb945ea0ab7864734fa3856 and 340ba4e1dc6386581839c0b28c8fe8a1f4aeb70b unchanged. Document bounded 2D implementation, evidence and open gates; production source and historical manifests are unchanged.
2026-10-18 07:54:54 -07:00
Frank14f 8403956a9a Merge reviewed MRT window validation and tolerance wording into dev 2026-10-18 22:18:09 +08:00
TRON 185a919cc5 test: opt in to window-ledger DFG observations with separate receipts 2026-10-18 06:23:04 -07:00
ClaudeandClaude Opus 5.5 aceea293a3 docs: drop 'rigorous' wording for the window tolerance (no threshold change)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-18 13:19:44 +00:00
ClaudeandClaude Opus 5.5 a233c90324 test: measurement-only A-versus-window timing for shifted-MRT refined DFG
A (per-base read-and-sum per 80-step interval), W (window + step(80) +
one read) and W1 (window + 80 x step(1)) over equal simulated duration
from the same fresh state and warm-up, 3 interleaved repeats. Bitwise
populations and per-interval total impulses (documented engineering
tolerance) are compared outside timing; health checks untimed. Records
candidate source identity (revision, dirty flag, file hashes) and does not
use or modify frozen refined-DFG manifests/results.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-18 13:09:31 +00:00
ClaudeandClaude Opus 5.5 f851aecf73 test: shifted-MRT no-Jet window gate with step(0), reset and split-step checks
Separate GPU class for a shifted MRT, all-blocked, stationary-body case
without Jets: window totals vs summed per-base reads (substep-scaled
tolerance), bitwise populations vs a raw-only stepper, a single step(N)
stepper with bitwise-equal window rows and populations, step(0)
non-change, and reset after a window. SRT/Jet test stays separately
scoped. Test-only.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-18 13:03:18 +00:00
ClaudeandClaude Opus 5.5 51202fc1c3 test: substep-scaled tolerance and bitwise populations in window GPU gate
Scale the window-vs-summed-reads tolerance by the actual absolute fine
substep contributions (last_raw after every fine hop), labelled a
conservative engineering tolerance rather than a proof. Compare
populations by finite FP32 bits plus NaN masks and reject infinities.
Test-only.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-18 12:59:09 +00:00
ClaudeandClaude Opus 5.5 d930323479 feat: optional observation-window raw exchange ledger
FixedPatchStepper(observe_window_exchange=True), which requires
observe_raw_exchange, allocates a second per-link FP64 ledger per body
level. While a window is open, the unchanged BlockAccumulateExchange
kernel also accumulates into it after each fine hop. Small API:
start_exchange_window() zeroes and opens at the current completed step;
read_exchange_window(body_id, level=) is non-destructive and reports
impulse with rates over the integer window duration. initialize/
_initialize_raw and step failure invalidate; remap builds a new instance
with no open window; Jet amplitude updates may stay in-window. Default
disabled: no allocation and no extra launch; last_substep/last_base_step
unchanged. summarize_exchange gains window='window' with duration.
Host contract tests (mocked driver) and a GPU gate against summed
per-base reads with a reordering-bound FP64 tolerance.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-18 12:54:44 +00:00
ClaudeandClaude Opus 5.5 6c53d2e74a test: fix flat uniform DDF masking and clarify harness labels
Simulation.get_ddf() is flat (9*ny*nx); view it as (Q, cells) before
applying the fluid mask, with a flat-DDF regression. Label A/E as
runner-like force-read workloads (values discarded, no aggregation or
validation; no macro/probe/CSV cost; not benchmark throughput) and split
status lines into CONSTRUCTED and WARM_READY. Test/doc only.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-18 12:33:07 +00:00
ClaudeandClaude Opus 5.5 724afb607c test: physical health and stricter parity in timing harness
Untimed physical-leaf/fluid health after warm-up and after each timed
window using the existing runner limits (finite macros, rho in [0.5,1.5],
max Mach <= 0.2); refined masks as in run_refined_dfg. Parity comparator
rejects unequal level counts and any infinity; matching NaN stays allowed
only as a storage mask. Regression tests for both. No numerical gate or
production change.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-18 12:29:21 +00:00
ClaudeandClaude Opus 5.5 77bab1c4ea test: apply timing harness review caveats
Explicit stream synchronization before/after each timed loop (refined
FixedPatchStepper stream, uniform Simulation stream, in their contexts);
required --max-wall-seconds outer timeout checked between variants and in
per-step loops; untimed finite leaf/fluid health checks; force notes for
B/C/E' (no host reads; final base interval only; whole-window average with
different summation order). Parity stays A/B/C vs A and E/E' vs E only.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-18 12:27:16 +00:00
ClaudeandClaude Opus 5.5 15fb58e36f test: measurement-only refined DFG MRT timing harness
Wall-time A/B/C/E/E' variants over equal simulated duration, reusing
run_refined_dfg setup functions. Fresh state and identical warm-up per
repeat, 3 interleaved repeats, construction/JIT, warm-up and bitwise
population/NaN-mask parity checks outside timed regions. B, C and E' are
labelled timing-only (no valid force history). No numerical or
production change.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-18 12:25:43 +00:00
TRON 4d4b9ba00a test: compare all-dense MRT fine stepping with blocked layouts 2026-10-18 03:51:53 -07:00
TRON 2abc48f0d8 test: select matched MRT DFG pilot with separate provenance 2026-10-18 03:49:21 -07:00
ClaudeandClaude Opus 5.5 3ea131e92c test: MRT refinement coverage and obsolete rejection fix
Remove MRT from the FixedPatch2D rejection matrix (TRT and other
rejections retained); convert host MRT tests to stdlib unittest; add GPU
gates for unshifted dense-vs-blocked MRT two-level roots (exact bits) and
a shifted all-blocked three-level MRT smoke checking per-level omega.
No numerical source change.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-18 10:31:25 +00:00
ClaudeandClaude Opus 5.5 00d7a54829 feat: opt-in MRT collision for blocked/refined stepping
Additive compile-time COLLISION_MODEL == 2 branches in BlockStep,
BlockChannelStep and patch_collide repeat the uniform collide_dispatch
MRT sequence (zero forcing, omega clamp, collide_mrt_no_force). SRT
statements, including the shifted retained-delta/direct-momentum path,
are unchanged under the alternate branch. Guards accept SRT or MRT only;
TRT, LES, non-FP32, non-double-buffer and shifted dense/mixed refinement
stay rejected. Transfers, subcycling, BFL, raw ledgers, channel closures,
shifted-Jet SRT guard and PeriodicBlockStepper are untouched. Existing
MRT operator, shifted representation and fixed kinetic rates are reused.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-18 10:26:55 +00:00
TRON 9805383f9c test: integrate periodic Taylor-Green AMR assessment 2026-10-18 00:24:50 -07:00
TRON 1f263b9e46 test: retain and localize channel GPU parity failures 2026-10-18 00:24:09 -07:00
TRON b23cb45adc test: retain independent Jet CV continuation measurements 2026-10-18 00:15:52 -07:00
TRON 413f7afade test: integrate matched refined DFG pilot preparation 2026-10-18 00:15:52 -07:00
TRON af984eab37 test: integrate explicitly repinned uniform LES shear diagnostic 2026-10-18 00:15:52 -07:00
TRON cd3a657f9d test: explicitly repin validation to reviewed channel source 2026-10-17 23:55:51 -07:00
TRON fa5d0c22a9 test: cover channel outlet clamp and damping controls 2026-10-17 23:53:24 -07:00
TRON 5b4610441c feat: add matched SRT channel closure for blocked AMR root 2026-10-17 23:53:24 -07:00
TRON 20ae677092 test: add pinned LES baseline and temporary candidate diagnostics 2026-10-17 23:47:56 -07:00
TRON 69e9b78de9 test: integrate pinned Re100 and jet control-volume validation 2026-10-17 23:38:53 -07:00
ClaudeandCodex d79e3f6f0a Reserve a pressure condition on Jet, velocity remains the only implemented one
Jet gains a last field condition='velocity'. 'pressure' raises
NotImplementedError in __post_init__ before profile/amplitude validation, so a
pressure jet never reaches surface_link_velocity, tables or kernels; unknown
values raise ValueError. Amplitude stays a lattice velocity (not a flow rate);
no pressure units, field reuse, tables or kernel changes are introduced.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
(cherry picked from commit fbf6f1d122)
2026-10-17 01:00:10 -07:00
Codex 9dddf5d812 Gate shifted velocity Jets to all-blocked callers 2026-10-17 00:46:49 -07:00
Codex b77f2238dd Use direct momentum in opt-in shifted blocked equilibrium 2026-10-17 00:18:00 -07:00
Codex c33caf636d Retain shifted density perturbation in opt-in blocked collision 2026-10-16 23:28:29 -07:00
Codex aaf35c6505 Add opt-in shifted raw remap GPU lifecycle gate 2026-10-16 23:28:09 -07:00
Codex b811b643e7 Support tagged shifted storage in blocked host transfers 2026-10-16 23:27:28 -07:00
Codex fbe73779c1 Build refinement transfers from union and pin physical body support 2026-10-16 20:51:29 -07:00
TRON 1e8e2c9a69 Clarify raw exchange metadata and streamline host tests 2026-10-16 18:58:30 -07:00
Codex c750493b07 Add opt-in row-owned raw boundary exchange for blocked refinement 2026-10-16 18:47:04 -07:00
ClaudeandClaude Opus 5.5 21bcb8a141 Keep the __main__ guard last in the multipatch unit test
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-17 01:37:44 +00:00
ClaudeandClaude Opus 5.5 8fa9ac0253 Test the initialize entry adapter forms
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-17 01:37:34 +00:00
ClaudeandClaude Opus 5.5 c11b138a09 Accept legacy named arrays in FixedPatchStepper.initialize
initialize(coarse_g=..., fine_g=..., child_g=...) raised TypeError after the
switch to *level_g. A small entry adapter (_initial_levels) maps either the
positional per-level form or the original names to one per-level tuple and
rejects mixed or incomplete forms with TypeError before any state check.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-17 01:37:24 +00:00
ClaudeandClaude Opus 5.5 7ecb179a41 Migrate stepper tests to the level-list representation
Schedule test drives _pairs[i].explode/coalesce and patches _advance(index,
buffer) for the stale L1->L2 feed mutant; remap rejection test patches
_boundary_hosts entries and hierarchy.pairs instead of the read-only views;
the GPU launch-failure test patches _pairs[0].explode. Assertions unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-17 01:36:41 +00:00
ClaudeandClaude Opus 5.5 edce582a2d Mark wall rows OUTER in a zero-refinement hierarchy
build_hierarchy(cfg, [], wall_aware=True) left both base wall rows ACTIVE;
the refined path already marked them OUTER. Add the regression test.
Found by native review of eeb90ac.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-17 01:31:42 +00:00
ClaudeandClaude Opus 5.5 baba5e02d9 Drive FixedPatchStepper by level lists and one recursive hop
The constructor builds lbm.hierarchy geometry, per-level layouts, kernel
configs, boundaries and leaf masks as lists, then one _build_level per level
and one _build_pair per adjacent pair. step() runs _hop(0): a child explodes
from its parent's hop source and advances twice, then the parent gathers
halos, stages receiver-local restriction, applies BFL and steps. Launch
sequence for existing two/three-level cases is unchanged; depth >= 4 works
for fully blocked hierarchies with bodies/Jets on the finest level.

New keywords refinements/level_blocks/level_objects/level_jets (L0 included);
legacy keywords are normalised by _legacy_levels and are mutually exclusive
with them. The dense two-level path stays as an isolated branch in _hop
(fused PatchCoarseStep root, dense fine BFL). Removed _child, _middle_kind
storage, _explode/_coalesce/_ghosts/_donors/_targets/_children,
_advance_child, _blocked_fine_boundary and _remap_blocks; existing public
attributes and the private names tests still read are thin read-only views.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-17 01:30:58 +00:00
ClaudeandClaude Opus 5.5 eeb90ace9a Add host-only arbitrary-depth refinement hierarchy builder
lbm/hierarchy.py loops the existing pair logic (FixedPatch2D/FixedPatchSet2D
for L0->L1, nest_patch/nest_patch_set for deeper pairs, _middle_config for
the per-level config chain) and returns validated per-level configs, pair
tables and composed kinds for any depth. Legacy scalar window forms are
accepted so existing public shapes are unchanged. Validates each config copy
because LBMConfig.omega is only computed by validate(). Not yet used by the
stepper.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-17 01:19:29 +00:00
ClaudeandClaude Opus 5.5 77c034a29a Move host-only blocked table helpers into refinement_tables
Pure move of blocked_fine_tables, blocked_kind, blocked_base_tables,
_BlockedBoundary and _prepare_blocked_boundary out of the pycuda-importing
refinement_stepper into a numpy-only module, so CPU tests can import them
directly. refinement_stepper re-exports the public names; no behaviour change.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-17 01:19:19 +00:00
TRON 60ad6b8b0d Generalize synchronized remap to multiple pinned body rectangles 2026-10-16 11:32:42 -07:00
TRON 864a220dbe Add research measured-strain fluid refinement example 2026-10-16 11:09:49 -07:00
TRON 6a7e9226db Add bounded pinned-circle manual L2 remapping 2026-10-16 10:41:56 -07:00
TRON 766658185f Add explicit synchronized L2 runtime continuation 2026-10-16 10:12:40 -07:00
TRON 999d3a0e94 Add synchronized CPU leaf population remap 2026-10-16 10:07:34 -07:00
TRON a24e6d2742 Support bounded three-level separated patch unions 2026-10-16 09:18:07 -07:00
TRON 20fb16ded5 Support stationary bodies and geometry Jets on nested L2 2026-10-16 08:49:08 -07:00
ClaudeandClaude Opus 5.5 64665319a4 Multipatch: fine_objects and jets on several patches (level-wide projection)
prepare_fine_boundary accepts a FixedPatchSet2D: objects are projected once
onto the level-wide fine grid (FixedPatchSet2D.fine_origin = (0, 0), same
coarse cell-edge -> fine cell transform), each circle must lie inside one
patch, coarse transfer cells are checked against the covered union, and body
ids stay object positions, so the existing jet one-body-per-jet, overlap and
(receiver, dir) writer checks run once over the whole level (caller obj_id
cannot bypass them). The stepper no longer rejects fine_objects/jets with
several patches; blocked link tables, BFL and the jet amplitude cache are
reused unchanged. No kernel change. README/docstring scope updated.

Tests: CPU translation/ids/rejections (outside one patch, one jet over two
bodies at zero amplitude); GPU one body via the new path == single-patch path
(both modes), two bodies (+jets, amplitude switch) == tiled single (bitwise).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-16 14:59:48 +00:00
ClaudeandClaude Opus 5.5 f1dcf329ff README: minimal three-level (nested child) usage and limits
Doc-only: child coordinates in L1 window cells, three arrays in/out, 1:2:4,
single body-free chain; example reuses the accepted 16/24/24 fixture.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-16 14:54:05 +00:00
ClaudeandClaude Opus 5.5 dd9a4dc4b8 Three levels: step unpacks only the first two levels; README multipatch nits
step() did 'c, f = self._levels', which raises for three levels before any
launch (root review). The child level is driven from the fine hops. Other
_levels uses are per-level loops or explicit indices. README multipatch
example now defines rest locally and states coarse/fine NaN separately.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-16 14:39:29 +00:00
ClaudeandClaude Opus 5.5 76555de4b8 Three levels: nested body-free child patch on a single chain
FixedPatchStepper(..., child=(x0,y0,x1,y1), child_block=(by,bx)) adds an L2
patch in L1 window cells (requires fine_block/base_block, one L1 patch, no
bodies/jets). nest_patch() builds the L1->L2 FixedPatch2D (2*nu on L1) and
the composed L1 kind (inherited INNER/OUTER kept, child-covered ACTIVE made
OUTER), rejecting from the actual tables: coverage outside ACTIVE, donors or
receivers not uncovered ACTIVE, surviving ACTIVE pulls of covered/OUTER cells
without a child-supplied arrival, and overlap with L1's restriction footprint.

Step order per L1 hop: explode L1(src)->L2, two L2 hops (halo, step), L1 halo,
receiver-local L2->L1 staging into src, L1 step. The second hop thus feeds L2
from the new L1 G; L2 is never refilled from L0; L0 stays once per step (1:2:4).
Existing kernels only; a small _Pair holds the child transfer bindings (explode
from the child module, parent window stride). Two-level API unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-16 14:35:57 +00:00
ClaudeandClaude Opus 5.5 6301887093 Multipatch: validate fine block before modulo, raw-core GPU checks, README usage
FixedPatchSet2D.fine_layout rejects non-positive, float, bool or wrong-length
block sizes with ValueError before any modulo (was ZeroDivisionError/TypeError).
The face gap-4 GPU test now checks raw owner cores directly by kind/covered
for every patch (ACTIVE finite, OUTER/holes/covered NaN; INNER not asserted),
not only the masked download and reversed-order parity. README documents the
body-free multipatch call, scope and level-wide fine shape.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-16 14:22:00 +00:00
ClaudeandClaude Opus 5.5 0397b6ebb7 Multipatch: CPU guards and frozen GPU gates through the new interface
One rectangle via the multipatch path is bit-identical to the old
single-patch blocked path (both modes, raw masks); S1 two-patch 16x32 equals
the 16x16 one-patch run tiled (bitwise), in both rectangle orders; face
gap-4 pair is order-invariant with exact covered/hole masks. Mass printed
as a diagnostic only.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-16 14:01:41 +00:00
ClaudeandClaude Opus 5.5 4c8240ea13 Multipatch: FixedPatchSet2D host metadata and opt-in FixedPatchStepper path
Several separated (>= 4 coarse cells) body-free 2:1 patches share one
level-wide fine grid stored by a sparse BlockLayout2D over the patch
supports. FixedPatchSet2D re-addresses each FixedPatch2D's tables to level
coordinates (same rows/child order, canonical patch order). The stepper
accepts a sequence of rectangles as bounds (requires fine_block and
base_block; rejects fine_objects/jets), reusing the existing blocked step
sequence and kernels. Helpers use a covered mask instead of one rectangle
and skip unstored fine holes. No kernel changes.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-16 14:00:50 +00:00
ClaudeandClaude Opus 5.5 93d1cddd27 BlockLayout2D.build: check capacity before generating regular origins
c397e08 moved the 64-bit capacity check after np.arange(nby*nbx), so an
over-limit regular layout allocated before rejecting. Check arithmetic
block count (regular) or validated selected count (sparse) first; mock
regression asserts no np.arange before the ValueError.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-16 03:27:13 +00:00
ClaudeandClaude Opus 5.5 68ecaf9e81 BlockLayout2D.to_dense: restore hole-only NaN fill guard
cc64abc dropped the guard, so full layouts with integer arrays raised on
an empty NaN assignment (regression caught by test_to_dense_dtype_contract).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-16 03:20:56 +00:00
ClaudeandClaude Opus 5.5 cc64abcafe BlockLayout2D.to_dense: require floats when the layout has holes
Holes are filled with NaN, which bool/str silently mangled and integers
rejected with a conversion error. Sparse layouts now raise a clear
ValueError for non-floating arrays; full layouts keep any dtype.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-16 03:16:52 +00:00
ClaudeandClaude Opus 5.5 aecee19c19 BlockLayout2D: copy caller-supplied origins
An int64 C-contiguous origins array was kept by reference (and frozen in
the caller's hands), so mutating it later changed layout.origins and
block_cell without changing owner/halos. Copy before marking read-only;
regression checks origins, owner and block_cell invariance.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-16 03:15:37 +00:00
ClaudeandClaude Opus 5.5 fa7fd9097a Test: map the q<.5 variant of a sparse cut link separately
The fixture listed (fluid_idx=13, dir=3) twice with different q, so the
existing repeated-link rejection fired before the sparse checks.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-16 03:14:55 +00:00
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 99ddb5fc27 Test: fine jet ownership uses remapped physical owners
Caller obj_id 99 spanning 2x2 fine blocks: driven rows carry the single
remapped owner 0 across several block ids, accepted; source id unchanged.
Caller ids (99, 7) under one tube are rejected at amplitude 0 and .002
on the 32x24 fixture; source ids unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-16 02:42:04 +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 063508d1a3 Jet amplitude setter: failed state on device errors, commit after upload
FixedPatchStepper.set_jet_amplitude validates index/amplitude and builds
the new rows before touching the device; invalid input leaves the
instance usable. A copy/sync error marks it failed (as initialize/step/
download do) and re-raises; host state (_jets, blocked velocity table)
commits only after a successful upload. CurvedLinkSoA.set_jet_amplitude
likewise uploads a new array first and commits jets/surface_velocity
afterwards. Focused mocked-driver tests for dense and blocked copy
failure, invalid input and IndexError.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-15 08:49:35 +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 aebef52345 Wire Jets into FixedPatchStepper fine level (dense and blocked)
FixedPatchStepper(..., jets=()) passes jets (coarse cell-edge frame, as
fine_objects) to prepare_fine_boundary, which runs the shared assignment
checks before CUDA. Dense fine path: assign_surface with jets and the
boundary's true hits. Blocked path: surface_link_velocity with jets/hits;
unit-amplitude shapes cached. set_jet_amplitude (new/ready only) validates
first, then rewrites the dense SoA column or the blocked jet rows and
re-uploads only the velocity buffer after a stream sync. Scheduling,
kernels and launch ABI unchanged.

tests/validation/multigrid/test_refinement_jets.py: mocked-driver CPU
checks and frozen GPU gates G1-G3 (layout identity, jet vs legacy <=1e-6,
amplitude switch).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-15 08:42:51 +00:00
ClaudeandClaude Opus 5.5 f26410f94a Merge base-blocked FixedPatchStepper 906e0d9 into claude/jet
Exact codex/refinement-blocked-base-20261015 head, cleared by Astra/root.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-15 08:41:38 +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
Frank14f 906e0d9a0e Support blocked parent storage in fixed patch stepping 2026-10-15 16:25:26 +08: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
ClaudeandClaude Opus 5.5 ca5a145107 README: primary demo command uses --fine-block 16 20
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-15 05:11:47 +00:00
ClaudeandClaude Opus 5.5 23ac099475 Example usage guards: reject negative --steps; document blocked command
Primary documented command (example docstring and README) now passes
--fine-block 16 20; omitting it keeps the dense default unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-15 05:11:39 +00:00
ClaudeandClaude Opus 5.5 749f103ea8 Example/docs closure fixes
- README: close the Manual stream control code fence before the new
  section; snippet now builds rest-equilibrium inputs (runnable as shown).
- Example: diagnostics use the known fluid-leaf masks (uncovered coarse
  minus slot-mode wall rows; fine ACTIVE minus solids) and raise on any
  non-finite population or rho <= 0 there instead of filtering by
  finiteness. No solver changes.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-15 05:11:13 +00:00
ClaudeandClaude Opus 5.5 5304525e39 Add fixed-patch circle example and README scope section
examples/fixed_patch_circle.py: 32x24 coarse, patch (8,6,24,18), circle
(16,12) R2.15 in the cell-edge frame with the tested 0.7/0.85 aperture;
--mode periodic|slot_reservoir, --speed (+/-, 0 passive), optional
--fine-block BY BX, default 128 coarse steps; rest-equilibrium
postcollision initialization, caller-owned context, fluid-only leaf
mass/density/speed printed every 32 steps; no output files.
README: experimental backend usage and scope (limits, cell-edge frame,
whole-allocation divisibility, fine_block as AMR infrastructure without
speedup claim, unavailable features). No solver changes.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-15 05:06:19 +00:00
ClaudeandClaude Opus 5.5 5c37d75dc4 Validate physical fine_cfg before surface_link_velocity
The blocked actuated path called the helper with an unvalidated fine
config (nq=0), so receiver*nq+dir collapsed distinct writers and the
unique-writer guard fired. Validate after wall-aware sanitization, as the
dense path does before assign_surface; the test's fine_cfg helper too.
Unique-writer guard unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-15 04:49:34 +00:00
ClaudeandClaude Opus 5.5 1a274817cd Test: Astra's actuated seam fixture (angle 0.7, half-width 0.85)
Asserts 21 aperture links, all with nonzero velocity, and 3 halo-writer
plus 2 halo-donor aperture rows in each decomposed layout (actuation
coverage across seams, not only geometric cut-link coverage). Velocity
is given in coarse units; prepare_fine_boundary scales it once. The GPU
gate remains storage equivalence; no zero-mass-change claim.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-15 04:45:57 +00:00
ClaudeandClaude Opus 5.5 7bf6101460 Blocked fine storage: velocity-only surface actuation on fixed circles
- curved_links.surface_link_velocity: pure host helper extracted from
  CurvedLinkSoA.assign_surface (which now calls it; dense path unchanged).
  Rows follow physical cut-link order.
- blocks.cu BlockCurvedBoundary: one nullable trailing surface_velocity
  argument (2 floats/link), same convention as CurvedBoundaryKernel; no
  exchange output. Both call sites pass it explicitly (PeriodicBlockStepper
  passes null; single-level behaviour unchanged).
- FixedPatchStepper blocked mode accepts actuated stationary circles,
  validated against the physical fine_cfg; uploads the velocity table only
  when any actuation spec exists and fails before BFL if that buffer is
  missing (even at zero amplitude). Blocked exchange diagnostics are
  unavailable; dense exchange behaviour unchanged. No force aggregation,
  no motion, no new numerical formula.
Tests: 1x1 seam (0,0), receivers in 4 blocks, all q<.5 links fallback 0;
dense SoA never built in blocked mode; launch order incl. null vs velocity
pointer; missing-buffer guard at 0 and 0.002; helper == assign_surface;
aperture crosses a seam; GPU: periodic and slot_reservoir, +/-0.002,
8 coarse steps, dense vs 1x1/2x2/4x2 exact values + NaN masks.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-15 04:45:17 +00:00
ClaudeandClaude Opus 5.5 2bbf82121e Blocked fine storage: passive stationary circles via receiver-local BFL
FixedPatchStepper(fine_block=..., fine_objects=[circle]) now accepts
passive stationary circles; any surface actuation is rejected before CUDA
(dense fine path unchanged). prepare_fine_boundary still decides legality
on the dense fine grid; its SoA is mapped by the new array-based storage
adapter blocks.blocked_link_tables (map_cut_links: unique receiver owner
and local writer, row order kept; blocked flags sized nblocks*L), which
PeriodicBlockStepper._static_circles now also uses (single-level legality
builder unchanged). Per fine hop on the same buffer: halo -> existing
BlockCurvedBoundary -> BlockStep(flags, kind). No CUDA changes.
Tests: fixture 76 links / 68 q<.5 and 8 seam writes + 8 seam donors per
decomposed layout (both modes); adapter flags sizing; mocked launch-order
contract; GPU: periodic and slot_reservoir, 8 coarse steps, dense fine
body vs 1x1/2x2/4x2 fine blocks, exact values + NaN masks on masked
downloads and raw final arrays, ACTIVE fluid finite, solid/OUTER NaN.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-15 04:25:09 +00:00
ClaudeandClaude Opus 5.5 59921a0181 Blocked fine: fix INNER assertion, skip empty halo uploads, explicit fixture
- GPU test: after hop 2 some INNER_GHOST populations are NaN (pulled from
  OUTER poisoned on hop 1; 236 slots in pinned CPUREF); assert ACTIVE
  finite and OUTER NaN, keep the full dense-vs-blocked raw value/NaN-mask
  comparison.
- A 1x1 non-periodic fine layout has zero halo pairs: skip the halo table
  uploads (CUDA rejects mem_alloc(0)); _fine_halo already skips launch.
  CPU guard test with driver doubles.
- Drop the class-level fine_layout default; the followup fake backend now
  sets fine_layout = None explicitly.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-15 03:52:42 +00:00
ClaudeandClaude Opus 5.5 dc5850c198 Add opt-in blocked fine storage to FixedPatchStepper
fine_block=(by, bx) partitions the ENTIRE fine_shape (incl. the four-cell
patch ghost band) with a non-periodic one-cell-halo BlockLayout2D; body-
free only (fine_objects rejected in blocked mode; dense fine-body and
actuation path unchanged). Per coarse step on the same stream:
BlockExplode into ghost owner cores -> gather -> BlockStep(kind) ->
gather -> BlockStep(kind) -> unchanged PatchCoarseStep reading remapped
owner-core child slots in the original row/child order. Public arrays
keep the dense fine shape; only the private allocation is blocked.
blocks.cu: explicit BlockExplode; BlockStep gains nullable kind
(OUTER skip pull + NaN, INNER pull only, ACTIVE pull + SRT).
PeriodicBlockStepper passes an explicit null kind (raw launch ABI).
refinement.cu/refinement.py and coarse numerics unchanged.
Tests: CPU rejections and table remap (dense (q,cell) and child order
preserved, owner cores, kinds); GPU gate: periodic and slot_reservoir,
8 coarse steps, dense vs 1x1/2x2/4x2 fine blocks bit-identical in
masked downloads and raw coarse/unpacked fine incl. ghost NaN masks.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-15 03:48:54 +00:00
ClaudeandClaude Opus 5.5 3e44e90ca5 Test: negative-radius regression at integer center (16, 12)
At the half-integer center the -0.1/-0.5 circles were already rejected
as unresolved, so the case did not exercise the finite/positive-radius
guard; an integer center makes the squared radius mark one solid cell.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-15 03:46:14 +00:00
ClaudeandClaude Opus 5.5 eeda651626 Reject nonfinite or nonpositive circle geometry; tuple-normalize objects
_static_circles now checks finite center/radius and radius > 0 before
build_flag_mask (a negative radius squared to a one-cell solid), matching
prepare_fine_boundary. objects is converted to a tuple before the
emptiness test so an empty iterable takes the body-free path.
CPU tests: negative/NaN radius and nonfinite center rejected before CUDA;
empty iterator skips circle preparation.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-15 03:29:46 +00:00
ClaudeandClaude Opus 5.5 1a2d58312d Add stationary passive circles across same-level block seams
blocks.cu: BlockCurvedBoundary passes the receiver-local core cell and the
block-offset fi to the unchanged apply_bouzidi_link (Uw=Vw=0, obs=nullptr),
so k_s and the q<1/2 donor follow the window image the next pull reads.
BlockStep takes nullable block-cell flags; solid cores store NaN each step.
Adds core/flags.cuh, core/obs.cuh and boundary/curved_boundary.cuh.
block_stepper.py: objects=() accepts stationary passive circles only; host
preparation rejects before CUDA: non-circle/moving/actuated/sensor roles,
overlap, domain-edge contact, and any fluid core (all rows/columns, periodic
neighbors) whose pull from a solid lacks exactly one cut link. Uses
map_cut_links for unique receiver owner/local writer. Order per step:
halo copy -> BFL -> pull/collide, no copy in between. Fluid-only
initialize validation; solids NaN.
Tests: CPU rejections/tables; GPU 32x24, nu .1, 8 steps, circle
(15.5,11.5) R4.3 with halo-write and halo-donor presence asserted,
1x1/2x2/4x2 bit-identical, finite fluid/NaN solid, FP64 BFL+pull/SRT
<= 3e-6 on fluid; drift reported. Body-free gate unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-15 03:25:36 +00:00
Frank14f 865bb0d6e0 Merge claude/block-gpu-periodic for bounded integration validation 2026-10-15 11:08:38 +08:00
ClaudeandClaude Opus 5.5 7071ed32a6 Test fixture: set _step_count for a complete ready state
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-15 02:59:40 +00:00
ClaudeandClaude Opus 5.5 7281d91fd6 Release the compiled module on close
close() now clears _module (initialized to None) inside the active
context together with the function references; lifecycle test asserts
it is retained on failed activation and cleared after close.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-15 02:59:08 +00:00
ClaudeandClaude Opus 5.5 4645e48a2c Test fixture: give fake backend mock halo table pointers
step() reads _dst/_src before the launch; without them the failed-launch
test raised AttributeError instead of the intended RuntimeError.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-15 02:55:39 +00:00
Frank14f 99c86e441c Integrate grok/wall-transfer-validation for bounded validation 2026-10-15 10:53:20 +08:00
Frank14f a0a13402f3 Integrate claude/block-layout for bounded validation 2026-10-15 10:53:20 +08:00
ClaudeandClaude Opus 5.5 4029a0b27e Add body-free periodic GPU consumer for BlockLayout2D
blocks.cu: separate compilation entry with NX/NY = block window (halo
included), blockIdx.z selects the block; BlockHaloCopy refreshes halos
from owner cores, BlockStep pulls/collides core cells with the existing
compute_rho_u/compute_feq/collide_srt_no_force. Existing kernels and
refinement numerics unchanged.
block_stepper.py: PeriodicBlockStepper (D2Q9/SRT/FP32 double buffers,
doubly periodic layout); launch-limit and free-memory checks before any
allocation; uploads only halo pairs; spare buffer starts NaN; lifecycle
mirrors FixedPatchStepper.
Tests: CPU contract doubles (rejections before CUDA/allocation, initialize
guards, failure/close/retry) and one GPU case: 32x24, 8 steps, 1x1/2x2/4x2
splits bit-identical, FP64 oracle max abs <= 3e-6, drift reported.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-15 02:49:09 +00: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 d27d344f43 Add source-path header comment to blocks.py
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-15 02:39:58 +00: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 3a7967f4cc Document baseline scope, clean CPU checks and retained limitations 2026-10-15 10:18:01 +08:00
Frank14f 263f3b0c7a Preserve bounded validation evidence and historical failures 2026-10-15 10:13:51 +08:00
Frank14f cdbb9c42f6 Add jet, surface and fixed-patch tests and runnable examples 2026-10-15 10:13:49 +08:00
Frank14f ed1a6ee54e Preserve D2 repairs and add bounded jet and fixed-patch kernels 2026-10-15 10:13:49 +08:00
Frank14fandCursor 6e3756c587 fix(esopull): correct init layout and pre-streaming semantics (v0.5.1)
EsoPull curved boundaries and wall BCs now use consistent backing-layout
reads; InitEsoPull writes equilibrium in t=0 EsoPull layout. Cache N_OBJS
after compile and atomic config header writes to avoid parallel races.
Adds config screening tools, flume configs, and FP16S/EsoPull diagnosis doc.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-27 22:32:01 +08:00
Frank14fandCursor 00b957f904 feat(esopull): runtime body sync for EsoPull streaming mode
- New esopull_sync.cu: DecodeCellsToPhysical + EncodePhysicalToCells
  (compact-list mode, ddf_shifting-aware, encode applies collision).
- sync_bodies() now branches for double_buffer vs esopull: decode
  backing layout to physical DDF on GPU -> host patch -> collide +
  encode back to backing layout. No temp_gpu, no full-grid copy.
- 4 new integration tests covering esopull add/remove/cycle/roundtrip.
- ddf_shifting + esopull + sync_bodies jointly verified (1300 steps
  stable after add/remove).
- Bump version to 0.5.0.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-21 22:31:02 +08:00
Frank14fandCursor 04c2bc75ea feat(obs): unified zero_obs control and time-normalised readback
- Replace split zero_force_segment / zero_sensor_segment with unified
  zero_obs_async() — a single memset covers all three obs segments
  (force, torque, sensor), resetting the step accumulator.
- Add _obs_accum_steps counter so read_*(normalize=True) returns the
  physically meaningful per-step average for all telemetry fields.
- Sensor now always applies area-normalisation internally; the normalize
  parameter only controls the additional time-normalisation step.
- run() gains zero_obs=True parameter (default) to control reset-on-step.
- 7 new integration tests covering accumulation, zeroing, and normalise.
- Fix bug in test_sensor_accuracy.py (undefined loop variable i).
- Bump version to 0.4.0 for the API change.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-21 00:50:20 +08:00
Frank14fandCursor 7a609b2c76 chore: remove legacy, sync generated config headers, fix inlet kernel
- Remove legacy/ directory (superseded by current architecture).
- Sync auto-generated config headers (config_grid.h, config_objects.h,
  config_method.h, config_physics.h) for current LBMConfig defaults.
- Sync zou_he_local.cuh inlet kernel changes.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-20 18:48:23 +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
Frank14fandCursor d5b7e98750 feat(compat): FP16S and ddf_shifting compatibility, EsoPull curved closure
Phase A: FP16S store precision verification
- Kan99b K2 FP16S: quantization sensitivity documented (St 0.170 -> 0.142)
- Sah04 S2 FP16S: PASS (St error 1.53% within 5% gate)
- Sah04 S4 FP16S: diverges at high blockage (known limitation)

Phase B: ddf_shifting code fixes
- Fix inlet west_velocity_rho_closure for shifted DDF (common.cuh)
- Fix curved force/torque accumulation for shifted DDF (curved_boundary.cuh, aux_kernels.cu)
- Fix host upload_ddf() asymmetry (field.py)
- Add checkpoint streaming/ddf_shifting match check (checkpoint.py)
- MRT shifting fix: MRT is NOT shift-invariant; unshift/reshift around collision
- Generalize inlet knowns repair from Zou-He to all west inlet schemes

Phase C: EsoPull curved boundary semantic closure (from round 2)
- streaming/esopull_semantic_helpers.cuh: single truth for physical-value semantics
- step/esopull_macro.cu: MacroscopicEsoPullKernel for correct GPU diagnostics
- SensorKernel, ForceRegionKernel share semantic helpers
- Kan99b K2: bit-identical to double-buffer
- Code-level comments document compatibility boundaries
- README updated with compatibility matrix
- output/round3_compatibility_summary.md: full round documentation

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-03 10:48:42 +08:00
Frank14fandCursor b110591433 feat(body): add force_region, fix sensor API, reorganize docs
- Add force_region object type: local Guo forcing via sparse compact list
- ForceRegionSoA container, ForceRegionKernel, stepper dispatch
- add_body("force_region", ...) + set_force(id, fx, fy) API
- Fix read_sensor(normalize=...) not being passed from Simulation layer
- Fix force_region incorrectly entering curved cut-link path (P0 blocker)
- Clean up module boundaries: body/__init__ no longer imports from lbm
- Circluar import fix: common/streakline <-> pathline
- Package data globs fixed for recursive kernel files
- Version unified to 0.3.0
- Performance analysis: pycuda launch overhead vs GPU compute at various grid sizes
- Nsight Systems + Nsight Compute profiling data and report
- Documentation reorganized under docs/ (audit, validation_specs)
- README overhaul: multi-body examples, validated benchmarks, force_region docs

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-01 18:07:55 +08:00
Frank14f 2e052480c2 重构body api,性能分析,项目整理 2026-05-31 01:42:58 +08:00
Frank14f 4758eb3215 Add streakline post-processing and exp control-matrix batch runners (vorticity + streakline) 2026-05-27 19:19:51 +08:00
Frank14f 50b2b6a7ca zou_he inlet无法保障稳定,加入新的inlet模式 2026-05-18 17:51:46 +08:00
Frank14f ce492f2794 Sah04验证部分通过,临时修复部分NEQ inlet解决高阻塞流动。kan99b验证初期。 2026-05-16 21:52:06 +08:00
Frank14f 925417abcb Undermind审计前,Cursor重构 2026-05-12 19:08:49 +08:00
Frank14f 654e3290a4 重构:分级设计,EsoPull 2026-04-17 21:50:38 +08:00
Frank14f b339f302d3 Add TRT-LES diagnostics and plotting functionality
- Introduced new functions for computing and plotting TRT-LES fields.
- Enhanced case diagnostics to include mass drift and inlet variance metrics.
- Updated configuration to support inlet profile selection and TRT magic parameter.
- Modified existing functions to accommodate new diagnostic calculations.
- Improved case tagging to include inlet profile and TRT parameters.
- Added checks for fluid dynamics and diagnostics in the run_case function.
2026-04-06 15:57:44 +08:00
Frank14f 5076e5d789 improve LES stability 2026-03-29 22:16:20 +08:00
Frank14f f3e2e557d4 D3Q19 SRT 2026-03-17 18:14:56 +08:00
Frank14f d3b32c8be3 重构: 采用模块化 src 布局
- 重组代码为模块化结构:lbm/, common/, cuda/
- LBM 相关代码移至 src/CelerisLab/lbm/
- 通用工具移至 src/CelerisLab/common/
- CUDA 编译器移至 src/CelerisLab/cuda/
- 更新所有导入路径以适配新结构
- 提供灵活的导入接口(直接导入/模块导入/命名空间风格)
- 为未来扩展(FEM, SPH, MPM 等)做好准备
2026-02-20 15:02:24 +08:00
Frank14f 1137e9a247 SyncTest 2026-02-15 23:13:03 +08:00
Frank14f 0e1b69a55b GiteaSyncTest 2026-02-15 23:12:12 +08:00
Frank14f 304d4f3fe5 Gitea sync 2026-02-15 22:53:38 +08:00
Frank14f 99c175042a Initial commit: CelerisLab v0.2.0 with src layout 2026-02-15 22:36:46 +08:00
559 changed files with 131486 additions and 2150 deletions
+56
View File
@@ -0,0 +1,56 @@
---
description: CUDA/C++ naming — macros, kernels, device helpers, module growth
globs: src/**/*.cu,src/**/*.cuh,src/**/*.h
---
# CUDA and GPU-side naming (CelerisLab)
## File banner and guards
- First line of each hand-written `.cu` / `.cuh`: `// CelerisLab – <path_under_lbm/kernels/>` (en-dash `–`), matching siblings (e.g. `operators/collision_srt.cuh`, `step/one_step_double.cu`).
- Include guards: `CELERIS_<PATH_UPPER>_<STEM>_CUH` (match existing pattern, e.g. `CELERIS_OPERATORS_COLLISION_SRT_CUH`).
- Auto-generated headers under `lbm/kernels/config/` must start with:
`// AUTO-GENERATED by CelerisLab compiler – DO NOT EDIT MANUALLY`
## Module domains (plan for growth)
Keep names readable across domains. Today most GPU code lives under `lbm/kernels/`; future areas may add parallel trees (e.g. particles, deformable solids). Use consistent **semantic** prefixes in identifiers when ambiguity is likely:
| Domain | Scope (conceptual) | Identifier hint |
|--------|-------------------|-----------------|
| Orchestration | Host-side launch, thin wrappers | Already mostly Python; CUDA entry files stay thin |
| Common | Shared numerics / helpers used by multiple domains | Prefer neutral names (`clamp01`, `dot3`) or `cel_*` only if truly project-global |
| LBM | Lattice, collision, streaming, macroscopic | `collide_*`, `stream_*`, `macro_*`, step drivers `one_step_*` — keep physics meaning in the name |
| Body / IBM | Immersed boundaries, rigid surfaces | `ibm_*`, `curved_*`, `cut_link_*` style names where they describe physics |
| Future: flexible solids | Not present yet | Reserve `flex_*` or a dedicated subdirectory prefix when added |
| Future: particles | Not present yet | Reserve `part_*` or `particle_*` under a dedicated subtree when added |
Do not rename working kernels for style alone in a mixed PR with behavior changes; batch renames in a dedicated change after audit.
## Config macros (`config_*.h`)
- Macros are compile-time switches and constants. Prefer **layer + clear token**:
- **Grid**: `NX`, `NY`, `NZ`, `DIM`, `NQ`, … (existing tier “Global/Grid”).
- **Physics**: `VIS`, `RHO`, `U0`, … (existing).
- **Method**: group by sub-area where possible — collision (`COLLISION_MODEL`, …), streaming (`STREAMING_MODEL`, …), LES (`USE_LES` / future `LES_*`), inlet/outlet (`INLET_*`, `OUTLET_*`), stability guards (`OMEGA_COLLISION_*`, `TRT_MAGIC_PARAM`, …).
- **Objects / case**: `N_OBJS`, …
- When **adding** macros, pick names that won’t collide across layers and that encode the tier (document in `configs/CONFIG.md` and in compiler mapping).
- Full normalization of legacy macro names is a **separate refactor** (compiler + all `#ifdef` / macro uses).
## Device functions and kernels
- Device helpers: `__device__ __forceinline__`; prefer small verbs (`compute_feq`, `apply_bc_wall`).
- Pointer parameters that are not aliased: use `__restrict__` where appropriate.
- Kernel entry points (`__global__`): name should state **what step** and **which path** (e.g. `step_lbm_double_buffer`), not only `kernel_launch`.
## Flags and constants
- Cell flags live in `core/flags.cuh`: keep `FLAG_*`, `MASK_*`, and helpers (`is_fluid`, …). Do not change bit layout without a versioned migration plan.
- Python flag constants in `lbm/descriptors.py` must stay consistent with GPU flags; any change updates both sides and user docs.
## Section comments
- File-level title: `// ==== Title ====` or equivalent single banner.
- Subsections: `// --- Section ---` or aligned `// -----` blocks — pick one style **within a file** and match neighbors.
+47
View File
@@ -0,0 +1,47 @@
---
description: Layout, forbidden paths, doc sync across README / CONFIG / code
alwaysApply: true
---
# Project layout and documentation discipline (CelerisLab)
## Source tree (authoritative roles)
- [`src/CelerisLab/simulation.py`](src/CelerisLab/simulation.py): Top-level orchestration API (`Simulation`).
- [`src/CelerisLab/config.py`](src/CelerisLab/config.py): `LBMConfig` / `BodyConfig`, load/validate JSON.
- [`src/CelerisLab/configs/`](src/CelerisLab/configs/): JSON defaults and [`CONFIG.md`](src/CelerisLab/configs/CONFIG.md) (human-oriented parameter reference).
- [`src/CelerisLab/cuda/`](src/CelerisLab/cuda/): CUDA context, compile pipeline, **generation** of `lbm/kernels/config/*.h`.
- [`src/CelerisLab/lbm/`](src/CelerisLab/lbm/): Python field/stepper; [`lbm/kernels/`](src/CelerisLab/lbm/kernels/) holds `.cu` / `.cuh` implementation.
- [`src/CelerisLab/body/`](src/CelerisLab/body/): Rigid-style objects, `ObjectManager`, GPU sync for IBM/sensors.
- [`src/CelerisLab/common/`](src/CelerisLab/common/): Shared host utilities (checkpoint, preprocess, …).
Future domains (flexible solids, particles, etc.) should get **new packages** under `src/CelerisLab/` (e.g. `flex/`, `particle/`) and, if they need GPU code, sibling trees under a clear namespace — not ad-hoc files at repo root.
## Do not edit by hand
- `src/CelerisLab/lbm/kernels/config/*.h` — generated by the compiler from `LBMConfig`; change [`cuda/compiler_v2.py`](src/CelerisLab/cuda/compiler_v2.py) and JSON/schema instead.
- `**/*.ptx` — build artifact.
## Low-value context for agents
- [`legacy/`](legacy/): superseded; do not extend.
- [`ref/`](ref/): external reference trees; not part of the shipping package.
(Also listed in [`.cursorignore`](.cursorignore) to save indexing cost.)
## Configuration and documentation sync (critical)
Agents often update one layer and leave others stale. After changing **any** of the following, reconcile **all** that apply in the same task or an immediately following doc-only commit:
1. **JSON keys or shape** in `configs/config_lbm.json` / `config_body.json`
2. **Fields or validation** in `config.py`
3. **Generated macro names or tiers** in `compiler_v2.py` → `kernels/config/*.h`
4. **[`configs/CONFIG.md`](src/CelerisLab/configs/CONFIG.md)** — tables and “config → code” diagram
5. **[`README.md`](README.md)** — Quick Start JSON example, API bullets, Project Layout if paths change
6. **Docstrings** on `Simulation` and other public entry points if behavior or parameters change
Goal: one mental model — README example, CONFIG.md, and actual loader agree.
## Tests
- Behavioral changes should touch or add coverage under [`tests/`](tests/) when feasible.
+34
View File
@@ -0,0 +1,34 @@
---
description: Python style for CelerisLab — path header, docstrings, English comments
alwaysApply: true
---
# Python style (CelerisLab)
## File header
- Every `src/CelerisLab/**/*.py` file starts with a single-line path comment so agents can orient without reading the body:
- Format: `# CelerisLab/<path_under_package>` (e.g. `# CelerisLab/simulation.py`).
- Match the real path under `CelerisLab/` after edits or moves.
## Language
- All comments and docstrings in Python source are **English**. User-facing prose in `configs/CONFIG.md` may stay Chinese if that file is explicitly maintained for Chinese readers.
## Docstrings and structure
- Module docstring: one-line summary plus at least one structured block where useful (`Usage::`, `Responsibilities:`, `Design:`).
- Public classes and public functions/methods should have a docstring that states purpose; use Google-style sections (`Args:`, `Returns:`, `Raises:`) when parameters or return value are non-obvious.
- Section dividers in long files: `# -- Section name ---------------------------------------` (consistent with existing files like `simulation.py`).
## Types
- Prefer type hints on public APIs (`Simulation`, `ObjectManager`, `LBMField`, config loaders). Completeness can improve incrementally; do not block features on perfect annotation coverage.
## Imports
- Avoid obvious dead imports when touching a file, but **do not** run broad “import cleanup only” refactors as a standalone task unless asked.
## Placeholders
- Stub methods: `pass` plus a short docstring; mark intent with `(placeholder)` or `(future)` where appropriate.
+10
View File
@@ -0,0 +1,10 @@
# Cursor indexing / context — keep noise out of agent view
# (Independent of .gitignore; ref/legacy are huge or obsolete.)
# ref/
legacy/
output/*.pdf
**/*.ptx
**/__pycache__/
.git/
+75
View File
@@ -0,0 +1,75 @@
# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
*$py.class
*.so
# Distribution / packaging
.Python
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
wheels/
*.egg-info/
.installed.cfg
*.egg
# CUDA compilation outputs
*.ptx
*.cubin
# IDE
.vscode/
.github/
.idea/
*.swp
*.swo
*~
# Jupyter Notebook
.ipynb_checkpoints
# PyCharm
.idea/
# Unit test / coverage reports
htmlcov/
.tox/
.coverage
.coverage.*
.cache
.pytest_cache/
nosetests.xml
coverage.xml
*.cover
# Environments
.env
.venv
env/
venv/
ENV/
env.bak/
venv.bak/
# MacOS
.DS_Store
# Temporary files
*.tmp
*.bak
*.log
# reference:
ref/
output/
legacy/
+85
View File
@@ -0,0 +1,85 @@
Jet / fixed-patch review baseline — 2026-10-15
Base main: 6e3756c587ec08ab6a55c4a1a5f4671822d3f0a0
Branch: baseline/jet-amr-20261014
Publication target: Gitea Frank14f/CelerisLab only. This baseline does not
advance main, publish to GitHub, or add new solver behavior.
Scope
The approved inventory contributes 43 previously tracked modifications and
282 new files: D2 correctness/build/state repairs; planar slot/reservoir jet;
static-circle surface actuation; one fixed 2:1 refinement patch; fine-interior
circle integration; tests, examples and small historical validation records.
Three reviewed repair logs are additionally retained: final-unit.log,
final-gpu.log and simplification-checks.log. This explanation is the only new
project document. Total: 329 changed/added paths relative to base main.
Implementation: ed1a6ee54e07a5efbdc3f1880fde4cc357b10d7c (41 files)
Tests/examples: cdbb9c42f6bfc65ec319313fb4e16cdc04dfdb95 (48 files)
Historical evidence: 263f3b0c7addce7bacbb068f75ea707cf20b6810 (239 files)
Historical source snapshots are evidence, not alternative runtime modules.
Explicit exclusions
The user's local changes to src/CelerisLab/lbm/kernels/config/config_grid.h,
config_method.h, config_objects.h, config_physics.h and
tests/postproc/experiment.ipynb are not included. Their already committed
base-main versions remain in the tree. Their five original-user-files backups
are excluded. Also excluded: the six pre-existing docs/design files,
docs/multilevel_grid_architecture_analysis.md, tests/audit/body删减功能.md,
tests/validation/multigrid/MULTIGRID_VERIFICATION_STRATEGY.md, the twenty files
under research/audit-2026-10-09 and research/design-2026-10-09,
research/j3-lag-2026-10-12/trajectory.h5, caches and the other twenty-two ignored
historical output files. These exclusions preserve local originals; they are
not deletions from the working copy. Historical manifests/reports can reference
excluded material. In particular analyze_j3_saved_frames.py needs the omitted
17.2 MB trajectory, and historical example images/summaries are not all bundled.
This is a selected review baseline, not a self-contained archival data package.
Fresh clean-checkout checks
Detached checkout of 263f3b0c7addce7bacbb068f75ea707cf20b6810 was clean before
and after both successful batches. Its four generated config headers and
experiment notebook were byte-equal to base main; excluded untracked files
were absent. Existing pycuda_3_10 interpreter; PYTHONPATH explicitly selected
the clean checkout's src, which was asserted at startup. CUDA_VISIBLE_DEVICES
was empty. No CUDA context/GPU simulation or new CFD trajectory was requested.
pytest selection 1 (tests/unit): test_refinement.py, test_fine_surface.py.
Result: 24 passed, 23 subtests passed, exit 0; pytest time 0.75 seconds.
pytest selection 2 (tests/unit): test_build_contracts.py,
test_context_ownership.py, test_initializers.py, test_simulation_lifecycle.py,
test_state_regressions.py, test_surface_actuation.py, test_planar_velocity.py,
test_slot_velocity.py, test_reservoir.py.
Result: 152 passed, 13 subtests passed, exit 0; pytest time 5.06 seconds.
Both used -q -p no:cacheprovider, PYTHONNOUSERSITE=1,
PYTHONDONTWRITEBYTECODE=1, PYTEST_DISABLE_PLUGIN_AUTOLOAD=1,
OPENBLAS_NUM_THREADS=1 and OMP_NUM_THREADS=1. Boundary-header tests use the
existing C++ compiler; compilation-contract tests mock the CUDA compiler.
The first host-contract batch was interrupted when the temporary monitoring
script raced a removed private build directory. Its test exit is unknown;
it is not counted as a pass. Only the monitor was corrected and that batch
rerun; the initial geometry batch was not repeated. Project code and test
criteria were unchanged. The final documentation-only commit does not alter
the tested implementation, tests, configuration or historical evidence.
Historical limits retained
- J3 positive/negative full velocity steady-state criteria did not pass.
- The local-stress implementation README records Claude's review as incomplete;
numerical execution is not a substitute for that implementation review.
- repair provenance.json retains earlier 124/66 totals; final logs record
130 unit +13 subtests and 74 GPU tests. simplification-checks.log describes
an earlier phase with known XFAILs, not a new result on this baseline.
- The 24-coarse-step joint run demonstrates startup disturbances crossing the
interface, potentially acoustic. It does not establish a developed jet,
physical accuracy, convergence order or long-term stability. Raw FP32 mass
residuals remain nonzero despite the independently measured rounding ledger.
- Fixed-patch support is not dynamic/block-level AMR, moving rigid bodies,
complete 3D or multi-GPU support. Historical full suites were not rerun here.
Publication screening
Approved candidate bytes and the three logs were checked for common embedded
credential/private-key patterns and unrelated private-location indicators;
unchanged tracked blobs and staged content were also checked. No findings were
detected. This bounded check is not a general security audit. Excluded files
were hash-protected. No credentials, accounts, environments or remotes were
modified by the baseline preparation.
+21
View File
@@ -0,0 +1,21 @@
MIT License
Copyright (c) 2026 Frank14f
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
+712
View File
@@ -0,0 +1,712 @@
# CelerisLab
**GPU-Accelerated Lattice Boltzmann Method (LBM) CFD Solver**
CelerisLab is a high-performance computational fluid dynamics solver based on the Lattice Boltzmann Method, leveraging NVIDIA CUDA for GPU acceleration. It provides a Python API for scripting, real-time control loop integration, and scientific workflow automation.
## Features
- **GPU Acceleration**: CUDA kernels for high-performance simulation (384x192 D2Q9: ~4400 MLUPS on V100)
- **D2Q9 / D3Q19 Lattice**: 2D and 3D lattice implementations
- **Multiple Collision Models**: SRT, TRT, and MRT operators; Smagorinsky LES subgrid model
- **Dual Streaming Paths**: Standard double-buffer pull and memory-efficient esoteric-pull (EsoPull). EsoPull is verified as numerically equivalent to double-buffer for D2Q9 curved-boundary MRT (Kan99b K2 validation).
- **Curved Boundary Bouzidi**: Immersed boundary support for complex geometries with wall velocity control
- **Flexible Boundary Conditions**: NEQ-extrapolation pressure outlet, parabolic/uniform velocity inlet, half-way bounce-back walls
- **Rotating Body Control**: Real-time setting of body rotation speeds via `sim.set_body()`
- **Force / Torque / Sensor Readback**: On-demand force, torque, and area-averaged sensor velocity
- **Physics Validated**: Strouhal numbers match Sah04 (confined cylinder) and Kan99b (rotating cylinder) references
## Quick Start
### Single cylinder
```python
from CelerisLab import Simulation
sim = Simulation()
sim.add_body("circle", center=(50, 50), radius=10)
sim.initialize()
for step in range(10000):
sim.run(1)
macro = sim.get_macroscopic() # {"rho": ..., "ux": ..., "uy": ...}
force = sim.read_force(0) # [fx, fy] on body 0
sim.close()
```
### DRL control loop
```python
from CelerisLab import Simulation
sim = Simulation()
sim.add_body("circle", center=(256, 128), radius=10)
sim.add_body("sensor", center=(300, 128), radius=10)
sim.initialize()
for episode in range(100):
# Step the simulation (auto uploads action, downloads obs)
sim.run(100)
# Read individual body telemetry (primary API)
data = sim.read_body(0)
print(f"step={sim.stepper.step_count} "
f"force=({data.force[0]:.4f},{data.force[1]:.4f}) "
f"sensor=({data.sensor[0]:.4f},{data.sensor[1]:.4f})")
# DRL policy inference (replace with your model)
action_omega = 0.001 * (0.5 - data.force[0])
# Set action (host-only, will be auto-uploaded next run)
sim.set_body(0, omega=action_omega)
sim.close()
```
### Async control (performance-oriented, custom stream)
```python
import pycuda.driver as cuda
stream = cuda.Stream()
sim.set_body(0, omega=0.002) # host-only
sim.run(100, stream=stream) # action uploaded, steps run, obs downloaded on stream
# stream is synced inside run() -- obs is ready
data = sim.read_body(0)
```
### Manual stream control (max overlap)
```python
import pycuda.driver as cuda
stream = cuda.Stream()
# Skip transfers for the first batch, just enqueue kernels
sim.run(100, stream=stream, upload_act=False, sync_obs=False)
# ... other GPU work can overlap with the kernel launches ...
# Later: sync and read
stream.synchronize()
obs = sim.read_bodies(stream=stream) # sync already done, just read pinned buffer
```
### Fixed 2:1 refinement patch (experimental backend)
`FixedPatchStepper` advances one fixed 2:1 refinement patch inside a coarse
grid, optionally with stationary circles in the fine region and a prescribed
normal surface velocity (blowing/suction). It is a standalone backend, not part
of `Simulation`. Runnable demo (blocked fine storage; omit `--fine-block`
for dense): `PYTHONPATH="$PWD/src" python examples/fixed_patch_circle.py --fine-block 16 20`.
```python
import numpy as np
from CelerisLab.body.geometry.circle import CircleGeometry
from CelerisLab.body.objects import SimObject, SurfaceActuation
from CelerisLab.config import LBMConfig
from CelerisLab.cuda.context import CudaContext
from CelerisLab.lbm.equilibrium import compute_feq_d2q9
from CelerisLab.lbm.refinement_stepper import FixedPatchStepper
cfg = LBMConfig(nx=32, ny=24, viscosity=.1)
body = SimObject(0, geometry=CircleGeometry(16.0, 12.0, 2.15), center=(16.0, 12.0), radius=2.15,
surface_actuation=SurfaceActuation(0.7, 0.85, 0.002)) # angle, half-width, speed
with CudaContext(0) as ctx, FixedPatchStepper(cfg, (8, 6, 24, 18), context=ctx,
fine_objects=[body], fine_block=(16, 20)) as run:
rest = np.asarray(compute_feq_d2q9(1.0, 0.0, 0.0), np.float32)[:, None, None]
# (9, ny, nx) postcollision populations per level; non-leaf cells are discarded.
run.initialize(np.broadcast_to(rest, (9, *run.patch.coarse_shape)),
np.broadcast_to(rest, (9, *run.patch.fine_shape)))
run.step(128) # coarse steps; fine level takes two per step
coarse_g, fine_g = run.download() # NaN on covered, ghost and solid cells
```
Scope and limits:
- The examples below use D2Q9, SRT, FP32, double buffer, unshifted, no LES or
forcing. Fixed 2:1 hierarchies can use level lists of arbitrary depth; the
legacy two/three-level forms are shown below.
- `coarse_boundary="periodic"` (default) or `"slot_reservoir"` (bottom slot, top
reservoir; patch needs `y0 >= 4`, `y1 <= ny-4`). Periodic mode ignores the wall/slot config fields.
- Object centers/radii use the coarse **cell-edge** frame (cell `I` spans `[I, I+1)`),
unlike `Simulation`'s integer-node frame. Surface speeds are in coarse lattice units.
- Bodies must be stationary circles whose whole boundary stencil lies in the fine
active region, clear of the coarse/fine transfer cells; violations are rejected
before any GPU allocation.
- `fine_block=(by, bx)` stores the fine level in fixed-size blocks; `by`/`bx` must
divide the WHOLE fine allocation, i.e. `2*(y1-y0)+8` by `2*(x1-x0)+8` including the
four-cell ghost band. It gives results identical to dense storage and is
infrastructure for future block AMR, not a speedup.
- Several regions: pass a sequence of `(x0, y0, x1, y1)` rectangles as
`bounds`, with both `fine_block` and `base_block`. Transfers are built once
from their union; adjacent, overlapping and concave unions are accepted when
their actual dependencies close. There is no fixed rectangle-gap rule.
The fine level is then one level-wide grid `(2*ny, 2*nx)`:
`run.patch.fine_shape` gives it, `initialize`/`download` use it, and only the
grid-aligned tiles intersecting the union plus its four-cell ghost band are stored.
Block sizes must divide the level-wide grid; rectangle edges need not align
with tiles. Order of rectangles does not matter. `fine_objects`/`jets` work
as for one patch: each circle (same coarse cell-edge frame) must lie wholly
inside the union's active region with
its boundary stencil clear of transfer cells; a jet may not select links of two
different bodies, even across regions. Wall-touching patches remain unsupported.
For nesting, use the level lists or legacy child forms below.
```python
cfg = LBMConfig(nx=32, ny=16, viscosity=.1)
rest = np.asarray(compute_feq_d2q9(1.0, 0.0, 0.0), np.float32)[:, None, None]
with CudaContext(0) as ctx, FixedPatchStepper(
cfg, ((4, 4, 12, 12), (16, 4, 24, 12)), context=ctx,
fine_block=(4, 4), base_block=(4, 4)) as run:
run.initialize(np.broadcast_to(rest, (9, *run.patch.coarse_shape)),
np.broadcast_to(rest, (9, *run.patch.fine_shape))) # (9, 32, 64)
run.step(32)
coarse_g, fine_g = run.download() # coarse: NaN on every covered cell;
# fine: NaN on every non-ACTIVE cell
```
- Legacy three-level scalar chain: add `child=(x0, y0, x1, y1)` in
**L1 window cells** (the patch's fine grid including its 4-cell ghost band) and
`child_block`, with `fine_block` and `base_block`. L2 must sit inside L1's
ACTIVE cells, away from L1's ghost band and transfer footprint (checked before
any GPU allocation). `initialize` and `download` take/return three arrays; each
level is NaN on its non-ACTIVE (and child-covered) cells. One coarse step = 2 L1
steps = 4 L2 steps. One L1 patch only. Optional stationary circles and Jets
live on L2 via `child_objects` and `child_jets`; `fine_objects`/`jets` retain
their L1 meaning and must be empty in this mode. All object and Jet geometry
uses the **L0 edge frame**, not the child bounds' L1 window frame. L2 has
dx=dt=0.25, so prescribed lattice velocity is unchanged. Each whole body and
its BFL stencil must be inside L2 ACTIVE cells, outside the transfer footprint.
A Jet may select one physical body across multiple blocks, never two bodies.
```python
from CelerisLab.body.geometry.circle import CircleGeometry
from CelerisLab.body.objects import SimObject
from CelerisLab.body.jets import Jet, Tube, Parallel
cfg = LBMConfig(nx=16, ny=16, viscosity=.1)
body = SimObject(0, geometry=CircleGeometry(8., 8., .8), center=(8., 8.), radius=.8)
jet = Jet(Tube((6.5, 8.), 0., 3., .3), Parallel(0.), amplitude=.002)
rest = np.asarray(compute_feq_d2q9(1.0, 0.0, 0.0), np.float32)[:, None, None]
with CudaContext(0) as ctx, FixedPatchStepper(
cfg, (4, 4, 12, 12), context=ctx, fine_block=(4, 4), base_block=(4, 4),
child=(8, 8, 16, 16), child_block=(4, 4),
child_objects=[body], child_jets=[jet]) as run:
shapes = (run.patch.coarse_shape, run.patch.fine_shape, run.child_patch.fine_shape)
run.initialize(*(np.broadcast_to(rest, (9, *s)) for s in shapes)) # 16², 24², 24²
run.step(4)
run.set_jet_amplitude(0, -.002, level=2) # default level=1 still addresses L1
run.step(4)
coarse_g, l1_g, l2_g = run.download() # solids/covered/nonleaves are NaN
```
- Level lists: `refinements[l]` describes level `l+1` in allocated level-`l`
integer cells; use a rectangle list for a union, or a scalar rectangle for a
single window (a scalar child requires a scalar parent). `level_blocks`,
`level_objects` and `level_jets` each have one entry per level, including L0.
These lists are mutually exclusive with the legacy patch keywords. Three or
more levels require all-blocked storage and bodies/Jets only on the finest
level. Every adjacent pair must preserve inherited ACTIVE coverage, valid
donors/receivers, surviving pulls and the upstream transfer footprint.
Level `l` takes `2**l` steps per base interval. This describes implemented
topology and scheduling, not accuracy or convergence qualification.
- Blocked body levels can enable `observe_raw_exchange=True` and call
`read_raw_exchange(body_id, level=...)` after a completed base interval.
It reduces unique cut-link observations into wall/aperture/total force,
torque and mass exchange in base-lattice units per unit depth, for the last
base interval (default) or `window="last_substep"`.
`observe_window_exchange=True`, alongside `observe_raw_exchange=True`, enables
`start_exchange_window()` / `read_exchange_window(body_id, level=...)` across
completed base intervals. These are raw boundary-reaction diagnostics, not a general
stress or nozzle-load accuracy claim; dense body layouts are unsupported.
- Not available: checkpoints, moving bodies, L1 bodies/Jets in a three-level
chain, automatic dynamic refinement, `Simulation` integration. Qualification
depends on the tested configuration; see [the validation scope](docs/validation/2d_scope.md).
CPU topology/schedule tests alone do not establish GPU numerical correctness,
general convergence or long-time stability.
## Installation
### Prerequisites
- Python 3.8+
- NVIDIA GPU with CUDA Compute Capability 6.0+
- CUDA Toolkit 11.0+
- NVIDIA drivers
### Install from source
```bash
git clone <repository_url>
cd CelerisLab
pip install -e .
```
### Dependencies
- `pycuda>=2020.1` — CUDA Python bindings
- `numpy>=1.19.0` — numerical computing
- `scipy>=1.5.0` — special functions for vortex initialization
## API Reference
### Simulation
```python
sim = Simulation(
lbm_config_path: Optional[str] = None, # path to config JSON
body_config_path: Optional[str] = None, # path to body config JSON
device_id: int = 0, # GPU device index
)
```
#### Body creation
| Method | Returns | Description |
|--------|---------|-------------|
| `sim.add_body(type="circle", center=(x,y), radius=r)` | int body_id | Add a cylinder body (primary API) |
| `sim.add_body(type="sensor", center=(x,y), radius=r)` | int body_id | Add a velocity sensor |
| `sim.add_body(type="force_region", center=(x,y), radius=r)` | int body_id | Add a force application region |
| `sim.add_cylinder(center, radius)` | int body_id | Convenience wrapper (deprecated) |
| `sim.add_sensor(center, radius)` | int body_id | Convenience wrapper (deprecated) |
| `sim.add_object(obj)` | int body_id | Add pre-configured SimObject |
Future geometry types (polygon, mesh) will use the same `add_body()` function with a different `type` parameter.
#### Runtime control
| Method | Description |
|--------|-------------|
| `sim.initialize()` | Recompile if needed, flow field + sync objects to GPU |
| `sim.run(steps, *, upload_act=True, sync_obs=True, zero_obs=True, stream=None)` | Run N LBM steps. See stream subsection below. |
| `sim.set_body(id, omega=...)` | Set body rotation speed (host array only, uploaded at next `run()`) |
| `sim.read_body(id, *, normalize=True)` -> BodyTelemetry | Unified telemetry: {force, torque, sensor} from pinned buffer |
| `sim.read_bodies()` -> ndarray | Flat array of all bodies' telemetry (batch DRL read) |
| `sim.read_force(id, *, normalize=True)` -> ndarray | Force vector [fx, fy] |
| `sim.read_torque(id, *, normalize=True)` -> ndarray | Torque [tz] |
| `sim.read_sensor(id, *, normalize=True)` -> ndarray | Area-averaged velocity; time-normalised when normalize=True |
| `sim.set_force(id, fx=..., fy=...)` | Set force density on a force_region object |
**Action/obs transfer model:** `set_body()` / `set_force()` are host-only — they modify
the host action array without triggering GPU upload. The GPU buffer is automatically
updated at the start of the next ``run()`` call when ``upload_act=True`` (the default).
**Obs telemetry model:** GPU kernels accumulate force, torque, and sensor readings into
the ``obs_gpu`` buffer via ``atomicAdd``. By default, ``run(zero_obs=True)`` clears the
entire ``obs_gpu`` buffer (all three segments) and resets an internal step counter before
stepping. After the step group, telemetry is downloaded to a pinned host buffer when
``sync_obs=True``.
All three readback methods accept a ``normalize`` keyword:
- ``normalize=True`` (default): divides the raw GPU value by the accumulated step count,
yielding a **per-step average** — the physically meaningful quantity for most use cases.
- ``normalize=False``: returns the raw GPU-accumulated sum (no time division).
**Sensor special handling:** Area-normalisation (dividing by the number of sensor cells)
is **always applied internally** in ``read_sensor()``, regardless of the ``normalize`` flag.
The ``normalize`` parameter only controls the additional time-normalisation step.
``run()`` parameters:
- ``steps``: Number of LBM steps.
- ``upload_act`` (default True): Upload host action array to ``action_gpu`` before stepping.
- ``sync_obs`` (default True): Download ``obs_gpu`` to host pinned buffer after stepping.
- ``zero_obs`` (default True): Zero all obs segments (force, torque, sensor) on GPU and
reset the step accumulator before the step group. Set ``False`` to accumulate
telemetry across multiple ``run()`` calls.
- ``stream`` (default None): CUDA stream for all operations. ``None`` uses an internal stream.
- ``checkpoint_interval`` (default 0): If >0, save an HDF5 checkpoint every N steps.
Use ``upload_act=False, sync_obs=False`` to skip all transfers and enqueue pure
kernel launches on a user-provided stream, then sync and read later.
#### Runtime body topology sync
| Method | Description |
|--------|-------------|
| `sim.remove_body(id)` | Stage a body for removal (committed at next `sync_bodies()`) |
| `sim.sync_bodies()` | Commit pending add/remove edits: recompile kernel, rebuild flags/compact lists, patch DDF, re-upload to GPU |
`sync_bodies()` applies all staged body edits (added via `add_body()` and removed via `remove_body()`) to a running simulation without full reinitialization. The GPU flow field is preserved; only the body-related topology is rebuilt.
**Limitations:**
- Abrupt body introduction causes a transient; force readback is finite but may take 50+ steps to settle
- Verified for `"circle"` type bodies; sensors and force_regions are also expected to work
(they produce no curved links so the DDF patch is simpler)
```python
# Add a body to an already-initialized simulation
sim = Simulation()
sim.initialize()
sim.run(500)
sim.add_body("circle", center=(256, 128), radius=10)
sim.sync_bodies() # recompile + patch
sim.run(500)
force = sim.read_force(0)
# Remove the same body at runtime
sim.remove_body(0)
sim.sync_bodies() # recompile + patch flags/DDF
sim.run(500)
```
**Note:** If `run()` is called without a preceding `sync_bodies()`, any staged edits are silently discarded.
### force_region usage
```python
# Create a circular force application region
fr_id = sim.add_body("force_region", center=(50, 50), radius=15)
# Set force density (lattice units, implicit GPU upload)
sim.set_force(fr_id, fx=0.001, fy=0.0)
# The region applies Guo forcing on each step. Zero force = no-op.
sim.set_force(fr_id, fx=0.0, fy=0.0) # disable force
```
**Persistence note:** `set_force()` only updates the host action array. The GPU
buffer is synced at the next `run()` call. If `sync_to_gpu()` is called manually
before `run()`, the force will be reset to zero. For the common usage pattern
(initialize -> set_force -> run -> set_force -> run ...), this is not an issue.
### Comparison: body types
| Type | Flag overlay | Produces cut-links | Readback | Runtime control |
|------|-------------|-------------------|----------|-----------------|
| `"circle"` | OBSTACLE + BC_CURVED | Yes (Bouzidi) | force/torque | `set_body(id, omega=...)` |
| `"sensor"` | FLUID + SENSOR_FLAG | No | area-averaged velocity (always); optional per-step average | None needed |
| `"force_region"` | FLUID + FRC_REGION | No | None | `set_force(id, fx=..., fy=...)` |
#### Data access
| Method | Description |
|--------|-------------|
| `sim.get_macroscopic()` | Download DDF, return dict with rho/ux/uy |
| `sim.get_ddf()` | Download raw DDF array |
| `sim.get_flags()` | Copy host-side flag array |
| `sim.update_runtime_params(omega=..., fx=..., fy=...)` | Update runtime constants without recompile |
#### Checkpoint / Snapshot
| Method | Description |
|--------|-------------|
| `sim.save_checkpoint(path)` -> str | HDF5 checkpoint with full state |
| `sim.load_checkpoint(path)` | Restore from HDF5 (config must match) |
| `sim.snapshot()` / `sim.restore()` | In-memory field snapshot |
#### Low-level access
| Attribute | Description |
|-----------|-------------|
| `sim.bodies` | ObjectManager for direct GPU buffer access (action_gpu, obs_gpu) |
| `sim.stream` | Internal CUDA stream for async operations |
| `sim.field` | LBMField (GPU memory + curved/sensor SoA handles) |
| `sim.stepper` | LBMStepper for fine-grained step control |
### LBMStepper (advanced usage)
```python
stepper.step(n=1, *, action_gpu, obs_gpu, stream=None)
```
When fine-grained control is needed (e.g., custom async patterns), step manually:
```python
stream = cuda.Stream()
sim.bodies.zero_obs_async(stream)
sim.stepper.step(
1,
action_gpu=sim.bodies.action_gpu,
obs_gpu=sim.bodies.obs_gpu,
stream=stream,
)
stream.synchronize()
sim.bodies.increment_obs_steps(1) # manually track steps for normalize
force = sim.read_force(0) # normalize=True: divides by 1 step
```
## Configuration
### Config file location
`Simulation()` resolves `config_lbm.json` in this order:
1. Explicit path argument to `Simulation(path)`
2. `$CELERISLAB_CONFIG_DIR/config_lbm.json`
3. `./configs/config_lbm.json` (current working directory)
4. The copy shipped inside the installed package
### Config structure
```json
{
"grid": {
"lattice_model": "D2Q9",
"nx": 512, "ny": 256, "nz": 1
},
"physics": {
"data_type": "FP32",
"viscosity": 0.0035,
"velocity": 0.03,
"rho": 1.0
},
"method": {
"collision": "SRT",
"streaming": "double_buffer",
"store_precision": "FP32",
"ddf_shifting": false,
"les": { "enabled": false, "cs": 0.16, "closed_form": true },
"trt": { "magic_param": 0.1875 },
"inlet": {
"profile": "parabolic",
"scheme": "zou_he_local",
"trt_neq_damp": 0.5,
"regularized_neq_damp": 0.5
},
"outlet": {
"mode": "neq_extrap",
"backflow_clamp": true,
"blend_alpha": 0.7,
"srt_neq_damp": 0.5
},
"y_wall_bc": "bounce_back",
"omega_guard": { "min": 0.01, "max": 1.99 }
},
"cuda": {
"threads_per_block": 256,
"compute_capability": "auto"
}
}
```
Full parameter documentation lives in `src/CelerisLab/configs/CONFIG.md`.
## Performance
### Benchmarks (V100, D2Q9, 384x192)
| Config | Streaming | MLUPS |
|--------|-----------|-------|
| Re100 MRT noLES | double_buffer | ~4400 |
| Re100 MRT noLES | esopull | ~4400 |
### EsoPull streaming mode
EsoPull (Esoteric-Pull) is a single-buffer streaming scheme that uses half the memory of double-buffer. It is **fully supported** for 2D D2Q9 with curved boundaries, rotating cylinders, sensors, and force regions.
Current verification scope (v0.5.1, confirmed bit-identical to double-buffer):
- 2D D2Q9 only (D3Q19 not yet implemented)
- MRT collision with both regularized and zou_he_local inlets
- Fixed and rotating cylinder benchmarks:
| Benchmark | D | EsoPull CD | Double-buffer CD | CD diff |
|-----------|---|-----------|-----------------|---------|
| Kan99b K2 | 20 | 1.101 | 1.137 | <3.2% |
| Kan99b K2 | 30 | 1.082 | 1.146 | <5.6% |
- Runtime body topology sync via ``sync_bodies()`` -- add and remove bodies at runtime
- ``get_macroscopic()`` uses GPU kernel for physically correct output
- ``get_ddf()`` returns backing-layout data (not physical DDF) in EsoPull mode
Enable via config: `"streaming": "esopull"`
### FP16S store precision
Half-precision storage is supported for the DDF buffer. All computations are performed in FP32; only storage uses FP16 with a scaling factor.
**Known limitation (v0.5.1):** FP16S combined with Bouzidi curved boundaries produces ~30-40% CD error even with ddf_shifting enabled. This is inherent to Bouzidi's per-direction DDF reads — FP16 quantization noise (~3e-5 per value) is not averaged across directions. DDF shifting is essential for FP16S (keeps values near 0 where FP16 has best precision), but does not fully resolve the Bouzidi incompatibility.
Verified benchmarks:
- Sah04 S2: St error within 1.5% (channel + curved + inlet/outlet)
- Kan99b K2: ~30% CD error with ddf_shifting (FP16S quantization noise through Bouzidi)
- Kan99b K2 without ddf_shifting: >100% error (unusable)
- High-blockage cases (S4 beta=0.9): May diverge earlier than FP32
For force-critical applications with curved boundaries, use FP32 storage. FP16S is suitable for applications where the curved boundary is simple (large D) or force accuracy is secondary.
Enable via config: `"store_precision": "FP16S"`
### ddf_shifting mode
Stores `f_i - w_i` instead of `f_i` to improve FP16 accuracy. Supported with the following verified combinations:
| Collision | Streaming | Inlet | Curved body | Status |
|-----------|-----------|-------|-------------|--------|
| MRT | double_buffer | zou_he_local | cylinder | Verified (K2 metrics match FP32) |
| MRT | double_buffer | regularized | cylinder | Verified (K2 metrics match FP32) |
| MRT | esopull | zou_he_local | cylinder | Verified (sync_bodies tested, bit-identical to double-buffer) |
| MRT | esopull | regularized | cylinder | Verified (bit-identical to double-buffer) |
| SRT | double_buffer | any | cylinder | Expected to work (f-feq style) |
**Known limitations (ddf_shifting):**
- Verified configurations as of v0.5.1: **D2Q9 + MRT + double_buffer + any_inlet** and **D2Q9 + MRT + esopull + any_inlet** (sync_bodies add, remove, stepping stable)
- MRT shifts to physical space before collision, shifts back after (SRT/TRT are shift-invariant natively)
- D3Q19 MRT shifting patch has a ``compute_feq`` inconsistency (not in scope for 2D-only)
- Host ``upload_ddf()`` path is asymmetric (repaired)
- Checkpoint now enforces streaming and ddf_shifting match
### Performance characteristics
The GPU is the primary runtime cost. Python overhead is minimal.
**384x192 (validation grid):** GPU kernel time is ~78 μs/step, of which OneStep is ~5.9 μs (MRT D2Q9). The remaining time is dominated by pycuda kernel launch overhead (~37 μs per launch).
**3000x300 (production grid):** Estimated GPU compute time is ~530 μs/step, with pycuda overhead fixed at ~111 μs, yielding ~83% GPU utilization.
`sim.set_body()` and `sim.read_force()` data transfers are negligible (~1 μs for 72 bytes).
For a detailed breakdown, see [docs/performance_analysis.md](docs/performance_analysis.md).
## Body Module Architecture
```
body/
__init__.py Package exports
objects.py SimObject container + ObjectState / ObjectControl
manager.py ObjectManager: GPU buffer lifecycle, sync, telemetry
registry.py BodyRegistry: pure add/remove/query
action_smoother.py ActionSmoother for control input ramping
geometry/ Shape implementations (CircleGeometry, Geometry ABC)
coupling/ Body-fluid coupling: SoA packing, force/torque
preprocess/ Grid preprocessing: flag overlay, cut-link building
```
## Module Boundaries
- `body/` — geometry, rigid-body state, preprocessing, force/torque readback
- `lbm/` — lattice Boltzmann kernels, field memory, stepper
- `cuda/` — compilation pipeline, context lifecycle
- `common/` — shared utilities (checkpoint, render, streakline pathline)
Geometry is **separated from boundary methods**. CircleGeometry produces geometry-agnostic CutLink records. The SoA packer (`body/coupling/soa_packer.py`) is the single point that knows the kernel memory layout. Adding a new shape (polygon, mesh) requires only a new `Geometry` subclass.
## Validated Benchmarks
| Benchmark | Description | Key metrics | Precision |
|-----------|-------------|-------------|-----------|
| Sah04 S1-S4 | Confined stationary cylinder | Strouhal matching Sahin & Owens (2004) | St error < 5% |
| Kan99b K0-K5 | Rotating cylinder in open domain | St, Cd, Cl matching Kang et al. (1999) | See tolerance table |
| Sensor accuracy | GPU sensor vs CPU flow-field average | Match to 1e-9 | Verified |
Run validation scripts:
```bash
conda run -n pycuda_3_10 python tests/validation/run_kan99b_rotating_cylinder.py
conda run -n pycuda_3_10 python tests/validation/run_sah04_st_matrix.py
conda run -n pycuda_3_10 python tests/validation/test_sensor_accuracy.py
```
## Performance baseline
```bash
conda run -n pycuda_3_10 python tests/validation/run_perf_baseline.py \
--lattice-model D2Q9 --nx 384 --ny 192 --collision MRT
```
## Project Layout
See [docs/tests_overview.md](docs/tests_overview.md) for a complete guide to the test suite.
```
src/CelerisLab/
simulation.py High-level API
config.py LBMConfig / BodyConfig dataclasses
body/ Object management, geometry, GPU sync
cuda/ CUDA context, compilation, PTX load
lbm/ Field, stepper, kernels (CUDA source)
common/ Preprocess, checkpoint, render, streakline
tests/
validation/ Regression runners (Kan99b, Sah04, sensor, perf)
postproc/ Post-processing scripts (exp_ctrl_matrix, streakline)
specs/ Validation spec documents
audit/ Audit reports (archived, see docs/)
output/ Test outputs (force CSV, vorticity PNG, checkpoints)
docs/
performance_analysis.md GPU/Python profiling report
audit/ Audit findings (round 1-2, kernel layer, body refactor notes)
validation_specs/ Validation methodology documents
legacy/ Superseded code (FlowField, compiler v1, macros.h)
ref/ External reference implementations (FluidX3D)
```
## Collision model recommendations
| Use case | Recommended config |
|----------|-------------------|
| Low Re (<= 500) | SRT or TRT, LES off |
| Medium Re (500-2000) | MRT or SRT+LES |
| High Re (2000-5000) | MRT+LES (most robust); SRT+LES; TRT+LES with `omega_guard.max` in 1.90-1.99 |
## Common control loop patterns
### Sync control (simple)
```python
sim.set_body(0, omega=0.002)
sim.run(10)
data = sim.read_body(0)
```
### Async control (performance-oriented)
```python
sim.set_body(0, omega=0.002) # host-only, ~1 μs
sim.stepper.step(10, ..., stream=sim.stream)
sim.bodies.increment_obs_steps(10) # track steps for normalize
sim.bodies.download_obs_full_async(sim.stream)
sim.stream.synchronize()
force = sim.read_force(0) # per-step average force
```
Use ``sim.run()`` for the common case -- it stores the step count automatically:
```python
sim.set_body(0, omega=0.002)
sim.run(10, stream=sim.stream)
force = sim.read_force(0) # per-step average force
```
## Vortex initialization
```python
from CelerisLab.lbm.initializers import add_vortex
add_vortex(sim.field, center=(50, 50), radius=10.0, strength=1.0, vortex_type="lamb")
```
## Streakline visualization
```python
from CelerisLab.common.streakline import Streakline, ReleaseConfig, IntegratorConfig
streak = Streakline(release_points=..., nx=nx, ny=ny)
for step in range(steps):
sim.run(1)
if step % sample_every == 0:
macro = sim.get_macroscopic()
streak.observe(ux=macro["ux"], uy=macro["uy"], step=step)
streak.render("streakline.png")
```
## Validation campaigns
- [Periodic Taylor–Green AMR](docs/validation/taylor_green.md): analytic periodic-decay pilot and frozen baseline-relative assessment.
- [Matched refined DFG](docs/validation/refined_dfg.md): frozen SRT uniform/refined comparison, requiring channel GPU gates before execution.
- [DFG 2D-2 Re100](docs/validation/dfg_re100.md): frozen periodicity and official-reference comparisons, with a declared noncanonical outlet.
- [Uniform LES shear decay](docs/validation/uniform_les_flow.md): independent continuum-oracle flow diagnostic, baseline and isolated corrected source variants.
- [Smagorinsky helper comparison](docs/validation/les_helpers.md): pinned baseline versus an output-local two-coefficient candidate, without production edits.
- [Jet-circle control volume](docs/validation/jet_circle_cv.md): bounded AMR versus uniform-grid conservation diagnostic.
The runners are in `tests/validation`, their CPU tests in `tests/unit`, and compact reference/source guards in `tests/validation/data`. Current Re100/Jet source guards explicitly pin the reviewed AMR-channel experiment; historical d79 evidence remains tied to its original checkpoint commits. New runs record actual Git HEAD separately from source origin. These campaigns preserve pinned production code; successful CPU checks alone do not establish GPU or physical validation. Keep generated results outside tracked files.
## Citation
```bibtex
@software{celerislab2026,
author = {Frank14f},
title = {CelerisLab: GPU-Accelerated Lattice Boltzmann Method Solver},
year = {2026},
url = {https://github.com/frank14f/CelerisLab}
}
```
## License
MIT License — see LICENSE file for details.
File diff suppressed because it is too large Load Diff
@@ -1,13 +0,0 @@
# Task 7 minimal offline preservation
User-approved shared backup for continued work by root, Claude and Grok. This independent backup branch does not update the release candidate, main, dev or tags.
Source snapshot: `0f8fdbc30ea640c764b38ee598d8f4d135c81c85`, branch `release-prep/2d-jet-multilevel-20261020`, tree `e0ab4a6b974d188e8bf1a1cedd0d2705ef27cefe`. The snapshot contains 247 selected source/test/documentation files; it is not a full Git history.
`horsea-required.tar.gz` is the original unchanged 729332-byte pack. Its 309 payload files and embedded manifest were verified after Horsea-to-Mac transfer. It contains the saved SRT input NPZ/PTX, matching-cache/rebuilt SASS text, exact RNE scratch scripts/results/provenance, and recent gate/integration summaries. No credentials, raw caches, cubins, training outputs or unrelated data are included. Git authentication is not part of this backup.
The embedded manifest retains its original local-preservation wording. The user subsequently explicitly approved sharing this exact pack through this Gitea backup branch; the original archive and manifest bytes are preserved.
After retrieval, verify the files against `SHA256SUMS` before unpacking. `MANIFEST.json` lists each payload origin, byte size and SHA256. The archive contains regular files only and no absolute or parent-traversal paths.
Evidence limitations remain: blocked historical SASS was rebuilt, matching uniform cache usage was not bound to the old run receipt, and current-candidate GPU reproduction plus measured GPU reciprocal were not executed. This backup does not establish release acceptance or an SRT fix.
@@ -1,4 +0,0 @@
4ae14dd3cf28a4f3d7c17ec9a56a6b2bf18a3b1348dc78f4706c8a46b4cb7263 MANIFEST.json
8f605aeac6e61c3471fbd2c602bb1567e97508d81b18ebcbd3bff50b31a100c3 README.md
5c08447090c269320e32f9f390419254d77213986620dc759df1d84b12f07bfe UPLOAD-AUDIT.json
b898e60d0bf782f62ded61fc3d4264b45d1bb106cd0722de85e24d432e9c564b horsea-required.tar.gz
@@ -1,11 +0,0 @@
{
"archive_sha256": "b898e60d0bf782f62ded61fc3d4264b45d1bb106cd0722de85e24d432e9c564b",
"archive_bytes": 729332,
"manifest_file_count": 309,
"archive_member_count": 310,
"verified_all_files": true,
"forbidden_paths": [],
"secret_pattern_hits": [],
"head": "0f8fdbc30ea640c764b38ee598d8f4d135c81c85",
"upload_scope": "Only original verified archive, its embedded manifest, checksum and concise retrieval README; no credentials or Git authentication copied."
}
+209
View File
@@ -0,0 +1,209 @@
## 审计结论(第二轮)
本轮审计的视角与上一轮不同。上一轮聚焦"主链路上是否有显式 bug"(找到了 16 项)。本轮审计的四个维度:
| 维度 | 上一轮 | 本轮 |
|---|---|---|
| 主链路正确性 | 找显式 bug | 确认修补正确、无回归 |
| 代码架构质量 | 少量提及 | 系统评估 Python 层职责分离 |
| 新代码 | 不存在 | streakline.py 全篇 + test runners |
| 跨层一致性 | 仅一处 | 系统性检查 config → compiler → kernel → docs 同步 |
核心结论:**上次 16 项修补经逐条审查确认正确,无回归。**
### 第二轮修改完成状态
根据审计发现,已完成以下修改:
| 修改项 | 状态 |
|---|---|
| EsoPull 添加 y=1/NY-2 半格 bounce-back 修正(D2Q9 + D3Q19) | ✅ 已实施 |
| `macro.cuh` diagnostic 函数标注 | ✅ 已标注 `// --- Diagnostic only ---` |
| `config.py` `omega_max` 默认值 1.99 → 1.96 | ✅ 已修改 |
| `BC_MOVING`/`BC_PERIODIC` 代码注释说明 | ✅ 已添加 TODO 注释 |
| Streakline 模块重构:779 行单文件 → `common/streakline/` 子包 (5 文件) | ✅ 已完成 |
| `run_kan99b_streakline.py` 更新为新 API | ✅ 已完成 |
| `run_exp_ctrl_matrix_streakline.py` 更新为新 API | ✅ 已完成 |
| `render_vorticity_field` 移到 `common/render.py` | ✅ 已完成 |
| `ParticleTrailSet` 移到 `common/pathline.py` | ✅ 已完成 |
| 向后兼容 shim `common/streakline.py` | ✅ 已创建(带 DeprecationWarning) |
---
## 状态说明
- `[已确认]` 经代码审查确认正确
- `[无法确认: 需运行验证]` 需数值算例确认,不能单靠读代码定论
- `[新发现]` 本轮审计首次发现
- `[已修复]` 已实施修改
- `[保留说明]` 当前不修,但需在代码或文档中明确限制
---
## 第一轮审计修补确认
逐一确认 16 项"已解决"修补在代码中的真实状态。**全部 [已确认],无回归。**
| 问题 | 结论 | 关键文件:行号 |
|---|---|---|
| `lbm/__init__.py` 导出错误 | 已确认 | 当前导出真实存在的 `add_vortex` |
| forcing 主链路 + 预因子不一致 | 已确认 — 三模型统一使用 `c_tau = 1-omega/2` | `operators/collision_srt.cuh:15`, `collision_trt.cuh:35`, `collision_mrt.cuh:41/116` |
| TRT outlet NEQ 重构未补齐 | 已确认 — COMPILE_MODEL==0\|1 时全分布 damped NEQ | `boundary/outlet/pressure_neq.cuh:45-51` (D2Q9) |
| `add_vortex()` 动量当速度 | 已确认 — `ux = sum(f*cx) / rho_safe` | `lbm/initializers.py:57-58` |
| Sensor 面积归一化 | 已确认 — ObjectManager 层已提供 | `body/manager.py` |
| `sync_to_gpu()` 重置非流体 | 已确认 — 已收缩为只覆盖 obstacle interior | `body/manager.py` |
| curved donor 合法性 | 已确认 — 扩展到实际 domain flags | `body/objects.py` `_donor_is_fluid` |
| curved Bouzidi 时序 | 已确认 — 步前写入 obstacle source slot | `lbm/stepper.py:70-71` → `step/aux_kernels.cu:14` |
| `q >= 0.5` 分支读错时间层 | 已确认 — 读 `load_ddf(fi, ...)` 即同一步 post-collision | `boundary/curved_boundary.cuh:73-75` |
| moving wall 修正未按 q 分支 | 已确认 — 分三路:fallback / q<0.5 / q>=0.5 | `boundary/curved_boundary.cuh:30-43` |
| 初始化链路 flag 叠加顺序 | 已确认 — obstacle overlay → init kernel preserve → equilibrium | `step/init_flow.cu:48-52`, `lbm/stepper.py:43-54` |
| `config_body.json` 未进入初始化 | 已确认 — Simulation 已消费 | `simulation.py` |
| inlet `U0` 语义 | 已确认 — 已补充截面平均速度注释 | `configs/CONFIG.md`, `README` |
---
## 本轮发现与处理
### CUDA Kernel 层
| 严重度 | 问题 | 文件:行号 | 处理 |
|---|---|---|---|
| **[新发现]** [高] | **`BC_MOVING` 与 `BC_PERIODIC` 标记未在 step kernel 中分发。** `core/flags.cuh` 定义了两种标记,但 step kernel 中没有 `is_moving()` 或 `is_periodic()` 分支。设了这两种标记的 cell 会静默 fall through 到 `bounce_back_swap()`。 | `step/one_step_double.cu`, `step/one_step_esopull.cu` | **[保留说明]** 已添加 TODO 注释,暂不实现 |
| **[新发现]** [高] | **EsoPull 缺少 y=1/NY-2 的显式半格 bounce-back 修正。** Double-buffer 路径有该修正而 EsoPull 无。 | `step/one_step_esopull.cu` | **[已修复]** 已添加 D2Q9 和 D3Q19 分支,标注了未来可能需要更精确方案 |
| **[新发现]** [中] | **`USE_DDF_SHIFTING` 路径完整性存疑。** 审查后确认:`macro.cuh` 和 `init_flow.cu` 已处理 shifted,各 collision/curved operator 通过 `load_ddf`/`store_ddf` 抽象层自动适配。**实际已完整,无需修改。** | — | **[已确认无需处理]** |
| **[新发现]** [低] | **`compute_pressure` 与 `compute_pressure_perturbation` 未标注诊断用途。** | `operators/macro.cuh:160-166` | **[已修复]** 已标注 `// --- Diagnostic only ---` |
| **[新发现]** [低] | **Curved/Sensor kernel 无运行时下标越界保护。** 完全依赖 host 侧验证。 | `step/aux_kernels.cu:26-99` | **[保留说明]** 设计选择:不引入多余合法性检查 |
### 第一轮遗留待验证项复查
| 待验证项 | 状态 | 说明 |
|---|---|---|
| **MRT D2Q9 moment transform/inverse** | **[无法确认: 需运行验证]** | 方向索引与 paired ordering 自洽,moment 投影物理正确。但全部系数的数值精度需在 Poiseuille 或衰减涡算例中验证。 |
| **EsoPull 邻壁 vs double-buffer 一致性** | **[已修复]** | 已添加 y=1/NY-2 反弹修正。需运行验证确认。 |
| **Force 提取与 host 侧归一化** | **[无需处理]** | Cd/Cl 管道经确认语义一致。 |
| **Plain linear Bouzidi / TRT 不兼容** | **[保留说明]** | 注释已存在且准确,引用了 [Gin08b]。无方法级替代方案。 |
---
## 架构与设计审计
### Streakline 模块重构
**旧 `common/streakline.py` (779 行) 已被拆解为 `common/streakline/` 子包:**
```
src/CelerisLab/common/
streakline/ 后处理子包
__init__.py 导出 Streakline, ReleaseConfig, IntegratorConfig
_config.py 配置 dataclass + FlowFrame 内部类
_integrate.py 核心积分引擎 (RK4 + 时空插值)
_render.py 密度图渲染 (render_density)
_streakline.py Streakline 类 (被动消费者)
render.py 涡度计算与渲染 (从旧 streakline 移出)
pathline.py ParticleTrailSet + render_trails (从旧 streakline 移出)
preprocess.py 增加 cylinders_from_triangle_layout
```
**核心设计变更:**
| 旧设计 | 新设计 |
|---|---|
| `run_streakline_online(sim, ...)` 控制仿真循环 | `Streakline.observe(ux, uy, step)` 被动接收帧 |
| `run_streakline_offline(frames, ...)` 批处理帧列表 | 移除(无需求) |
| `render_streakline_density(positions, ages, ...)` 15 参数 | `Streakline.render(path)` 内部维护状态 |
| `ParticleTrailSet` 与正确实现混在同一文件 | 移到独立 `pathline.py` |
| `render_vorticity_field` 与粒子跟踪无关 | 移到独立 `render.py` |
| `gaussian_blur2d` 用 `np.apply_along_axis` | 改为显式 `for` 循环 + `np.convolve` |
| `minimal_axes=True/False` 分支重复 | 合并为单路径 `_save_minimal_image` |
**用法示例:**
```python
streak = Streakline(release_points=..., nx=nx, ny=ny, cylinders=...)
# 在自己的仿真循环中:
macro = sim.get_macroscopic()
streak.observe(ux=macro["ux"], uy=macro["uy"], step=step)
# ...同时可以做 body actions、checkpoint、其他模块...
streak.render("output.png")
```
### Body 模块
| 严重度 | 问题 | 行号 | 处理 |
|---|---|---|---|
| **[架构]** | **`ObjectManager` 承担 8 种以上职责。** `sync_to_gpu()` 单枪匹马编排了全部流程。 | `body/manager.py` (423 行) | **[暂不处理]** |
| **[架构]** | **`Cylinder.get_curved_list()` ~180 行包含 7 种职责。** 内嵌函数无法单独测试。 | `body/objects.py:110-291` | **[暂不处理]** |
| **[架构]** | **自上一轮审计以来 body 模块重构进展为零。** | 全部 | **[暂不处理]** |
### Config/API 层
| 严重度 | 问题 | 行号 | 处理 |
|---|---|---|---|
| **[已确认]** | **FP16C 被正确拒绝。** | `config.py:119-123` | ✅ |
| **[已确认]** | **28/28 参数通过四层一致性检查。** | B4a 参数追踪表 | ✅ |
| **[已确认]** | **OBS 布局四层完全匹配。** | B4d 对比表 | ✅ |
| **[架构/低]** | **CONFIG.md 写"建议整除"而非"必须"。** 代码用 ceiling division。 | `configs/CONFIG.md:13`, `lbm/stepper.py:272-274` | **[保留说明]** |
| **[已修复]** | **`LBMConfig` 默认 `omega_max=1.99` → `1.96`,与 JSON/CONFIG 一致。** | `config.py:84` | ✅ |
### 跨层 Flag/常量同步
| 问题 | 状态 |
|---|---|
| **`FLAG_*` 常量 Python ↔ CUDA 同步** | **[已确认]** 全部一致 |
| **`LBMParams` struct 布局耦合** | **[保留说明]** |
| **V_TAYLOR 硬编码 1** | **[保留说明]** |
---
## 测试覆盖率审计
### Validation runner 与文档一致性
| 结论 | 项目 | 说明 |
|---|---|---|
| **[通过]** | Sah04 runner S1-S4 | 四个锚点全部定义并运行 |
| **[缺口]** | Sah04 runner `--u-max` | `u_max_nominal=0.1` 写死 |
| **[缺口]** | Sah04 runner high-beta 网格 | 默认直径与文档推荐不一致 |
| **[通过]** | Kan99b runner K1-K5 | 全部 5 个 case,K2 有 gate |
| **[缺口]** | Kan99b runner K3-K5 | 未做抑制分类自动检测 |
| **[通过]** | 输出机器可读 | 均输出 JSON/CSV |
### 测试基础设施
| 严重度 | 结论 |
|---|---|
| **[严重缺口]** | **零 pytest/unittest 基础设施。** |
| **[严重缺口]** | **四个旧待验证项仅 EsoPull 已修,余三项(MRT、curved boundary、force 归一化)未覆盖。** |
### 建议的最低测试覆盖面(优先级排列)
1. **MRT 单元测试**(uniform flow / Poiseuille / decaying vortex)— 单元级
2. **力系数归一化测试** — 单元级
3. **Curved boundary 单列测试** — 单元级
4. **EsoPull vs double-buffer 一致性**(Poiseuille 流对比)— 单元/集成级
5. **Validation runner smoke 测试** — 验证级
---
## 保留说明
- **`BC_MOVING` / `BC_PERIODIC` 未分发** — 已标注 TODO,暂不实现
- **Curved/Sensor kernel 无运行时越界检查** — 设计选择(依赖 host 验证)
- **Plain linear Bouzidi 与 TRT 不天然相容** [Gin08b] — 注释已存在
- **Curved wall 无质量守恒修正** — 长时间高 Re 周期 curved flow 可能出现力漂移 [San18]
- **入口 `U0` 是截面平均速度**,抛物入口峰值为 `1.5*U0`
- **角点 flag 语义不一致**:初始化时按 inlet/outlet 分类,边界核又落回 `bounce_back_swap()`
- **3D 刚体旋转契约是 z 轴占位实现**(`aux_kernels.cu:58-63`,`Ww = 0.0f`)
- **Curved boundary 仍是圆形几何特化**,没有为任意离散几何留出入路径
- **`LBMParams` struct 布局** 在 Python `struct.pack` 与 CUDA struct 之间硬耦合
- **CONFIG.md NT 整除性措辞**:写"建议",代码用 ceiling division
---
## 修改项汇总
| 类别 | 计数 |
|---|---|
| 第一轮修补确认 | 12 项全部 [已确认] |
| 本轮已修复 | 6 项 |
| 保留说明 | 10 项 |
| 暂不处理 | Body 重构 / 测试基础设施 / Validation runner 缺口 |
+325
View File
@@ -0,0 +1,325 @@
## 目标
第二阶段不再以补丁式修 bug 为主,而是重建 `body` 与 `LBM` 之间的模块边界,形成可持续扩展到 Bouzidi、IBM、粒子和多相耦合的骨架。重构后的代码需要保持短文件、清晰职责、显式契约,并避免几何语义直接渗入 CUDA 核心计算链路。
## 第一阶段与第二阶段的边界
### 第一阶段
目标是验证当前修复后的代码没有恶化,并保住最基本执行链路。
- 能稳定计算流场
- 能读取力与力矩
- Bouzidi 路径不出现新的时序性错误
- 初始化、flag、object overlay 不再互相污染
- 现有接口不做大改,只修运行期 bug 和明显契约错误
### 第二阶段
目标是结构性重构,而不是继续在旧链路上叠加特例。
- 重构 `body`
- 重构 curved boundary 数据链
- 为 IBM 预留统一入口
- 为简单几何和离散几何建立同一中间表示
- 为未来多相与多物理场保留清晰耦合面
## 当前架构的核心问题
### 主要问题
| 模块 | 当前问题 | 后果 |
|---|---|---|
| `body` | 几何、flag overlay、compact list、action、obs、coupling 混在一起 | 任一功能扩展都会牵动整条链路 |
| `objects.py` | 几何对象直接生成 Bouzidi 专用数据 | 简单几何和离散几何无法共享同一接口 |
| `curved_boundary` | 几何解释、边界格式、移动壁修正、力提取绑在同一层 | 替换边界方法成本高 |
| `ObjectManager` | 过度集中,已经接近万能管理器 | 可读性下降,后续只能继续膨胀 |
| host-device contract | 分散在多个文件,缺少统一定义 | 调试困难,容易出现隐式耦合 |
### 本质判断
当前最大问题不是公式本身,而是缺少稳定的中间层。几何对象、边界方法、运行时打包目前没有被拆开,导致代码很难既简洁又可扩展。
结合本轮修 bug 的经验,再补一条判断:很多问题不是几何本身出错,而是 donor、fallback、time layer 这类数值语义散落在不同文件中,读代码时必须来回跳转才能确认。当前项目更适合把这些语义集中写进少数注释位置,而不是继续加更多隐式保护逻辑。
## 第二阶段的目标架构
### 顶层模块
保持两大物理模块:
- `LBM`
- `body`
但它们之间不直接互相了解实现细节,而通过显式中间数据结构耦合。
### 推荐分层
| 层级 | 职责 | 不应负责 |
|---|---|---|
| `simulation` | 装配模块,定义推进顺序 | 几何处理,边界公式细节 |
| `body` | 几何、刚体状态、预处理、力回收 | DDF 操作,LBM 核心算法 |
| `lbm` | 格子流体、collision、streaming、boundary operator | 几何来源,刚体业务语义 |
| `coupling` | cut-link、IBM marker、body-fluid 数据交换 | 具体几何类定义,具体 collision 实现 |
## 推荐的 body 内部结构
### 目标
`body` 应只表达拉格朗日对象和几何处理,不直接承载 LBM 业务逻辑。
补充边界:`body` 负责管理对象并产出统一 cut-link 几何记录,`lbm` 只消费 cut-link 做数值计算。对象类型区分、几何来源、以及“该记录来自圆柱还是离散几何”都不应进入 LBM kernel 视野。
### 推荐文件树
```text
body
geometry
base
circle
sphere
polygon
mesh
state
rigid_body_state
particle_state
preprocess
flag_overlay
cut_links
ibm_markers
sensors
runtime
action_buffer
telemetry_buffer
registry
coupling
wall_velocity
force_torque
```
### 说明
- `geometry` 只回答几何问题
- `state` 只保存状态量
- `preprocess` 负责把几何投影到欧拉网格
- `runtime` 负责 GPU 上传与 buffer 管理
- `coupling` 负责 body 与 fluid 的交换规则
进一步要求:
- `geometry` 不直接生成 Bouzidi 专用 SoA
- `preprocess` 先产出统一 cut-link 结果,再由更薄的一层做运行时打包
- `runtime` 不回头参与几何判断
- 单文件保持简短,避免再出现一个文件同时含几何、打包、上传、观测解释四类职责
## 推荐的 LBM 边界
### LBM 应该看到什么
LBM 只应看到这些输入:
- `flag`
- `cut-link records`
- `IBM marker records`
- `runtime params`
- `obs buffers`
LBM 不应知道:
- 该 link 来自圆柱还是三角网格
- 该对象是粒子还是障碍物
- 该边界记录由哪种 host 几何算法产生
## curved boundary 的重构方向
### 核心原则
不要把 curved boundary 等同于 Bouzidi。
需要拆成三个维度:
- 几何表示
- 边界处理方法
- 运动模型
补充一条实现原则:donor、fallback、time layer 等关键数值语义,优先通过集中注释写清楚,不额外引入很多“自动保证语义”的复杂逻辑。当前项目更优先保持代码短、直、可读。
### 建议的统一中间表示
定义通用 `cut-link record`,至少包含:
| 字段 | 含义 |
|---|---|
| `fluid_idx` | 流体格点索引 |
| `dir` | 指向边界的格子方向 |
| `q` | 交点沿链路的位置 |
| `body_id` | 所属物体 |
| `hit_point` | 壁面交点 |
| `lever_arm` | 相对参考点的力臂 |
| `normal` | 壁面法向 |
| `motion_tag` | 静止、平移、旋转等 |
| `scheme_tag` | Bouzidi、half-way、未来 TRT-compatible scheme |
| `fallback_tag` | donor 非法时的退化方式 |
补充约束:
- `cut-link record` 只表达几何命中结果与最小运行时字段,不直接长成某一种 kernel 专用格式
- donor 的来源与时间层语义不额外做复杂自动推断,靠集中注释写清楚
- 记录字段命名要直接对应 kernel 使用含义,避免同一字段在不同文件中有不同解释
### 这样做的好处
- 圆形和离散几何可以输出同一种记录
- Bouzidi 与 IBM 可以共享一部分几何预处理
- boundary kernel 只消费记录,不关心几何来源
- 以后替换边界方法时,不必回改对象类
- donor、fallback、hit-point 这类契约可以在少数固定注释位置集中说明,而不是散落在对象类和 kernel 两侧
## IBM 的预留方式
IBM 不应和 Bouzidi 混成一条链,而应与 cut-link 平行。
建议另设统一 `marker record`,用于:
- 插值点位置
- 支撑域格点
- 权重
- 与刚体的归属关系
这样未来可以并存:
- cut-link boundary
- IBM boundary
- 混合策略
## 运行时契约的建议
### 必须显式化的契约
应把 host-device contract 从各文件中收口,单独维护。
建议集中定义:
- action buffer layout
- telemetry buffer layout
- cut-link record layout
- marker record layout
- force torque sign convention
- body velocity contract
### 运动状态契约
即使短期只做 2D 圆柱旋转,也建议按最终形式设计:
| 状态 | 建议字段 |
|---|---|
| 平移 | `vx vy vz` |
| 角运动 | `wx wy wz` 或 2D 的 `omega` 特化视图 |
| 参考点 | `cx cy cz` |
| 姿态 | `theta` 或旋转表示 |
不要再把 3D 路径固化为“只读一个 z 轴 `omega`”。
## 第二阶段推荐顺序
### 阶段 2A
先把职责边界拆开,不追求新功能。
- 拆 `ObjectManager`
- 建立 `BodyRegistry`
- 建立 clean `runtime buffer` 层
- 建立单独的 geometry preprocess 层
- 把“对象管理”和“cut-link 产出”分开
验收标准:
- `body` 不再直接知道具体 LBM kernel 调度
- `ObjectManager` 不再承担几何、obs、state、flag 全部职责
- `objects.py` 不再直接输出某一种 boundary method 专用打包格式
### 阶段 2B
重构 curved boundary 数据链。
- 定义统一 `cut-link record`
- 让圆柱先输出新 record
- 让 Bouzidi kernel 消费新 record
- 把现有 `CurvedLinkSoA` 从“Bouzidi 专用”改成“通用 cut-link buffer`
- donor 与 fallback 的契约集中写入注释,不额外增加复杂语义保护代码
验收标准:
- kernel 不需要知道几何来源
- host 侧可以替换 cut-link builder 而不改 kernel 接口
- 读 builder 与 kernel 时,不需要跨很多文件才能理解 donor 和 fallback 的基本语义
### 阶段 2C
为 IBM 留入口。
- 定义 `marker record`
- 预留独立 preprocess 和 runtime buffer
- 暂不实现完整 IBM 细节,只把架构位置留好
验收标准:
- IBM 不需要重写 body 骨架
- IBM 与 Bouzidi 可以共存于同一 body 系统
### 阶段 2D
补文档与契约说明。
- 当前能力
- 预留能力
- 不支持项
- 2D 与 3D 差异
- TRT 与 plain Bouzidi 的限制
## 不建议做的事
- 不要继续强化万能 `ObjectManager`
- 不要让几何对象直接生成某一种边界格式专用 SoA
- 不要把 curved boundary 和 Bouzidi 永久绑定
- 不要在 3D 运动契约上继续堆占位特例
- 不要在第二阶段把多相、IBM、粒子一起全做完
- 不要为了“自动保证语义”继续增加很多隐式逻辑分支,优先用集中注释把契约写清楚
- 不要引入必须跨很多文件来回跳转才能理解的 host-kernel 组织方式
## 第二阶段完成后的理想状态
### 代码层面
- 文件更短
- 模块职责更单一
- host-device contract 更显式
- kernel 更专注于数值操作
- geometry 与 boundary method 解耦
### 扩展层面
后续可自然扩展到:
- 离散几何 cut-link
- IBM marker 链路
- 粒子和刚体共用 body runtime
- 多相流对 body 的额外 coupling
### 维护层面
后续新增功能时,优先在对应层增加文件,而不是回到单个 manager 中继续堆逻辑。
## 建议的执行方式
第二阶段执行前,先固定一个简短设计约束:
- 单文件不过长
- 新增模块必须有明确职责说明
- 任何 host-device 数据结构必须有集中定义
- 新接口先定义契约,再写 kernel
- 能通过新增 builder 解决的问题,不要回写到 geometry 类中
- donor、fallback、time-layer 等关键数值语义必须在少数固定位置集中注释说明
- 优先保持文件短和职责单一,不为“保险”堆太多诊断与保护代码
这个阶段的核心产出不是新功能,而是一个能长期承载新功能的骨架。
+102
View File
@@ -0,0 +1,102 @@
# Config method diagnosis: FP16S and EsoPull analysis
**Resolution status: EsoPull — FIXED (v0.5.1); FP16S — inherent Bouzidi incompatibility (not fixable without architecture change).**
---
## 1. Overview
| Method | Original Failure | Root Cause | Status |
|--------|-----------------|------------|--------|
| **EsoPull** | NaN at D=20; CD ~500-700% error at D=30 | 3 bugs: (1) InitEsoPull wrote physical layout not EsoPull layout; (2) wall BCs used raw `load_ddf` instead of EsoPull semantics; (3) `PrepareEsoPullCurvedKernel` used post-streaming read for pre-streaming force calc | **FIXED v0.5.1** — EsoPull now bit-identical to double-buffer for Kan99b K2 |
| **FP16S** | 30-40% CD error even with ddf_shifting | Bouzidi per-direction DDF reads accumulate FP16S quantization noise without direction-averaging cancellation | **Inherent** — requires architecture change (TYPE_E equilibrium boundaries) |
---
## 2. FP16S analysis (unchanged from v0.5.0)
### 2.1 Root cause
Bouzidi curved boundary reads INDIVIDUAL DDF values per direction per cut-link, with no averaging across directions. At omega~1.9, Re~100, NEQ magnitudes occupy only 1-3 FP16S quantization steps (~3e-5/step). The interpolation ratio (1/q, up to 2x) and moving-wall correction amplify the noise.
FluidX3D avoids this because `update_force_field()` loads ALL 9 (or 19) directions from neighbor cells into FP32, where averaging cancels quantization noise.
### 2.2 Known working combinations (FP16S)
| ddf_shifting | Inlet | D | CD error | Notes |
|---|---|---|---|---|
| True | zou_he_local | 30 | ~32% | Best FP16S result |
| True | zou_he_local | 60 | TBD | Larger D may fare better |
| False | any | any | >>100% | Shifting essential for FP16S |
### 2.3 Recommendations
FP16S is only usable when D is large (D >= 60) OR when force accuracy is secondary. For production Kan99b validation, use FP32. A proper fix would require a FluidX3D-style TYPE_E equilibrium boundary with full-cell momentum summation.
---
## 3. EsoPull root causes and fixes (v0.5.1)
### 3.1 Bug #1 (critical): InitEsoPull physical-layout write
**File**: `lbm/kernels/step/init_flow.cu`
`InitEsoPull` called `write_equilibrium` which wrote `fi[k, i] = f_eq[i]` (physical layout). But `load_f_esopull(t=0)` expects EsoPull backing layout where paired directions are scattered across neighbor cells. At step 0, every direction was read from the wrong slot, producing garbage DDF for collision.
**Fix**: Added `write_equilibrium_esopull` and `write_rest_equilibrium_esopull` that scatter equilibrium values directly into the EsoPull t=0 backing layout: odd directions to neighbor forward slots, even directions to local reverse slots. Also corrected an odd/even slot swap bug discovered during testing.
### 3.2 Bug #2 (moderate): Wall boundary functions use raw `load_ddf`
**File**: `lbm/kernels/boundary/bounce_back.cuh`
`apply_wall_freeslip_d2q9_y_pull` and `apply_wall_bb_d2q9_y_pull` used `load_ddf(fi, index_f(k, slot))` to read opposite-direction values. In EsoPull mode, `fi[k, slot]` is a backing slot, not a physical direction, so the wrong values were used for half-way bounce-back.
**Fix**: Extended function signatures with `t` and `j` parameters. When `t > 0`, use `load_physical_dir_pre_streaming` to resolve the correct pre-streaming value in EsoPull layout. When `t == 0`, fall back to raw `load_ddf` (correct for double-buffer).
### 3.3 Bug #3 (critical for CD): Pre-streaming vs post-streaming semantics error
**File**: `lbm/kernels/step/aux_kernels.cu`, `lbm/kernels/streaming/esopull_semantic_helpers.cuh`
`PrepareEsoPullCurvedKernel` used `load_physical_dir_esopull()` to read DDF values for Bouzidi force computation. This helper returns POST-streaming values (the distribution that arrived at a cell after streaming). However, Bouzidi force calculation requires PRE-streaming values — the post-collision distribution that sat at the fluid cell in each direction BEFORE streaming (matching what double-buffer `CurvedBoundaryKernel` reads from `fi_in[k_f, dir]`).
For odd directions (E, N, NE, SE), `store_f_esopull` writes the pre-streaming value to a NEIGHBOR cell. `load_physical_dir_esopull` then reads the WRONG cell's value for ~50% of directions, producing a systematic ~8x force error.
**Fix**: Added `load_physical_dir_pre_streaming` in `esopull_semantic_helpers.cuh`. This resolves the pre-streaming value by:
- Using `tp = t ^ 1` (previous step's parity) for direction/slot resolution (because `store_f_esopull` at step t-1 wrote the values)
- Reading odd-direction values from the neighbor cell (where `store_f_esopull` scattered them)
- Reading even-direction values from the local cell
- Falling back to `load_physical_dir_esopull` at t=0 (init layout, not store layout)
All three DDF reads in `PrepareEsoPullCurvedKernel` (`f_toward`, `f_toward_ff`, `f_opp_same`) were updated to use the pre-streaming variant.
### 3.4 Results
| Run | Mode | D | St | CD | CD error pre-fix | CD error post-fix |
|-----|------|---|------|------|----------|------------|
| MR2 | double-buffer (baseline) | 20 | 0.16913 | 1.1367 | — | 2.96% |
| MR3 | esopull | 20 | 0.16508 | 1.1009 | ~716% | **0.28%** |
| MR1 | double-buffer (baseline) | 30 | 0.16992 | 1.1455 | — | 3.76% |
| B1 | esopull | 30 | 0.16647 | 1.1129 | ~539% | **0.81%** |
**EsoPull is now numerically equivalent to double-buffer for Kan99b K2 (MRT, D=20/30, rotating cylinder with curved boundaries).**
### 3.5 What the original diagnosis got wrong
1. **Section 3.3 (init mismatch)**: Correctly identified but underestimated — the suggested "skip first step" fix would NOT work because `EsoPullStep(t=0)` itself also operates on wrong semantics from init layout.
2. **Section 3.5 (inlet secondary issue)**: Incorrect. The EsoPull inlet/outlet functions already used `load_f_esopull()` (not raw `load_ddf`) for neighbor DDF reads since they were added. This was never a contributing factor to the CD error.
3. **Section 3.6 (verdict)**: Correctly identified init as root cause of NaN, but missed the pre-streaming bug which was the true cause of CD ~500-700% error. The init bug alone could not explain such a large persistent error.
---
## 4. Files modified in v0.5.1
| File | Change |
|------|--------|
| `lbm/kernels/step/init_flow.cu` | Added `write_equilibrium_esopull` / `write_rest_equilibrium_esopull`; modified `InitEsoPull` to use them |
| `lbm/kernels/streaming/esopull_semantic_helpers.cuh` | Added `load_physical_dir_pre_streaming`; updated usage comments |
| `lbm/kernels/step/aux_kernels.cu` | Changed 3 `load_physical_dir_esopull` calls to `load_physical_dir_pre_streaming` in `PrepareEsoPullCurvedKernel` |
| `lbm/kernels/boundary/bounce_back.cuh` | Extended wall function signatures; added EsoPull pre-streaming read path; updated module docstring |
| `lbm/kernels/step/one_step_esopull.cu` | Updated wall function calls to pass `j` and `t` |
| `tests/validation/run_kan99b_rotating_cylinder.py` | Added `--streaming` CLI parameter |
+126
View File
@@ -0,0 +1,126 @@
# Sub-agent A: CUDA Kernel & Fix Verification
## 1. 旧修正确认
### 结论: [已确认] Curved Bouzidi 时序 — aux_kernels.cu:26-65 + stepper.py:71 + one_step_double.cu:20
**理由**: `stepper.py:71` 中 `_launch_curved()` 在 `OneStep` 之前调用。`aux_kernels.cu` 的 `CurvedBoundaryKernel` 写入 `f.ddf_gpu`(当前 buffer),其后 `OneStep` 从同一 buffer 做 `stream_pull_load` — 同一时间步内完成"前写入→后拉取"。`one_step_double.cu:20` 中的 `apply_boundary_pull` 对 `is_curved(fl)` 直接 return,确保流体节点不会二次覆盖。调用顺序确认无误。
### 结论: [已确认] q>=0.5 分支时间层 — curved_boundary.cuh:73-75
**理由**: `q >= 0.5` 分支读取 `load_ddf(fi, index_f(k_f, dir_opp))`,其中 `fi` 是当前步骤的 DDF buffer。旧代码读的是前一时间步的缓冲区(`fi_in`),现在读的是当前的 `fi`,即上一时间步碰撞后的 post-collision 数据。Bouzidi 两分支算法都要求同一时间层的 post-collision 数据 [Bou01],当前写法满足此要求。
### 结论: [已确认] Moving wall 修正按 q 分支 — curved_boundary.cuh:30-43
**理由**: `bouzidi_linear_moving_correction` 函数三路分支:
- `fallback_class != BOUZIDI` → `2 * alpha_ci_dot_uw`(半格加移动修正)
- `q < 0.5` → `2 * alpha_ci_dot_uw`(Bou01 公式)
- `q >= 0.5` → `alpha_ci_dot_uw / q`(Bou01 公式)
各项系数与文献一致,`alpha_ci_dot_uw = 3 * w_i * (c_i · u_w)`。
### 结论: [已确认] Forcing 预因子统一 — collision_srt.cuh:15, collision_trt.cuh:35, collision_mrt.cuh:41/116
**理由**: 三个文件的类内路径都使用了 `c_tau = 1.0f - 0.5f * omega` 并将 `c_tau * Fin[i]` 增量加到碰撞输出中。`collide_dispatch()`(helpers.cuh:33-37/46-50)在 `d_params.fx/fy/fz`非零时调用 `compute_guo_forcing()` 生成 `Fin`,然后传入对应碰撞函数。三者完全一致。
### 结论: [已确认] TRT outlet NEQ 全分布重构 — pressure_neq.cuh:45-51(D2Q9):89-95(D3Q19)
**理由**: `#if COLLISION_MODEL == 0 || COLLISION_MODEL == 1` 把 TRT 纳入全分布 damped NEQ 分支(与 SRT 同级),对所有 NQ 方向做 `f[i] = feq_tar[i] + beta * fneq`,其中 `fneq = f_neb[i] - feq_neb[i]`,`beta = OUTLET_SRT_NEQ_DAMP`。已不再是"少量未知方向"路径。
### 结论: [已确认] add_vortex() 除以 rho — initializers.py:55-58
**理由**: `ux_old = sum(f[i] * cx[i]) / rho_safe`,`uy_old = sum(f[i] * cy[i]) / rho_safe`。旧 bug 是动量除以 rho 这一步缺失,现在存在 `rho_safe` 分母。
### 结论: [已确认] Init flag overlay 顺序 — simulation.py:139-159 + init_flow.cu:48-58 + body/manager.py:115-127
**理由**: 顺序为 `build_channel_flags()`(干净通道)→ `build_flags()`(叠加物体)→ `upload_flags()`(上传GPU)→ `stepper.initialize()`(运行 init kernel 保持 obstacle flag)。`init_flow.cu:finalize_domain_flag` 对 `is_obstacle(fl)` 直接返回原 flag。`sync_to_gpu(rebuild_flags=False)` 在初始化时不重复构建 flags。`_rest_nonfluid()` 的二次重置已移除。
---
## 2. 待验证项复查
### 结论: [已确认] MRT D2Q9 方向序与符号 — collision_mrt.cuh:46-54,79-92
**理由**: 经子代 agent 验证:
- `m[3]` = f1−f2 + f5−f6 + f7−f8 = ρ·ux(与 `macro.cuh:36` 的 `compute_rho_u()` 完全一致)
- `m[5]` = f3−f4 + f5−f6 − f7 + f8 = ρ·uy(一致)
- `m[7]` = f1+f2−f3−f4 = ρ·(ux²−uy²)(一致)
- 逆变换系数 `g[0] += (dm0 − dm1 + dm2)/9` 等均符合 `M·M⁻¹ = I`
- `meq[4] = −ρ·ux`、`meq[6] = −ρ·uy` 符号正确(正交基结构)
- 无符号错误。MRT D2Q9 的 paired 方向排列下的矩变换自洽。
### 结论: [已确认] Esopull 邻壁行处理 — one_step_esopull.cu vs one_step_double.cu
**理由**: 逐行对比 `one_step_esopull.cu:76-151` 与 `one_step_double.cu:65-144`。Double-buffer 在 line 88-94 有显式 `is_fluid(fl) && (y==1 || y==NY-2)` 块调用 `apply_wall_bb_y_pull`,而 Esopull 没有对应分支。**但这不构成 bug** — Esopull 交替读写模式(`load_f_esopull` / `store_f_esopull`,`esopull_single_buffer.cuh:33-77`)天然避免了从 y=0 壁面节点直接拉取垃圾数据:
- 偶数步:f[3] 读取本地 `fi[n, 4]`(前一步该节点的 -y 方向),f[4] 读取 `fi[j[3], 3]`(y=2 的 +y 方向)
- 奇数步同理交错
两个时间步的综合效果等价于半格 BB 的反射,无需显式修正。壁面节点 (y=0) 经 `apply_boundary_esopull` → `bounce_back_swap` 处理,不会积累垃圾。
### 结论: [无法确认: 需运行验证] Force 提取与符号约定 — curved_boundary.cuh:90-97 + obs.cuh + manager.py:328-338
**理由**: 链路追踪如下:
1. `curved_boundary.cuh:91-97`: `fx = c_x * (f_toward + f_reflected)` 累加到 `obs[obs_force_index(body_id, 0)]`
2. `obs.cuh:11`: `obs_force_index(id_obj, d) = OBS_FORCE0_FLOATS + id_obj * DIM + d`(起点=0)
3. `manager.py:read_force()`: 返回 `self.obs_pinned[i0:i0 + d]`,无符号反转
- 存储的是流体动量交换量 (fluid momentum exchange),不是物体受力的直接值(牛顿第三定律要求 `F_body = -F_fluid`)。如果外部 Cd/Cl 归一化时把 obs 直读值当做物体受力,符号会反转。需用已知算例(如静止圆柱的阻力系数)确认当前实践是否在外部做了隐含的取反。
---
## 3. 架构缺陷
### 结论: [未改] Curved boundary 仍假设圆形/球形 — curved_boundary.cuh + body/objects.py:110-291
**理由**: `Cylinder.get_curved_list()` 对每个 cut link 调用 `find_circle_intersection` / `find_sphere_ray_segment`,完全依赖于圆/球几何参数(center + radius)。没有通用多边形/三角网格接口。旧审计标记的 [待重构] 未处理。
### 结论: [未改] 3D 旋转为 z 轴占位 — aux_kernels.cu:58-63
**理由**: `CurvedBoundaryKernel` 的 D3Q19 分支中 `Ww = 0.0f`,且 `Uw = -omega * ry; Vw = omega * rx` 只包含 xy 平面转动。任何具有 z 分量的刚体旋转都不会产生正确的壁面速度。
### 结论: [已备注] Bouzidi-TRT 不相容注释 — curved_boundary.cuh:17-21
**理由**: 注释明确说明 "plain linear Bouzidi interpolation ... is not a TRT-parametrized curved-wall family",位置精准且语意清晰。
---
## 4. 新发现
### 4a. `_no_force` 碰撞变体为死代码 — collision_srt.cuh:25, collision_trt.cuh:57, collision_mrt.cuh:95
**问题**: `collide_srt_no_force`、`collide_trt_no_force`、`collide_mrt_no_force` 三个函数在编译后的任何内核路径中均不被调用。`collide_dispatch` (helpers.cuh:15-69) 始终通过带 `Fin` 数组的普通变体执行碰撞,当外力为零时通过 `zero_forcing(Fin)` 将 `Fin` 全清零。死代码约 40 行。
**影响**: 无功能影响,增加维护成本。`zero_forcing` 仅用于栈初始化,并非无用调用。
### 4b. BC_MOVING / BC_PERIODIC 有定义无处理 — flags.cuh + 全内核搜
**问题**: `FLAG_BC_MOVING (0x0060)` 和 `FLAG_BC_PERIODIC (0x0050)` 在 `flags.cuh` 有定义,Python 侧 `descriptors.py` 也有对应常量。但 CUDA 内核中没有针对 `is_moving()` 或 `is_periodic()` 的分支处理:
- `one_step_double.cu:apply_boundary_pull` 只有 `is_curved/is_inlet/is_outlet/BBS` 分支
- 任何单元格若被标记 `BC_MOVING`(非 curved 路径)将落入 `bounce_back_swap()` 分支,得到 std half-way BB 而非移动壁面速度修正
**影响**: 只有当 obstacle 使用 `BC_CURVED` 配合 `cl_body_id` 进入 curved boundary kernel 才能获得正确移动壁面速度。`BC_MOVING` 直接标记在通道壁面或其他固体节点上无效果。
### 4c. Outlet NEQ 的 `OUTLET_MODE` 嵌套逻辑可读性隐患 — pressure_neq.cuh:25-62
**问题**:
```
#if OUTLET_MODE == 1 → 纯拷贝未知方向
#else → 普通路径
#if COLLISION_MODEL==0||1 → 全分布 NEQ(含 TRT)
#elif OUTLET_MODE == 2 → 混合模式
#else → 少量未知方向重构(默认 OUTLET_MODE=0 路径)
#endif
#endif
```
当 `OUTLET_MODE=0`、`COLLISION_MODEL=2`(MRT)时,代码进入最内层 `#else` 分支(少量未知方向重构),而非全分布 NEQ。这与注释宣称的"SRT 和 TRT 使用全分布 NEQ"一致(MRT 未承诺),但 MRT outlet 路径与 SRT/TRT 行为不同,可能导致 MRT 结果系统性偏差。
**影响**: MRT outlet 行为与 SRT/TRT 不一致,应至少加注释说明此差异,或行为对齐。
### 4d. `collide_inlet_ghost` 对 `y=0/NY-1` 的过滤 — one_step_double.cu:102-103, one_step_esopull.cu:106-107
**问题**: `collide_inlet_ghost = is_inlet(fl) && interior_y && inlet_scheme_uses_post_collision_ghost()`,其中 `interior_y = (y>0 && y<NY-1)`。`y=0` 和 `y=NY-1` 的 inlet 节点不会触发 ghost 碰撞。但 `inlet_scheme_uses_post_collision_ghost()` 只在 `INLET_SCHEME==0`(Zou-He)时返回 true,而 x=0 inlet 节点原本处于 y=0 或 y=NY-1 时,已被 `build_channel_flags` 覆盖为 `SOLID|BC_WALL`(角点优先),因此这些节点本身不是 inlet,过滤是安全的。
**影响**: 当前无实际影响(角点 wall 覆盖 inlet),但代码隐含的逻辑依赖比较脆弱。如果未来修改建标记序,可能在 y=0/ymax inlet 节点产生未碰撞 ghost 状态。
### 4e. 传感器归一化在 manager 层正确实现 — aux_kernels.cu:67-99 + manager.py:348-365
**结论**: `SensorKernel` 做逐格点求和,`ObjectManager.read_sensor(normalize=True)` 除以 `sensor_cell_counts[body_id]`。已实现,正确。
### 4f. `inlet_target_u` 对 y=0 和 y=NY-1 的保护 — inlet/common.cuh:34
**影响**: `y_clamped = fminf(NY-2, fmaxf(1.0, y))` 使 y=0 节点获得 y=1 的 inlet 速度。对正确定义的 `SOLID|BC_WALL` 角点无实际影响,属于保护性逻辑。
### 4g. `compute_omega_minus` 在 ω⁺ = 2.0 时分母为零 — collision_trt.cuh:24-26
**问题**: `1.0f / omega_plus - 0.5f` 当 `omega_plus = 2.0` 时为 `0.5 - 0.5 = 0`,导致除零。实际路径中 `omega_col` 在 `collide_dispatch` 中被钳位(helpers.cuh:56),假设 `OMEGA_COLLISION_MAX < 2.0` 则为安全。
**影响**: 低风险(依赖外部宏正确配置)。
### 4h. `west_velocity_rho_closure` 在 u_target ≥ 1.0 时除零 — inlet/common.cuh:47-48
**问题**: `rho = sum(...) / (1.0f - ux_target)`,当 `ux_target >= 1.0` 时除数为 0 或负数。物理上入口马赫数小于 1 可避免,但无运行时保护。
**影响**: 低风险(物理约束),但崩溃行为不如显式断言清晰。
---
## 总结
| 类别 | 数量 | 关键项 |
|------|------|--------|
| 旧修正确认 | 7/7 | 全部确认正确 |
| 待验复查 | 3 | 2 确认, 1 需运行时验证 |
| 架构缺陷 | 3 | 圆形硬编码、3D占位、TRT注释齐全 |
| 新发现 | 8 | 4a死代码、4b未处理BC、4c MRT outlet差异、4d脆弱逻辑依赖、4e已实现、4f无害保护、4g除零边界、4h无保护输入 |
**最高优先级**: 4b (`BC_MOVING` 无处理路径)、4c (MRT outlet 路径与 SRT/TRT 不一致)、force 符号约定需运行验证。
+35
View File
@@ -0,0 +1,35 @@
# Compatibility and API changes
Changes that can make a previously accepted setup or call behave differently.
Each entry names the commit, the affected entry points and the observable result.
## 87c3a31: cut-link ownership is validated for every body
`validate_cut_link_ownership` (`body/preprocess/flag_overlay.py`) now runs for
passive bodies as well as Jet/aperture bodies. Every cut link must have an
active fluid receiver (FLUID set, SOLID clear), and each `(receiver, direction)`
population may have only one writer.
Rejected with `ValueError`, before flags, populations or device buffers change:
1. Overlapping or touching passive solids whose cut links write the same
population ("Boundary requires unique cut-link writers").
2. A body whose cut-link receiver is a non-fluid cell, e.g. a channel wall row
or the inlet/outlet column ("Cut links must have active fluid receivers").
Both were previously accepted silently for passive bodies; the interpolated
boundary then had undefined results. The rules apply to the cut links of all
bodies together, so a passive body overlapping a Jet body is rejected as well.
The check runs in `Simulation.initialize`, runtime body sync (`sync_bodies`),
checkpoint save and checkpoint load (`common/checkpoint.py`). Load validates
before restoring anything, so a checkpoint whose saved geometry violates either
rule no longer restores; rebuild the geometry with separated bodies.
## 87c3a31: `Simulation.read_surface_exchange` accepts Jet-driven bodies
`read_surface_exchange(id)` previously required `SurfaceActuation` on the body.
It now also accepts bodies that own Jet aperture links, including Jets with zero
or negative amplitude (the aperture test is geometric). Bodies with neither
`SurfaceActuation` nor aperture links still raise
`ValueError("Body has no surface actuation")`. The value is unchanged: the latest
step's wall/aperture exchange, not total nozzle force.
@@ -0,0 +1,62 @@
# Selective LES normalization integration on dev8403956
This change reuses the reviewed correction from 5465832 without merging its
branch history. The only production change is the two closed-form coefficients
18 -> 18 sqrt(2) and their explanatory comments in turbulence_smag.cuh. Its SHA256
is a3db46c2e7d27530b2d1436e65cdbed0b72cc7e047bfbeef2a640877271b51aa.
Defaults, iterative/deviatoric/capped closure, collision dispatch, AMR guards,
and all other production source files are unchanged.
## Separate source contract; unchanged experiment
The single existing flow runner now accepts `--experiment dev8403956`.
Its separate source_pins_dev8403956.json pins all 101 production files from the
committed 8403956 baseline; corrected mode permits only the exact reviewed
header substitution. Results record the actual checkout commit, import path,
experiment name and manifest SHA256. No arbitrary manifest-path override exists.
Omitting the option still selects the original historical source manifest.
That manifest, the original paired receipts, scalar preparation manifests and
independent continuum oracle are unchanged. Historical baseline and corrected
receipts remain evidence for their own exact sources, not new dev receipts.
Historical guards intentionally reject this different dev source tree. Eight
production files already differed between the historical source snapshot and
8403956; neither the old manifest nor its acceptance is silently regenerated.
The physical experiment and every numerical acceptance threshold are unchanged:
8 x 34 nodes, halfway y walls, periodic x, unforced D2Q9/SRT, shifted FP32,
double-buffer streaming, Cs=0/.16/1, checkpoints 519/1038/2075. Each case has one
actual advancing warm-up followed by complete initial-state restoration before
READY. Total launches are 6,225 measured plus three warm-ups. Cs=1 remains an
amplified diagnostic, not a physical coefficient recommendation.
## Host checks
PYTHONDONTWRITEBYTECODE=1 python -m unittest discover -s tests/unit -p 'test_smagorinsky_normalization.py' -v
PYTHONDONTWRITEBYTECODE=1 python -m unittest discover -s tests/unit -p 'test_les_flow_*.py' -v
The direct-current-header test is copied unchanged from reviewed 5465832:
120 tensor parameter cases, Cs=0/equilibrium and omega guards, converged
trace-free iterative comparison, and mutation detection in both lattice
algebras. This is scalar D2/D3 algebra coverage, not 3D-flow qualification.
Flow tests retain analytic/reference checks and add current named-source,
reverse-patched baseline, variant rejection, unrelated-source tampering and
immutable historical-default checks. The temporary baseline is constructed
only inside a test directory; production is never reverse-patched.
## Pending final-commit GPU gate
After independent review and explicit executor authorization, run from the
exact committed candidate checkout, selecting the authorized physical GPU:
CUDA_VISIBLE_DEVICES=<physical-GPU> PYTHONDONTWRITEBYTECODE=1 python tests/validation/run_uniform_les_flow.py --root "$PWD" --experiment dev8403956 --variant corrected --run-gpu --device 0 --output <new-evidence-directory>/corrected.json
Retain all source hashes, exact commit/import/device identity, manifest hash,
three READY/reset records, complete result JSON, stdout/stderr and actual exit.
Require all frozen gates, DONE passed=true and exit 0. Compare with historical
corrected evidence without relabeling it as current evidence. The old-vs-new
normalization discrimination already exists; no new baseline GPU run is needed
unless review finds a changed exercised uniform solver path.
No GPU result is claimed by this integration preparation. This does not expand
LES qualification to MRT, forcing, AMR LES or three-dimensional turbulent flows.
@@ -0,0 +1,57 @@
# Experimental projected G explosion
`FixedPatchStepper(..., explosion="projected_linear")` changes only the existing
G-to-G explosion reconstruction. The omitted/default `"constant"` selector retains
the same kernel, launch arguments and device allocations. Projected mode adds two
compact tables per adjacent pair; recursion, collision, BFL, restriction, buffer
ownership and synchronized publication are unchanged. `remap_child` preserves it.
Runtime eligibility is periodic-root, fully blocked D2Q9/SRT/FP32, body/Jet-free,
without LES; the fixed-patch backend has no forcing interface. Shifted and unshifted
storage use the same reconstruction. One generic builder handles scalar windows,
unique union rows and all adjacent hierarchy pairs without depth/rectangle caps.
Donors are original explosion donors intersected with owned, uncovered ACTIVE
cells. An axis uses centered differences only if both neighbors are legal;
otherwise both addresses repeat the center. Nested layout periodicity is explicit.
No covered cells, holes, inactive cells or stale halo copies enter the stencil.
The 33-line kernel is unchanged from our `519473a` experiment and retains its
mathematical attribution. Host tests cover union decomposition, concavity, narrow
gaps, grazing packet paths, offsets, sparse/nested owner addresses, three/four-level
source timing, unchanged constant dispatch, remapping and shifted/unshifted actual
kernel arithmetic compiled as host C++. These are not CUDA or flow validation.
## Reviewed bounded evidence
The `1aa8110` CUDA gate, with production exactly `a135252`, passed exact-dev
omitted/default and explicit-constant equivalence, per-population reconstruction,
scalar/union/four-level scheduling, alternate layouts, and changed remapping in
both storage modes. Operator maximum error was 2.98023224e-8; the eight-step
concave replay maximum was 1.58037614e-7. Whole-step mass/momentum remain
finite diagnostics, not an FP32 conservation certificate. Reviewed evidence:
`7aa66ff0542175092753ea099f40b903ece0527e`.
The fresh four-case `2cf9853` N128/256 Taylor–Green repeat retained all `11901a7`
settings and gates. All 20 main scalar rows and 260 early-pressure samples matched
the older receipts exactly; this is not field-array equality. Projected worst
velocity was 0.001995299260844 versus 0.002 (only 0.235% margin), pressure
0.012157174904932 and energy 0.001184362645162. Constant velocity
0.004418076615223 failed its gate, so the aggregate verdict remains false.
The projected early sampled pressure peak was 0.021621453573334; it remains a
descriptive sampled maximum. Reviewed evidence: `90849a55cad4a0da9b72747da7bfe6eb75962a44`.
The old N64 projected failures remain relevant. These results support only this
bounded plumbing gate and short periodic Re100 smooth-decay experiment. They do
not establish union/multilevel physics accuracy, convergence, long-time stability,
body/Jet, boundary, forcing, MRT or LES suitability. Constant remains the default.
## Separate LES source profile
The two older LES source manifests and the historical default are unchanged and
correctly reject this different source tree. The existing LES runner now offers
`--experiment a135252`, pinning all 101 actual committed corrected source files.
Its explicit baseline-header override describes only a synthetic isolated reverse
control, never the committed a135252 header. The unchanged corrected-only uniform
LES regression (Cs=0/.16/1) is the remaining integration gate; no LES result is
inherited from the projected evidence. The separate historical jet-CV `channel.py`
pin mismatch predates this port and is not addressed here.
+73
View File
@@ -0,0 +1,73 @@
# Raw multilevel boundary exchange (opt-in candidate)
Use `FixedPatchStepper(..., observe_raw_exchange=True)` and, after a successful
base step, `read_raw_exchange(body_id, level=l, window="last_base_step")`.
The alternative window is `"last_substep"`. Body IDs are object positions within
the named level, not the object's original user label. The torque reference is
that circle's geometry.center (the center used to construct BFL arms), reported
in the root edge frame. A differing SimObject.center does not change this reference. Current geometry
restrictions are unchanged: fixed complete bodies on the finest level, isolated
from the transfer footprint. New observation currently requires blocked body
storage; dense-body configurations raise before device allocation. Existing
dense diagnostics are unchanged.
Each result contains `wall`, `aperture`, `total`, with `force`, `torque`,
`impulse`, `angular_impulse`, `mass_into_fluid`, and `mass_rate`. These are raw
boundary momentum reaction, not validated stress or whole-nozzle mechanical
load. No GI/advective correction or guessed thrust is added. Apertures retain
their geometric classification when their prescribed velocity is zero.
All results are base-lattice units per unit out-of-plane depth. For local
spacing and timestep h=dt, raw `(jx,jy,tz,dm)` converts to impulse
`(h*dt*jx,h*dt*jy,h*h*dt*tz)` and mass `h*h*dm`.
The accumulator intentionally accepts h and dt separately to make the spatial
and temporal conversion explicit; the current acoustic hierarchy supplies dt=h.
The stored rx/ry arms run from geometry.center to the actual wall hit, not to
the fluid node. For this raw exchange j=c_i(a+b), moving the arm from the fluid
node to the hit adds q*c_i, whose cross product with j is zero. Thus either arm
gives the same raw torque (up to floating-point rounding); this equivalence
must not be assumed for a future nonparallel stress/advective correction.
Force/torque are impulse/angular impulse divided by the reported window length.
`dm=b-a` is positive into the exterior fluid, while j is the opposite of the
fluid's momentum change across that cut link. Interpolated BFL can introduce
mass drift; dm is an observation, not an assertion of impermeability.
`last_base_step` means [t-1,t] even after step(n); `last_substep` means [t-h,t]
and is not a common instantaneous sample across levels. A Jet amplitude set
before step(1) applies to all its substeps. Reads are repeatable; step(0) leaves
them unchanged. Initialization and a remap candidate invalidate observation.
Only successful stream synchronization publishes a window; failed instances
reject reads rather than returning partially advanced measurements.
Storage is one FP32 [N,4] raw array and one FP64 [N,4] integral per measured
level, plus row metadata. No substep history is stored. Same-stream sequencing
is halo/restriction -> BFL -> independent row accumulation -> step. There are
no accumulation atomics or body obs offsets (blocked n_objects remains zero).
Disabled observation allocates neither observation buffer and launches no
accumulation kernel. The standalone periodic block caller passes explicit
null optional arguments.
## Gates
CPU (standard library unittest, plus existing NumPy dependency):
PYTHONPATH=src python -m unittest discover -s tests/unit -p test_raw_exchange.py -v
GPU, explicitly on a CUDA host with the existing environment:
PYTHONPATH=src python -m unittest discover -s tests/validation/multigrid -p test_raw_exchange_gpu.py -v
The GPU suite includes an independent actual-population cut-link census and
ACTIVE-fluid momentum/mass ledger with non-body boundary flux, observation
on/off population equivalence, dense/blocked row comparison, three block
partitions, zero/step/reversed/disabled Jet amplitudes, depth-four eight-sample
accumulation, and a short-time whole-domain uniform-fine comparison with the
same physical geometry, viscosity and Jet velocity. The uniform reference
uses a test-only adapter to the standalone kernel's optional inputs.
These are implementation checks. They do not establish physical Jet/stress
accuracy, long-time AMR error, or convergence order. Resolution/long-time
studies and independently validated continuum load benchmarks remain separate.
GPU gates were prepared but not run in the authoring environment (no CUDA,
PyCUDA or nvcc); run them before merging this candidate.
+34
View File
@@ -0,0 +1,34 @@
# MRT reuse in blocked/refined stepping (candidate)
Base `9805383`. Opt-in by `LBMConfig(collision="MRT")`; SRT remains the default and its
kernel statements, including the shifted retained-delta/direct-momentum path, are unchanged
under the alternate compile branch.
## What changes
- `blocks.cu` (`BlockStep`), `step/block_channel.cu` (`BlockChannelStep`) and `refinement.cu`
(`patch_collide`) gain a compile-time `COLLISION_MODEL == 2` branch that repeats the uniform
`collide_dispatch` sequence with zero forcing: `compute_rho_u`, omega clamp to
`[OMEGA_COLLISION_MIN, OMEGA_COLLISION_MAX]`, `collide_mrt_no_force`.
- Kernel and host guards accept SRT or MRT only. TRT, LES, non-FP32 storage, non-double-buffer
streaming, and shifted dense/mixed refinement remain rejected.
- Transfers, subcycling, BFL, raw exchange ledgers and channel closures are untouched. The
existing pressure-NEQ outlet selects its MRT branch (unknowns-only NEQ extrapolation) from
`COLLISION_MODEL`, so MRT channel parity must use uniform MRT as reference.
## Contracts (existing operator, not redefined here)
- Shifted storage uses the existing MRT representation (equilibrium moments from `rho - 1`),
not the SRT retained-delta/direct-momentum precision. Mass and momentum are conserved
moments (relaxation rate 0).
- Kinetic rates are the operator's fixed `s_e = s_eps = s_q = 1.2` on every level; the shear
rate is the existing per-level omega. Under acoustic 2:1 scaling the physical bulk viscosity
therefore halves on each finer level. No rate rescaling is applied.
- No LES, no external forcing (`d_params` force fields stay zero).
- Shifted Jets stay SRT-only: `body/jets.py` keeps its existing guard. This extension does not
provide shifted MRT Jets.
- `PeriodicBlockStepper` (uniform blocked stepper) remains SRT-only.
## Evidence status
CPU: `tests/unit/test_refinement_mrt.py` (host guards, source contract). GPU:
`tests/validation/multigrid/test_refinement_mrt_gpu.py` (uniform-MRT channel parity, AMR MRT
smoke) and unchanged SRT GPU tests. Strict parity may be subject to cross-kernel FMA
contraction differences already documented for SRT. Not a DFG/benchmark validation.
@@ -0,0 +1,22 @@
# Blocked AMR root channel increment
Opt in with `FixedPatchStepper(..., coarse_boundary="channel", base_block=(by,bx), fine_block=(fy,fx))`, or the existing level-list form. Every level must be blocked. The supported boundary is the existing uniform D2Q9/SRT/FP32 double-buffer channel: local Zou-He west inlet, pressure-NEQ east outlet, stationary halfway bounce-back y walls. Uniform and parabolic inlet profiles and shifted/unshifted storage are supported; the existing configuration guards still reject MRT/LES and incompatible storage. This does not change the external DFG MRT reference.
`step/block_channel.cu` is a small root-only kernel. Fine kernels, transfer kernels and recursive hop scheduling are unchanged. Global coordinates and the global profile height/velocity are separate from block-local storage strides. Corner ownership and collision phases match `OneStep`:
- y-edge ghosts (including corners): pull, pair swap, no collision
- west ghosts at interior y: Zou-He reconstruction then SRT collision
- east ghosts at interior y: pressure NEQ from the immutable left input node, no collision
- physical fluid beside y walls: same-node opposite-input correction then collision
The root uses the uniform SRT equilibrium arithmetic, including the existing shifted rho-minus-one path, to preserve matched-root semantics. Fine `BlockStep` retains its existing shifted direct-momentum/retained-density arithmetic. This increment is not a migration of fine arithmetic.
Root halo topology stays wrapped like the uniform kernel, solely to reproduce its complete evolved ghost state as well as physical populations. It does not make the physical inlet/outlet periodic. Evolved root state includes boundary ghosts, while public fluid-leaf downloads exclude them. Initialization must provide finite positive-density root ghost states. Private raw snapshots preserve them exactly for same-representation continuation; public leaf-only downloads are not restart states. Channel remapping remains explicitly unsupported.
`channel.py` checks the actual explosion donors and restriction receivers are uncovered bulk fluid and checks actual receiver-local restriction slots against pressure-donor and wall-correction reads. No arbitrary large padding or block-aligned patch restrictions are added. Keep the physical domain dimensions exact: choose legal root block divisors (including full width) instead of padding a benchmark domain. Stationary circles/Jets retain the existing finest-level and transfer-footprint rules.
## Gates
- `tests/unit/test_channel_root.py`: host semantics, minimal footprint, overlap rejection, raw-state/public-leaf separation; actual production uniform and blocked kernels under a CPU launch shim, five non-equilibrium steps, all corners, profiles, representations, y seams and a one-cell-wide block outlet donor.
- `tests/validation/multigrid/test_channel_root_gpu.py`: exact uniform-versus-blocked full-state GPU parity; AMR finite-state and block-split invariance with/without a stationary circle and velocity Jet; amplitude update and raw snapshot round-trip.
- GPU tests require explicit device admission by the caller. CPU-header algebra is not CUDA execution or external physical validation. The current increment does not establish DFG drag/lift/pressure acceptance or a performance speedup; those need matched SRT controls and a separate benchmark run.
+88
View File
@@ -0,0 +1,88 @@
# Fixed three-level rectangle unions
This page describes the legacy three-level entry point of `FixedPatchStepper`,
with rectangle unions on either adjacent pair. The `refinements` level-list
entry point also supports arbitrary depth; three or more levels require
all-blocked storage and bodies/Jets only on the finest level. This is not
general AMR: there is no per-region timestep, moving geometry, automatic
dynamic refinement or L1 body support in the three-level form.
All regions share one current/spare buffer pair per level. The existing schedule
advances L0 once, L1 twice and L2 four times per base step, with aggregate transfers.
No CUDA kernel changes are involved.
## Explicit coordinate frames
Keep the existing scalar `child=(x0,y0,x1,y1)` for a single scalar parent patch.
Its coordinates retain their original meaning: half-open integer indices in the
allocated L1 window, including its ghost band.
The new keyword `child_rectangles_in_parent=[...]` is mutually exclusive with
`child`. It accepts a scalar or a set parent and interprets every rectangle in
the actual allocated L1 array, including ghost bands and holes. It never infers
region-local coordinates. The physical root cell edge corresponding to an L1
index `(x,y)` is `parent.fine_origin + (x,y)/2`:
- A scalar L1 parent has a shifted window origin.
- A set L1 parent has origin `(0,0)` and public shape `(2*ny,2*nx)`.
- A child set has public shape twice the allocated L1 shape. Its root origin is
the L1 allocated origin, even when the parent is a scalar window.
For a 16x16 root, scalar parent `(4,4,12,12)` and scalar child `(8,8,16,16)`
are physically equivalent to parent set `[(4,4,12,12)]` with child set
`[(12,12,20,20)]`. A child set on the *scalar* parent instead uses
`[(8,8,16,16)]`. Reusing the same numbers after changing the parent frame can
move the physical region.
Both adjacent pairs are built from their unions, without a fixed rectangle-gap
rule. Adjacent, overlapping and concave unions are accepted only when their
actual transfer dependencies close. The whole child union must preserve
inherited ACTIVE coverage, uncovered ACTIVE donors/receivers, surviving pulls, and the upstream
restriction footprint. Sparse holes remain unowned; inherited INNER remains
stream-only and OUTER remains invalid. Block sizes must divide their allocated
level grids. Sparse storage owns every grid-aligned tile intersecting the union
plus its four-cell ghost band; rectangle and support edges need not align with
tile edges.
## Example
```python
run = FixedPatchStepper(
cfg, [(4, 4, 20, 28), (24, 4, 44, 28)], context=ctx,
base_block=(4, 4), fine_block=(4, 4), child_block=(4, 4),
child_rectangles_in_parent=[(16, 16, 32, 40), (56, 16, 80, 40)],
)
```
This example uses a 48x32 root. `initialize` and `download` use three Q-major
dense arrays. Public arrays and masks still scale with the full allocated
extent; sparse device buffers do not remove that host-memory limit.
Stationary whole-circle `child_objects` and `child_jets` use root edge
coordinates and a single L2 boundary object. Body IDs are physical object-list
positions, not region IDs or caller `obj_id`. Complete boundary stencils must
avoid the transfer footprint. Change a child Jet with
`set_jet_amplitude(index, value, level=2)`; L1 bodies/Jets remain unsupported.
## Verification
CPU geometry, table, pre-CUDA rejection, schedule and cleanup tests:
```sh
PYTHONPATH=src python -m unittest discover -s tests/unit -p 'test_refinement*.py' -v
```
`tests/unit/test_union_refinement.py` covers union dependencies and tile
ownership; `tests/unit/test_hierarchy.py` covers composed geometry through four
levels. `tests/unit/test_raw_exchange.py` checks the four-level host schedule
with CUDA mocks. These establish topology/control-flow coverage, not numerical
qualification at every depth or interface shape.
Explicit GPU gates are in
`tests/validation/multigrid/test_refinement_three_level_multipatch_gpu.py`.
They cover physical-frame equivalence, twins, asymmetric refinement, multiple
children, reversed order, independently varied aligned layouts, public/raw
masks and two L2 bodies with static/zero/driven/switched Jets. Snapshots are
0/1/2/8. CPU mocks do not execute CUDA and do not establish numerical accuracy.
GPU equivalence gates supplement the separately frozen independent dense
three-level numerical replay; passing either alone is not a conservation,
performance or physical-accuracy claim.
+266
View File
@@ -0,0 +1,266 @@
# CelerisLab Performance Analysis Report
Date: 2026-05-31
GPU: Tesla V100-SXM2-16GB (CUDA 12.4)
Test grid: 384x192 D2Q9, MRT, double_buffer, FP32
Tools: cProfile (Python), Nsight Systems (GPU timeline), Nsight Compute (kernel metrics)
## 1. Performance Tree (384x192, MRT, 1 cylinder + 1 sensor)
### Per-step breakdown (batch=100, 100 steps per launch group)
```
┌──────────────────────────────────────────────────────────────┐
│ One LBM Step (~100 steps, ~7.8ms total) │
├──────────────────────────────────────────────────────────────┤
│ │
│ Python Layer (CPU) ~40 μs/step (0.5%) │
│ ├── _launch_curved() ~6 μs │
│ ├── step_fn() (cuLaunchKernel) ~22 μs │
│ ├── _launch_sensor() ~5 μs │
│ └── loop overhead (Python for _ in range) ~5 μs │
│ │
│ GPU Kernel Layer (V100) ~13 μs/step (99.5%) │
│ ├── CurvedBoundaryKernel ~4.0 μs (30%) │
│ │ grid=(2,1,1) block=256 regs=31 288 threads total │
│ │ → latency-bound (too few threads to fill SM) │
│ ├── OneStep ~5.9 μs (44%) │
│ │ grid=(2,192,1) block=256 regs=39 73,728 threads │
│ │ → mixed compute+memory (53% DRAM bw, 22% SM util) │
│ └── SensorKernel ~3.5 μs (26%) │
│ grid=(2,1,1) block=256 regs=21 305 threads total │
│ → latency-bound │
│ │
│ Memory Transfers (negligible, <1 μs/step) │
│ ├── set_body(): 72 bytes H2D (action upload) │
│ └── read_force(): 60 bytes D2H (obs download, async) │
└──────────────────────────────────────────────────────────────┘
```
### Wall-clock contributions (2000 steps, batch=100)
| Layer | Total time | Per step |
|-------|-----------|----------|
| Python (cProfile) | 0.901s (warmup+measured, 70 batches) | ~12.9ms/100-step batch |
| GPU kernel (Nsight) | 0.071s (5300 kernel invocations) | 13.4 μs |
| Batch NVTX range (nsys) | 7.8ms for batch=100 | 78 μs/step (incl. Python) |
**Key insight:** The per-step GPU kernel time is only ~13 μs. The nsys batch timing (78 μs/step) includes Python overhead, kernel launch overhead, and stream synchronization.
## 2. Python Layer Details (from cProfile, T4)
| Function | Cumulative time | Calls | Per call | % of run time |
|----------|----------------|-------|----------|---------------|
| Simulation.__init__ | 1.125s | 1 | 1.125s | 62% (one-time) |
| LBMStepper.step | 0.901s | 70 | 12.9ms | 50% of step time |
| pycuda function_call | 0.769s | 21001 | 36.6 μs | 42% of step time |
| _launch_sensor (inside step) | 0.409s | 7000 | 58 μs | — |
| _launch_curved (inside step) | 0.311s | 7000 | 44 μs | — |
| pycuda _build_arg_buf | 0.357s | 21001 | 17 μs | 20% of step time |
| manager.sync_to_gpu | 0.017s | 1 | — | one-time (init) |
| set_body | <0.001s | 20 | <50 μs | negligible |
| read_force | <0.001s | 20 | <50 μs | negligible |
**Conclusion:** The Python layer is extremely thin. The dominant cost in `stepper.step()` is `pycuda.driver.function_call` (~37 μs per kernel launch) which is the `cuLaunchKernel` overhead from the Python-CUDA bridge. This is an unavoidable cost of using pycuda.
## 3. GPU Kernel Details (from Nsight Systems)
### OneStep (MRT, 384x192, 5300 invocations)
| Metric | Value |
|--------|-------|
| Grid | (2, 192, 1) |
| Block | (256, 1, 1) |
| Registers per thread | 39 |
| Min duration | 5.57 μs |
| **p50 duration** | **5.86 μs** |
| p90 duration | 6.11 μs |
| Max duration | 7.65 μs |
| Total (5300 steps) | 31.2 ms |
### CurvedBoundaryKernel (1 cylinder at center, 5300 invocations)
| Metric | Value |
|--------|-------|
| Grid | (2, 1, 1) |
| Block | (256, 1, 1) |
| Registers per thread | 31 |
| Total threads | 288 active out of 512 launched (56% utilization) |
| **p50 duration** | **4.00 μs** |
| Total (5300 steps) | 21.2 ms |
### SensorKernel (1 sensor, 5300 invocations)
| Metric | Value |
|--------|-------|
| Grid | (2, 1, 1) |
| Block | (256, 1, 1) |
| Registers per thread | 21 |
| **p50 duration** | **3.55 μs** |
| Total (5300 steps) | 18.9 ms |
### Batch Scaling (from Nsight NVTX ranges)
| Batch size | Total time (100 steps) | Effective per step |
|------------|----------------------|-------------------|
| 1 step/launch | 8.08 ms | 80.8 μs |
| 10 steps/launch | 7.86 ms | 78.6 μs |
| 100 steps/launch | 7.78 ms | **77.8 μs** |
**Observation:** Batch size has only a 4% effect on total time between batch=1 and batch=100. This is because the GPU kernel itself is only ~13μs of the total ~78μs. The remaining ~65μs is the pycuda launch overhead + stream sync.
## 4. SRT vs MRT Comparison (from cProfile + ncu)
| Metric | SRT (T1) | MRT (T2) | Ratio |
|--------|----------|----------|-------|
| stepper.step total (70×100 steps) | 0.190s | 0.191s | **1.01x** |
| pycuda function_call count | 7001 | 7001 | 1.0x |
| pycuda function_call time | 0.146s | 0.147s | 1.01x |
| ncu Duration | 10.05 μs | 10.53 μs | 1.05x |
| Registers per thread | — | 39 | — |
| SM Throughput | 18.88% | 22.23% | 1.18x |
| Memory Throughput | 52.73% | 52.92% | 1.00x |
| FMA pipe utilization | 27.3% | 32.3% | 1.18x |
| Executed IPC (active) | 1.18 | 1.24 | 1.05x |
| L1/TEX hit rate | 6.82% | 6.82% | 1.0x |
| L2 hit rate | 54.03% | 54.06% | 1.0x |
| Simulation.__init__ | 1.113s | 1.298s | 1.17x |
**Key finding: MRT is only 5% slower than SRT at this grid size.** Both are dominated by memory access (53% DRAM bandwidth utilization), not compute. MRT's extra FMA operations increase SM throughput from 18.9% to 22.2% but don't elongate wall time because the kernel is limited by the L1TEX scoreboard stalls (49.9% of warp cycles). The top stall reason is **waiting for L1TEX data** (scoreboard dependency), not waiting for compute pipelines.
The grid (384 blocks) is too small to fill the GPU — only 0.8 full waves across 80 SMs. At production scales (3000×300), the SM throughput for MRT would approach 50-60% and the 5% gap over SRT would widen to ~15-20%.
## 5. CUDA API Breakdown (from Nsight Systems)
| CUDA API | Total time (over whole run) | Per call | Notes |
|----------|---------------------------|----------|-------|
| cuCtxCreate_v2 | 123 ms | 123 ms | One-time, CUDA context creation |
| cuModuleLoad | 1.46 ms + 1.02 ms | 1.2 ms | Kernel compilation (one-time per compile) |
| cuLaunchKernel (warmup + measured) | ~47 μs per call | 47 μs | pycuda overhead from cProfile ~37 μs + CUDA driver overhead |
| cuMemcpyHtoD (init: 14KB) | 21-45 μs | varies | Config data upload |
| cuMemcpyHtoD (action: 72 bytes) | ~1.15 μs | 1.15 μs | Body rotation upload |
| cuMemcpyDtoH (DDF: 2.6MB) | 1.02 ms + 2.26 ms | 1-2 ms | Full DDF download (get_macroscopic) — one-time in profiled run |
**DTOH overhead:** The 72-byte action H2D takes ~1.15 μs, and the 60-byte obs D2H would take ~1 μs. These are truly negligible at any scale.
## 6. Bottleneck Identification
### Current bottleneck (384x192): pycuda kernel launch overhead
At this grid size, GPU compute time (13 μs/step) is dominated by pycuda's cuLaunchKernel overhead (~37 μs per kernel × 3 kernels = ~111 μs + Python loop ~7 μs = ~~78 μs/step from nsys, ~129 μs/step from cProfile). The **GPU is idle about 80% of the time** waiting for the next kernel launch.
### What would change at larger grids
| Grid size | GPU time/step (est.) | pycuda overhead | GPU idle |
|-----------|--------------------|----------------|----------|
| 384x192 | ~13 μs | ~37 μs × 3 = 111 μs | **80%** |
| 600x600 | ~33 μs | ~37 μs × 3 = 111 μs | 55% |
| 1000x500 | ~47 μs | 111 μs | 35% |
| 3000x300 (exp_ctrl) | ~530 μs | 111 μs | **17%** |
| 5000x500 | ~1.6 ms | 111 μs | 7% |
**At your production scale (3000x300), GPU utilization would be ~83%.** The pycuda overhead becomes acceptable.
### Where optimization would matter
1. **Reducing pycuda kernel launch overhead** — This is the #1 bottleneck for small grids. The 37 μs/launch comes from pycuda's argument buffer packing (`_build_arg_buf: 17 μs`) + CUDA driver overhead. Switching to `pycuda.driver.LaunchKernel` with pre-packed arguments could reduce this, but it would require significant changes to pycuda.
2. **Combining curved boundary into OneStep** — Would eliminate 2 of 3 kernel launches per step (save ~74 μs). For your production grid (3000x300), this would save about 12% of total time.
3. **Using larger batch sizes** — Already confirmed: batch=100 vs batch=1 saves about 4% total time on 384x192. The savings increase with grid size.
### Where optimization would NOT matter
1. **`set_body()` / `read_force()` overhead** — Already <1 μs. Not worth any optimization effort.
2. **GPU memory bandwidth** — The DDF read/write (5.3 MB/step) is only 2.5% of V100 HBM2 bandwidth. Not the bottleneck.
3. **Python loop overhead** — 5 μs/step loop from `for _ in range(n)` is negligible.
4. **Registry / Body API** — dict lookups and property access are sub-microsecond. Not relevant.
## 7. Performance Model
```
Per-step time (384x192 MRT) =
Python_overhead(~40 μs) ← fixed for any grid size
+ CurvedBoundaryKernel(~4 μs per link-group)
+ OneStep(~5.9 μs)
+ SensorKernel(~3.5 μs per sensor-group)
Per-step time (general) ≈
pycuda_launch_kernels_3 × 37 μs
+ grid_cells × (pull_load + collide + pull_store) / V100_FLOPs
Scaling:
- 384x192: ~78 μs/step (GPU 17%, pycuda 83%)
- 3000x300: ~640 μs/step (GPU 83%, pycuda 17%)
- 6000x600: ~2.5 ms/step (GPU 96%, pycuda 4%)
```
## 8. Nsight Compute Deep-Dive Metrics
### OneStep (MRT) — Nsight Compute full metrics
| Metric | Value | Interpretation |
|--------|-------|----------------|
| Duration (ncu) | 10.53 μs | (ncu includes replay passes; nsys p50=5.86 μs is the real runtime) |
| Registers per thread | 39 | Well below V100 limit of 64. **No register spill to local memory.** |
| Grid | (2, 192, 1) × 256 = 384 blocks | Only 0.8 full waves — grid too small to fill 80 SMs |
| Memory Throughput | 52.9% of HBM2 peak | Moderate bandwidth usage |
| SM Throughput | 22.2% of peak | Low — limited by L1TEX scoreboard stalls |
| FMA pipe active | 32.3% of active cycles | Most-used pipeline, but not saturated |
| L1/TEX hit rate | 6.82% | Low — DDF reads are scattered across the grid |
| L2 hit rate | 54.0% | Moderate — half of cache-line requests hit L2 |
| Top stall reason | L1TEX data wait (49.9%) | Scoreboard dependency on global memory reads |
| IPC (active) | 1.24 inst/cycle | Far below V100's theoretical 4 IPC |
| Active warps/scheduler | 6.09 | Out of 16 max — low occupancy |
| Eligible warps/scheduler | 0.97 | Only 1 warp per cycle is ready to issue |
**Why the kernel does not saturate the GPU:**
- The grid (384 blocks = 73,728 threads) is too small. V100 has 80 SMs with 64 warps each = 5120 warps capacity. This kernel only uses 384 blocks × 2 warps/block = 768 warps (15% occupancy).
- Scoreboard stalls dominate (49.9%). Each warp waits on L1TEX for nearly half its cycles. This is the DDF pull phase: reading from neighbor cells at scattered memory addresses.
- The memory access pattern is suboptimal: only 26.9 of 32 bytes per sector are utilized for global loads that miss L2.
**Optimization potential:** The ncu reports "Est. Speedup: 6.45%" for memory access pattern improvements and "47.27%" for reducing L1TEX stalls. The 47% figure is misleading — it comes from the low grid occupancy, not from actual compute inefficiency. At production grid sizes (3000×300), active warps per scheduler would increase to ~12+ and the stall ratio would drop significantly.
### CurvedBoundaryKernel — Nsight Compute full metrics
| Metric | Value | Interpretation |
|--------|-------|----------------|
| Duration (ncu) | 5.60 μs | Tiny kernel, completely latency-bound |
| Grid | (2, 1, 1) × 256 = 512 threads | Only 2 blocks — **0.0 full waves** |
| Registers per thread | (from nsys) 31 | Low — no spill |
| Memory Throughput | 0.63% of HBM2 | Essentially zero bandwidth utilization |
| SM Throughput | 0.20% of peak | The GPU is doing nothing for this kernel |
| Active warps/scheduler | 1.87 | Out of 16 max — extremely low occupancy |
| Eligible warps/scheduler | 0.06 | Nearly 0 — almost never ready to issue |
| No Eligible | 94.45% | **94% of cycles have no warp ready to issue** |
| Est. Local Speedup | 97.57% | Nsight says there's 97% headroom |
**This is a latency-bound kernel by design.** Only 288 threads for the curved links. The 5.6 μs runtime is dominated by launch overhead (context switching, instruction cache misses). There is no meaningful optimization for this kernel because it cannot use more threads — there are only 288 cut links.
**Impact:** At 4 μs per step, this kernel adds negligible runtime. Even with 100 cut links, the total curved time would still be <10 μs.
### SensorKernel — Nsight Compute full metrics
| Metric | Value | Interpretation |
|--------|-------|----------------|
| Duration (ncu) | 4.54 μs | Even smaller than curved |
| Memory Throughput | 0.63% of HBM2 | Near-zero |
| SM Throughput | 0.14% of peak | GPU doing nothing |
| Active warps/scheduler | 1.84 | Extremely low |
| Eligible warps/scheduler | 0.04 | Almost never ready |
| No Eligible | 96.83% | 97% idle cycles |
| L1/TEX hit rate | 48.53% | Much better than OneStep (localized access pattern) |
Same conclusion: negligible overhead, no meaningful optimization possible.
## 9. Recommendations
1. **For production runs (3000x300)** — The architecture is well-optimized. Use `--batch 10` to amortize pycuda overhead. GPU utilization is ~83%.
2. **For small-grid sweeps (384x192)** — The pycuda launch overhead dominates. If you need to run many small-grid parameter sweeps, consider:
- Grouping multiple independent simulations into a single process
- Or accepting that small-grid runs are launch-overhead limited
3. **For kernel tuning** — At production scale (3000x300), the main kernel (OneStep MRT) uses only 39 registers (no spill), achieves 53% DRAM throughput and 22% SM throughput on 384x192. At 3000x300, SM throughput would approach 50-60% and GPU utilization would be ~83%. No further kernel optimization is needed for current use cases.
4. **Three-kernel architecture is not a problem** — Despite being split into 3 kernels (CurvedBoundary + OneStep + Sensor), the total GPU kernel time is only ~13.4 μs/step. The curved and sensor kernels are latency-bound with negligible impact. Merging them into OneStep would save ~7 μs/step but add branch divergence in the OneStep grid kernel.
+61
View File
@@ -0,0 +1,61 @@
# Opt-in shifted blocked candidate
This candidate is based on fbe7377. The default remains unshifted. Enable with
`LBMConfig(ddf_shifting=True)` only on the supported routes below.
| Route | Candidate support |
|---|---|
| PeriodicBlockStepper, FP32 D2Q9 SRT double-buffer, no LES | shifted or unshifted |
| FixedPatchStepper, every level blocked and same representation | shifted or unshifted |
| Passive stationary circular BFL boundary and raw exchange | supported candidate scope |
| Synchronized three-level child remap | private raw shifted snapshot, exact overlap/copy |
| Dense root/refinement or mixed representation | rejected for shifted |
| Slot/reservoir, surface actuation, velocity Jet | existing public shifted exclusion retained |
| Other collision/lattice/storage/streaming/LES combinations | existing exclusions retained |
The D2Q9 equilibrium helper accepts a retained density offset only in shifted
compilation. BlockStep computes delta=sum(g) before adding the unit density;
velocity uses the existing macro calculation. The existing SRT collision and
all unshifted expressions remain. No global precision type or duplicate
collision implementation is introduced. Ordinary shifted Simulation callers
still use the existing rho−1 overload; this candidate does not change their
numerical method.
Public initialize receives physical populations and performs shifted subtraction
in FP64 before the one FP32 storage cast. Public shifted download returns FP64
physical populations with exact-rational D2Q9 background weights. Internal raw
snapshots retain FP32 g and a representation tag; runtime remap never decodes
and re-encodes overlap. Exact mass is interpreted as 1+sum(g), and momentum as
sum(c*g); analyses should use raw values for tiny perturbation budgets. The
FP32 BFL force constants have their own arithmetic rounding; no exact global
conservation claim follows from shifting.
Planar helper formulas include their shifted reference-density offsets and have
actual-header host tests. Their public shifted route remains excluded until a
separate test-gated migration. Next velocity-Jet work must validate physical
wall density, incoming/outgoing populations, raw force/mass, ownership and
transfer interactions before relaxing that restriction.
Evidence so far: selected-cell CUDA replay favored retained-delta shifting;
this is not full-solver validation. Host algebra/storage/remap tests and staged
GPU continuation, three-grid cylinder physics, raw budgets, Couette helper
stress and measured runtime are separate gates. Original failed experiments
remain evidence; no acceptance threshold is relaxed.
## Direct-input-momentum equilibrium candidate
The shifted BlockStep now constructs the linear equilibrium term from input
momentum j, without reconstructing rho*u. For opposite axis pairs the odd term
is j/3; for diagonal pairs it is (jx +/- jy)/12, evaluated with explicit
round-to-nearest division. The even term is
w*[delta + 4.5*(c dot j)*(c dot u) - 1.5*(j dot u)].
This is the same second-order D2Q9 equilibrium in exact arithmetic. Original SRT,
storage, boundaries, and transfers are unchanged. No collision residual or force
is corrected afterward. Existing four/five-argument equilibrium APIs are retained;
only shifted blocked collision calls the new six-argument momentum helper.
The all-fluid read-only CUDA replay reduced signed x-momentum error by 120–2285x
at five sampled states, with lower mass/momentum and second-moment RMS errors.
Signed mass bias was larger (~1e-12/cell/hop), so full evolving mass budgets remain
mandatory. This local evidence does not establish physical convergence or speed.
The unshifted default and its arithmetic path remain unchanged.
+172
View File
@@ -0,0 +1,172 @@
# Synchronized leaf G remap and manual continuation
This is a CPU state-transfer component, **not a runtime adaptive solver**.
It changes only an L2 rectangle union in a three-level periodic hierarchy.
The body-free case is shown first; stationary L2 bodies/Jets follow the bounded
support contract below. L0/L1 topology, relaxation parameters, direction order,
physical frame and completed time remain unchanged. Existing geometry checks
validate child support/nesting and actual transfer dependencies, without a fixed
rectangle-gap rule. The three-level remap limit is unchanged by the stepper's
arbitrary-depth level-list support. The CPU helper itself adds no CUDA,
scheduler, allocator, boundary handling, collision or ghost refill. A bounded
runtime adapter is described below.
```python
from CelerisLab.lbm.refinement import FixedPatchSet2D
from CelerisLab.lbm.synchronized_remap import RemapTopology, remap_synchronized
# cfg: D2Q9/SRT/FP32/unshifted/double_buffer, nz=1, no LES
parent = FixedPatchSet2D.from_config(cfg, [(4, 4, 20, 28), (24, 4, 44, 28)])
old = RemapTopology.from_config(cfg, parent, [(16, 16, 32, 40)])
new = RemapTopology.from_config(cfg, parent, [(20, 16, 36, 40)])
candidate = remap_synchronized(
old, new, current_g, base_count=7, level_steps=(7, 14, 28),
phase="postcollision_g", origin=(0., 0.), spacing=1.,
)
```
The example has a 48×32 root; both child supports allow 4×4 blocks.
Child bounds use the parent's allocated L1 coordinates, not rectangle-local
indices. A scalar FixedPatch2D parent is also supported: its shifted L1 window
origin is retained. Physical lower edges are `origin + spacing*(x,y)` on L0,
`origin + spacing*(parent.fine_origin + (x,y)/2)` on L1 and
`origin + spacing*(parent.fine_origin + (x,y)/4)` on L2.
Factory options `coarse_boundary` and `objects` must declare `"periodic"` and
an empty collection; L2 bodies use `child_objects` as described below.
LBMConfig's channel settings do not select this operator's boundary mode.
Geometry metadata is factory-created;
manual mutation/forging of metadata is unsupported. Caller certifies the
actual state matches the declared boundary and has no forcing, that all device
work and old readers are quiescent, and that inputs are the **current owned-leaf
postcollision G**.
Count/phase stamps check consistency, not freshness or active-buffer identity.
`current_g` is three NumPy Q-major arrays `(9,ny,nx)`. For blocked inputs,
pass `layouts=(base_layout, fine_layout, child_layout)`; each optional `None`
entry denotes dense input. Every leaf must have an owner. Only owner cores
are read, never redundant block halos. Mixed precision is rejected. FP64 is
accepted for CPU reference tests; this does not enable FP64 runtime storage.
Outputs `candidate.g` are separate dense arrays regardless of input layout.
Memory scales with public grid extents, not only sparse allocated blocks.
Same-level leaf overlap is copied bitwise in physical coordinates. Newly
refined L2 copies all nine values from its valid old L1 parent. Newly exposed
L1 receives the complete four-child mean, including q0. Covered parents,
ghosts and holes never serve as donors; NaN/Inf outside leaves is ignored,
while nonfinite required leaves or nonpositive density reject the operation.
Restriction uses FP64 quarter-weight accumulation and rounds to the input
dtype. New nonleaves are NaN. Source arrays/metadata are not changed.
`candidate` retains `base_count`, `level_steps`, `phase`, `origin`, `spacing`
and new `topology.leaf_masks`. Existing `FixedPatchStepper.initialize` resets
the counter: using it is **not** a continuation adapter. This component neither
publishes a candidate nor retires old state. Runtime table rebuild/halo refill
and correct first-step scheduling are handled only by the explicit adapter below.
Tests accumulate leaf-area integrals in FP64 for each population, mass and
momentum. The declared absolute tolerance is `2e-13 * sum(abs(old population
integrals))` for FP64, `2e-7 * scale` for FP32, accounting for reduction and
restriction rounding (not a solver accuracy bound). Coarse→fine→coarse copy
round-trips preserve state; coarsening arbitrary fine structure loses it and
is not invertible. No kinetic accuracy or stability claim follows.
```sh
PYTHONPATH=src python -m unittest discover -s tests/unit -p 'test_synchronized_remap.py' -v
```
## Explicit runtime continuation
`replacement = current.remap_child(rectangles)` returns a new ready
`FixedPatchStepper` at the **same absolute step_count**. It supports only
periodic three-level runs with no L0/L1 bodies and an existing L2
`FixedPatchSet2D`; stationary L2 bodies/Jets follow the support contract below.
Scalar or union L1 parents are supported; scalar `child=` is deliberately
rejected. L0/L1, relaxation and block sizes stay fixed.
No tagger, scheduler, in-place replacement, or general rollback is provided.
The method holds the stepper lock, validates geometry, synchronizes its stream,
and downloads the actual current owned leaves. It certifies postcollision G
and completed 1:2:4 counts internally, applies the CPU helper, rebuilds all
geometry/transfer/kind/halo buffers, and uploads both current and spare buffers.
No old halo is reused. The regular step schedule fills transit ghosts/halos
before use. `initialize` itself still resets the count to zero.
The old stepper remains ready, unchanged and independently usable. The caller
owns **both** objects and must close both before closing their shared CUDA
context. Candidate construction or upload failure releases only candidate
resources; an actual old-device synchronization/read failure marks the old
stepper failed, consistent with its existing failure semantics.
```python
replacement = current.remap_child([(20, 16, 36, 40)])
# Explicitly choose the returned continuation only after success.
current.close()
current = replacement
current.step() # advances the preserved absolute count by one
```
CPU lifecycle mocks cover fresh current-buffer reads, exact transfer, separate
ownership, time preservation, ordinary initialization reset, unsupported states
and geometry, and candidate/source failure cleanup. GPU tests are predeclared
in `tests/validation/multigrid/test_runtime_child_remap_gpu.py`: identity next
step bitwise, shifted A→B→A with two intervals between changes, uniform moving
and nonequilibrium states, exact CPU remap and overlap, both buffers reset,
finite leaves, exact masks and absolute counts. They were not run on the CPU
host. The separate independent FP64 capture/replay gate is max population
error **3e-6**, with exact masks; remap mass/momentum allow FP32 roundoff.
Per-population conservation is not an advancement target under collision.
### Bounded pinned-body extension
`replacement = current.remap_child(rectangles, child_objects=original_objects)`
also accepts stationary Circles inside the L2 union. Each body's **physical
boundary, complete BFL support and current per-link velocity must remain
identical**. Rectangles are not pinned: they may be split, merged or resized,
and other fluid coverage may change, including within the same connected union,
provided that physical support is unchanged. Existing nesting, union transfer
dependencies, full-circle containment, reverse cut-link
coverage and two-hop BFL transfer-footprint checks still apply. This is manual
remapping, not adaptive body tracking or runtime body editing.
Supply all original root edge-frame definitions in their construction order.
Do not pass `current.child_boundary.objects`: those are projected fine-local copies.
There is no retained mutable original-object registry. Before reading device
state, remapping reprojects the supplied definition onto the old topology and
compares exact ordered circle centers/radii, flags, physical cut links, body
IDs, q, lever arms, hits, BFL support,
legacy SurfaceActuation specification and current per-link velocity against
the existing boundary. Omission, changed geometry/actuation or changed physical
boundary/BFL support fail without device reads or allocations; reordered bodies fail
too. Root object IDs are still assigned by list position, as in the constructor.
Jets are taken from the live L2 boundary, including the most recent successful
`set_jet_amplitude(..., level=2)`. There is no replacement-Jets argument or
constructor-time Jet snapshot. New blocked addresses may differ; the physical
boundary and velocities must match exactly.
`RemapTopology.from_config(..., child_objects=..., child_jets=...)` prepares a
typed `FineBoundary2D`; it derives L2 fluid leaves as ACTIVE minus SOLID. No
caller mask is accepted. Solids, ghosts and holes are never donors and remain
NaN, physical-fluid overlap is exact, and exposed L1 still restricts all four
old fluid children. The helper checks old/new physical boundary and velocity
equality too. Its immutable `pinned_rectangles` is legacy containment metadata,
not a remap eligibility constraint; it may be empty for a seam-spanning body.
Scalar-parent window offsets remain part of the coordinate conversion.
Focused CPU mocks: `tests/unit/test_pinned_body_remap.py`.
`tests/unit/test_union_body_support.py` also checks seam-spanning circles,
rectangle repartition/resize, unchanged physical support and live-Jet
preservation. These host checks do not establish GPU evolution accuracy.
GPU declarations:
`tests/validation/multigrid/test_pinned_body_remap_gpu.py`, covering no-op
next-step bitwise identity, moved-fluid A→B→A, current-amplitude preservation,
physical boundary/velocity equality, source independence and absolute counts.
Multiple-body CPU coverage: `tests/unit/test_multiple_pinned_remap.py`.
`tests/validation/multigrid/test_multiple_pinned_remap_gpu.py` adds two pins,
two independently updated Jets, variable fluid-region counts and add/move/remove
immediate comparisons with CPU transfer. All nine solid-excluded area-weighted
population integrals, exact overlap and nonleaf NaNs are checked.
These new GPU cases have **not been run here**. They do not establish evolution
accuracy. A 3e-6 FP32-vs-FP64 evolution gate requires a separate independent
BFL reference; the body-free replay gate above does not establish that claim.
+44
View File
@@ -0,0 +1,44 @@
# Test Suite Overview
## Test hierarchy
Three tiers:
- **`tests/unit/`** — pure Python, no GPU. Covers isolated logic (pending edits, sync plan construction, flag masks, equilibrium helpers).
- **`tests/integration/`** — requires GPU. Covers the full body topology sync pipeline (recompile, DDF patch, unified obs/act) and stream API.
- **`tests/validation/`** — requires GPU, long-running (hours). Physics regression against Kan99b, Sah04, and sensor accuracy references.
## Running tests
```
conda run -n pycuda_3_10 python -m pytest <test_path> -v
```
| What you want to verify | Command |
|---|---|
| Body module logic after refactor | `pytest tests/unit/ -v` |
| sync_bodies pipeline (no DDF patch) | `pytest tests/integration/test_sync_bodies_skeleton.py -v` |
| DDF patch after add/remove | `pytest tests/integration/test_ddf_patch.py -v` |
| Unified action/obs + stream API | `pytest tests/integration/test_unified_obs.py -v` |
| Full body add/remove e2e | `pytest tests/integration/test_body_sync_e2e.py -v` |
| All integration tests | `pytest tests/integration/ -v` |
| All tests (unit + integration) | `pytest tests/unit/ tests/integration/ -v` |
| Physics regression | `python tests/validation/run_kan99b_rotating_cylinder.py` |
## Per-file coverage
| File | GPU | Tests | What it covers |
|---|---|---|---|
| `test_pending_edits.py` | No | 14 | stage_add / stage_remove / has_pending_edit / clear_pending_edits lifecycle |
| `test_sync_plan.py` | No | 16 | build_flags_for, build_compact_lists_for, build_next_objects, build_sync_plan, commit_pending |
| `test_body_flags.py` | No | 6 | FRC_REGION / SENSOR_FLAG / OBSTACLE bits for each body type |
| `test_equilibrium.py` | No | 4 | compute_feq_d2q9 and compute_macro_from_ddf numerical correctness |
| `test_sync_bodies_skeleton.py` | Yes | 7 | sync_bodies flow: recompile, esopull guard, step count preservation, pending discard |
| `test_ddf_patch.py` | Yes | 5 | DDF patch after add/remove: finite forces, released region is fluid |
| `test_unified_obs.py` | Yes | 5 | host-only set_body, auto transfer, stream API, DRL loop pattern |
| `test_body_sync_e2e.py` | Yes | 2 | Full add -> remove -> checkpoint -> load -> run cycle |
## Notes
- `pycuda.autoinit` is required for all integration tests (selects GPU 0 by default; set `CUDA_VISIBLE_DEVICES` to change).
- The curved boundary kernel produces NaN in obstacle-adjacent fluid cells over long runs; DDF patch tests use 50-step verification windows.
+53
View File
@@ -0,0 +1,53 @@
# Bounded 2D implementation and validation scope
This inventory starts from dev `8403956a9afc0b0bb89265cec374392013d89016` and
integrates only the reviewed LES normalization production correction from
`95cb6d2b9f43c1bdd46cbf27f03f0dfc0877cfb0`. The merged production bytes match that
tested candidate exactly; the scope-test changes are retained from `53fad767`.
GPU receipts remain associated with their exact tested commits, not relabeled as
a new merged-commit run. Historical source identities and gates remain unchanged.
## Implementation boundaries
- Uniform D2Q9 supports SRT, TRT and MRT. An available collision selector does not
qualify every wall, inlet/outlet, forcing, storage or LES combination.
- Fixed refinement supports SRT/MRT, FP32 and double-buffer streaming; TRT and LES
are rejected. Shifted refinement requires all-blocked storage. Refined channel
boundaries have narrower configuration guards than uniform boundaries.
- Uniform checkpoints support compatible same-method continuation. Changing
collision or LES parameters is a different evolution, not exact continuation.
Jet checkpoints and refined checkpoints are unsupported; synchronized remapping
is not persistent restart.
- Keep these conclusions 2D. Local D3Q19 operator tests do not establish a supported
3D Simulation runtime.
## Evidence and remaining gaps
| Area | Available evidence | Boundary of the conclusion |
|---|---|---|
| MRT cylinder flow and observation windows | Full matched uniform/refined MRT DFG and the window-ledger campaign passed their frozen periodicity, reference and matched-comparison gates. The window campaign used `185a919`; its MRT/no-LES numerical path remains unchanged. Current dev also contains independently scoped test/documentation changes and the LES correction, which do not extend MRT qualification. | This does not qualify other collision/boundary combinations or every refinement interface. Timing improvements are not additional accuracy evidence. |
| Uniform forced channel | Six Poiseuille GPU cases on `8403956`: SRT/TRT/MRT at wall-normal resolutions H16/H32 passed. | This is the tested analytic channel configuration, not open-boundary or all-layout qualification. |
| Uniform restart | Ten SRT/MRT checkpoint GPU tests passed on `8403956`; the separate representative TRT same-method double-buffer continuation GPU case also passed (one test). | This covers the tested same-method continuation configurations. No LES, Jet or refined checkpoint claim follows. |
| Taylor–Green refinement | Independent topology checks are available. The actual-rate phase GPU regression passed one test across two layouts, with errors 1.584e-7 and 4.500e-9. | The physical interface-accuracy gap remains open. Passing topology and phase checks does not establish convergence or close that accuracy gate. |
| Porous Couette and annulus | Prior campaign evidence exists and must remain associated with its original setup and source. | The reconstructed annulus is a validation helper, not qualification of a public boundary-condition API. Do not infer absence of evidence from a missing current rerun. |
| LES normalization | The reviewed correction is integrated. Exact `95cb6d2` GPU validation passed all nine observations and frozen gates, with three warm-up/reset records, verified 101-source/import identity, DONE and exit 0. Last two SGS decrement relative errors were 6.276e-4 and 6.124e-5 against the unchanged 0.15 gate. | Scope is unforced uniform D2Q9/SRT, shifted FP32, double-buffer streaming and the tested wall-bounded x-periodic shear. No TRT/MRT LES, forcing, EsoPull, objects, refinement or 3D turbulence qualification follows. |
Historical uniform SRT cylinder-startup and inlet-rounding findings remain separate
from the passed MRT DFG result. Raw exchange/window consistency is a measurement
contract, not a general stress or force-accuracy certification. Existing source-pinned
runners may intentionally reject a newer checkout; never silently repin old receipts.
## Remaining work
The related host checks passed (67 checks); they do not replace the GPU or
physical-accuracy evidence above. Preserve the existing SRT checkpoint cases,
historical LES manifests and all frozen numerical criteria.
Continue the TG accuracy investigation using its actual fine-level rates and
the established analytic convention. Keep the physical accuracy gate open until
the relevant comparison passes. Review this integration independently before
publication; no new merged-commit GPU run is claimed here.
No repeat of the accepted full MRT DFG or Cartesian expansion across unsupported
combinations is required by this document. Main integration remains a separate
review of complete, bounded feature scope.
+60
View File
@@ -0,0 +1,60 @@
# DFG 2D-2 Re100 GPU campaign (validation-only)
## Current experimental source provenance
This development branch now includes the reviewed AMR-channel source changes originating in `5338864748ac67fe2544487c059ba149ebf916da` and `47b05bc8abfc957fe876b0c63bdb386e3c6cbaa5`. The current full-source manifest pins the latter reviewed source snapshot, including the new channel files. This is an explicit new experiment; neither source review nor host tests transfer historical d79 GPU/flow acceptance to it. The channel GPU gate has not yet run at integration time.
New run JSON records the source-origin pin plus `checkout_revision` (actual Git HEAD), `checkout_dirty`, and the experimental-source label. The origin pin is not claimed to be the run's checkout commit. Numerical definitions and thresholds are unchanged. Runs require a Git checkout for this runtime identity; source hash checks remain active.
Historical d79 Re100/Jet execution stays reproducible at `69e9b78de9483a5ff21e2d0c74311d240bfaf88c`; the d79 LES diagnostic checkpoint is `20ae6770924df15f31305aad56e44a54a3dd4d88`. Their manifests and existing result files are not rewritten. Use those commits to reproduce or interpret old d79 evidence. The current AMR-channel experiment requires its own GPU and applicable flow evidence.
## Scope and locked definitions
Explicitly pinned AMR-channel experimental production snapshot (see provenance below). Uniform D2Q9/MRT, shifted FP32, double buffer, no LES, stationary cylinder and no-slip walls. This is not an AMR, jet, or full canonical-outlet certification.
Physical geometry: [0,2.2] × [0,0.41], center (0.2,0.2), radius .05, rho=1, nu=.001, inlet mean=1 and peak=1.5. D is lattice diameter; dx=.1/D, dt=U_lattice*dx, nu_lattice=U_lattice*D/100. U_lattice=.01 gives peak inlet Mach .02598. Existing local Zou–He inlet is selected in validation config only. Existing pressure-NEQ outlet is unclamped: **it does not impose the canonical vector do-nothing condition nu*d_n(u)-p*n=0**. The existing production channel-flow initial condition is used, not zero velocity. Periodic eligibility is delayed to t*=250 (25 physical seconds), with fixed end t*=300 (30 seconds).
Official source: https://wwwold.mathematik.tu-dortmund.de/~featflow/en/benchmarks/cfdbenchmarking/flow/dfg_benchmark2_re100.html
The 20141124 official newer reference archive has higher-order line-integration force data and supersedes the older example table for this comparison. The compact tests/validation/data/dfg_re100/reference_cycle.json preserves the last complete lift-minimum cycle from lv6/dt4. Reference Cd=[3.164266,3.227392], Cl=[-1.021286,.986571], pressure difference=[2.420371,2.507013], St=.301841. These are derived sampled extrema, not exact analytical values. Official mean=(min+max)/2 and amplitude=max-min; separate time averages are also recorded.
## Exact commands and startup ownership
Use the existing CUDA/PyCUDA environment; no package installation or production edits required. From the repository root, use a new task-owned output path:
export PYTHONPATH="$PWD/src${PYTHONPATH:+:$PYTHONPATH}"
python -m pytest -q tests/unit/test_re100.py
CUDA_VISIBLE_DEVICES=0 python tests/validation/run_dfg_re100.py --diameter 20 --speed .01 --mode pilot --output output/validation/pilot_d20_u001 > pilot.log 2>&1
Pilot is t*=5 (10,000 steps), with dense .02-t* sampling to calibrate diagnostic cost. It cannot pass periodicity or external benchmark validation. Root launch owner reviews health, memory, timing and stdout before full runs; the full pair is not launched automatically.
CUDA_VISIBLE_DEVICES=0 python tests/validation/run_dfg_re100.py --diameter 40 --speed .01 --mode full --output output/validation/full_d40_u001 > d40.log 2>&1
CUDA_VISIBLE_DEVICES=1 python tests/validation/run_dfg_re100.py --diameter 80 --speed .01 --mode full --output output/validation/full_d80_u001 > d80.log 2>&1
These are separate invocations, not a parallel shell script. A single root launch owner serializes startup/compilation across all Horsea work. Do not launch the next process until the previous log contains an explicit `READY {...}` line. READY comes after the first physical sample, including Simulation initialize, sim.run, read_force and get_macroscopic, so lazy runtime/diagnostic paths are exercised. That sample remains in the physical trajectory/history. No hidden warmup/reset, no later new diagnostic kernel. Do not treat a process merely existing as READY. Keep separate output directories and retain exit codes/logs. GPU assignment is chosen by root after checking existing workloads; shown indices are examples of physical device selection.
## Measurement, frozen criteria and outcomes
Force uses advancing link-momentum exchange, accumulated in batches <=100 steps, combined in FP64; Cd/Cl=2F/(U_lattice² D). Force timestamp is the batch midpoint. Pressure uses fluid-only h/2h extrapolation to cylinder front/back points and physical conversion 1/(3 U_lattice²), at each sample endpoint. For phase comparisons endpoint pressure is interpolated to the same cycle phase. Both raw times are saved.
Before t*=240 sample width=.5; afterwards .02 (about 166 samples per lift cycle). Pilot uses dense sampling throughout. Extract complete lift-minimum-to-minimum cycles using quadratic local minimum locations, accepting periods 2–5 t*. Latest five complete cycles must be consecutive with the last ending no more than 5 t* before the final observation, and must start at or after t*=250. Eligibility requires lift amplitude >=.2, period range/mean <=.005, Cd/Cl/pressure min and max ranges <=.005 absolute, cycle-mean mass range/mean <=1e-4, and each cycle's mean mass-flux imbalance <=.005. Instantaneous flux equality is not required in this unsteady compressible LBM diagnostic.
Reference gates: Cd extrema relative errors <=2%, Cl extrema absolute errors <=.03, pressure extrema relative errors <=2%, St relative error <=2%. These are predeclared engineering tolerances, not official uncertainty intervals. Phase-aligned waveform RMS errors, extrema, midpoint means, time means, amplitudes, outlet residual, sampled density bounds and Mach are all reported. Waveform RMS is diagnostic (no retroactive gate). No threshold changes after GPU results. At cap, failed periodicity stays incomplete. Invalid/nonfinite state, rho outside [.5,1.5], or sampled max Mach>.2 causes a safety stop; this is a gross-health guard, not a Mach-independence claim.
A case_reference_pass requires both periodicity and reference gates. Every raw case keeps suite_validated=false. The two-grid comparison must report each case and errors; matched-Mach D40/D80 is evidence of resolution sensitivity only, not an asymptotic convergence order. If either fails or finer errors increase materially, report the failure instead of adjusting thresholds. No full canonical/AMR/Mach-independent validation claim is allowed.
## Resource and calibration plan
D20: 441×84=37,044 nodes, pilot 10,000 steps. D40: 881×166=146,246 nodes, 1,200,000 full steps. D80: 1761×330=581,130 nodes, 2,400,000 full steps. Main double-buffer DDF arrays alone cost 72 bytes/node: 2.7/10.5/41.8 MB decimal. Flags, masks, macro host arrays, body buffers and CUDA context/JIT memory add overhead; root verifies actual free GPU/host memory and disk before launch. Conservative per-process reservation: 1 GiB VRAM and 2 GiB host RAM, excluding shared/compiler overhead; measurements take precedence.
Historical Re20 D80 U=.01 step throughput was ~6082 MLUPS (45.9 seconds/480k steps). At equal throughput D80 Re100 full advancing steps would take ~229 seconds, excluding dense full-field downloads/reduction and compile overhead. D40 estimate must be calibrated, not assumed proportional. Pilot records startup_seconds, step_seconds, measurement_seconds, mlups. For each full grid, calibrate a same-grid pilot if D20 cannot predict cost adequately. Full has about 3480 records (480 coarse+3000 dense); use measured seconds/step × full steps plus seconds/record ×3480 plus startup. D20-to-D80 extrapolation is only a rough planning upper/lower guide, not an ETA commitment.
Only geometry.npz, one final_field.npz, history.csv, summary.json and stdout/stderr are persisted. No per-step or repeated full-field snapshots. D80 final float64 rho/ux/uy plus mask are <15 MB uncompressed; history/summary several MB, compact versioned reference/source guards <50 KiB. Budget <100 MB per case and <500 MB whole campaign including logs and optional externally retained archives, safely below 2 GiB; root still checks baseline Horsea usage. Retain sparse evidence only.
## CPU validation and remaining execution
Ten tests cover geometry/units/config, pressure scaling, periodic and nonperiodic synthetic histories, immutable production hashes, and self-reference comparison. CUDA execution is not available in the preparation environment and has not been claimed. Run pilot first on Horsea; do not confuse successful CPU tests with GPU readiness.
## Reference provenance and reproduction
Only the compact derived cycle is versioned. Its source URL, official ZIP SHA-256, column selection, and cycle-selection description are embedded in reference_cycle.json. Raw archives and GPU results are not repository inputs. To reproduce it, obtain the exact archive identified there, verify its SHA-256, and extract logs/results_cc2d_bench2_referencenew/bdforces_q2_lv6_dt4 and pointvalues_q2_lv6_dt4. Use physical time column 2 multiplied by 10, drag/lift columns 4/5, and pressure columns 7 minus 12 (one-based columns). Build rows with mass=flux_in=flux_out=1, then call periodic.extract(rows, min_time=0) and select the last complete cycle. The source guard is tests/validation/data/dfg_re100/source_manifest.json; it verifies the current reviewed production snapshot rather than equating its origin with the validation branch HEAD.
+115
View File
@@ -0,0 +1,115 @@
# Jet-circle closed-control-volume pilot
## Current experimental source provenance
This development branch now includes the reviewed AMR-channel source changes originating in `5338864748ac67fe2544487c059ba149ebf916da` and `47b05bc8abfc957fe876b0c63bdb386e3c6cbaa5`. The current full-source manifest pins the latter reviewed source snapshot, including the new channel files. This is an explicit new experiment; neither source review nor host tests transfer historical d79 GPU/flow acceptance to it. The channel GPU gate has not yet run at integration time.
New run JSON records the source-origin pin plus `checkout_revision` (actual Git HEAD), `checkout_dirty`, and the experimental-source label. The origin pin is not claimed to be the run's checkout commit. Numerical definitions and thresholds are unchanged. Runs require a Git checkout for this runtime identity; source hash checks remain active.
Historical d79 Re100/Jet execution stays reproducible at `69e9b78de9483a5ff21e2d0c74311d240bfaf88c`; the d79 LES diagnostic checkpoint is `20ae6770924df15f31305aad56e44a54a3dd4d88`. Their manifests and existing result files are not rewritten. Use those commits to reproduce or interpret old d79 evidence. The current AMR-channel experiment requires its own GPU and applicable flow evidence.
Status: CPU preparation only. No GPU run or production change. Current source origin: reviewed AMR-channel snapshot 47b05bc8abfc957fe876b0c63bdb386e3c6cbaa5; this new experiment has no inherited d79 GPU acceptance. tests/validation/data/jet_circle_cv/source_manifest.json checks all tracked source file hashes before importing GPU code.
## Execute only after root-owned GPU serialization
From the repository root, with REPO set to the repository root and an absent output directory:
```sh
PYTHONPATH=src python -m pytest -q tests/unit/test_jet_circle_cv.py
python tests/validation/run_jet_circle_cv.py --repo "$REPO" --output "$OUTPUT" --plan
CUDA_VISIBLE_DEVICES="$VERIFIED_IDLE_GPU" python tests/validation/run_jet_circle_cv.py --repo "$REPO" --output "$OUTPUT"
```
The runner does not select, reserve, or contact a GPU machine. It requires one explicit CUDA_VISIBLE_DEVICES value, at least 1 GiB free, and refuses an existing output directory. It imports existing PyCUDA; no installation. Default pilot: 800 base steps, 8 output windows, at most 1800 seconds after READY. READY is printed only after both steppers compile, execute one base/two fine warmup hops, exercise download/raw paths, and reset initial state/time. A pre-READY silence may be compilation, not stepping progress. Root owns any overall startup timeout and all launch serialization.
## Physical/numerical case
Periodic root box 192 by 128, center (96,64) in root cell-edge coordinates, D=24.084, U0=.03, nu=.0072252, Re_D=100, beta=Vj/U0=.1, rho0=1. Unforced D2Q9 SRT FP32, no DDF shifting, no LES. The slightly noninteger diameter was selected solely to avoid q clipping at all three planned scales. Circle is stationary. Two uniform radial sectors at pi/2 and 3pi/2, half-width pi/12: top blows outward +.003, bottom sucks inward -.003; remaining wall has zero velocity. This periodic transient is NOT DFG, infinite-stream drag, or statistical high-Re validation. End time is t*=t U0/D approximately .9965.
AMR bounds (48,32,144,96). Finest dx=dt=.5 in root lattice units, nu_fine=2 nu, finest D=48.168. Full-domain fine reference is 384 by 256 with exactly the same finest spacing, timestep, viscosity, collision and storage. Root tau=.5216756, fine tau=.5433512, Mach approximately .05196.
AMR uses actual public FixedPatchStepper Jet construction and raw observation. The uniform blocked reference reuses the existing test_raw_exchange_gpu.py optional-input validation adapter: production Jet-derived velocity/force-arm arrays feed the unchanged blocked curved kernel. Its normal public PeriodicBlockStepper API is passive-only. This does not claim there is no uniform Jet route anywhere: Simulation.add_jet exists, but the same-blocked-kernel adapter removes a backend/storage confound for this comparison. No new public backend is introduced. Runtime asserts matching directions, q, fallback and true hit coordinates after frame conversion; both sectors must resolve links. Unclamped q/no fallback is required.
## Independent measurements and signs
Two closed rectangles: (72,44,120,84) and (64,40,128,88), wholly within the finest patch. Every contour face has two active-fluid stencil layers. Capture physical postcollision populations at t=0 and every completed base interval. Collision conserves density/momentum; these are valid endpoint moments, NOT precollision stress estimates.
For each contour, M and P sum fluid-cell rho and rho*u times h^2, excluding the staircase solid. Face midpoint quadrature integrates rho*u dot n and [rho*u*u+p*I-mu*(grad u+grad u.T)] dot n. Velocity gradients use centered differences in root-length units, mu=rho*nu, p=(rho-1)/3. Constant pressure subtraction integrates to zero on a closed rectangle. No raw exchange enters these field quantities.
Trapezoidal time integration samples every base step over the SAME reported [step_start,step_end] as cumulative raw impulses/masses. For each window:
- mass into fluid through body surface = delta M + integral outer mass flux
- raw boundary reaction target = -delta P - integral outer momentum-minus-traction flux
Raw rows are [Jx,Jy,angular impulse,mass into fluid]; each uniform fine hop scales by [.25,.25,.125,.25], exactly as the AMR interval ledger. Both fine hops are accumulated. AMR observation time endpoints and the public raw reduction are checked. Reports separate total, wall, aperture, blowing and suction raw rows. Coefficients divide force by .5*rho0*U0^2*D. These are momentum reactions including aperture transport; neither raw aperture nor total raw reaction is labelled solid-only hydrodynamic traction.
Independent aperture mass estimates integrate measured rho*u dot e_r over true arcs using 64-point Gauss quadrature and nearest active-fluid samples. No target velocity or raw row enters this estimate. Reports include maximum sampling distance, actual signed raw mass rates and nominal signed volume flux ±2*(pi/12)*R*Vj. Near-wall nearest-node sampling is only a first-order diagnostic, not certified wall extrapolation. Nominal volume flux is not asserted to equal measured mass flow at finite density variation.
Inventory near the circle is a staircase-cell approximation; its geometric error and face/time quadrature errors can appear in CV residuals. Two-contour spread and grid refinement are essential. No exact continuum force value, solid traction recovery, jet hardware load, or physics acceptance is claimed. Output status is deliberately PILOT_DIAGNOSTIC_ONLY even on successful execution.
## Scope, refinement, resources
Default one pilot only. Estimated device envelope 128 MiB, required free 1 GiB; bounded JSON only, conservatively under 2 MiB, no population snapshots or per-step logs. Every base step downloads both fields for independent quadrature, so PCIe/CPU diagnostic cost is intentional. Six CPU tests cover descriptor/source identity, uniform flux cancellation, affine convective divergence, quadratic viscous sign/coefficient, matched geometry/Jet selection and diffusive scaling.
Optional --scale 2 or 4 doubles/quadruples all lengths and divides U,V by that scale, holds lattice nu fixed, and scales steps/windows by scale^2: physical Re and t* match, Mach decreases. Source and geometry guards repeat. Device estimate scales as scale^2; memory gate requires twice the estimate or 1 GiB, whichever is greater. Scale 4 is not part of default authorization/readiness. --re 400 requires --allow-re400 and a separate reviewed root launch decision after Re100 evidence; no automatic promotion.
Compare AMR/reference velocity error, signed reaction coefficients, each contour's independently measured reaction and residual, contour spread, signed mass budgets, and measured aperture flux. Freeze numerical tolerances only after agreeing a scientifically appropriate convergence criterion; this preparation imposes only structural/finite-state guards. A completed pilot cannot establish convergence.
Follow-on design retained: porous Couette crossflow with u=U*expm1(Re_V*y/H)/expm1(Re_V), v=V and unequal exact wall shear. It requires validation-only planar geometry and is intentionally not implemented here.
### Amplitude, geometry, and high-Re limits
Both Jet amplitudes are constant throughout the run and every fine substep; geometry is fixed. There is no runtime switch, per-step forcing schedule, or moving-wall velocity in this campaign. Construction/packing happens once, with identical uploaded amplitudes in the uniform adapter. This avoids any substep timing ambiguity from amplitude changes.
Every case records actual tau_root and tau_fine. For this fixed s=1 geometry and speed, Re400 would give nu=.0018063, tau_root=.5054189 and tau_fine=.5108378, close to the SRT limit .5. The implemented Re choices are a bounded campaign menu, not a universal physical Reynolds-number ceiling. Higher-Re evidence may require a larger initial resolved geometry or a different justified grid/relaxation design before launch. Diffusive refinement at constant lattice nu improves spatial/Mach resolution but does not move tau farther from .5; simply selecting scale=2 does not cure a poor tau. No all-Re, LES or three-dimensional realism claim follows from this pilot.
The source guard checks production file content against the current reviewed source origin, not validation-branch HEAD. This runner is validation-only; generated results and frozen execution-package archives are not committed.
## Measurement-only continuation (frozen design before execution)
The original 800-step pilot and its audit remain historical evidence, not an acceptance target. The following adds diagnostics only; it neither modifies production kernels nor adjusts velocity commands to improve measured flux. Use the canonical validation Git branch, with the same source-manifest check and checkout provenance record. No standalone replacement source archive is needed.
Run the pair serially under root-owned GPU allocation, from the checked-out repository:
```sh
python tests/unit/test_jet_circle_cv.py -v
python tests/unit/test_jet_cv_measurements.py -v
CUDA_VISIBLE_DEVICES="$VERIFIED_IDLE_GPU" python tests/validation/run_jet_circle_cv.py --repo "$PWD" --output "$NEW_OUTPUT_S1" --continuation --steps 3200 --scale 1
CUDA_VISIBLE_DEVICES="$VERIFIED_IDLE_GPU" python tests/validation/run_jet_circle_cv.py --repo "$PWD" --output "$NEW_OUTPUT_S2" --continuation --steps 3200 --scale 2
python tests/validation/analyze_jet_cv_continuation.py "$NEW_OUTPUT_S1" "$NEW_OUTPUT_S2" --output "$COMPARISON_JSON"
```
Both output directories must be absent. `--plan` prints configuration without CUDA. `--continuation` deliberately accepts only Re100, scale1/2, and 3200 reference steps: a bounded campaign, not a physical Re ceiling. Actual steps are 3200 and 12800, reaching the same t*=3.986048829. Physical circle/box/contours and beta remain fixed; all root lengths grow by s, U and jet speed shrink by s, lattice nu remains .0072252. Both runs retain tau_root=.5216756 and tau_fine=.5433512, with Mach .0519615/s. This diffusive refinement changes the finite-Mach/compressibility error as well as grid resolution; it is not an isolated spatial-error order study.
### Units, cadence, and reconstructibility
Reference length/time are one scale-1 root lattice length/time; density reference is one. Convert scale-s root quantities by: length /s, time /s², velocity times s, mass /s², momentum and impulse /s, force times s, angular impulse /s², pressure times s². Volume and mass rates are unchanged. The nominal signed aperture volume rate is ±.0189155293672 in reference units at every scale. A mass flux divided by rho_ref times that rate is a reference-density diagnostic, not an actual-volume-flow ratio. Saved Q and M remain separate.
Exact raw observations accumulate every completed base interval, including both fine substeps. Field downloads occur only at shared reference times 0..100 at dt=1, then 100..3200 at dt=4: 876 samples per run, compared with 3201/12801 possible every-base samples. Every 100-reference-time window boundary is included. Trapezoidal integration uses the actual variable time gap, with the raw ledger covering exactly the same endpoints. No missing sample is silently treated as unit dt. Sampling is denser during abrupt startup; it is not a guarantee of resolving all high-frequency acoustic modes. Offline coarsening can expose some time-quadrature sensitivity but cannot rule out unresolved-frequency aliasing.
`samples_s*.npz` stores at every sample: density minima/maxima/max perturbation and max speed for uniform fluid, AMR root leaves and AMR fine leaves; composite full-domain mass; CV endpoint inventory and flux; separate advective, pressure and negative-viscous-traction momentum fluxes; nearest-fluid mass proxy; extrapolation ray primitive values; linear/quadratic reconstructed Q and M; and cumulative raw wall/aperture/total/blowing/suction rows. Associated JSON identifies axes, units, conversion factors, hashes and snapshot metadata. Composite AMR mass sums root leaves at area1 and fine leaves at area.25, then divides by s². Covered cells are excluded. Global periodic mass change minus total raw body mass is reported, so a transfer/interface mass error cannot hide behind the two contours lying wholly within the fine patch.
Five compressed primitive snapshots at reference times 0,100,800,1600,3200 retain rho, reference velocity, origin and spacing for uniform, AMR root and AMR fine grids. Inactive/solid entries are NaN. These are full primitive grids at sparse times, not downsampled images or distributions. They permit independent spatial quadrature, field inspection, masks and inventory reconstruction. Per-sample split flux/inventory arrays allow independent temporal integration without rerunning GPU work. FP32 saved primitive snapshots introduce their own rounding; FP64 sampled diagnostic/ray arrays remain in the sample file.
### Independent aperture estimators and limitations
Thirty-two Gauss points per true aperture arc, with rays at distances 1.5,2.5,3.5 finest-cell widths into the fluid, sample rho,u,v by bilinear interpolation using only active fluid nodes. No commanded wall value or raw population enters reconstruction. Linear and quadratic outward-normal extrapolations separately reconstruct rho and u; integrate Q=integral(u.n ds) and M=integral(rho*u.n ds). Retain ray positions, normals, weights, primitive samples and coefficients, making every estimate reproducible. The nearest-fluid 64-point mass proxy is preserved for continuity with the pilot and remains explicitly a proxy.
Neither estimator is an exact wall value or validated wall model. Extrapolation amplifies noise and may yield unphysical density; do not clamp it to force agreement. Sector endpoints contain nonsmooth prescribed velocity changes, and interpolation may mix their neighborhood. Linear-versus-quadratic spread, ray density extrema, resolution changes and analytic manufactured tests constrain interpretation, but their agreement is not proof of low bias. Two grids alone cannot establish asymptotic convergence. Nominal geometry/profile flux is exact for the commanded uniform radial profile; comparison with reconstructed Q diagnoses estimator plus numerical-boundary error, not automatically a Jet defect. Raw reaction remains momentum transport plus traction; no nozzle-load or solid-only force claim.
### Predeclared comparison criteria
These criteria are fixed before the continuation runs. There is no new physical acceptance threshold and no tolerance fitted to the pilot:
1. Structural validity: exact source/provenance, matched geometry/parameters, unclamped q/no fallback, both apertures resolved, finite positive active-node density and finite velocity at every saved field sample, complete scheduled samples, contiguous matching raw intervals, and all declared files/hashes. Runtime does not promise positivity between saved samples.
2. Report every window's signed and gross quantities, maximum sampled errors, and early (reference t<=800) versus later (t>800) norms separately. Normalize mass residual by rho_ref*abs(Q_command)*window_duration, and reaction residual by .5*rho_ref*U_ref²*D_ref*duration. Avoid dividing by a near-zero net mass or instantaneous force.
3. Recompute contour residuals using the complete sampled grid and every second/fourth sample, always retaining endpoints. Save their changes as a temporal-sensitivity proxy, not an error bound. Compare both contours and both backends; show mass, Cx and Cy components separately.
4. A directionally resolved reduction in a component's RMS CV residual is flagged only if coarse-minus-fine RMS exceeds twice the largest observed temporal coarsening change. This is an evidence-of-trend flag, never a physics PASS. If a component plateaus or grows, decompose temporal/spatial/staircase/boundary effects before proposing production changes.
5. Compare reconstructed Q/command and M/(rho_ref*command) separately, at identical physical windows, retaining both extrapolations. Regard refinement improvement as persuasive only when it exceeds estimator spread and temporal variation. Inspect density and global mass alongside it. Agreement of AMR and uniform ledgers alone cannot validate their shared boundary treatment.
6. Four D/U in a periodic unforced domain remains transient consistency evidence. Two scales do not prove order, stable shedding, infinite-stream drag, all-Re capability, or readiness to promote Re400. Formal physical acceptance needs an additional reference/error budget and appropriate time/domain evidence.
### Runtime and storage budget
Actual earlier scale-1 pilot cost was 52.3884s launch-to-exit, 46.1414s after READY for800 steps with full-field diagnostics every base step. A naive same-diagnostic3200-step scale-1 extrapolation is about210s; the new876 field samples reduce transfer count but add ray diagnostics and compression. Use conservative planning envelopes210–500s for scale1 and900–3200s for scale2, not timing guarantees. The scale2 conservative envelope accounts for4x cells and4x root steps; sparse sampling mitigates but does not eliminate that cost. Post-READY safety caps are1200s and5400s respectively, replacing the unsuitable fixed1800s assumption. Root owns compilation/startup timeout and serial launch decisions.
Device-envelope estimates remain128/512MiB for s1/s2, at least1GiB free (or twice estimate). Output estimate is under64MiB per run including five primitive snapshots and876 sample records; no all-time populations are saved. Plan/metadata and sampled files are rewritten at each100-reference-time window to retain bounded partial evidence if interrupted. READY still follows compiled warmup and state/time reset, before measured stepping begins.
+40
View File
@@ -0,0 +1,40 @@
# Smagorinsky baseline/candidate helper diagnostic
This validation-only diagnostic compares exact d79 production headers with a temporary candidate. It does not modify production source. The candidate changes only the D2Q9 and D3Q19 closed-form factors from 18 to 18 sqrt(2), plus comments defining |S| = sqrt(2 S:S) and self-consistent effective tau. The small reviewed patch and expected header hashes are in `tests/validation/les/data`; no copied headers, solver trees, raw results, or binary fixtures are versioned.
## Prepare and verify on the CPU
From the repository root, choose a new output directory:
```sh
python tests/validation/les/prepare.py --output-dir output/les-host/candidate
python tests/validation/les/test_candidate.py --candidate-dir output/les-host/candidate --output output/les-host/host_results.json
```
Preparation checks both actual production header hashes against d79, copies only `descriptors.cuh` and `turbulence_smag.cuh` into output-local baseline/patched include trees, applies the reviewed patch only to the latter, and verifies all four resulting hashes. It refuses an existing candidate directory. The host test verifies candidate hashes again and refuses an existing evidence file. The Git branch HEAD may include validation commits; header content, rather than HEAD identity, is the pin.
The independent host oracle constructs second-order Hermite populations and solves the independently derived quadratic by bisection:
tau * (tau - tau0) = 9 Cs^2 ||Pi_neq|| / (sqrt(2) rho)
There are **736 parameter cases**, covering D2Q9/D3Q19; Cs=0,.08,.16,.24; tau0=.6,.8,1.2; rho=.7,1,1.3; equilibrium, isotropic stress, pure shear, and trace-free diagonal extension; all coordinate planes and both signs; density-scaled Pi and separate fixed-Pi/nonunit-rho probes. The test checks quadratic residuals, closed/default-three/converged-200 iterations, bit-identical unchanged iterative output, and an additional explicit cap-active manufactured probe. Existing g++ and Python stdlib are sufficient; no installation is attempted. Compilation products are temporary. Previously reviewed host maxima were omega error 1.394302e-7 and quadratic residual 1.201202e-7; this is not CUDA fast-math evidence.
## Authorized GPU diagnostic
Use the existing working PyCUDA/NumPy environment and an explicitly selected device, through the same serialized GPU launch owner as the other campaigns:
```sh
CUDA_VISIBLE_DEVICES="$VERIFIED_IDLE_GPU" python tests/validation/les/run_gpu.py --run-gpu --device 0 --output-dir output/les-gpu
```
Device 0 is the logical device after CUDA visibility filtering. The output directory must not exist. The runner materializes and verifies the isolated include trees under `output/les-gpu/candidate`, then runs baseline and patched processes sequentially. Each process compiles one SourceModule at a time synchronously and synchronizes each probe. There are no background jobs, worker pools, or parallel compiler calls. No machine contact, device selection, reservation, or environment setup is performed by the runner.
Each version has exactly **48 scalar GPU cases**, 96 total: D2Q9/D3Q19, Cs=.16/0, equilibrium/shear/isotropic/cap-active manufactured stress, and closed/default-three/converged-200 branches. This is the frozen GPU matrix, not the expanded 736-case host matrix. Outputs `baseline.json` and `patched.json` contain raw scalar omega values and device name. Completion means only the diagnostic executed; an independent comparison against the declared host oracle is still required. A failed run leaves partial evidence for inspection and must not be overwritten.
## Interpretation and limits
Full-stress versus deviatoric-stress selection, iterative viscosity cap, iteration count/relaxation, omega guards, collision dispatch, and AMR guards remain unchanged. Closed and iterative paths intentionally remain different for isotropic or cap-active stresses. No settings or Cs defaults change. High stress is a helper diagnostic, not an admissible flow-state claim.
The corrected scalar formula is justified only under the stated stress-strain estimate. MRT full-trace stress does not generally share one shear relaxation rate, so its bulk coupling remains uncertified. Force-corrected non-equilibrium stress and Guo-force interaction also remain uncertified. These manufactured tests are unforced and do not cover full TRT/MRT collision, streaming modes, shifted storage, walls/Jets, flow solutions, or 3D turbulence. Existing guard statements are preserved, not newly comprehensively tested; the main matrix is guard-inactive. No AMR LES support is added or enabled.
Production integration and removal of this temporary candidate fixture are separate decisions after GPU and applicable flow evidence. CPU success alone does not approve a production change.
+70
View File
@@ -0,0 +1,70 @@
# Matched SRT uniform / refined DFG Re100 preparation
Status: CPU-preflight checked; **not GPU executed or approved to execute**. No physical acceptance or speedup claim. No production source changes. Root owns GPU admission and integration.
## Frozen setup
Canonical source snapshot: integrated commit `cd3a657f9d3833e812c3cca173525f165b48710a`. Production origin remains candidate `47b05bc8abfc957fe876b0c63bdb386e3c6cbaa5` (on `5338864`, on `69e9b78`); production files are byte-identical. The integrated Re100 helper header/PIN records that origin explicitly. Both commit identities are retained in the manifest. `tests/validation/data/refined_dfg/source_manifest.json` hashes all production source files plus the existing DFG geometry/pressure helper, periodicity helper and official reference cycle. An integrated checkout may have a different commit but must have identical pinned file contents. No MRT external-reference run is reused as the matched uniform control.
Both cases: SRT, shifted FP32, double buffer, no LES, no applied force, stationary cylinder, local Zou–He parabolic inlet, halfway y walls, identical pressure-NEQ outlet with **all nine nonequilibrium components damped by 0.5**, backflow clamp disabled. This outlet is not the exact canonical DFG do-nothing condition. Raw cylinder reaction observation is a diagnostic, not applied forcing.
Physical units use D=0.1 m, mean U=1 m/s, ν=0.001 m²/s, density reference=1; domain 2.2×0.41 m, cylinder center (0.2,0.2) m. Uniform D80: 1761×330, dx=0.00125 m, dt=0.0000125 s, ν_lattice=.008. Refined root D40: 881×166, dx=.0025 m, dt=.000025 s, ν_lattice=.004; fine dx/dt/ν match uniform D80. All lattice mean speeds are .01.
Fixed half-open patch **(40,24,320,140)** in root edge coordinates maps to x=[.09875,.79875] m, y=[.0575,.3475] m. The body and about six diameters of downstream wake are fine; wall layers and far wake remain coarse. Bounds are frozen before outcomes, not tuned afterward. Geometry-only leaf-count and nominal collision-work ratios to uniform are ~.419 and ~.321. These omit real launch/transfer/halo/measurement costs and are not measured speedups. The narrow root block height is legal but potentially expensive; do not infer speed from leaf count.
Exact root dimensions are tiled by (by,bx)=(2,881); no padding. Fine allocated shape (240,568), including four-cell halos, uses (8,8). `host_geometry` calls production channel transfer-overlap checks and complete fine cut-link/donor/transfer guards before any CUDA import.
### Half-cell conversion
Uniform integer nodes have physical coordinates (i*dx, (j-.5)*dx). Root edge coordinates therefore map to ((X-.5)*dx_root, (Y-1)*dx_root). Body edge center=(80.5,81), radius=20; wall edges Y=1,165; source planes X=.5,880.5. Fine local body nodes are `(body_edge - fine_origin)/.5 - .5`.
Body and physical wall planes match exactly. The axes have different phases. With fine origin O=(38,22):
- x_f = [O_x+(j+.5)/2-.5] dx40 = (j+75.5) dx80, versus x_uniform = i dx80. Fine x samples have a half-fine-cell (quarter-root-cell) offset.
- y_f = [O_y+(k+.5)/2-1] dx40 = (k+42.5) dx80, versus y_uniform = (l-.5) dx80. The y samples align exactly for l=k+43.
This difference follows from the inlet's ghost-node plane versus the half-way y-wall planes. The host phase test checks both mappings. Compare interpolated observables, not pointwise arrays or bitwise equality; x-phase error, the different fine collision arithmetic, wall resolution, and coarse/fine transfer effects all contribute to discrepancies. No field-difference acceptance is claimed by this runner. Initial fluid state samples the same analytic parabolic equilibrium as uniform production initialization; root boundary ghosts start at rest. It is not asserted to be bitwise identical across different grids/arithmetic.
## Observations and gates
- Every AMR base step is individually followed by `read_raw_exchange(..., window='last_base_step')`: two fine substeps, root-lattice per-unit-depth impulse integrated over [n,n+1]. `step(n)` alone retains only its last base interval, so it cannot support averaging the whole batch.
- Uniform `Simulation.run(batch)` / `read_force` gives the mean over that batch; multiply by batch before accumulating. Cd/Cl divide the interval mean reaction by 0.5 U_lattice² D_lattice in each case. Force unit is ρ dx³/dt² per depth, so fine-uniform lattice force is twice root force for the same physical load.
- Force timestamps are observation-interval midpoints. Pressure uses physical decoded postcollision density at the interval end, extrapolated from fluid-only points one/two **fine** cells outside the cylinder using existing `pressure_probes`. Pressure difference is normalized by ρ_ref U_physical². Existing periodic helpers align pressure onto force cycles.
- Public AMR downloads exclude nonleaves. Fixed geometry masks, not state-dependent finiteness masks, check all fluid populations and sum ρ dx_level²; covered root cells, body, boundaries and fine halos are excluded. Corrupt NaN fluid cannot disappear from the mass check. Mass is per-unit-depth ρ_ref·m². Uniform uses its physical fluid flags and dx². Different sampling of the circular boundary means initial discrete fluid volume can differ slightly; compare temporal stability, not identical absolute mass.
- Flux samples root/uniform x-index 2 and -3, summed with dx and physical velocity conversion. Those planes differ by grid-scale offsets; cycle-average inlet/outlet balance is the gate, not direct pointwise flux equality.
- Dense measurement width Δt*=.02 in the pilot and for t*≥240, otherwise .5. Pilot ends t*=5; full ends t*=300. Same existing five-cycle periodicity, mass, flux, and reference gates are imported without modification. Both official-reference diagnostics and refined-versus-uniform cycle comparisons are written. `matched_case_pass` refers only to matched SRT agreement, not certification of canonical DFG or the broader suite.
- Safety stop: nonfinite state/reaction, Mach>.2, or density outside [.5,1.5]. GPU durations include required exchange reads and synchronization in stepping; full wall time also includes host measurements. Do not report pure-kernel throughput from these numbers.
## Commands
From the repository root, CPU only:
```sh
PYTHONPATH=src python tests/unit/test_refined_dfg.py
python tests/validation/run_refined_dfg.py --mode plan --output /tmp/refined-dfg-plan-new
```
Fourteen CPU tests are retained in tests/unit/test_refined_dfg.py. Plan JSON is configuration output only; no preparation result files are committed. The initial attempt to use pytest was unavailable in this interpreter; tests use standard-library unittest and NumPy instead.
Only after root channel GPU gates pass and root explicitly admits an idle physical GPU, root may run:
```sh
CUDA_VISIBLE_DEVICES=<admitted-device> timeout --signal=TERM --kill-after=30s <caller-hard-budget>s python tests/validation/run_refined_dfg.py --mode pilot --gpu-gates-approved --max-wall-seconds <caller-soft-budget> --output <new-pilot-directory>
CUDA_VISIBLE_DEVICES=<admitted-device> timeout --signal=TERM --kill-after=30s <caller-hard-budget>s python tests/validation/run_refined_dfg.py --mode full --gpu-gates-approved --max-wall-seconds <caller-soft-budget> --pilot-results <completed-pilot-directory> --output <new-full-directory>
```
`--gpu-gates-approved` is a caller attestation, not proof that GPU tests ran. Full mode additionally requires both matched healthy pilots through t*=5 with identical source hashes, bounds and runner hash. No GPU/Mac/remote operation has been performed for this preparation. Pilot/full outputs must be new/empty. Uniform runs first; an unhealthy case stops the campaign. A full run that fails periodic/matched gates exits nonzero.
## Bounded execution and receipt validation
No pilot throughput is known yet; the caller must set a finite positive `--max-wall-seconds` rather than treating an invented estimate as calibration. After valid pilots, the full-run calibrated budget is 3 × sum_over_cases[startup_seconds + 60 × (pilot_wall_seconds − startup_seconds)]. The full run uses the smaller of that estimate and the caller's explicit ceiling. This uses total measured pilot evolution/observation cost and the full/pilot physical-time ratio (300/5); 3× is a declared safety margin, not a runtime guarantee. The plan records both budgets.
The campaign deadline begins before the first case initialization. Cooperative checks surround initialization, every AMR root step or uniform ≤100-step batch, and measurements. On observed expiry, the runner stops, writes a nonpassing `wall_time_limit` receipt, and exits 3. A blocking CUDA call cannot be interrupted by these checks: the external `timeout` watchdog is required, with a hard budget chosen slightly above the soft budget to permit cleanup. Hard termination may leave partial CSV data and no final receipt; that never qualifies as a completed pilot.
Each case emits `READY` with strict finite JSON and saves `ready.json` only after its first healthy complete observation, after initialization, actual stepping, force readback, macro/pressure/mass/flux paths and CSV flush all succeeded. No early initialization-only READY is emitted.
Full-run pilot validation rejects nonfinite JSON constants and numeric overflow, wrong case/mode/status, nonboolean health, missing/duplicate/out-of-order rows, wrong step counts or observation times, missing numeric observations, health-limit violations, absent/mismatched READY receipts and invalid timing calibration. It requires exactly 250 observations spanning the full dense t*=5 pilot, source/runner hashes and frozen bounds. Tests include the reviewer's exact NaN-endpoint regression and malformed receipt variants. Synthetic test fixtures exist only in temporary directories and are not simulation results.
## Integrated source import guard
The runner's source defaults to this repository root. Before geometry or GPU work, it verifies the pinned source/helper/reference contents and requires the imported CelerisLab package to be exactly `<source>/src/CelerisLab/__init__.py`. An installed DynamisLab copy or another cached checkout is rejected. Integration changes paths/readability and this explicit import assertion; geometry, numerical definitions, gates, and receipt validation remain frozen. Any new path-formatted runner has its own hash, so old preparation pilot receipts cannot authorize a full run of this integrated runner.
+71
View File
@@ -0,0 +1,71 @@
# Matched MRT DFG pilot preparation
Preparation only: this test-only extension reuses the existing runner and existing MRT
operator. GPU admission awaits reviewed MRT capability results; no pilot/full execution
is implied by CPU preflight. No production, historical SRT manifest, reference data,
periodic gate, geometry, initialization or observation algorithm is changed here.
## Selection and provenance
Use `--collision MRT` for **both** uniform D80 and refined root D40/fine D80. There are
no independently selectable collision models per case. Default remains SRT.
MRT verifies `data/refined_dfg/source_manifest_mrt.json`, pinned to reviewed numerical
source snapshot `3ea131e92c057843034f11a1c574301a2430dfce`, including the shared geometry,
pressure/cycle helpers and official reference. Test-only commits may change HEAD without
changing this numerical source pin. Plan, READY, case summaries and comparison separately
record `checkout_revision` and `checkout_dirty` using existing source-provenance helper;
the runner hash remains separate. Collision is recorded in every receipt, and full-mode
validation rejects missing or different collision labels in plan, either summary or either
READY receipt, in addition to existing source/runner/health/time checks.
The historical SRT manifest remains byte-for-byte unchanged. SRT on the MRT candidate
checkout deliberately fails that source pin; use a matching historical checkout via
`--source` for SRT. No fallback or automatic repinning is permitted. Historical SRT
failure/diagnostic evidence remains attached to its original source and runner hashes;
it cannot authorize an MRT full run. The existing failed-observation step-reporting
undercount is not changed in this narrowly scoped selection patch.
## Frozen physical comparison
All settings remain those documented in `refined_dfg.md`: U_lattice=.01, physical mean
U=1 m/s, D=.1 m, shear ν=.001 m²/s, fixed physical domain/body/wall planes, patch
(40,24,320,140), shifted FP32 double buffers, no LES/forcing/Jets, finest dx=.00125 m,
finest dt=.0000125 s, unchanged half-cell frame conversion and axis-specific phase.
Force interval accumulation, physical leaf mass, pressure interpolation, flux sampling,
safety thresholds, t*=5 pilot and t*=300 cap are unchanged. Existing accuracy/periodicity
criteria are imported unchanged. Both MRT cases are fresh runs; old MRT or SRT results
are not substituted as controls.
Both cases use the **existing MRT pressure-NEQ branch**: only unknown directions q2/6/8
are extrapolated. This differs from SRT's all-nine .5-damped branch; the retained
`srt_neq_damp=.5` configuration value is inactive under MRT. Backflow clamp remains off.
The outlet is still noncanonical relative to exact DFG do-nothing conditions.
The reused MRT operator keeps fixed kinetic rates `s_e=s_eps=s_q=1.2` on all levels;
only the shear rate follows existing per-level viscosity. Physical bulk relaxation
therefore differs between coarse and fine levels. Transfer operators and subcycling
are unchanged. This is the candidate's declared behavior, not a new fully mode-scaled
MRT transfer scheme. Do not tune rates, the patch or gates after seeing outcomes.
Capability smoke/parity gates do not establish DFG accuracy or speedup.
## CPU and admission commands
From this checkout:
```sh
python tests/unit/test_refined_dfg.py
python tests/validation/run_refined_dfg.py --collision MRT --mode plan --output /tmp/new-mrt-dfg-plan
```
After root verifies the candidate MRT root/parity/refinement capability results and admits
an idle device, the paired pilot may use the existing bounds and external watchdog:
```sh
CUDA_VISIBLE_DEVICES=<admitted-device> timeout --signal=TERM --kill-after=30s <hard-budget>s python tests/validation/run_refined_dfg.py --collision MRT --mode pilot --gpu-gates-approved --max-wall-seconds <soft-budget> --output <new-mrt-pilot-directory>
```
The flag is caller attestation, not evidence. An unhealthy first case prevents the second.
Existing strict pilot receipt validation and calibrated wall-time controls remain; full
mode is not being admitted as part of this preparation. Root must review both healthy
pilot outcomes and separately decide any full-run admission.
+58
View File
@@ -0,0 +1,58 @@
# Refined DFG MRT timing harness (measurement only)
`tests/validation/time_refined_dfg.py` times the matched MRT refined/uniform DFG Re100 setup of
`run_refined_dfg.py` (same configuration, geometry and initial state functions). No numerical,
physics-gate or production change; no force or accuracy result is produced.
| Variant | Loop | Force reads |
|---|---|---|
| A | refined `step(1)` + `read_raw_exchange` per base step | runner-like force-read workload (values discarded) |
| B | refined `step(1)` only, no host reads (`observe_raw_exchange` stays on) | timing-only |
| C | refined single `step(N)` | timing-only; ledger keeps the final base interval only |
| E | uniform `sim.run(<=100)` + `read_force` | runner-like force-read workload (values discarded) |
| E' | uniform single `sim.run(2N)` | timing-only; at most a whole-window average, different summation order |
- No variant retains a valid force history; A/E omit the runner's interval aggregation and
validation, and no variant includes macro/probe/CSV costs. Results are not full benchmark
throughput.
- Status lines: `CONSTRUCTED` (construction/JIT complete) and `WARM_READY` (first warm-up and
health check passed) per case.
- Equal simulated duration: N refined base steps vs 2N uniform D80 steps.
- Every repeat starts from the same fresh state (refined `initialize`, uniform `snapshot/restore`)
and the same warm-up; construction/JIT, warm-up, downloads and parity checks are untimed.
- The actual stepping stream is synchronized explicitly before and after each timed loop; the
wall timer (`time.perf_counter`) is the only source. No CUDA-event span is called kernel time.
- `--max-wall-seconds` is required for GPU runs (outer timeout, checked between variants and
every 100 steps in per-step loops).
- Final populations and NaN masks must be bitwise identical to the first A repeat (A/B/C) or the
first E repeat (E/E'); refined and uniform grids are never compared. Leaf/fluid populations
must be finite. Physical health (finite leaf/fluid macros, rho in [0.5, 1.5], max Mach <= 0.2,
the existing runner limits) is checked after warm-up and after each timed window. Matching NaN
is accepted only as a storage mask; any infinity or level-count mismatch fails parity. All
parity/health checks are untimed.
- Cases run sequentially (uniform, then refined) in one process with startup serialized;
variants are interleaved within each repeat. A-B and B-C are measured comparative
differences under GPU variability, not exact causal decompositions.
Usage (root selects one verified idle GPU):
PYTHONPATH=src python -m unittest tests/unit/test_time_refined_dfg.py
python tests/validation/time_refined_dfg.py --output <new> --plan
CUDA_VISIBLE_DEVICES=<gpu> python tests/validation/time_refined_dfg.py --output <new> --max-wall-seconds <s>
Defaults: 2000 base steps, 200 warm-up base steps, 3 repeats. Profiler capture and the
`observe_raw_exchange=False` variant are deferred until these measurements exist.
## A versus observation-window ledger (`tests/validation/time_window_dfg.py`)
Measurement-only comparison on the same shifted-MRT refined setup: A (per-base `step(1)` +
`read_raw_exchange`, summed per 80-base-step interval), W (`start_exchange_window`, `step(80)`,
one window read) and W1 (window with 80 x `step(1)`, isolating the read pattern from call
batching). Same fresh state, warm-up and simulated duration; populations must be bitwise equal
to the first A repeat and per-interval total impulses within the documented engineering
tolerance, all outside timing. The candidate source is recorded (checkout revision, dirty flag,
file hashes); frozen refined-DFG manifests/results are not used or changed.
PYTHONPATH=src python -m unittest tests/unit/test_time_window_dfg.py
python tests/validation/time_window_dfg.py --output <new> --plan
CUDA_VISIBLE_DEVICES=<gpu> python tests/validation/time_window_dfg.py --output <new> --max-wall-seconds <s>
+117
View File
@@ -0,0 +1,117 @@
# Opt-in observation-window ledger in the DFG runner
This test-only integration adds `--exchange-window` to `run_refined_dfg.py`. It uses the
existing production ledger; no collision, boundary, transfer, physical setup, reference,
periodicity gate or acceptance threshold changes. Default remains the historical
per-base-step observation path. Uniform stepping/force accumulation is unchanged.
For the refined case, each existing observation interval opens a new ledger at completed
base step `begin`, advances exactly the same `n` base intervals, and reads the integrated
root-lattice impulse for `[begin, begin+n]`. The contract requires root units, `window`
kind, `2*n` fine samples, matching endpoints, and fine dt=.5. The existing coefficient
calculation still divides this impulse by `n` and `.5*U_lattice**2*D_root`; force timestamps
remain `(begin+n/2)*U_lattice/D_root`. It does not divide an already averaged force again.
Pressure/macro/physical-leaf mass measurements and safety checks remain at the original
interval end. Pilot interval is 80 root steps; early full-run intervals remain 2000, and
any final shortened interval uses its actual `n`.
The opt-in uses one `step(n)` call and one window read per observation, rather than `n`
Python calls/readbacks. Internal subcycling and per-base synchronization remain owned by
the same backend. Cooperative deadline checks surround that complete interval; unlike
the default path they cannot interrupt between base steps inside `step(n)`. The existing
external hard watchdog is still required. The full-run cadence/cap is documented here,
but this preparation does not admit a full run or a GPU operation.
## Provenance and receipt separation
`source_manifest_window.json` pins the reviewed a233c9032487a6006e950d1e327079b00466c410
snapshot (production ledger origin d930) plus existing helper/reference files. Both SRT
and MRT are supported by this explicit opt-in source pin; collision selection remains
independent and shared by the two cases. Existing SRT and MRT manifests are untouched.
Default mode continues to reject the changed candidate under those historical pins;
use a matching historical `--source` checkout to run its default path. There is no
silent repinning, source fallback, or reuse of historical outputs as candidate evidence.
Plan, READY, summaries, timeout/comparison receipts now record `observation_mode` as
`last_base_step` or `window`, alongside collision and actual checkout provenance. On a
uniform receipt this labels its **paired campaign's refined observation mode**, not a
change to uniform observation. Full-mode pilot validation rejects missing or mismatched
mode labels in the plan, either case summary, and either READY receipt. Source/runner
hash, collision, completeness and health checks remain. Cross-mode pilot reuse is denied.
The earlier short A/W/W1 timing/capability evidence is not a full-run speedup or accuracy
claim. Mathematical impulse integration/units are unchanged; floating-point reduction
order can differ, so bitwise equality of force sums is not promised. Physics acceptance
continues to use the existing frozen gates. Historical failures/results are untouched.
CPU preparation commands, from the repository root:
```sh
python tests/unit/test_refined_dfg.py
PYTHONPATH=src python -m unittest tests.unit.test_raw_exchange_window tests.unit.test_time_window_dfg -v
python tests/validation/run_refined_dfg.py --collision MRT --exchange-window --mode plan --output /tmp/new-window-dfg-plan
```
Root must independently review and admit any execution. An admitted paired pilot uses
the existing watchdog, device selection, `--gpu-gates-approved`, positive
`--max-wall-seconds` and a new output directory, adding only `--exchange-window` to the
selected collision's pilot command. No GPU or remote action was performed for this patch.
## Public Jet diagnostic option
`--collision MRT --exchange-window --jet-scenario zero|fixed|reverse` selects
unshifted FP32, no LES, constant transfer on both existing public backends. Default
`none` and the historical manifests remain unchanged. `zero` registers both Jets at
zero amplitude and retains every existing DFG verdict, including pressure. `fixed`
uses outward radial parabolic sectors at pi/2 and 3pi/2, half-width pi/12, peaks
(+.001,-.001). Both use the existing D40/D80 geometry and U=.01. Sector origins are
(80.5,81) in root edge coordinates and (160,160.5) in uniform node coordinates;
radial extent is [0,1.005R]. `reverse` keeps those peaks through t*=300, updates both
public setters at that completed boundary, and continues to 305 with opposite signs.
Fixed diagnostic windows are 250–260, 260–270, 270–280, 280–290 and 290–300; reversal
adds 300–305. Histories retain exact interval endpoints and root/uniform lattice
impulses. The refined window uses total exchange; uniform uses public `read_force`
batch averages. Driven windows report mean/min/max/RMS Cd/Cl without applying DFG
reference or periodicity gates. Exit zero means healthy execution, not qualification;
`matched_case_pass` remains false. No independent CV or stress-load claim is made.
This opt-in records current source/helper hashes with the existing manifest format,
checkout revision/dirty state and runner hash. Pilot/full must match that snapshot
and the exact scenario. It does not relabel current source as historical evidence.
Use the existing bounded plan/pilot/full commands with the three option flags above;
full requires the matching completed t*=5 paired pilot. `step_seconds` includes force
readback; observation/overhead and total wall time are separate, not kernel throughput.
Add `--observe-cv` to record independent scalar control-volume samples from the
already downloaded public macros. The pilot exercises this path at t*=.02..5;
full records 501 endpoints at 290..300. Each `cv_history.jsonl` row contains actual
root time, preceding interval start/duration/impulse, and two inventories/outward
fluxes ordered [mass,Px,Py]. Exclude the first row's preceding impulse: that row
supplies the initial inventory. Uniform native impulse converts by .5² to root
units; refined ledger impulse is already in root units. Explicit native-aligned
contours differ by .25 root cells in x and are recorded in the plan. Cropping
retains the two-cell face-gradient stencils. No fields or per-link arrays are saved.
`cv_observation_seconds` is the CV portion of observation/overhead time. Helper hash
and the observation flag must match pilot/full. Time integration, temporal
coarsening and any physical assessment remain separate offline work.
## Bounded resolution and placement controls
Defaults remain `--case both --uniform-diameter 80 --placement wide`. Single-case
runs use `--case uniform` or `--case refined` and never report a matched-case pass.
Their own reference/periodicity or driven-diagnostic results remain available.
A single zero-Jet full run exits successfully only when its periodicity and the
unchanged complete DFG reference verdict pass; driven completion is not qualification.
The D160 option requires `--case uniform --uniform-diameter 160` and an explicit
public Jet scenario. U and Jet speeds stay .01 and ±.001; viscosity is .016,
grid 3521×658, center (320,320.5), radius80. CV uses root spacing/time factor .25,
origin (.375,.75), impulse factor .0625, root viscosity .004, and x-face shift .125.
`--case refined --placement compact` selects root bounds (48,48,128,128), fine
168×168 and origin (46,46), with the same D40/fineD80 body/Jet resolution. Its CV
contours are (52,52,112,112) and (50,50,120,120); complete face-gradient stencils
are clear of both solids and the transfer footprint. Compact is refined-only.
CV metadata gives each grid's spacing/origin/contours explicitly. Case, uniform
diameter and placement must match the newly completed pilot in every receipt.
+161
View File
@@ -0,0 +1,161 @@
# Periodic 2D Taylor–Green AMR campaign (prepared, not GPU-qualified)
This validation harness complements DFG Re100 and Jet/body tests. It measures
smooth 2D periodic decay and errors crossing fixed refinement interfaces at
Re_L=100 and 1000. It does **not** certify 3D turbulence, LES, Jet performance,
wall conditions, dynamic refinement or general high-Re flows.
## Reference and conventions
Primary implementation-author documentation, checked 2026-10-18:
- TensorMesh, exact velocity and pressure with a consistent phase:
https://docs.tensor-mesh.com/example_gallery/fluid/taylor_green.html
- AeroSim Nassu, 2D decay, energy and lattice-length Re definition:
https://docs.aerosim.io/nassu/validation/analytical/04_taylor_green_vortex_2d/README.html
We use the TensorMesh phase, rescaled to length L=N root cells:
k = 2*pi/L; A(t) = U*exp(-2*nu*k*k*t)
ux = -A*cos(k*x)*sin(k*y)
uy = A*sin(k*x)*cos(k*y)
p/rho0 = -A*A/4 * (cos(2*k*x)+cos(2*k*y))
E = <|u|^2>/2 = U*U/4 * exp(-4*nu*k*k*t)
Pressure is kinematic, with rho0=1. A global velocity sign reversal leaves
pressure unchanged; exchanging sine/cosine without the corresponding pressure
phase can reverse its sign. CPU tests independently check momentum residuals.
The nonlinear acceleration is a pressure gradient, **not zero**; the AeroSim
page's prose calling advection zero is not adopted. Do not mix phase variants
from different references. The formulas above are verified by substitution,
not by trusting a copied pressure expression.
Re_L=U*L/nu, not Re_k=U/(nu*k)=Re_L/(2*pi). U=.03 in lattice units,
Ma=U/cs=.0519615, cs^2=1/3, nu_root=.03*N/Re_L. Acoustic refinement uses
h_l=dt_l=2^-l: lattice velocity stays U, nu_l=2^l*nu_root and
tau_l=.5+3*nu_l. The worst root tau is .50288 (N32/Re1000), omega=1.98855,
inside the existing config guard. No viscosity clamping or guard override.
All initial arrays are physical FP64 equilibrium populations, supplied to the
public shifted-FP32 postcollision-G initializer. rho=1+3p at each true cell
center. These are valid equilibrium postcollision states, but do not include
Chapman–Enskog nonequilibrium stress; startup acoustic/kinetic error remains in
the measurements and is shared with uniform baselines. The incompressible
reference is not an exact finite-Mach LBM solution. This is why resolution alone
need not remove the full error floor.
## Geometry and workload
All patches use level-wide union form, so origins are zero, including fine
arrays with holes. Coordinates are (index+.5)*2^-level. Metrics integrate only
ACTIVE leaves, each weighted by 4^-level. Covered cells and halo cells never
enter norms or mass. Geometry tests prove exact single coverage at root-cell
resolution. All blocks are 8x8, and both root dimensions are periodic.
At each root N=32,64:
- 2 levels: L1 rectangle (N/8,N/8,7N/8,3N/4), in L0 indices.
- 3 levels: same L1 plus L2 rectangle (3N/4,N/2,3N/2,5N/4), in L1 indices.
These off-axis boundaries cross nonzero flow and gradients rather than sitting
only on symmetry or stagnation lines. Whole geometry scales with N.
16 cases: at each Re, uniform N=32,64,128,256 plus AMR (root32/root64)x(depth2/depth3).
Each AMR case therefore has both a same-root uniform baseline and a uniform
baseline at its finest spacing. Uniform N is its own lattice length, so nu and
step count are scaled to represent the same nondimensional solution.
Samples t*=tU/L = 0,.12,.24,.36,.48. End time is 16*N base steps, a meaningful
.48 domain turnover or 3.016 vortex-scale turnover times (scale 1/k).
At Re1000 energy decays about 7.3%; at Re100 about 53.1%. No plots or full fields;
each case writes five diagnostic rows and provenance, incrementally.
## Running (GPU owner must schedule launches)
CPU checks, from the repository root:
PYTHONPATH=src python -m unittest discover -s tests/validation/taylor_green -p 'test_*.py' -v
One GPU case, on the scheduled worker after checking occupancy:
CUDA_VISIBLE_DEVICES=<physical-id> python tests/validation/taylor_green/run_case.py --repo /path/to/reviewed/checkout --re 100 --n 32 --depth 1 --output output/taylor_green/re100_n32_d1.json
Depth 1 is uniform. Run uniform cases before AMR for each Re; inspect baseline
screening failures before proceeding. For a complete matrix, repeat the uniform
call with N=32,64,128,256 and AMR calls with N=32,64 / depth=2,3, at each Re.
Use serial process startup on the parent's assigned Horsea GPUs. This harness
does not schedule or acquire GPUs. No GPU was used during preparation.
python tests/validation/taylor_green/assess.py output/taylor_green/re*_n*_d*.json --output output/taylor_green/assessment.json
The local API/geometry review used clean staging commit
cd3a657f9d3833e812c3cca173525f165b48710a. This is **not** a claim of results on d79
or any historical commit. Each runtime output records actual Git HEAD/dirty
state, an aggregate source-tree hash, plus SHA256 of all harness Python files. Assessment refuses dirty checkouts and mixed source
or harness identities. Keep reports outside the checkout or .gitignore them so
new outputs do not change its dirty flag between cases. The source-tree hash excludes bytecode caches; production qualification requires
a clean checkout.
The runner uses the existing PeriodicBlockStepper / FixedPatchStepper periodic
paths only. It does not depend on the new channel-root implementation.
## Preregistered assessment, before any GPU results
All sampled times must satisfy finite screening ceilings:
- Relative composite velocity L2 <= 5%
- Relative globally gauge-adjusted pressure L2 <= 15%
- Relative kinetic-energy error <= 5%
- Composite mass drift from downloaded t0 <= 1e-5
These are screening budgets, not literature-certified tolerances. Acceptance
also requires all 16 cases, common source/harness, correct nondimensional times
and viscosity, and baseline-relative checks on worst post-startup-sample errors:
- AMR error <= max(2 * same-root uniform error, declared numerical floor).
- Root64 AMR error <= max(.9 * root32 AMR error, floor), for each depth/Re.
- Uniform256 error <= max(.9 * uniform32 error, floor).
Floors: velocity .002, pressure .02, energy .004. They are declared low-Mach /
equilibrium-startup budgets, not fitted to observed results. Ma^2=.0027 motivates
their scale; it is an asymptotic expectation, not a proof of those coefficients.
The coarse baseline sets the AMR budget because much of the domain remains
coarse. The finest uniform error and AMR/fine ratio are always reported, with no
claim that partial refinement should match a fully fine domain. A pass below a
floor is bounded accuracy, not a measured convergence order. Report errors and
ratios even for a pass. Failure requires diagnosis or a separately preregistered
follow-up, never retroactive tolerance tuning. Higher Re is deliberately absent;
Re100/1000 must first be stable, resolved and reviewed.
Diagnostics use one global pressure gauge, direct cell-center analytic values,
kinetic energy per unit reference mass, and actual leaf cell areas. Composite
midpoint quadrature introduces a small initial energy integration error, retained
rather than subtracted. Mass drift is relative to downloaded t0, so density
initialization and mixed-grid quadrature do not masquerade as time drift.
## Pilot scheduling and transfer-consistency scope
Start with one uniform case and one matched AMR case; the 16-case matrix is a
qualification plan, not authorization to launch every case automatically. The
GPU owner reviews the pilot before expanding it. Each process prints a flushed
READY only after initialization, a real base step exercising every level's
kernel/halo/transfer path, and a finite positive-density download check. That
step belongs to the measured trajectory; it is not discarded warmup. PROGRESS
messages contain each of the five diagnostic samples. READY alone is not an
accuracy pass. Reports include per-level active cells, hops and collision updates.
The complete matrix costs 768,540,672 active collision updates and 21,504 root
intervals, excluding ghost streaming, halos, transfers and diagnostic work.
Uniform N256 is the largest case (268,435,456 updates / 4096 intervals per Re).
AMR N64/depth3 needs 50,987,008 updates / 1024 intervals. These are work counts,
not GPU wall-time estimates. Baseline comparisons remain available on failed
screens and partial pilots; absent/nonfinite operands are null, never passing.
Acoustic viscosity scaling and unchanged lattice velocity do not by themselves
prove nonequilibrium-stress consistency across refinement interfaces. A smooth
collocated Chapman–Enskog postcollision nonequilibrium has a (tau-1)*h factor;
the existing implementation instead uses volumetric piecewise-constant explosion
and stream-only ghosts. Whether that actual transfer construction achieves the
needed stress accuracy is an unresolved question for this pilot to measure.
It is not a proven defect, and a collocated-state scaling factor must not be
inserted into this different transfer operator without a separate derivation
and validation. This campaign measures the current operator and makes no
theoretical stress-consistency certification or production-kernel change.
## Repository integration
The four Python harness files remain together under tests/validation/taylor_green, so runtime provenance hashes precisely this harness directory. Formatting changes produce a new harness identity; preparation and integrated receipts must not be mixed. All analytic definitions, numerical floors, assessment gates, sample times, and source-import assertions are unchanged. Production source is unchanged from the cd3 snapshot; these periodic tests do not waive the separate channel GPU gate.
+90
View File
@@ -0,0 +1,90 @@
# Bounded uniform-grid LES flow validation: prepared, GPU NOT RUN
## Status and scope
Prepared for independent review, then an explicitly authorized Horsea run only. No production files were edited, no normalization patch was applied to a full solver checkout, and no GPU was used. This is a small end-to-end **wall-bounded, x-periodic** shear-decay test, not a fully periodic 2D test. It exercises the actual production Simulation → Stepper → OneStep → Smagorinsky → SRT dispatch and double-buffer pull streaming, plus existing halfway bounce-back walls.
The original fully periodic-y plan is unsupported at the pinned revision: both `one_step_double.cu:90` and `one_step_esopull.cu:133` replace wall-adjacent incoming populations for every fluid node on y=1 and NY-2 regardless of its neighboring flags. `tests/validation/run_poiseuille.py:1–10` already documents this. Merely changing all flags to FLUID does not remove this behavior. The present test deliberately matches those real walls; it does not modify the kernels or claim a periodic-y public API.
Only unforced SRT, D2Q9, FP32 shifted storage and double-buffer streaming are included. No MRT/TRT, force correction, EsoPull, AMR, Jet, 3D turbulence or physical LES coefficient calibration is certified. In continuum this unidirectional incompressible shear is trace-free; small finite-Mach/discretization stresses in the LBM are not asserted to vanish exactly. The underlying scalar-helper audit remains the cleaner normalization isolation.
## Exact source contract
Baseline is explicitly repinned to the production snapshot in `cd3a657f9d3833e812c3cca173525f165b48710a`, whose reviewed AMR-channel source origin is `47b05bc8abfc957fe876b0c63bdb386e3c6cbaa5`. This new experiment does not inherit historical d79 GPU/flow acceptance. The original preparation remains associated with d79; its results are not rewritten.
`tests/validation/data/les_flow/source_pins.json` records all 101 tracked production source files from that snapshot. The runner checks every hash before importing CelerisLab or touching a GPU. It accepts only:
- `--variant baseline`: all baseline hashes, including helper SHA256 `ff7f000297ee0817e255ad9fcb6a13b647e3ddd5b206518d35f38d2895a9f501`.
- `--variant corrected`: the same source bytes except helper SHA256 `a3db46c2e7d27530b2d1436e65cdbed0b72cc7e047bfbeef2a640877271b51aa`, from the independently reviewed `tests/validation/les/data/smagorinsky_normalization.patch` artifact.
The runner records the actual checkout commit and exact imported package. It never applies a patch itself. Run it against separate isolated full checkouts. The patch candidate's minimal header tree is not a runnable solver checkout. A source mismatch is a blocker, not permission to regenerate pins from an arbitrary new checkout.
Relevant pinned implementation evidence:
- `tests/integration/test_numerical_gpu.py:24–85`: equilibrium construction, installation of spatial postcollision state, count=1 adapter, raw population observation and x-periodic/walled flags.
- `tests/validation/run_poiseuille.py:29–78`: production Simulation use with periodic x, halfway y walls and downloaded populations.
- `src/CelerisLab/lbm/kernels/core/layout.cuh:87–104`: actual modulo neighbors.
- `src/CelerisLab/lbm/kernels/boundary/bounce_back.cuh:18–38`: incoming populations copied from opposite local input directions.
- `src/CelerisLab/lbm/kernels/operators/helpers.cuh:53–61`: LES effective omega feeds actual SRT collision.
- `src/CelerisLab/cuda/compiler_v2.py:56–95`: compiler snapshots into private temporary build directories; package sources are not rewritten.
## Geometry, units and initial state
8×34 nodes: 8 periodic-x columns, 32 fluid rows, 2 ghost-wall rows. Relative to the bottom physical wall, fluid centers are y=0.5,...,31.5; physical halfway walls are y=0 and 32. Every x edge fluid node is explicitly FLUID; all top/bottom ghost nodes are SOLID|BC_WALL. Thus unused inlet/outlet configuration has no inlet/outlet flags to act on. There are no bodies, Jets or external forces.
Lattice units: dx_LBM=dt_LBM=1, rho=1, nu=0.02, tau0=0.56, U=0.04, H=32. Initial u_x(y)=U sin(pi y/H), u_y=0. The maximum Mach number is 0.0693. Height-based Re=U H/nu=64; a wavelength-based Re would differ and is not used. No dimensional physical length/time/viscosity is asserted without a user-supplied unit mapping.
Initialize equilibrium populations, encode shifted FP32, upload both DB buffers and set completed-count=1 following the existing integration-test adapter. That count is storage metadata: physical elapsed time starts at 0 after installation. Observe density and momentum directly from current postcollision populations, adding the descriptor weights in float64; do not mix in cached macro fields. This uses a clearly labeled validation-only raw state/flag adapter, not a promised public `set_periodic` or `set_velocity_profile` API.
Cases: LES enabled/closed-form with Cs=0 (molecular control), Cs=.16 (ordinary-coefficient sanity), then Cs=1 (amplified normalization diagnostic). Cs=1 is intentionally not a physically recommended SGS coefficient. Initial peak modeled nu_t/nu = Cs² Δ² U(pi/H)/nu = 0.19635; estimated effective tau remains near 0.56–0.5718, far from omega guards. Standard default Cs=.16 yields a much weaker signal at these safe parameters and is not used to make a decisive short-run normalization claim. No defaults are changed.
Observe at elapsed steps 519, 1038, 2075, approximately 0.1, 0.2, 0.4 molecular decay times. Three cases total 6225 measured advancing launches plus 3 warm-up launches per checkout (6228 total), three snapshots each. Population buffers contain only 272×9 FP32 entries each (about 9.6 KiB), apart from ordinary driver/compiler/context overhead. No frames, trajectories or heavy output. Full result JSON is a few tens of KiB. Runtime depends on compilation/device; no performance claim is made.
## Independent continuum reference
For u=(u(y),0), |S|=sqrt(2 S:S)=|du/dy|. Therefore
du/dt = d/dy [(nu + (Cs Delta)^2 |du/dy|) du/dy],
u(0,t)=u(H,t)=0.
`tests/validation/les_flow_oracle.py` integrates this equation directly with centered finite-volume face fluxes and SSPRK2, at 128 and 256 cells on the same physical H=32 domain. Stability step size uses the nonlinear flux derivative nu+2(Cs Delta)^2|gradient|. Boundary face gradients use the zero Dirichlet value across a half cell. It does not import or reproduce the LBM quadratic/helper. A separate fixed-n=256 test halves the CFL factor from .4 to .2 for Cs=0,.16,1 at every checkpoint, requiring relative changes below 1e-8; measured maximum is 1.8141e-10. This isolates temporal error from the spatial-refinement test.
Crucially the SGS filter Delta=1 stays fixed as the CPU oracle mesh changes from dy=.25 to .125. Confusing oracle spacing with filter width would change the PDE and invalidate convergence. Future LBM grid refinement also needs an explicit physical-unit/filter-width scaling contract; this artifact does not silently reinterpret Cs or Delta when resizing H.
Cs=0 is checked directly against U sin(pi y/H) exp[-nu(pi/H)^2 t]. The nonlinear reference includes evolving higher harmonics, rather than assuming it remains a sine. At the final time, host oracle predicts 5.1706% SGS reduction in the fundamental amplitude and 1.5409% full-profile separation between standard and old coefficient conventions. The old convention reference is computed by changing continuum Cs to Cs/2^(1/4), purely as a diagnostic; it does not replace standard acceptance.
## Predeclared criteria (do not tune after seeing GPU results)
- Initial decoded profile relative L2 <= 1e-5; otherwise no advancing test.
- Molecular Cs=0 profile error against analytic decay <= 0.003 at every checkpoint.
- Cs=1 full-profile error against standard nonlinear oracle <= 0.005 at every checkpoint.
- Oracle 128/256-grid interpolated relative difference <= 8e-5 at every checkpoint.
- Relative error in SGS fundamental-amplitude decrement <= 0.15 at the last two checkpoints. Decrement is measured from actual Cs=0 amplitude minus actual Cs=1 amplitude; reference uses analytic Cs=0 minus the nonlinear oracle. The first checkpoint remains a transient diagnostic for this increment gate.
- Fluid mean-density drift <= 5e-5, max |u_y| <= 1e-5 and x-column velocity spread <= 1e-6 at every checkpoint; finite populations, strictly positive finite fluid density and finite decoded velocity/profile/diagnostics required throughout observations, including startup and warm-up.
Reasons: molecular 0.3% leaves room for finite-lattice dispersion, equilibrium-start kinetic transient and FP32 error at H=32; nonlinear 0.5% is substantially below the predicted 1.54% old-vs-standard separation. The 15% increment tolerance is below the old convention's approximately 29% viscosity-coefficient deficit, while allowing continuum/lattice differences. Directly subtracting the two measured amplitudes reduces common lattice error. Oracle convergence is over 60 times tighter than the nonlinear profile bound. These are declared engineering test gates, not GPU-validated uncertainty estimates; a failure requires diagnosis/refinement and an explicitly revised experiment, never a post-hoc tolerance edit to obtain a pass.
Both baseline and candidate are judged against the same standard convention. Baseline is expected to fail SGS criteria if the flow reproduces the scalar finding; an exit 1 with valid evidence is useful. The runner reports old-convention profile error but never masks baseline failure. Candidate passing alone is insufficient if baseline does not demonstrate meaningful discrimination. Review both results and source pins together.
## Host verification and later GPU commands
From the repository root, using existing Python/NumPy and the existing pytest environment:
PYTHONDONTWRITEBYTECODE=1 PYTHONPATH=src python -m pytest -q tests/unit/test_les_flow_oracle.py tests/unit/test_les_flow_runner.py
Nine tests cover analytic decay, independent-oracle mesh convergence, symmetry/positivity/energy decay, filter invariance, fixed-grid timestep halving, signal discrimination, invalid density/velocity rejection, source pins/candidate/tamper rejection and the no-GPU-without-opt-in CLI guard. The integrated tests preserve those checks. No PyCUDA import or GPU run is required for them. Cs=.16 uses the same 0.5% full-profile safety/sanity bound; its SGS increment is not a discriminatory normalization gate.
The source-guard tests materialize temporary candidate headers with the existing reviewed LES preparation tool; the GPU entrypoint uses `tests/validation/run_uniform_les_flow.py`, `tests/validation/les_flow_oracle.py`, and `tests/validation/data/les_flow/source_pins.json` in that repository layout.
After review, make isolated full baseline and corrected checkouts of the exact base. Apply only `tests/validation/les/data/smagorinsky_normalization.patch` to the corrected checkout; do not edit the benchmark/production tree. On authorized Horsea, with existing NumPy, PyCUDA, nvcc and driver, run sequentially and select the authorized physical GPU explicitly:
CUDA_VISIBLE_DEVICES=<physical-GPU> PYTHONDONTWRITEBYTECODE=1 python tests/validation/run_uniform_les_flow.py --run-gpu --device 0 --root <isolated-baseline> --variant baseline --output <new-evidence-dir>/baseline.json
CUDA_VISIBLE_DEVICES=<physical-GPU> PYTHONDONTWRITEBYTECODE=1 python tests/validation/run_uniform_les_flow.py --run-gpu --device 0 --root <isolated-corrected> --variant corrected --output <new-evidence-dir>/corrected.json
`--device 0` is the logical ordinal within CUDA_VISIBLE_DEVICES. Do not use a shell `&&` between these: baseline's expected standard-criterion failure must not suppress the corrected run. Existing output files are refused. A JSON `READY` line is printed separately for each case only after source verification, compilation, initialization, raw-state installation, one actual advancing OneStep launch, post-warm-up macro validation, complete restoration of both DB buffers/flags/count to the initial state, profile readback and CUDA synchronization. It gives source identity, device, Cs, warm-up/reset confirmation, installed-profile error and maximum measured steps. This is the first trustworthy startup checkpoint, not a statement that the physics passed. `DONE` is printed after all three cases and all criteria; failures/compile errors before that remain incomplete runs.
Deliver both JSON files and stdout/stderr with artifact hashes. Review before any production integration. AMR LES guards remain untouched.
## Isolated candidate preparation
Use the current validation commit for two separate full checkouts, preserving the baseline. In the corrected checkout only, apply `tests/validation/les/data/smagorinsky_normalization.patch` with `git apply`; do not commit that experimental production change or update the pins. The runner requires exactly the baseline bytes plus the reviewed helper hash. The header-only scalar diagnostic tree is insufficient for this end-to-end flow. Baseline and corrected commands must run as separate Python processes; package import caching must never combine their implementations. Both reject an imported CelerisLab package outside the explicitly supplied checkout, including an installed DynamisLab copy. Retain the actual checkout commit, variant, exact header hash, and experimental source label with each result.
+489
View File
@@ -0,0 +1,489 @@
# Force region 最小方案设计
目标是在现有功能冻结的前提下,为项目增加一个**局部体力施加区域**,用于研究局部驱动与流场结构之间的关系。该功能的第一阶段只追求可用、低风险、低侵入,不追求最泛化的抽象,也不与 sensor 合并。
当前代码已经具备三条很明确的数据链:全场 `OneStep` 推进、稀疏 `curved` link 链、稀疏 `sensor` cell 链。`force_region` 更接近第三类:它是一个静态几何 footprint,加上运行时 action,而不是一个需要改变主域 flag 的边界对象。因此,第一阶段更适合沿用 `sensor` 风格的稀疏 cell 管理,而不是引入全场 owner map。
## 目标与非目标
| 类别 | 内容 |
|---|---|
| 目标 | 在圆形区域内对流体施加局部体力 |
| 目标 | 运行时更新区域体力参数,不重新编译 |
| 目标 | 尽量少改现有主热路径和已有稳定功能 |
| 非目标 | 与 sensor 统一成单一抽象 |
| 非目标 | 非圆形几何 |
| 非目标 | 3D |
| 非目标 | 多区域重叠叠加规则的完整设计 |
| 非目标 | 数值上最严格的“逐格 collision 内联 forcing”实现 |
## 需求边界
第一阶段建议只支持以下能力:
- `force_region` 是一个圆形 footprint
- 区域内部施加均匀体力 `fx, fy`
- 区域几何在初始化后不变
- 体力大小可在运行时更新
- 只对 fluid cell 生效
- 不要求读取区域平均速度
- 不要求与 `sensor` 或 `body` 的接口完全统一
这意味着第一阶段的问题不是“建立通用 actuator 体系”,而是“在现有框架内插入一条最小局部 forcing 数据链”。
## 现有代码中与该功能直接相关的结构
| 模块 | 当前作用 | 与 force region 的关系 |
|---|---|---|
| `body/geometry/circle` | 生成圆形 footprint | 可复用 |
| `body/manager` | 汇总 compact list 并上传 GPU | 适合新增 force-region list |
| `lbm/curved_links` | 稀疏 SoA 容器 | 可参考 `SensorSoA` 形式扩展 |
| `lbm/kernels/step/aux_kernels` | 稀疏辅助 kernel | 适合新增 `ForceRegionKernel` |
| `lbm/stepper` | 编排主 step 与辅助 kernel | 适合插入 force-region launch |
| `operators/helpers` | 现有全局 Guo forcing 路径 | 可复用公式与语义 |
需要特别注意的一点是:现有全局体力通过 `d_params.fx/fy/fz` 进入 `collide_dispatch()`。这条路径服务的是**全场统一 forcing**。局部体力如果要完全沿用同一语义,最严格的做法是让每个 cell 在线程内部读取本地 force。但这会推动设计进入全场 owner map 或 per-cell force field,而这不符合第一阶段的低侵入目标。
## 推荐的第一阶段总路线
推荐路线是:
- `force_region` 作为一种新对象类型存在
- 它不修改 domain flag
- 它只产出稀疏 cell footprint
- 由一个独立的 `ForceRegionKernel` 在主 step 外对这些 cell 做局部 forcing 修正
换句话说,第一阶段采用的是:
- **主推进仍保持全场统一**
- **局部 forcing 通过稀疏后处理 kernel 注入**
这不是最终最泛化的架构,但它与现有 `sensor` 管理方式一致,工作量低,也最不容易破坏当前稳定基线。
## 为什么不优先采用全场 owner map
全场 owner map 的优点是语义干净:`OneStep` 的每个 cell 都可直接知道自己是否属于某个区域,再把局部体力并入 collision forcing。这在数值上更直接,也更容易扩展到复杂局部 forcing。
但在当前阶段,这条路的代价偏高:
- 需要给全场新增一个 device-side 标识数组
- 需要改主 step kernel 形参和热路径逻辑
- 需要明确多区域覆盖规则
- 需要同时处理 double-buffer 与 esopull 路径中的局部 forcing 接入方式
对当前目标来说,这会把“加一个可用功能”变成“改造主推进语义”。因此,第一阶段更合适的路线仍是稀疏 compact list。
## 为什么不把 force region 直接并入 sensor
二者的几何 footprint 确实相似,都可以表示成“圆形覆盖的一批 cell”。但功能角色不同:
| 类型 | 本质 | 时序位置 |
|---|---|---|
| `sensor` | 读出局部信息 | step 后 |
| `force_region` | 修改 DDF 演化 | step 中或 step 后的局部修正 |
因此,第一阶段不建议在抽象层面合并二者。更合理的做法是:
- 复用几何 footprint 生成逻辑
- 保持独立对象语义
- 保持独立 kernel 与独立 compact list
这样既能少写代码,也不会把接口语义搅乱。
## 对象层建议
`force_region` 建议作为一种新的 body-side 对象类型,而不是把普通刚体、sensor、局部 forcing 区域全部塞进同一语义分支。
### 推荐最低要求
| 字段 | 作用 |
|---|---|
| `obj_id` | 索引 action 与 compact list |
| `geometry` | 圆形 footprint 来源 |
| `state` | 可沿用通用容器,但第一阶段基本不用 |
| `control` 或 action slot | 存 `fx, fy` |
| `type tag` | 区分普通 body、sensor、force_region |
### 不必在第一阶段敲死的点
下面这些都可以留给 coder 选择:
- 是加 `is_force_region` 布尔字段,还是引入更清楚的 `role` / `kind` 标签
- `fx, fy` 放在 `state`、`control`,还是直接只存在 `action` 打包层
- `add_body("force_region", ...)` 还是单独加 `add_force_region(...)`
第一阶段更重要的是把数据链接起来,而不是先做完美 API。
## 几何层建议
`body/geometry/circle` 已经有生成 sensor cells 的逻辑。这里最自然的做法不是复制一份,而是把“圆形 footprint cell 枚举”抽成一个中性函数。
### 推荐抽象
建议在 circle geometry 中形成一个中性能力,例如:
- `build_footprint_cells()`
然后:
- `sensor` 使用这批 cells 作为采样点
- `force_region` 使用同一批 cells 作为施力点
### 第一阶段不必决定的点
- footprint 是否严格包含圆内格点中心
- 是否允许边界一圈采用不同准则
- 是否为将来的 polygon/mesh 提前抽公共父类 helper
只要 footprint 定义在 host 和测试中保持一致即可。
## flag 处理建议
`force_region` 第一阶段**不应修改 flag field**。
原因很直接:
- 它不是 solid
- 它不是 boundary condition
- 它不是 sensor flag
- 它不参与 channel topology 构造
因此它应当是“有 footprint,但不 overlay flag”的对象。
这意味着在 `build_flags()` 过程中:
- 普通 body 继续覆盖 obstacle / curved 标记
- sensor 继续覆盖 sensor 标记
- force_region 返回零 mask,或根本不进入该分支
两种实现都可以,留给 coder 决定。若追求语义更清楚,倾向于根本不让它参与 flag merge。
## compact list 设计建议
第一阶段建议新增一条与 sensor 平行的数据链:
- `force_region cells`
- `force_region obj_id`
### 数据最小集
| 列 | 类型 | 作用 |
|---|---|---|
| `cells` | `uint32` | 被施力格点索引 |
| `obj_id` | `int32` | 从 action 中取 `fx, fy` |
这与 `SensorSoA` 的结构完全同型,只是消费 kernel 不同。
### 可选实现
| 方案 | 特点 |
|---|---|
| 单独建 `ForceRegionSoA` | 语义清楚,后续好扩展 |
| 复用 `SensorSoA` 结构实现新字段 | 改动少,但语义稍混 |
第一阶段更推荐单独建 `ForceRegionSoA`。这会多一点样板代码,但可读性更好,也避免后续 `sensor` 和 `force_region` 在 field 中混淆。
## action contract 建议
当前 `action` buffer 在 2D 下每对象为 `3 * dim = 6` 个 `float`,而现阶段只真正使用了最后一个 `omega`。这给了第一阶段一个很好的低成本入口:
- 不改 action buffer 总长度
- 不改编译期 layout 宏
- 先在已有 slot 中约定 `fx, fy` 的位置
### 一个可行的最小约定
| slot | 含义 |
|---|---|
| `0` | `fx` |
| `1` | `fy` |
| `5` | `omega` |
其余位置保留。
### 这里不必现在敲死
这部分可以留给 coder 做最终选择,只要满足两点:
- `force_region` kernel 能稳定读到 `fx, fy`
- 现有 `CurvedBoundaryKernel` 继续稳定读到 `omega`
若 coder 认为显式 helper 更重要,可以新增类似 `action_force_x()` / `action_force_y()` 的 device helper,而不是在 kernel 中直接写魔数偏移。
## kernel 路线建议
第一阶段最合适的是新增一个独立 kernel,例如:
- `ForceRegionKernel`
它应当像 `SensorKernel` 一样按 compact list 启动,而不是并入 `OneStep`。
### 建议职责
每个线程处理一个 force-region cell:
1. 读该 cell 的线性索引 `k`
2. 读所属对象 `obj_id`
3. 从 `action` 中读 `fx, fy`
4. 从当前 DDF 缓冲中加载该 cell 的 `f[NQ]`
5. 计算 `rho, ux, uy`
6. 按现有 Guo forcing 语义构造 `Fin`
7. 对该 cell 的分布函数做 forcing 修正
8. 写回 DDF
### 需要特别控制的事
第一阶段最好不要在这个 kernel 内部引入过多策略分支。尤其避免一开始就支持:
- 多个不同 forcing scheme
- 复杂边界跳过逻辑
- 非均匀空间 force
- 区域内按距离衰减的 force
先只做“圆内均匀体力”。
## ForceRegionKernel 应该写在哪个时间位置
现有 `stepper` 顺序大致为:
1. curved boundary
2. main step
3. sensor
第一阶段建议将其改为:
1. curved boundary
2. main step
3. force region
4. sensor
### 这样做的原因
- 主推进链尽量不动
- force region 作为局部修正子步存在
- sensor 若未来同时存在,可以读到施力后的局部结果
### 这里保留给 coder 的决策点
`ForceRegionKernel` 也可以放在 sensor 前后不同位置,但需要统一解释语义:
| 放置位置 | 语义 |
|---|---|
| 主 step 之后、sensor 之前 | sensor 读到施力后的状态 |
| sensor 之后 | sensor 读到施力前主步结果 |
若第一阶段不做 sensor 联动,则这只是将来兼容性的选择。默认更建议放在 sensor 之前。
## DDF 更新方式的设计空间
这里是实现中最需要留白的部分。第一阶段文档不应把写法锁死,但应给出边界。
### 必须满足的原则
- 局部体力的数值语义尽量对齐现有 `forcing_guo.cuh`
- 不应在 `ForceRegionKernel` 中引入与现有 collision family 矛盾的私有公式
- 若采用 operator splitting,应在注释中明确说明它不是“主 collision 内联 forcing”
### 可接受的实现方向
| 方向 | 特点 |
|---|---|
| 直接按 Guo forcing 增量对 `f[i]` 做修正 | 最小、直观 |
| 抽一个独立 helper,复用 `compute_guo_forcing()` | 与现有 forcing 公式最一致 |
| 在 kernel 中根据 collision family 调整 prefactor | 更接近现有 `collide_*` 写法,但代码稍重 |
### 第一阶段更适合的判断
更推荐:
- 尽量复用 `compute_guo_forcing()`
- 用很薄的一层 helper 完成 DDF 增量写回
但是否把 `c_tau = 1 - omega/2` 放在 kernel 里、helper 里,还是借新函数收口,可以留给 coder。
## 数值语义说明
第一阶段方案本质上是一个**局部 forcing 修正子步**,而不是严格在 `OneStep` 内逐格并入 collision forcing。这一点需要在实现处用注释写清楚。
### 这个选择的代价
- 语义上更像 operator splitting
- 与全局 forcing 在热路径中的时序并不完全相同
- 在强 forcing 情况下,可能与将来更严格实现有差异
### 这个选择的收益
- 主 kernel 改动极小
- 不需要全场 owner map
- 易于复用现有稀疏对象链路
- 第一阶段很快能得到可用结果
对当前“先追求使用”的目标,这个 tradeoff 是合理的。
## 过滤规则建议
第一阶段应当保持规则简单。
### 建议规则
- 只对 `is_fluid(fl)` 的格点施力
- 对 obstacle / wall / inlet / outlet 一律跳过
- 与 curved body footprint 重叠时,由 cell flag 决定是否生效,而不是 force-region 自己猜
### 这里不必先完善的点
- actuator 与 actuator 的重叠叠加规则
- 对 inlet/outlet 邻近区域的特殊处理
- 对 sensor / force_region 同 id 绑定的逻辑
如果第一阶段允许多个 force region 存在,最简单的策略是先约束:
- footprint 不应重叠
或者:
- 重叠行为未定义,由上层调用者避免
## 配置与 API 建议
这里也不需要一次性定死。
### 最小外部接口至少应支持
- 新建一个圆形 `force_region`
- 运行时更新它的 `fx, fy`
### 可选 API 形式
| 形式 | 特点 |
|---|---|
| `add_body("force_region", ...)` | 改动少,沿用现有入口 |
| `add_force_region(...)` | 语义更清楚 |
### 运行时控制也有两种自然路线
| 形式 | 特点 |
|---|---|
| 扩展 `set_body(id, fx=..., fy=...)` | 改动小 |
| 新增 `set_force_region(id, fx=..., fy=...)` | 语义清楚 |
第一阶段若追求少改代码,可优先沿用现有 `set_body()`。若 coder 认为 API 语义更重要,也可以新增专门入口。
## 对 `ObjectManager` 的建议
`ObjectManager` 已经偏大,因此第一阶段不建议再把很多新判断揉成一团。更合适的方式是:
- 在现有结构上增加一条最薄的新分支
- 尽量与 `sensor` 的组织方式平行
- 不在 `build_flags()` 中塞 force-region 的特例
### 在实现层面建议保持的分工
| 职责 | 位置 |
|---|---|
| 圆形 footprint 枚举 | `geometry` |
| force-region SoA 打包 | `body/coupling` 或与其平行的位置 |
| GPU buffer 生命周期 | `field` / SoA 容器 |
| kernel 调度 | `stepper` |
这能避免 `manager` 再次回到“万能管理器”的方向。
## 对测试的建议
第一阶段至少需要三类测试。
### 1. 结构测试
- `force_region` 不改变 flag field
- compact list cell 数与 footprint 预期一致
- action 更新后 GPU buffer 内容可追踪
### 2. 数值冒烟测试
- 静止流场中施加恒定 `fx` 后,区域内流体沿 x 方向加速
- `fx > 0` 与 `fx < 0` 响应方向相反
- `fy` 路径同理
### 3. 回归保护
- 未添加 `force_region` 时,结果与当前版本一致
- 添加 `force_region` 但 `fx=fy=0` 时,结果与当前版本一致或只存在舍入级差异
### 暂不要求的测试
- 与解析解严格比对
- 多 region 重叠叠加
- 强 forcing 的稳定性边界扫描
## 第一阶段完成后的理想状态
完成后,项目应具备以下能力:
- 能创建一个圆形局部施力区域
- 能在运行时改变其 `fx, fy`
- 不需要重新编译
- 不需要引入全场 owner map
- 不破坏现有 curved boundary 与 sensor 链路
- 不迫使 `body` 与 `lbm` 做新的深度耦合
从架构角度看,第一阶段的关键成果不是“得到最完美的 actuator 抽象”,而是验证:
- 稀疏 cell list 路线足以支撑局部 forcing 研究
- 现有系统能容纳一条新的 compact-list kernel 链路
## 第二阶段可能的演进方向
这些不属于当前实现范围,但第一阶段设计应避免把它们堵死:
- 读取 force-region 内平均速度或其他观测量
- 将 `force_region` 与 `sensor` 的 footprint builder 进一步共用
- 升级为更一般的 `region operator`
- 改为在 `OneStep` 内逐格读取局部 force
- 支持非圆形几何与 3D
第一阶段不需要为这些能力写完结构,只需要不要在命名和数据布局上把后路堵死。
## 建议的实现顺序
### 阶段 1
建立最小对象与 footprint 数据链。
- 新增 `force_region` 类型
- 让 circle geometry 能产出中性 footprint cells
- 新增 force-region SoA 与 GPU upload
### 阶段 2
接入运行时 action。
- 在 action slot 中为 `fx, fy` 留位置
- 增加 host 侧更新接口
- 保证不影响现有 `omega` 读取
### 阶段 3
新增局部 forcing kernel 并接入调度。
- 写 `ForceRegionKernel`
- 接入 `stepper`
- 明确与 sensor 的先后顺序
### 阶段 4
补最小测试与文档注释。
- 结构测试
- 冒烟测试
- 未启用时的回归保护
## 最终判断
第一阶段最稳妥的最小方案不是全场 owner map,也不是把 force-region 并进 sensor,而是:
- 把它当作一种新的稀疏 cell-list 对象
- 复用圆形 footprint 生成逻辑
- 通过独立 `ForceRegionKernel` 对局部 DDF 做 forcing 修正
- 在接口和数据布局上只做最低必要改动
这条路线与现有代码风格最一致,也为后续更严格或更泛化的实现保留了余地。
@@ -0,0 +1,398 @@
# Force region 验证清单
这份清单面向当前已经实现的最小版 `force_region`:
- 2D
- 圆形 footprint
- 运行时设置均匀 `fx, fy`
- operator-split 的局部 Guo forcing 修正
- 不与 sensor 绑定
当前最合理的验证思路不是一次追求“单一终极 benchmark”,而是分三层推进:
1. **代码回归层**:先确认新功能没有破坏旧链路
2. **物理正确性层**:先做最稳的流体响应验证
3. **研究使用层**:再进入圆柱尾迹中的局部强迫实验
文献上,LBM forcing 的核心依据仍是 Guo forcing 的离散处理 [Guo02d]。对 body-force 驱动的通道流,Poiseuille 流是最经典的基准之一,[Zou95b] 给出了平板间 Poiseuille 流的解析结果,[Guo02d] 也把 steady Poiseuille flow 作为 forcing 验证的一部分。对**空间变化** forcing 的风险与误差来源,[Sil20b] 给出了很直接的提醒:非均匀 body force 会把离散误差暴露得更明显,因此验证必须包含**网格、黏度、幅值**三个维度的稳健性检查。
## 一句话总策略
先不要一上来把 `force_region` 扔进圆柱尾迹做复杂控制。先用最简单、最容易解释的流场把它跑顺:
- 零强迫回归
- 单方向局部加速
- 长通道近似 Poiseuille
- 再进圆柱尾迹
## 第一层
### 必做回归检查
这些检查不依赖文献,但必须先过。
| 编号 | 目的 | 设置 | 预期结果 | 是否阻塞 |
|---|---|---|---|---|
| R1 | 新功能不引入假障碍 | 只加 `force_region`,不加圆柱 | `n_curved == 0`,flag 场不出现 obstacle / curved 覆盖 | 是 |
| R2 | 零强迫不改变解 | 加 `force_region`,但 `fx=fy=0` | 与无 `force_region` 基线一致,或只剩舍入级差异 | 是 |
| R3 | force 设置后可持续生效 | `set_force()` 后步进,再触发一次 action 刷新链路 | force 不被静默清零 | 是 |
| R4 | 符号方向正确 | 同一算例跑 `+fx` 和 `-fx` | 主流响应方向相反,幅值同量级 | 是 |
R2 很关键。它回答的是:当前实现是不是“只是多了一条 dormant 数据链”,而不是“只要建了 force_region 就改了解”。
## 第二层
### 物理正确性主验证
这部分建议按从简单到复杂的顺序做。
## Case A
### 静止流场中的单圆局部加速
这是最小物理 sanity check。
#### 设置建议
- 格子:`nx = 256`, `ny = 128`
- 碰撞:先用 `SRT`,LES 关闭
- 流动初值:入口速度设为 0 或足够小,先得到近静止背景流
- 不加圆柱
- force region:
- 圆心 `(96, 64)`
- 半径 `r = 12`
- 先做 `fx > 0, fy = 0`
- 强迫幅值:从小值开始,例如 `fx = 1e-6`, `5e-6`, `1e-5`
- 每组运行到准稳态或至少足够长,使局部响应明显
#### 该看什么
- `ux` 在 force region 附近应整体偏正
- 区域下游应形成沿 `+x` 延伸的动量尾迹
- `uy` 的主量级应明显小于 `ux`
- 将 `fx` 改成负值后,整幅图应沿 x 方向近似镜像
#### 预期结果
这个 case 没有一个成熟的“标准 benchmark 数字”,但应满足最基本物理响应:
- 加速方向与 force 方向一致
- 幅值随 `fx` 单调增强
- 小 force 下解的结构应平滑,不应出现棋盘格、局部爆点或非对称破缺
#### 判定标准
| 检查项 | 通过标准 |
|---|---|
| 方向性 | `fx > 0` 时主响应沿 `+x`,`fx < 0` 时相反 |
| 单调性 | 增大 `fx` 后,局部 `ux` 峰值与尾迹强度单调增大 |
| 对称性 | 在无背景横向偏置时,上下半区统计应近似对称 |
| 稳定性 | 小幅强迫下不出现数值振荡或孤立噪点 |
这个 case 的作用不是给出论文级定量结论,而是先证明:**局部 forcing 至少在最简单流场中按直觉工作。**
## Case B
### 长通道中的近 Poiseuille 验证
这是最重要的文献支持主验证。
Poiseuille 流是 LBM forcing 的经典基准,[Guo02d] 用 steady Poiseuille flow 验证 forcing 处理,[Zou95b] 给出了平板间 Poiseuille 流的解析形式。对当前代码,最现实的做法不是强行构造完全理想的周期通道,而是在**长通道中用超大圆形 force region 近似全域恒定体力驱动**,只在远离入口和出口的位置取剖面比较。
#### 建议设置
- 格子:`nx = 1024`, `ny = 128`
- 碰撞:先用 `SRT`;通过后再试 `TRT` / `MRT`
- LES:关闭
- 圆柱:不加
- 入口速度:尽量设小,避免 inlet 自身主导流场
- force region:
- 圆心放在通道中段,例如 `(512, 64)`
- 半径取足够大,使绝大多数通道内部 fluid cell 都被覆盖,例如 `r = 600`
- 强迫方向:`fx > 0, fy = 0`
- 强迫幅值:先从小值开始,避免压缩性误差,例如 `1e-6` 量级
#### 为什么这样设
当前 `force_region` 只有圆形 footprint,没有全域矩形 forcing,也没有 x 周期边界。因此最稳妥的近似是:
- 用超大圆把中部通道几乎全覆盖
- 只在远离入口和出口的位置取横截面
- 检查剖面是否接近抛物线
#### 该比对什么
对 fully developed Poiseuille,经典剖面是抛物线 [Zou95b]:
\[
u(y) = u_{max}\left(1 - \frac{y^2}{L^2}\right)
\]
其中中心线速度最大,壁面速度为 0。对当前代码,最重要的不是把解析常数拟合到最后一位,而是确认以下结构性特征:
- 中部横截面是单峰抛物形
- 中心线最大
- 贴壁速度接近 0
- `uy` 远小于 `ux`
- 沿 x 方向进入发展段后,剖面变化减小
#### 推荐取样方式
在以下几个 x 位置取横截面:
- `x = 256`
- `x = 512`
- `x = 768`
只要中后段两条剖面几乎重合,就说明流场已经接近 fully developed,可拿来与抛物线拟合。
#### 预期结果
- 中段与后段 `ux(y)` 应近似抛物线 [Guo02d, Zou95b]
- 若 `fx` 增大,剖面整体抬高,但形状仍保持单峰抛物型
- 中段以后,剖面随 x 的变化应减弱
#### 如何定量判定
建议做三个量:
| 指标 | 解释 | 通过建议 |
|---|---|---|
| 抛物线拟合残差 | 用最小二乘拟合 `u(y)=a-b(y-yc)^2` | 中后段残差明显小于入口附近 |
| 发展段一致性 | 比较两个下游截面 | 两条曲线基本重合 |
| 横向速度污染 | `max |uy| / max |ux|` | 远小于 1 |
#### 关于误差的解释
不要把这个 case 解释得过头。因为当前代码的边界条件并不是“理想周期 x + 纯 body-force 驱动”,所以更合理的表述是:
- 这是一个**近 Poiseuille** 验证
- 它主要验证 `force_region` 是否能在长通道里生成正确的 fully-developed 流动结构
- 它不是对解析解逐点 machine-accuracy 的测试
另外,[Zou95b] 指出 bounce-back 边界会引入一阶壁面误差。因此如果壁面附近有明显偏差,不必立刻把它归咎于 `force_region` 本身;重点看的是中部剖面形状与下游收敛行为 [Zou95b]。
## Case C
### 幅值扫描
这个 case 用来回答:当前 operator-split forcing 在多大范围内是“线性可解释”的。
#### 设置建议
复用 Case B,只扫描 `fx`:
- `1e-6`
- `2e-6`
- `5e-6`
- `1e-5`
- `2e-5`
#### 预期结果
在小 force 区间内:
- 中心线速度大致随 `fx` 单调增加
- 抛物剖面形状保持不变,仅幅值放大
- 若开始出现明显非对称、密度波动或剖面畸变,说明已进入“不再适合作为线性基准”的区间
#### 该记录的量
- 中心线最大速度
- 下游某截面的体积流量
- `rho` 偏离 1 的最大值
这一步的目的不是证明某个严格比例律,而是找到一个**数值上舒服的工作区间**。后面做圆柱尾迹控制时,应优先选这个区间内的 force 幅值。
## Case D
### 网格与黏度稳健性
这是空间变化 forcing 必须做的检查,[Sil20b] 对这一点尤其值得参考。该文的核心提醒不是“所有非均匀 forcing 都会错”,而是:**空间变化 body force 更容易把离散误差暴露出来**,因此需要明确看网格和黏度敏感性 [Sil20b]。
#### 推荐做法
选用 Case B 或 Case A 中一个已经表现稳定的设置,然后做:
### 网格扫描
- `256 x 64`
- `512 x 128`
- `1024 x 256`
保持物理几何比例一致。
### 黏度扫描
固定一个小 force 幅值,扫两到三个 `nu`。
#### 预期结果
- 网格加密后,主剖面与主流结构应收敛
- 黏度变化会改变速度幅值和扩散尺度,但不应引入新的奇怪畸变
- 如果某个设置对黏度特别敏感,优先检查强迫是否过强、局部 Mach 数是否过高、或 region 是否离边界太近
#### 如何解读
[Sil20b] 的重点是在 TRT 下讨论空间变化 force 的离散误差来源,并指出某些 force 展开会引入额外不一致项。当前实现采用的是一个 operator-split 的局部 Guo 修正,而不是把空间变化 force 直接并入 `OneStep` 的逐格 collision。因此这一步更应被视为:
- 对当前实现的**数值稳健性检查**
- 而不是与 [Sil20b] 的离散系统逐条同构比较
## 第三层
### 研究使用前的圆柱尾迹验证
在前两层都通过后,再进入最关心的 case:圆柱尾迹中的局部 forcing。
这里最重要的不是先追一个“标准答案数值”,而是先建立**可解释的响应地图**。
## Case E
### 圆柱后方局部推流
可用你已经验证过的固定圆柱 baseline,先选最稳的低 Re 工况,例如二维层流涡街基线。
#### 建议设置
- 使用你当前已经验证可靠的 2D 固定圆柱基线
- 先选一个自然涡街清晰、但还不太剧烈的 Re
- force region 放在圆柱后方近尾迹区
例如:
- 圆柱中心 `(xc, yc)`
- force region 中心可先试:
- `(xc + 2D, yc)`
- `(xc + 3D, yc)`
- 半径先从 `0.3D` 到 `0.8D` 扫
- 先做 `fx > 0, fy = 0`
#### 该看什么
- 尾迹中心线速度是否回升
- 近尾迹回流区是否缩短
- `Cl` 振幅是否降低
- `Cd_mean` 是否变化
- 涡脱落频率 `St` 是否偏移
- streakline / vorticity 图是否出现更对称或更拉长的尾迹结构
#### 预期结果
对于圆柱尾迹中的外加 forcing,不同 forcing 形式都说明了同一个大方向:**局部强迫会改写尾迹结构、拖曳、升力波动与脱落频率**。[Kim05b] 虽然研究的是壁面 blowing/suction 而不是体力区,但其结果清楚表明:分布式 forcing 可以显著抑制或改变 Kármán 涡街,从而改变 mean drag 与 lift fluctuation [Kim05b]。
对当前 `force_region`,更合理的预期是:
- 小 `fx > 0`:尾迹被顺流“拉长”,回流区可能缩短
- 足够合适的位置和幅值下:`Cl_rms` 下降,尾迹更接近对称
- 过强 forcing:可能引入新的不稳定结构,而不是单调“变好”
#### 判定方式
建议不要只看一张图,至少同时记录:
| 量 | 作用 |
|---|---|
| `Cd_mean` | 看平均阻力变化 |
| `Cl_rms` | 看升力波动是否被抑制 |
| `St` | 看脱落频率是否移动 |
| vorticity / streakline 图 | 看结构是否更对称、更拉长、或出现新模态 |
#### 这个 case 的定位
这是**研究型验证**,不是严格 benchmark。
更准确地说,它回答的是:
- `force_region` 是否足够稳定和可控,能够进入尾迹控制实验
- 不同位置、半径、幅值是否产生可解释的流场响应
而不是:
- 某个单一数字是否必须匹配文献到几个百分点
## 推荐的执行顺序
建议按下面顺序推进。
| 顺序 | 算例 | 作用 |
|---|---|---|
| 1 | R1-R4 | 先清掉实现错误 |
| 2 | Case A | 验证最基本物理响应 |
| 3 | Case B | 做文献支持最强的主验证 |
| 4 | Case C | 找到安全幅值区间 |
| 5 | Case D | 看网格与黏度稳健性 |
| 6 | Case E | 进入圆柱尾迹研究 |
## 每个算例建议保存的输出
为了后面快速回看,建议每个 case 固定保存下面这些量。
| 输出 | 是否必需 | 说明 |
|---|---|---|
| 配置文件快照 | 必需 | 保证能复现实验 |
| `fx, fy` 与 region 几何 | 必需 | force center, radius, amplitude |
| 一张 `ux` 场图 | 必需 | 看主流响应 |
| 一张 vorticity 图 | 推荐 | 看结构变化 |
| 一条下游横截面 `ux(y)` | 必需 | Poiseuille 与 channel 类验证最关键 |
| `rho` 最大偏离 | 推荐 | 监控压缩性污染 |
| 若有圆柱:`Cd_mean`, `Cl_rms`, `St` | 必需 | 尾迹控制最关键 |
## 最低通过线
如果时间紧,只要先达到下面这三条,就可以开始把 `force_region` 用进研究实验:
1. **零强迫回归通过**
2. **静止流场中局部加速方向正确、幅值单调**
3. **长通道中下游横截面能稳定收敛到近抛物剖面**
做到这三条,说明这个新功能至少已经:
- 不破坏旧功能
- 有正确方向性
- 能在最经典的 body-force 场景中生成合理结构
## 如何解读失败
### 若 Case A 失败
优先怀疑:
- action slot 读写
- force region footprint
- `is_fluid(flag[k])` 过滤
- `ForceRegionKernel` 写回 DDF 的路径
### 若 Case B 失败
优先怀疑:
- force region 是否真的覆盖了足够长的通道中段
- inlet/outlet 是否过强地主导了解
- force 幅值是否太大
- 取样截面是否还在入口发展段
### 若 Case D 失败
优先怀疑:
- spatially varying forcing 本身的离散误差被放大
- 当前 operator-split 修正对该参数区间不够稳
- 需要收缩到更小 force、更低 Mach、更细网格
## 最后的建议
当前 `force_region` 最适合先被当作一个**研究工具**,而不是一开始就当作“已严格 benchmark 的标准物理模块”。最稳妥的路线是:
- 用 [Guo02d] 和 [Zou95b] 支撑主验证思路
- 用 [Sil20b] 提醒自己必须做稳健性检查
- 用 [Kim05b] 作为圆柱尾迹控制的高层参考,理解应该关注哪些响应量
这样做,既能尽快把功能用于研究,也不会把验证叙事说得过头。
## 参考依据
- Guo, Zheng, Shi 讨论了 forcing term 的离散效应,并将 steady Poiseuille flow 作为数值验证的一部分 [Guo02d]
- Zou, Hou, Doolen 给出了平板间 Poiseuille 流的解析解,并指出 bounce-back 壁面会引入一阶误差 [Zou95b]
- Silva 分析了空间变化 body force 在 LBM 中的离散误差来源,说明非均匀 forcing 必须做网格与黏度稳健性检查 [Sil20b]
- Kim 和 Choi 表明分布式 forcing 可以显著改变圆柱尾迹、drag、lift fluctuation 和 shedding mode,可作为圆柱尾迹研究阶段的高层参照 [Kim05b]
+247
View File
@@ -0,0 +1,247 @@
# Rotating cylinder validation against [Kan99b]
## Goal
This validation should stay small, direct, and defensible.
The main design rules are:
- use the paper's direct numeric anchor at `Re = 100, alpha = 1.0` as the main hard benchmark
- use a low-rotation case to test the lift trend
- use suppression cases to test flow classification, not exact threshold fitting
- do not treat values read from figures near `alpha_L` as tight amplitude targets
This keeps the matrix representative without overfitting to sensitive threshold points.
## Strong numeric anchors from [Kan99b]
The strongest exact benchmark in the paper is the convergence case at `Re = 100, alpha = 1.0`.
| Quantity | Reference value |
|---|---:|
| `St` | 0.1655 |
| `mean C_L` | -2.4881 |
| `mean C_D` | 1.1040 |
| `C'_L` | 0.3631 |
| `C'_D` | 0.0993 |
For low rotation at `Re = 100`, the paper also gives the mean lift trend
\[
\overline{C_L} \approx -2.48\alpha
\]
which is a good secondary benchmark for small `alpha`.
The suppression thresholds are given as trends:
| Reynolds number | Expected `alpha_L` |
|---|---:|
| 60 | about 1.4 |
| 100 | about 1.8 |
| 160 | about 1.9 |
These threshold values should be used as regime guides, not as tight one-point numeric targets. In the suppression curve from [Kan99b] shown above, the boundary is exactly the kind of place where a small solver difference can change the observed state.
## Fixed solver setup
| Item | Setting |
|---|---|
| Dimension | 2D |
| Lattice | D2Q9 |
| Streaming | double buffer |
| Curved boundary | current Bouzidi moving wall implementation |
| Inlet profile | uniform |
| Top and bottom boundaries | free slip |
| Outlet | neq extrapolation |
| LES | off |
| Precision | FP32 |
| Cylinder diameter | `D = 30` lattice units |
| Cylinder radius | `R = 15` lattice units |
| Rotation input | update body omega only |
The baseline domain remains the current medium far field unless a later boundary sensitivity check shows otherwise.
## Inlet recommendation by collision model
Kan99b is an open-flow validation, not a confined-channel benchmark.
| Collision | Recommended inlet | Secondary choice | Avoid as primary |
|---|---|---|---|
| SRT | `equilibrium` | `regularized` | `zou_he_local` |
| TRT | `regularized` | `equilibrium` | `zou_he_local` until the anchor is stable |
| MRT | `regularized` or `zou_he_local` | `equilibrium` | `channel_stabilized` |
Keep one inlet family per collision model across the primary matrix.
## Lattice-unit mapping
Use
\[
U_\infty = 0.03
\]
With `D = 30`,
\[
\nu = \frac{U_\infty D}{Re} = \frac{0.9}{Re}
\]
| `Re` | `nu` | SRT equivalent `omega` |
|---|---:|---:|
| 60 | 0.015000 | 1.83486 |
| 100 | 0.009000 | 1.89753 |
| 160 | 0.005625 | 1.93470 |
The body rotation rate is
\[
\omega_{body} = \frac{2 \alpha U_\infty}{D} = 0.002\alpha
\]
| `alpha` | body omega |
|---|---:|
| 0.5 | 0.0010 |
| 1.0 | 0.0020 |
| 1.6 | 0.0032 |
| 2.0 | 0.0040 |
## Primary matrix
This is the recommended main validation set.
| Case | `Re` | `alpha` | Role |
|---|---:|---:|---|
| K1 | 100 | 0.5 | low-rotation lift trend check |
| K2 | 100 | 1.0 | strongest hard anchor |
| K3 | 60 | 1.6 | low-Re suppression classification |
| K4 | 100 | 2.0 | mid-Re suppression classification |
| K5 | 160 | 2.0 | high-Re suppression classification |
Optional baseline if needed for debugging or plots:
| Case | `Re` | `alpha` | Status |
|---|---:|---:|---|
| K0 | 100 | 0.0 | optional |
This matrix covers:
- one periodic low-rotation trend point
- one exact hard anchor with full force data
- suppression behavior at low, medium, and high Reynolds number
## How to judge each case
### K1
Use K1 to check the low-rotation lift law.
Target:
\[
\overline{C_L} \approx -2.48 \times 0.5 \approx -1.24
\]
This is a trend check, not a strict fluctuation-amplitude benchmark.
### K2
Use K2 as the hard benchmark case.
Preferred agreement band:
| Quantity | Preferred band |
|---|---:|
| `St` | within 3 percent |
| `mean C_L` | within 4 percent |
| `mean C_D` | within 5 percent |
| `C'_L` | within 8 percent |
| `C'_D` | within 10 percent |
### K3 to K5
Use K3 to K5 as suppression classification cases.
Primary success signature:
- `C'_L` collapses toward zero in the final window
- no sustained alternating wake remains
- flow classification agrees with the expected suppressed regime
These are not exact threshold-fitting cases. Do not over-interpret a small residual fluctuation if the wake is otherwise clearly in the suppressed class.
## Optional threshold bracket check
If later you want a more explicit threshold study, use pairs around `alpha_L` rather than a single point on the boundary.
Recommended pairs:
| `Re` | Lower point | Upper point |
|---|---:|---:|
| 60 | 1.3 | 1.5 |
| 100 | 1.7 | 1.9 |
| 160 | 1.8 | 2.0 |
These should still be treated as regime-location checks, not hard force targets.
## Run policy
| Case type | Total steps | Warmup | Statistics |
|---|---:|---:|---:|
| K1 and K2 | 180000 to 220000 | first 40 percent | last 60 percent |
| K3 to K5 | 220000 to 280000 | first 50 percent | last 50 percent |
The final statistics window should contain at least 20 shedding periods whenever the case remains periodic.
## TRT re-entry rule
Bring TRT back in this order:
1. K2 only
2. if K2 is stable and credible, run K1
3. only then run K3 to K5
This prevents TRT from expanding the matrix before the hard anchor is trustworthy.
## Deliverables
For each collision model, deliver:
- one table of run settings including collision, inlet scheme, wall type, `Re`, `alpha`, `nu`, and body omega
- one CSV per run with force history
- selected field images for wake classification
- one summary table with `mean C_D`, `mean C_L`, `C'_D`, `C'_L`, and `St`
- one short note stating whether suppression behavior matches [Kan99b]
## Recommended primary settings summary
| Collision | Wall | Inlet | Status |
|---|---|---|---|
| SRT | free slip | `equilibrium` | primary |
| TRT | free slip | `regularized` | primary if K2 is stable |
| MRT | free slip | `regularized` or `zou_he_local` | primary |
## MRT-only runner mapping
The current executable entrypoint is `tests/run_kan99b_rotating_cylinder.py`, and this round uses MRT-only scheduling:
- primary matrix is `K1-K5` with `MRT + regularized` inlet
- one extra control run is added at K2 with `MRT + zou_he_local`
- all runs keep `uniform` inlet profile, `free_slip` y-wall, `neq_extrap` outlet
- output rows include `case_id`, `variant`, `collision`, `inlet_scheme`, `grid`, `steps`, `burn_in`, `St`, `St_error_pct` (for K2), and force metrics
- K2 gate uses this document's per-metric tolerances for `St`, `mean C_L`, `mean C_D`, `C'_L`, `C'_D`
Example commands:
```bash
conda run -n pycuda_3_10 python tests/run_kan99b_rotating_cylinder.py \
--json-out tests/output/kan99b_validation/summary_runs.json
conda run -n pycuda_3_10 python tests/run_kan99b_rotating_cylinder.py \
--case K2 --save-vorticity
```
## Reference
[Kan99b] S. Kang, H. Choi, and S. Lee, “Laminar flow past a rotating circular cylinder,” 1999.
+243
View File
@@ -0,0 +1,243 @@
# Sah04 confined-cylinder validation against [Sah04]
## Goal
This validation should use a small set of direct periodic anchors from [Sah04], plus a small secondary block for near-onset flow-state checks.
The main design rules are:
- do not use interpolated values from figures as hard targets
- do not use points on or extremely near critical curves as primary pass fail anchors
- report realized blockage and realized Reynolds number, not just nominal inputs
- use finer grids for high blockage so the narrow wall gaps are not under-resolved
This keeps the primary matrix small but still representative across moderate and high confinement.
## What counts as a hard benchmark from [Sah04]
The strongest periodic-flow anchors are the direct DNS values stated in the paper for developed unsteady states.
| Case | Blockage `beta` | Reynolds number | `St` target | Why it is a hard anchor |
|---|---:|---:|---:|---|
| S1 | 0.3 | 100 | 0.2115 | direct periodic DNS value |
| S2 | 0.5 | 200 | 0.3513 | direct periodic DNS value |
| S3 | 0.8 | 160 | `T ≈ 1.806`, so `St ≈ 0.5537` | direct case given in the paper |
| S4 | 0.9 | 200 | 0.5314 | direct periodic DNS value |
These should be the primary Sah04 validation anchors.
## What should not be a hard target
The following are useful for qualitative or secondary checks, but not for the main validation gate:
- critical onset values from Table IV
- any `St` or force value obtained by reading or interpolating a plot
- cases chosen only to complete a rectangular parameter grid
- points too close to the codimension two region or nearby neutral stability boundaries
This matters because the paper's stability map has several sensitive regions, especially at high blockage and near symmetry breaking. In the stability figure from [Sah04] shown above, those boundaries are exactly where a small setup difference can change the observed state.
## Geometry and blockage mapping
Keep the confined-channel layout and no-slip walls.
The validation table must always report both nominal and realized blockage.
With `D = 30` lattice units, the recommended realizations are:
| Case | `beta_nominal` | Suggested `H` | `beta_real` | Notes |
|---|---:|---:|---:|---|
| S1 | 0.3 | 100 | 0.3000 | exact |
| S2 | 0.5 | 60 | 0.5000 | exact |
| S3 | 0.8 | 38 or 37 | 0.7895 or 0.8108 | pick one and report it explicitly |
| S4 | 0.9 | 33 | 0.9091 | use this, not `H = 35` |
Do not silently rename `beta_real` as the paper blockage.
## Grid density policy
High blockage cases need more wall-normal resolution than the base grid.
Minimum rule:
- for `beta < 0.8`, the baseline grid with `D = 30` is acceptable for the first pass
- for `beta >= 0.8`, increase grid density by at least 2 times in each spatial direction before treating the result as validation quality
A practical way to do this is to keep geometry similarity while doubling the characteristic resolution:
- base cases: `D = 30`
- high blockage validation cases: at least `D = 60`
Recommended high blockage realizations on the refined grid:
| Case | `beta_nominal` | Suggested refined `D` | Suggested refined `H` | `beta_real` |
|---|---:|---:|---:|---:|
| S3 | 0.8 | 60 | 75 | 0.8000 |
| S4 | 0.9 | 60 | 67 | 0.8955 |
The point of this refinement is not only bulk accuracy. It is also to resolve the narrow cylinder wall gaps and reduce the risk that blockage effects are dominated by lattice geometry error.
## Primary matrix
This is the main Sah04 validation set.
| Case | `beta_nominal` | Primary target | Role |
|---|---:|---|---|
| S1 | 0.3 | `Re = 100`, `St = 0.2115` | moderate blockage periodic anchor |
| S2 | 0.5 | `Re = 200`, `St = 0.3513` | medium blockage periodic anchor |
| S3 | 0.8 | `Re = 160`, `St ≈ 0.5537` | high blockage periodic anchor |
| S4 | 0.9 | `Re = 200`, `St = 0.5314` | very high blockage periodic anchor |
This matrix is smaller than the older grid, but it covers:
- moderate confinement
- stronger confinement
- high blockage periodic shedding
- very high blockage periodic shedding
## Secondary onset block
These cases are recommended as flow-state checks, not hard `St` benchmarks.
| Case | `beta_nominal` | Suggested `Re` | Why it is useful | How to judge it |
|---|---:|---:|---|---|
| SO1 | 0.5 | about 130 | safely above first onset without sitting on the boundary | confirm sustained periodic state |
| SO2 | 0.7 | about 120 | tests near-onset behavior in a more sensitive blockage range | confirm sustained periodic state |
These points exist to answer a different question from the primary matrix:
- does the solver enter and maintain the right flow regime once slightly above onset
For SO1 and SO2, judge by:
- persistent nonzero `C'_L`
- a clean dominant spectral peak
- repeatable periodic wake structure
Do not fail these runs because the measured `St` differs slightly from a value read from a nearby figure.
## Inlet and wall policy
Sah04 is a confined-channel benchmark, so inlet consistency matters more than inlet variety.
| Collision | Wall | Inlet | Status |
|---|---|---|---|
| SRT | no slip | `channel_stabilized` | primary |
| TRT | no slip | `channel_stabilized` | primary |
| MRT | no slip | `channel_stabilized` | primary |
Keep the inlet family fixed across collision models in the primary matrix.
Secondary inlet comparison, only after the primary set is working:
| Collision | Optional inlet | Status |
|---|---|---|
| MRT | `regularized` or `zou_he_local` | exploratory |
| SRT or TRT | `equilibrium` or `regularized` | exploratory |
## Realized Reynolds number check
This is mandatory for Sah04.
For each run, record:
- nominal inlet definition
- developed downstream velocity profile
- measured `U_max,real`
- measured bulk velocity if available
- `beta_nominal`
- `beta_real`
- `Re_nominal`
- `Re_real`
Use the paper-consistent label
\[
Re_{real} = \frac{U_{max,real} D}{\nu}
\]
for the final comparison table.
If `Re_real` drifts materially from the intended target, treat that as a setup problem before treating it as a Strouhal miss.
## Run policy
| Case block | Total steps | Burn | Statistics |
|---|---:|---:|---:|
| S1 and S2 | 100000 to 160000 | first 35 to 40 percent | last 60 to 65 percent |
| S3 and S4 | 180000 to 260000 | first 45 percent | last 55 percent |
| SO1 and SO2 | 140000 to 220000 | first 45 percent | last 55 percent |
For high blockage refined runs, prefer the longer end of the window.
## Evaluation rule
Use a two-layer rule.
### Primary periodic anchors
| Case | Hard target use |
|---|---|
| S1 to S4 | hard periodic benchmark anchors |
Preferred agreement band:
- within 5 percent when `Re_real` is close to target and the spectrum is clean
- within 10 percent still acceptable if the run is clearly periodic and the residual mismatch is explainable by `Re_real` drift or geometry realization
### Secondary onset block
| Case | Hard target use |
|---|---|
| SO1 and SO2 | no hard `St` gate |
Success means:
- the flow is clearly unsteady and periodic
- the dominant frequency is stable over long windows
- the wake classification is consistent with being above onset
## Deliverables
For each run, deliver:
- one row with `beta_nominal`, `beta_real`, `Re_nominal`, `Re_real`, `nu`, collision, wall type, inlet scheme, and grid resolution
- one downstream velocity-profile plot
- one force-history CSV
- one `St` estimate with the exact analysis window stated
- selected wake images for flow classification
## Recommended minimum set
If compute budget is tight, run this order first:
| Priority | Runs |
|---|---|
| 1 | MRT on S1 to S4 |
| 2 | SRT on S2 and S4 |
| 3 | TRT on S2 and S4 |
| 4 | SO1 and SO2 only after the primary anchors are behaving |
## MRT-only runner mapping
The current executable entrypoint is `tests/run_sah04_st_matrix.py`, and it is now aligned to this document's primary S1-S4 matrix:
- collision is fixed to `MRT`
- inlet is fixed to `parabolic + channel_stabilized`
- case set is `S1-S4` only
- output rows include `case_id`, `collision`, `inlet_scheme`, `grid`, `steps`, `burn_in`, `St`, `St_error_pct`, `Re_real`, `beta_real`
- default hard gate is 5% (`--gate-pct` can relax it to 10%)
Example commands:
```bash
conda run -n pycuda_3_10 python tests/run_sah04_st_matrix.py \
--json-out tests/output/sah04_mrt/summary.json
conda run -n pycuda_3_10 python tests/run_sah04_st_matrix.py \
--case S3 --gate-pct 10 --final-vorticity-dir tests/output/sah04_mrt/vorticity
```
## Reference
[Sah04] M. Sahin and R. G. Owens, “A numerical investigation of wall effects up to high blockage ratios on two-dimensional flow past a confined circular cylinder,” 2004.
+181
View File
@@ -0,0 +1,181 @@
229:无控制:
```
SIGNAL_FEATURES0 = {
'action1': {
'mean': 0.0,
'components': [
(0.1354, 0.0, 1.600),
]
},
'action2': {
'mean': -0.0,
'components': [
(0.1354, 0.0, 2.099),
]
},
'action3': {
'mean': 0.0,
'components': [
(0.1354, 0.0, 1.639),
]
}
}
```
234:隐身:
```
SIGNAL_FEATURES1 = {
'action1': {
'mean': 0.0,
'components': [
(0.1354, 0.0, 1.600),
]
},
'action2': {
'mean': -0.01806,
'components': [
(0.1354, 0.0, 2.099),
]
},
'action3': {
'mean': 0.01806,
'components': [
(0.1354, 0.0, 1.639),
]
}
}
```
欺骗:
237 238 253:
```
SIGNAL_FEATURES2 = {
'action1': {
'mean': 0.0,
'components': [
(0.1354, 0.0026, 1.600), # 主频
]
},
'action2': {
'mean': -0.008730,
'components': [
(0.1354, 0.0045, 2.099), # 主频
(0.2708, 0.0010, 0.612),
]
},
'action3': {
'mean': 0.008730,
'components': [
(0.1354, 0.0045, 1.639), # 主频
(0.2708, 0.0010, -2.962),
]
}
}
```
257:
```
SIGNAL_FEATURES3 = {
'action1': {
'mean': 0.0,
'components': [
(0.1354, 0.0029, -2.619), # 主频
(0.2708, 0.0008, 2.856),
]
},
'action2': {
'mean': -0.0140,
'components': [
(0.1354, 0.0050, -0.933), # 主频
(0.2708, 0.0010, 0.801),
(0.1806, 0.0003, 1.854),
]
},
'action3': {
'mean': 0.014,
'components': [
(0.1354, 0.0050, -1.398), # 主频
(0.2708, 0.0010, 2.208),
(0.1806, 0.0003, 1.810),
]
}
}
```
260 (f*1.5):
```
SIGNAL_FEATURES4 = {
'action1': {
'mean': 0.0,
'components': [
(0.2031, 0.0026, 1.600), # 主频
]
},
'action2': {
'mean': -0.008730,
'components': [
(0.2031, 0.0045, 2.099), # 主频
(0.4062, 0.0010, 0.612),
]
},
'action3': {
'mean': 0.008730,
'components': [
(0.2031, 0.0045, 1.639), # 主频
(0.4062, 0.0010, -2.962),
]
}
}
```
262: (f*1.5):
```
SIGNAL_FEATURES5 = {
'action1': {
'mean': 0.0,
'components': [
(0.2031, 0.0029, -2.619), # 主频
(0.4062, 0.0008, 2.856),
]
},
'action2': {
'mean': -0.0140,
'components': [
(0.2031, 0.0050, -0.933), # 主频
(0.4062, 0.0010, 0.801),
(0.2709, 0.0003, 1.854),
]
},
'action3': {
'mean': 0.014,
'components': [
(0.2031, 0.0050, -1.398), # 主频
(0.4062, 0.0010, 2.208),
(0.2709, 0.0003, 1.810),
]
}
}
```
270 (f*2):
```
SIGNAL_FEATURES6 = {
'action1': {
'mean': 0.0,
'components': [
(0.2708, 0.0044, -2.619), # 主频
(0.8124, 0.0012, 2.856),
]
},
'action2': {
'mean': -0.014,
'components': [
(0.2708, 0.0075, -0.933), # 主频
(0.8124, 0.0015, 0.801),
(0.5418, 0.0005, 1.854),
]
},
'action3': {
'mean': 0.014,
'components': [
(0.2708, 0.0075, -1.398), # 主频
(0.8124, 0.0015, 2.208),
(0.5418, 0.0005, 1.810),
]
}
}
```
+493
View File
@@ -0,0 +1,493 @@
## Streakline postprocessing design
这份说明面向一个最小可实现的离线后处理程序。输入是按时间保存的二维速度场序列,输出是接近实验染色图的 streakline 图像。核心路线是连续释粒,因为 streakline 正是“固定位置持续释放染料后,在某个时刻所有已释放粒子的位置集合” [Lan96]。对非定常尾迹,这比单帧 streamline 更贴近实验图像 [Lan96]。
搜索和全文阅读给出的信息已经足够支撑第一版实现。最直接的方案是按保存时刻连续注入粒子,用时空插值后的速度场推进粒子,再将粒子云渲染为图像 [Lan96, Ken96]。如果纯粒子结果过于尖锐,再在推进后加入一个很小的随机扩散项,作为对真实染色液扩散的近似。更完整的被动标量法当然更物理,但实现成本更高,不适合作为第一版 [Kim04]。
## Core recommendation
| 方法 | 与实验染色图的对应 | 实现复杂度 | 适合作为第一版 |
|---|---|---:|---|
| 单帧 streamline | 弱 | 很低 | 不推荐 |
| 连续释粒 streakline | 强 | 低 | 最推荐 |
| streakline 加少量扩散 | 很强 | 低到中 | 推荐作为第二步 |
| 被动标量对流扩散 | 最强 | 中到高 | 暂不作为第一版 |
最小可实现路线如下:
- 从 CelerisLab 导出一串二维速度场快照 `u_x(x,y,t_k), u_y(x,y,t_k)`
- 选定一个固定释放点或一小段释放线
- 在每个保存时刻都注入新粒子
- 在两个相邻快照之间,用时间插值和空间插值计算粒子速度
- 用二阶或四阶时间积分推进粒子
- 删去出域粒子与进入固体的粒子
- 将当前时刻存活粒子按位置和年龄渲染成图像
这个程序逻辑直接对应 [Lan96] 的 streakline 算法,插值与推进细节由 [Ken96] 和 [Dar96] 支撑。
## Data contract
默认输入是规则 Cartesian 网格上的二维时间序列速度场。对当前项目,最自然的输入约定是:
| 名称 | 含义 |
|---|---|
| `t_k` | 第 `k` 个保存时刻 |
| `ux[k, j, i]` | 时刻 `t_k` 的 x 方向速度 |
| `uy[k, j, i]` | 时刻 `t_k` 的 y 方向速度 |
| `mask[j, i]` | 可选,固体与流体标记 |
| `x_i, y_j` | 网格坐标 |
第一版最好满足下面三条:
- 时间快照间隔固定或至少已知
- 网格坐标固定不动
- 固体几何位置已知,至少能判断粒子是否进入圆柱内部
如果输出来自 CelerisLab,本质上只需要把每个保存时刻的 `ux, uy` 和对应时间写出来即可。算法本身是通用的,并不依赖 LBM 本身。
## Mathematical model for the base streakline
### Particle motion
粒子位置满足拉格朗日运动方程 [Lan96]:
\[
\frac{d \boldsymbol{x}}{dt} = \boldsymbol{u}(\boldsymbol{x}, t)
\]
其中
\[
\boldsymbol{x} = (x, y), \qquad \boldsymbol{u} = (u_x, u_y)
\]
积分形式为 [Lan96]:
\[
\boldsymbol{x}(t + \Delta t) = \boldsymbol{x}(t) + \int_t^{t+\Delta t} \boldsymbol{u}(\boldsymbol{x}(\tau), \tau) \, d\tau
\]
streakline 在观察时刻 \(t_n\) 的定义是:从固定释放位置 \(\boldsymbol{x}_s\) 在过去各时刻持续注入的粒子,在 \(t_n\) 时刻的全部位置集合 [Lan96]。
### Time interpolation
速度场只在离散时刻存储,所以必须做时间插值。对位于 \(t_k \le t \le t_{k+1}\) 的任意子步,最简单的做法是线性时间插值 [Ken96]:
\[
\delta = \frac{t - t_k}{t_{k+1} - t_k}
\]
\[
\boldsymbol{u}(\boldsymbol{x}, t) = (1 - \delta) \, \boldsymbol{u}_k(\boldsymbol{x}) + \delta \, \boldsymbol{u}_{k+1}(\boldsymbol{x})
\]
这里 \(\boldsymbol{u}_k(\boldsymbol{x})\) 和 \(\boldsymbol{u}_{k+1}(\boldsymbol{x})\) 仍需通过空间插值得到。
### Spatial interpolation
在规则网格上,第一版直接用双线性插值即可。虽然 [Ken96] 讨论的是非结构网格上的点定位与线性插值,但其一般原则完全适用于规则网格:
- 先定位粒子所在单元
- 再用单元顶点速度插值得到粒子点速度 [Ken96]
若粒子位于单元局部坐标 \((\xi, \eta) \in [0,1]^2\),四个角点速度为 \(\boldsymbol{u}_{00}, \boldsymbol{u}_{10}, \boldsymbol{u}_{01}, \boldsymbol{u}_{11}\),则
\[
\boldsymbol{u}(\xi, \eta) = (1-\xi)(1-\eta) \boldsymbol{u}_{00}
+ \xi (1-\eta) \boldsymbol{u}_{10}
+ (1-\xi)\eta \boldsymbol{u}_{01}
+ \xi\eta \boldsymbol{u}_{11}
\]
## Time integration choice
[Lan96] 和 [Ken96] 都直接使用四阶 Runge Kutta。对你的第一版程序,推荐两个选项:
| 积分器 | 优点 | 缺点 | 建议 |
|---|---|---|---|
| RK2 | 简洁,容易调试 | 精度一般 | 最小原型可用 |
| RK4 | 文献最一致,精度更稳 | 每步插值次数更多 | 默认推荐 |
RK4 的更新式为 [Lan96, Ken96]:
\[
\boldsymbol{x}_{n+1} = \boldsymbol{x}_n + \frac{1}{6}(\boldsymbol{a} + 2\boldsymbol{b} + 2\boldsymbol{c} + \boldsymbol{d})
\]
其中
\[
\boldsymbol{a} = \Delta t \, \boldsymbol{u}(\boldsymbol{x}_n, t_n)
\]
\[
\boldsymbol{b} = \Delta t \, \boldsymbol{u}(\boldsymbol{x}_n + \tfrac{1}{2}\boldsymbol{a}, t_n + \tfrac{1}{2}\Delta t)
\]
\[
\boldsymbol{c} = \Delta t \, \boldsymbol{u}(\boldsymbol{x}_n + \tfrac{1}{2}\boldsymbol{b}, t_n + \tfrac{1}{2}\Delta t)
\]
\[
\boldsymbol{d} = \Delta t \, \boldsymbol{u}(\boldsymbol{x}_n + \boldsymbol{c}, t_n + \Delta t)
\]
[Ken96] 特别强调,RK4 的每一个子步都要重新做点定位与时空插值。这在规则网格上不难实现,只是意味着一次完整步进需要四次速度查询 [Ken96]。
## Practical timestep guidance
第一版不必上自适应步长,但步长不能随意设大。搜索里最重要的精度提醒来自 [Dar96]:
- 非定常粒子积分的误差常常由时间离散控制,而不是概念本身
- 合理步长必须不大于流动主要非定常时间尺度的同量级 [Dar96]
- 若时间步过大,粒子轨迹会在拓扑上都出错,而不仅是位置略偏 [Dar96]
对当前项目,最简单的工程准则是:
\[
\Delta t_{trace} \le \min \bigl(\alpha_t \, \Delta t_{save},\; \alpha_x \, \frac{\Delta x}{\max |u|} \bigr)
\]
其中 \(\Delta t_{save}\) 是两个保存快照之间的时间间隔,\(\Delta x\) 是网格尺度。第一版可取:
- \(\alpha_t = 0.1 \sim 0.25\)
- \(\alpha_x = 0.25 \sim 0.5\)
这不是文献中的严格上界,而是结合 [Dar96] 的结论给出的实现准则:粒子推进子步既要显著小于保存间隔,也不要一子步跨过太多网格。
[Ken96] 还给了一个很实用的自适应思路:根据相邻速度方向夹角调节步长。如果速度方向变化太快就减半,变化很小就加倍 [Ken96]。这很适合后续增强版,但不属于第一版必需项。
## Base streakline algorithm
### Release strategy
最符合染色实验的是连续释粒 [Lan96]。第一版可用两种释放方式:
| 方式 | 适用场景 | 建议 |
|---|---|---|
| 单点释放 | 针头式染料入口 | 最简单 |
| 短线段释放 | 更像细缝或细带注入 | 更稳健 |
如果实验是在圆柱上游某一点持续释放染色液,第一版就直接使用单点释放。
### Particle state
每个粒子只需保存:
| 字段 | 含义 |
|---|---|
| `x, y` | 当前坐标 |
| `t_birth` | 释放时刻 |
| `age` | 当前年龄 |
| `alive` | 是否仍在域内 |
第一版不需要保存整条历史轨迹。因为你要的是当前时刻的 streakline 图,而不是每个粒子的 pathline 曲线。
**常见误区(务必区分)**
| 概念 | 画什么 | 是否等于水洞染色迹线 |
|---|---|---|
| **Streakline(迹线)** | 固定源点**持续释粒**,在观察时刻 \(t_n\) 画出**所有仍存活粒子的当前位置**(可带年龄衰减权重) | 是 |
| **Pathline(迹线/轨道)** | 单个粒子从释放到当前的**整条历史轨迹** | 否 |
| **错误实现** | 每隔一段时间放一个粒子,再把**所有粒子走过的路径段**全部叠加到图上 | 否(这是 pathline 叠加,不是 streakline) |
水洞实验:针头在固定点连续注 dye → 某一时刻拍照 → 看到的是“此刻染料粒子在流场里的分布”,一条下游色带由**不同释放时刻、当前仍在本流场中的粒子**共同构成,而不是把每个粒子从出生到现在的轨迹都画出来。
### Main loop pseudocode
```text
given velocity snapshots U[k] = {ux[k], uy[k]} at times t[k]
given seeding point or seeding segment S
initialize empty particle list P
for k = 0 to N-2:
inject new particles at source S at time t[k]
set t_local = t[k]
while t_local < t[k+1]:
dt = min(dt_trace, t[k+1] - t_local)
for each particle p in P with p.alive:
v = interpolate_velocity(p.position, t_local)
advance p by one integration step using RK2 or RK4
update p.age
if p leaves domain:
p.alive = false
if p enters solid body:
p.alive = false
t_local = t_local + dt
optionally remove very old particles
optionally render current particle cloud
```
这个结构与 [Lan96] 的离散 streakline 算法一致,只是把“从 `t_k` 到 `t_{k+1}` 的一次推进”细化成多个更小的粒子子步,以满足 [Dar96] 对精度的要求。
### Velocity query pseudocode
```text
function interpolate_velocity(position x, time t):
find k such that t[k] <= t <= t[k+1]
compute delta = (t - t[k]) / (t[k+1] - t[k])
u_k = bilinear_interpolation(U[k], x)
u_k1 = bilinear_interpolation(U[k+1], x)
return (1 - delta) * u_k + delta * u_k1
```
这是第一版最核心的数值部件。只要这部分实现正确,streakline 程序主体就很直接。
## Small diffusion particle model
当纯 streakline 太细、太锐利、不像染色液图像时,可以给每个粒子加一个很小的随机扩散项。这不是严格的被动标量求解,但能以很低代价增加染色带宽度。
### Guiding idea
[Kim04] 表明,染料图像更接近一个被动标量浓度场,其基本控制方程是对流扩散方程:
\[
\frac{\partial c}{\partial t} + \boldsymbol{u} \cdot \nabla c = D \nabla^2 c
\]
其中 \(c\) 是染料浓度,\(D\) 是扩散系数。对第一版粒子法,一个常见近似是将每个粒子的位置更新写成“对流加随机扩散”:
\[
\boldsymbol{x}_{n+1} = \boldsymbol{x}_n + \Delta \boldsymbol{x}_{adv} + \Delta \boldsymbol{x}_{diff}
\]
其中 \(\Delta \boldsymbol{x}_{adv}\) 由 RK2 或 RK4 给出,扩散项取二维各向同性随机增量:
\[
\Delta \boldsymbol{x}_{diff} = \sqrt{2 D \Delta t}
\begin{bmatrix}
\eta_x \\
\eta_y
\end{bmatrix}
\]
这里 \(\eta_x, \eta_y \sim \mathcal{N}(0,1)\)。
这个形式本身是对扩散过程的标准随机游走近似。搜索结果提醒,随机游走模型如果处理不当会产生假漂移与错误浓度偏置 [Mac92]。因此第一版的使用原则应当很克制:
- 只用于加入少量模糊和厚度
- 不把粒子密度当成严格浓度
- 不在强近壁统计上过度解读结果
### Diffusive particle update pseudocode
```text
for each particle p in P with p.alive:
x_adv = RK4_step(p.position, t_local, dt)
sigma = sqrt(2 * D * dt)
dx_rand = sigma * normal(0, 1)
dy_rand = sigma * normal(0, 1)
x_new = x_adv + [dx_rand, dy_rand]
if x_new leaves domain:
p.alive = false
else if x_new enters solid:
p.alive = false
else:
p.position = x_new
p.age += dt
```
### Choosing the diffusion level
第一版不必试图从真实染料物性严格标定 \(D\)。更实用的做法是把 \(D\) 当作视觉匹配参数,并保持它足够小,使图像结构仍主要由对流控制。
[Kim04] 用 Schmidt 数控制扩散强弱。若已有参考速度 \(U\) 和长度尺度 \(L\),则
\[
Sc = \frac{\nu}{D}
\]
也可写成
\[
D = \frac{\nu}{Sc}
\]
对第一版,可以用下面的思路选扩散强度:
| 目标效果 | 建议 |
|---|---|
| 只想让线条略微变厚 | 取较大 `Sc`,即很小的 `D` |
| 想模拟明显洗开和模糊 | 取较小 `Sc`,即较大的 `D` |
| 不确定 | 先从几乎看不出的弱扩散开始 |
因为当前目标是“少量扩散”,所以推荐先把扩散当成弱修饰,而不是主导机制。
## Rendering logic
最终图像不需要把每个粒子的完整轨迹都画出来。更像实验染色图的做法是把当前存活粒子投影到图像网格上,生成粒子密度图或带年龄权重的强度图。
### Minimal rendering choices
| 方法 | 图像风格 | 实现难度 |
|---|---|---:|
| 直接散点 | 最简陋 | 很低 |
| 网格计数直方图 | 像浓度图 | 低 |
| 高斯核累积 | 更平滑 | 低到中 |
第一版推荐:
- 把每个粒子投到像素网格
- 对像素做计数或加权累积
- 最后做一次轻微 Gaussian blur
这与先做完整被动标量相比便宜很多,但视觉上已经会很接近实验染色图。
### Optional particle weighting
可以给粒子一个简单权重:
\[
I = \sum_p w_p K(\boldsymbol{x} - \boldsymbol{x}_p)
\]
其中 \(K\) 是像素核或 Gaussian 核。第一版里,权重 \(w_p\) 可直接取 1,也可对年龄做衰减,例如:
\[
w_p = \exp\left(- \frac{\mathrm{age}_p}{\tau_f} \right)
\]
这样旧粒子会逐渐淡出,图像不会无限堆积。
## Boundary handling
这部分先按最小原则处理即可。
| 情况 | 第一版处理 |
|---|---|
| 粒子出计算域 | 直接删除 |
| 粒子进入圆柱内部 | 直接删除 |
| 粒子贴近边界滑动 | 暂不专门处理 |
| 扩散后跨入固体 | 直接删除 |
这样做的优点是简单稳妥。后续若发现近壁 streakline 误差明显,再考虑反射、投影或更物理的壁面处理。
## Minimal implementation plan
### Version 1
目标是尽快得到可信的 streakline 图:
- 读取 `ux, uy, t`
- 单点连续释粒
- 双线性空间插值
- 线性时间插值
- RK4 粒子推进
- 出域删除与入固体删除
- 粒子计数成图
### Version 2
在不改变主体架构的前提下增强视觉效果:
- 增加短线段释放
- 增加年龄衰减
- 增加弱随机扩散
- 用 Gaussian 核代替简单计数
### Version 3
若后续发现实验图像明显受扩散与混合主导,再转向更重的模型:
- 被动标量对流扩散
- 用 \(Sc\) 或 \(D\) 做参数标定 [Kim04]
## Design decisions that are already justified by the literature
下面这些设计已经有足够文献支撑,可以直接采用:
- 用 streakline 而不是 streamline 对应持续染色实验 [Lan96]
- 用连续释放粒子离线重构 streakline [Lan96]
- 用时空插值从离散速度快照查询粒子速度 [Ken96]
- 用 RK4 作为默认推进器 [Lan96, Ken96]
- 把步长取得明显小于保存时间间隔,并避免一次跨过太多网格 [Dar96]
- 若需要更像染料图,可以加入弱扩散,或后续上升到被动标量 [Kim04]
## Recommended default choices
| 项目 | 默认选择 |
|---|---|
| 释放方式 | 单点连续释粒 |
| 空间插值 | 双线性 |
| 时间插值 | 线性 |
| 积分器 | RK4 |
| 粒子子步 | 保存步长的 0.1 到 0.25 |
| 固体处理 | 入固体即删除 |
| 输出图像 | 粒子密度图加轻微模糊 |
| 扩散 | 默认关闭,作为第二步 |
## Bottom line
对当前项目,最简洁且足够准确的程序逻辑不是去解新的染料场,而是先做一个离线连续释粒 streakline 后处理器。它只依赖时间序列速度场,程序结构清楚,数值风险也集中在可控的几个环节:时空插值、积分步长和边界删除 [Lan96, Dar96, Ken96]。在此基础上,再增加一个弱随机扩散项,就能以很小代价把图像从“几何上正确的粒子线”推进到“更像实验染色照片”的粒子云 [Kim04]。
## CelerisLab implementation mapping
Current implementation lives in:
- library: `src/CelerisLab/common/streakline.py`
- Kan99b demo CLI: `tests/run_kan99b_streakline.py`
- experiment notebook: `tests/experiment.ipynb` (CLEAN 5/6)
Available runtime modes:
- `online`: sample `Simulation.get_macroscopic()` directly in memory (no velocity snapshot files).
- `offline`: replay from an existing snapshot directory and run the same streakline integrator.
Dense release support:
- base upstream points are expanded by `release_mode` (`point|line|strip`).
- `strip` mode densifies both cross-stream (`line_count`, `line_span`) and downstream (`downstream_count`, `downstream_spacing`) directions.
### Performance notes (why it can feel slow)
Streakline post-processing is **CPU-side** in the current stack:
1. **GPU→host velocity copies** dominate for large grids (`nx=6000, ny=1200`). Each `get_macroscopic()` pulls full `ux/uy` arrays.
2. Particle RK4 + bilinear interpolation runs in NumPy on CPU (vectorized over particles, not GPU).
3. Rendering accumulates polylines into an image (optionally multi-threaded via `ThreadPoolExecutor`).
Practical tuning:
| knob | effect |
|---|---|
| `sample_every` | larger → fewer host copies, faster, coarser streaks |
| `max_particle_age` | `None` → no hard cutoff; trails survive until boundary/solid |
| `num_threads` | `0` = auto; sets OpenBLAS/OMP threads for blur/host ops |
| `blur_sigma` | `0` disables Gaussian blur pass |
For `experiment.ipynb` triangle case, use **`render_streakline_density(..., minimal_axes=True)`** on the **final alive particle cloud** (`positions`, `ages`). Do **not** accumulate and draw full path history (`render_snapshot_trails` is pathline-style debug only).
### Clean render style (experiment)
`render_snapshot_trails` defaults:
- white background
- red streaks, brighter toward the downstream end (`fade_along_trail=True`)
- black filled cylinders
- no axes, labels, colorbar, or release-point markers
Example commands:
```bash
# Online in-memory streakline (no snapshot write)
conda run -n pycuda_3_10 python tests/run_kan99b_streakline.py \
--mode online --domain M --re 100 --alpha 1.0 \
--sample-every 300 --n-snapshots 20 \
--release-mode strip --line-count 7 --downstream-count 6
# Offline replay from existing velocity snapshots
conda run -n pycuda_3_10 python tests/run_kan99b_streakline.py \
--mode offline \
--snapshot-dir tests/output/final_validation_round/streakline_kan99b_k2/velocity_snapshots \
--release-mode strip --line-count 7 --downstream-count 6
```
+121
View File
@@ -0,0 +1,121 @@
"""Public API demo: fixed 2:1 patch with a stationary, optionally actuated circle.
From this checkout, after checking the selected physical GPU is idle:
PYTHONPATH="$PWD/src" CUDA_VISIBLE_DEVICES=0 python examples/fixed_patch_circle.py --fine-block 16 20
... --speed -0.002 --fine-block 16 20 --mode slot_reservoir
Omit --fine-block for the (equivalent) dense fine storage.
A short smoke run (default 128 coarse steps): it shows setup, stepping and
fluid-only diagnostics, not a developed flow, accuracy or long-time stability.
Normal blowing/suction injects/extracts mass, so leaf mass is expected to change.
No files, plots or checkpoints are written.
"""
import argparse
from pathlib import Path
import numpy as np
import CelerisLab
from CelerisLab.body.geometry.circle import CircleGeometry
from CelerisLab.body.objects import SimObject, SurfaceActuation
from CelerisLab.config import LBMConfig
from CelerisLab.cuda.context import CudaContext
from CelerisLab.lbm.descriptors import D2Q9_EX, D2Q9_EY, SOLID
from CelerisLab.lbm.equilibrium import compute_feq_d2q9
from CelerisLab.lbm.refinement import ACTIVE
from CelerisLab.lbm.refinement_stepper import FixedPatchStepper
NX, NY, BOUNDS = 32, 24, (8, 6, 24, 18) # coarse cells; patch is half-open (x0, y0, x1, y1)
CENTER, RADIUS = (16.0, 12.0), 2.15 # coarse CELL-EDGE frame: cell I spans [I, I+1)
def config(mode):
if mode == "periodic": # x and y periodic coarse level
return LBMConfig(nx=NX, ny=NY, viscosity=.1)
# Bottom on-site velocity slot, top fixed-density reservoir, x periodic.
return LBMConfig(nx=NX, ny=NY, viscosity=.1, velocity=0, wall_normal_velocity=.001,
wall_slot_width=8, y_wall_bc="on_site_velocity", top_wall_bc="reservoir")
def leaf_masks(run, mode):
"""Known fluid leaves: uncovered coarse cells (minus wall rows in slot mode)
and fine ACTIVE cells outside the body."""
p = run.patch
x0, y0, x1, y1 = p.bounds
coarse = np.ones(p.coarse_shape, bool)
coarse[y0:y1, x0:x1] = False
if mode == "slot_reservoir":
coarse[[0, -1]] = False
solid = (run.fine_boundary.flags.reshape(p.fine_shape) & SOLID) != 0
return coarse, (p.fine_kind == ACTIVE) & ~solid
def leaf_diagnostics(coarse, fine, masks):
"""Fluid leaves only; a non-finite population or rho <= 0 there is an error.
Mass counts a fine cell as 1/4 of a coarse cell (2D, 2:1)."""
out = {}
for name, g, leaf, area in (("coarse", coarse, masks[0], 1.0), ("fine", fine, masks[1], .25)):
f = g[:, leaf].astype(np.float64)
rho = f.sum(axis=0)
if not np.isfinite(f).all() or (rho <= 0).any():
raise RuntimeError(f"non-finite population or non-positive density on a {name} fluid leaf")
ux = (np.array(D2Q9_EX)[:, None] * f).sum(axis=0) / rho
uy = (np.array(D2Q9_EY)[:, None] * f).sum(axis=0) / rho
out[name] = (area * rho.sum(), rho.min(), rho.max(), np.hypot(ux, uy).max())
return out
def main():
parser = argparse.ArgumentParser(description=__doc__.splitlines()[0])
parser.add_argument("--mode", choices=("periodic", "slot_reservoir"), default="periodic")
parser.add_argument("--speed", type=float, default=.002,
help="normal surface velocity, coarse lattice units (+ blows, - sucks, 0 passive)")
parser.add_argument("--fine-block", type=int, nargs=2, metavar=("BY", "BX"),
help="blocked fine storage; must divide the whole fine allocation (32 x 40 here)")
parser.add_argument("--steps", type=int, default=128)
args = parser.parse_args()
if args.steps < 0:
parser.error("--steps must be nonnegative")
root = Path(__file__).resolve().parents[1]
if Path(CelerisLab.__file__).resolve() != root / "src/CelerisLab/__init__.py":
raise RuntimeError(f"Set PYTHONPATH to {root / 'src'}")
# Aperture centred at angle 0.7 rad, half-width 0.85 rad (the tested fixture).
spec = SurfaceActuation(0.7, 0.85, args.speed) if args.speed else None
body = SimObject(0, geometry=CircleGeometry(*CENTER, RADIUS), center=CENTER, radius=RADIUS,
surface_actuation=spec)
cfg = config(args.mode)
fine_block = tuple(args.fine_block) if args.fine_block else None
# The caller owns the CUDA context; the stepper must be closed first (the
# nested with-statement does that).
with CudaContext(0) as context, FixedPatchStepper(
cfg, BOUNDS, context=context, coarse_boundary=args.mode,
fine_objects=[body], fine_block=fine_block) as run:
p = run.patch
# Rest equilibrium is already postcollision G, so no initial collision is
# needed. Non-leaf entries (covered, ghost, solid) are discarded by initialize.
rest = np.asarray(compute_feq_d2q9(1.0, 0.0, 0.0), np.float32)[:, None, None]
run.initialize(np.broadcast_to(rest, (9, *p.coarse_shape)),
np.broadcast_to(rest, (9, *p.fine_shape)))
storage = f"blocked {fine_block}" if fine_block else "dense"
print(f"mode={args.mode} fine storage={storage} speed={args.speed:+g} "
f"(fine allocation {p.fine_shape[0]}x{p.fine_shape[1]}, fine origin {p.fine_origin})")
masks = leaf_masks(run, args.mode)
start = leaf_diagnostics(*run.download(), masks)
for _ in range(0, args.steps, 32):
run.step(min(32, args.steps - run.step_count))
coarse, fine = run.download() # synchronized postcollision G, NaN on non-leaves
d = leaf_diagnostics(coarse, fine, masks)
mass = d["coarse"][0] + d["fine"][0]
rho_lo = min(d["coarse"][1], d["fine"][1])
rho_hi = max(d["coarse"][2], d["fine"][2])
speed = max(d["coarse"][3], d["fine"][3])
print(f"coarse step {run.step_count:4d}: leaf mass {mass:.9f} "
f"(change {mass - start['coarse'][0] - start['fine'][0]:+.3e}) "
f"rho [{rho_lo:.6f}, {rho_hi:.6f}] max |u| {speed:.3e}")
print("smoke run only: storage/stepping demonstration, not accuracy or stability evidence")
if __name__ == "__main__":
main()
+203
View File
@@ -0,0 +1,203 @@
"""Low-Re startup flow in an x-periodic confined domain; nozzle remains coarse.
From this checkout, after checking the selected physical GPU is idle:
PYTHONPATH="$PWD/src" CUDA_VISIBLE_DEVICES=0 python examples/fixed_patch_jet.py --output /tmp/patch-jet
The fixed-amplitude start includes acoustic transients, not a developed jet.
Only native leaf cells are plotted. No interpolation, restart or flow oracle.
Scale estimates use the continuous peak A=.02, not inlet mean speed: W/A=600,
H/A=2250, W**2/nu=1440, H**2/nu=20250, where H=NY-3=45 between on-site planes.
An acoustic crossing (~78 steps) does not imply that transients have disappeared.
Mach is sampled over all leaves every 50 steps and is usually inlet dominated;
the discrete inlet peak is slightly below continuous A. This is not an accuracy test.
The 120s checks are cooperative, not an exact interruption deadline. main elapsed
includes construction, advancement and plotting; it is not pure CFD timing.
"""
import argparse
from dataclasses import replace
import json
import os
from pathlib import Path
import tempfile
import time
import numpy as np
import CelerisLab
from CelerisLab.config import load_lbm_config
from CelerisLab.cuda.context import CudaContext
from CelerisLab.lbm.equilibrium import compute_feq_d2q9, compute_macro_from_ddf
from CelerisLab.lbm.refinement import ACTIVE
from CelerisLab.lbm.refinement_stepper import FixedPatchStepper
BOUNDS, AMPLITUDE, WIDTH = (16, 4, 32, 28), .02, 12
TIMES, MAX_MACH, MAX_SECONDS = (0, 300, 1200), .1, 120
def measure(arrays, masks, centers, initial_mass):
fields = []
for array, mask in zip(arrays, masks):
if not np.isfinite(array[:, mask]).all():
raise RuntimeError("Nonfinite leaf populations")
field = np.full((*mask.shape, 3), np.nan)
field[mask] = [compute_macro_from_ddf(f) for f in array[:, mask].T]
fields.append(field)
leaves = np.concatenate([f[m] for f, m in zip(fields, masks)])
speed = np.hypot(leaves[:, 1], leaves[:, 2])
mass = sum(area*a[:, m].sum(dtype=np.float64)
for area, a, m in zip((1, .25), arrays, masks))
record = dict(finite=bool(np.isfinite(leaves).all()), rho_min=float(leaves[:, 0].min()),
rho_max=float(leaves[:, 0].max()), speed_max=float(speed.max()),
sampled_max_Mach=float(speed.max()*np.sqrt(3)),
density_deviation=float(np.abs(leaves[:, 0]-1).max()),
discrete_leaf_mass=float(mass), mass_change=float(mass-initial_mass))
if not record['finite'] or record['rho_min'] <= 0 or record['sampled_max_Mach'] > MAX_MACH:
raise RuntimeError(f"Finite/positive-density/Ma<={MAX_MACH} guard failed: {record}")
walls = fields[0][[1, -2]]
record['macro_sum_rho_v'] = dict(zip(('Q_in', 'Q_out'),
(walls[:, :, 0]*walls[:, :, 2]).sum(axis=1).tolist()))
record['centerline'] = []
for level, y in ((1, 16.25), (0, 32.5)):
xs, ys = centers[level]
columns = np.argsort(np.abs(xs-24))[:2]
row = int(np.flatnonzero(ys == y)[0])
values = fields[level][row, columns].mean(axis=0)
record['centerline'].append(dict(level=level, x=24, y=y,
sampled_x=sorted(xs[columns].tolist()), rule='arithmetic mean of two neighboring native columns',
rho_ux_uy=values.tolist()))
return fields, record
def draw(out, snapshots, masks, centers):
import matplotlib
matplotlib.use('Agg')
import matplotlib.pyplot as plt
from matplotlib.collections import PolyCollection
def decorate(ax):
ax.set(xlim=(0, 48), ylim=(1.5, 46.5), aspect='equal', xlabel='X', ylabel='Y')
ax.plot([16, 32, 32, 16, 16], [4, 4, 28, 28, 4], color='tab:red', lw=1)
ax.axhline(1.5, color='black', lw=1)
ax.axhline(46.5, color='black', lw=1, ls='--')
ax.plot([18, 30], [1.5, 1.5], color='tab:orange', lw=4, clip_on=False)
fig, ax = plt.subplots(figsize=(6, 6), constrained_layout=True)
for mask, (xs, ys), dx in zip(masks, centers, (1, .5)):
yy, xx = np.meshgrid(ys, xs, indexing='ij')
cells = np.stack((xx[mask], yy[mask]), axis=-1)
vertices = cells[:, None, :] + dx*np.array([[-.5, -.5], [.5, -.5], [.5, .5], [-.5, .5]])
ax.add_collection(PolyCollection(vertices, facecolors='none', edgecolors='0.55', linewidths=.3))
decorate(ax)
ax.set_title('Native leaf grid: coarse dx=1, fine dx=0.5\n'
'Red: internal patch; orange: coarse slot; dashed: reservoir\n'
'Flow may cross patch sides; patch does not contain all startup flow', fontsize=10)
fig.savefig(out/'layout.png', dpi=150, bbox_inches='tight', pad_inches=.15)
plt.close(fig)
vmax = max(1., *(np.nanmax(np.hypot(f[..., 1], f[..., 2]))/AMPLITUDE
for fields in snapshots for f in fields))
fig, axes = plt.subplots(1, 3, figsize=(12, 4.8), constrained_layout=True)
for ax, step, fields in zip(axes, TIMES, snapshots):
for field, mask, (xs, ys), dx in zip(fields, masks, centers, (1, .5)):
speed = np.ma.masked_where(~mask, np.hypot(field[..., 1], field[..., 2])/AMPLITUDE)
image = ax.pcolormesh(np.r_[xs-dx/2, xs[-1]+dx/2],
np.r_[ys-dx/2, ys[-1]+dx/2], speed,
shading='flat', cmap='viridis', vmin=0, vmax=vmax, rasterized=True)
stride = int(4/dx)
yy, xx = np.meshgrid(ys, xs, indexing='ij')
selection = np.zeros_like(mask)
selection[::stride, ::stride] = mask[::stride, ::stride]
ax.quiver(xx[selection], yy[selection], field[..., 1][selection], field[..., 2][selection],
angles='xy', scale_units='xy', scale=AMPLITUDE/3, width=.005, color='white')
decorate(ax)
ax.set_title(f'coarse t={step}, fine steps={2*step}')
fig.colorbar(image, ax=axes, label='speed / imposed amplitude')
fig.suptitle('Low-Re startup flow in an x-periodic confined domain\n'
'Fixed-amplitude start includes acoustic transients; not steady/developed\n'
'Nozzle remains coarse; flow may cross patch sides (not fully enclosed)', fontsize=11)
fig.savefig(out/'velocity.png', dpi=150)
plt.close(fig)
def main():
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument('--output', type=Path, required=True)
out = parser.parse_args().output.resolve()
root = Path(__file__).resolve().parents[1]
if Path(CelerisLab.__file__).resolve() != root/'src/CelerisLab/__init__.py':
raise RuntimeError(f'Set PYTHONPATH to {root / "src"}')
out.mkdir(parents=True, exist_ok=False)
cfg = replace(load_lbm_config(str(root/'src/CelerisLab/configs/config_lbm.json')),
nx=48, ny=48, viscosity=.1, velocity=0., rho=1., wall_slot_width=WIDTH,
wall_normal_velocity=AMPLITUDE, y_wall_bc='on_site_velocity', top_wall_bc='reservoir',
lattice_model='D2Q9', collision='SRT', streaming='double_buffer',
store_precision='FP32', ddf_shifting=False, les_enabled=False)
report = dict(config=dict(nx=48, ny=48, bounds=BOUNDS, W=WIDTH, A=AMPLITUDE, nu=.1,
rho=1, tau_coarse=.8, tau_fine=1.1, coarse_boundary='slot_reservoir'),
guards=dict(check_every=50, positive_density=True, finite=True,
max_Mach=MAX_MACH, max_seconds=MAX_SECONDS,
timing='cooperative checks, not an exact interruption deadline'),
scale_estimates=dict(velocity_basis='continuous peak A, not inlet mean', H=cfg.ny-3,
W_over_A=WIDTH/AMPLITUDE, H_over_A=(cfg.ny-3)/AMPLITUDE,
W_squared_over_nu=WIDTH**2/cfg.viscosity,
H_squared_over_nu=(cfg.ny-3)**2/cfg.viscosity,
acoustic_crossing=(cfg.ny-3)*np.sqrt(3)),
notes='Node mass uses areas 1 and 1/4, not an exact physical volume integral. '
'Q_in/Q_out are bottom/top macro sum(rho*vy), not a closed population budget. '
'Mach maxima are sampled every 50 steps, not every-step peaks. '
'One acoustic crossing does not imply transient decay; no steady-state claim.',
samples=[], status='running', last_synchronized_coarse_step=0)
start, run = time.monotonic(), None
try:
with CudaContext(0) as context, FixedPatchStepper(cfg, BOUNDS, context=context,
coarse_boundary='slot_reservoir') as run:
p = run.patch
masks = [np.ones(p.coarse_shape, bool), p.fine_kind == ACTIVE]
masks[0][[0, -1]] = False
masks[0][4:28, 16:32] = False
centers = [(origin[0]+dx*(np.arange(shape[1])+.5),
origin[1]+dx*(np.arange(shape[0])+.5))
for shape, origin, dx in ((p.coarse_shape, (0, 0), 1),
(p.fine_shape, p.fine_origin, .5))]
initial = [np.broadcast_to(compute_feq_d2q9(1., 0., 0.)[:, None, None], (9, *m.shape)).copy()
for m in masks]
for x in range(cfg.nx):
v = AMPLITUDE*max(0., 1-((2*x-(cfg.nx-1))/WIDTH)**2)**2
initial[0][:, 1, x] = compute_feq_d2q9(1., 0., v)
run.initialize(*initial)
mass0 = sum(area*a[:, m].sum(dtype=np.float64)
for area, a, m in zip((1, .25), initial, masks))
snapshots = []
for step in range(0, TIMES[-1]+1, 50):
if time.monotonic()-start > MAX_SECONDS:
raise TimeoutError('120 second demonstration limit reached')
if step:
run.step(50)
report['last_synchronized_coarse_step'] = run.step_count
if time.monotonic()-start > MAX_SECONDS:
raise TimeoutError('120 second demonstration limit reached after chunk')
fields, sample = measure(run.download(), masks, centers, mass0)
sample.update(t=step, coarse_steps=step, fine_steps=2*step)
report['samples'].append(sample)
print(json.dumps(sample), flush=True)
if step in TIMES:
snapshots.append(fields)
with tempfile.TemporaryDirectory(prefix='.plot-', dir=out) as cache:
os.environ['MPLCONFIGDIR'] = cache
draw(out, snapshots, masks, centers)
if time.monotonic()-start > MAX_SECONDS:
raise TimeoutError('120 second demonstration limit reached after plotting')
report['status'] = 'complete'
except BaseException as exc:
report.update(status='failed', error=f'{type(exc).__name__}: {exc}',
last_synchronized_coarse_step=run.step_count if run is not None else 0)
raise
finally:
report['elapsed_seconds'] = time.monotonic()-start
report['elapsed_scope'] = 'main construction, advancement and plotting; not pure CFD time'
(out/'summary.json').write_text(json.dumps(report, indent=2)+'\n')
print(f'{report["status"]}: last synchronized coarse step '
f'{report["last_synchronized_coarse_step"]}; output={out}', flush=True)
if __name__ == '__main__':
main()
+76
View File
@@ -0,0 +1,76 @@
"""Public API demo: small periodic shear, one fixed 2:1 patch, eight coarse steps.
From this checkout, after checking the selected physical GPU is idle:
PYTHONPATH="$PWD/src" CUDA_VISIBLE_DEVICES=0 python examples/fixed_periodic_patch.py
This demonstrates initialization/stepping/leaf output, not interface accuracy.
There are no walls, objects, forces, checkpoint files or plots.
"""
from dataclasses import replace
from pathlib import Path
import numpy as np
import CelerisLab
from CelerisLab.config import load_lbm_config
from CelerisLab.cuda.context import CudaContext
from CelerisLab.lbm.equilibrium import compute_feq_d2q9, compute_macro_from_ddf
from CelerisLab.lbm.refinement import ACTIVE
from CelerisLab.lbm.refinement_stepper import PeriodicPatchStepper
def shear_equilibrium(shape, origin, dx, period):
"""Sample ux(y)=1e-3*sin(2*pi*y/period) at physical cell centers.
Centers are origin + dx*(index+.5); this shear is independent of x.
Fine origin includes patch offset AND the four-cell halo, with dx=.5.
Equilibrium is already postcollision G, so no initial collision is needed.
"""
y = origin[1] + dx * (np.arange(shape[0]) + .5)
ux = 1e-3 * np.sin(2*np.pi*y/period)
rows = np.stack([compute_feq_d2q9(1.0, float(u), 0.0) for u in ux], axis=1)
return np.repeat(rows[:, :, None], shape[1], axis=2)
def leaf_summary(coarse, fine, coarse_leaf, fine_leaf):
"""Use the same leaf masks/areas for initial and final mass."""
c, f = coarse[:, coarse_leaf], fine[:, fine_leaf]
mass = c.sum(dtype=np.float64) + .25*f.sum(dtype=np.float64)
macros = np.array([compute_macro_from_ddf(v) for v in np.concatenate((c, f), axis=1).T])
return mass, macros.min(axis=0), macros.max(axis=0)
def main():
root = Path(__file__).resolve().parents[1]
if Path(CelerisLab.__file__).resolve() != root / "src/CelerisLab/__init__.py":
raise RuntimeError(f"Set PYTHONPATH to {root / 'src'}")
cfg = replace(load_lbm_config(str(root / "src/CelerisLab/configs/config_lbm.json")),
nx=16, ny=16, viscosity=.1, velocity=1e-3, rho=1.0,
lattice_model="D2Q9", collision="SRT", streaming="double_buffer",
store_precision="FP32", ddf_shifting=False, les_enabled=False)
with CudaContext(0) as context, PeriodicPatchStepper(cfg, (4, 4, 12, 12), context=context) as run:
p = run.patch
coarse = shear_equilibrium(p.coarse_shape, (0, 0), 1.0, cfg.ny)
fine = shear_equilibrium(p.fine_shape, p.fine_origin, .5, cfg.ny)
coarse_leaf = np.ones(p.coarse_shape, dtype=bool)
x0, y0, x1, y1 = p.bounds
coarse_leaf[y0:y1, x0:x1] = False
fine_leaf = p.fine_kind == ACTIVE
coarse[:, ~coarse_leaf] = np.nan
fine[:, ~fine_leaf] = np.nan
run.initialize(coarse, fine)
initial_mass, _, _ = leaf_summary(*run.download(), coarse_leaf, fine_leaf)
run.step(8)
coarse, fine = run.download() # Both levels synchronized, stored postcollision G.
assert np.isnan(coarse[:, ~coarse_leaf]).all() and np.isnan(fine[:, ~fine_leaf]).all()
assert np.isfinite(coarse[:, coarse_leaf]).all() and np.isfinite(fine[:, fine_leaf]).all()
mass, low, high = leaf_summary(coarse, fine, coarse_leaf, fine_leaf)
print(f"periodic patch API demo: synchronized coarse_steps={run.step_count}, fine_steps={2*run.step_count}")
print(f"leaf mass: initial={initial_mass:.12g} final={mass:.12g} drift={mass-initial_mass:+.6e}")
for name, lo, hi in zip(("rho", "ux", "uy"), low, high):
print(f"leaf {name}: [{lo:.9g}, {hi:.9g}]")
print("covered coarse / fine halo: NaN; functional demonstration only")
if __name__ == "__main__":
main()
+78
View File
@@ -0,0 +1,78 @@
# Round 3: FP16S and ddf_shifting compatibility
Date: 2026-06-03
Duration: 8+ hours of code + testing
## Summary of work
This round added and verified FP16S store precision and ddf_shifting mode compatibility across the body module, curved boundary, and diagnostics pipeline.
## Primary achievements
### 1. MRT shifting fix (critical)
**Problem discovered:** D2Q9 MRT is NOT shift-invariant in moment space because M(w) produces non-zero entries in m[1] (energy) and m[2] (energy^2). Previous assumption that "f - feq cancels weights pairwise" only holds for SRT/TRT (per-direction collision), not for MRT (moment-space collision).
**Fix applied:** When `USE_DDF_SHIFTING=1`, `collide_mrt` now:
1. Unshifts `g[i] += w[i]` at entry (physical space)
2. Performs full MRT collision in physical space
3. Reshifts `g[i] -= w[i]` at exit
**Verified:** `MRT + ddf_shifting + zou_he_local` produces K2 results with `amp_CL` recovering from 0.007 to 0.476.
**Note on D3Q19:** Has a `compute_feq` inconsistency (shifted feq applied to unshifted g) that needs fixing before D3Q19 shifting is usable.
### 2. ddf_shifting code fixes
| Fix | File | Status |
|-----|------|--------|
| Inlet west_velocity_rho_closure +5/6 correction | `inlet/common.cuh` | Verified, both D2Q9 and D3Q19 |
| Curved force/torque +2*w_i correction | `curved_boundary.cuh`, `aux_kernels.cu` | Verified |
| Host upload_ddf() asymmetry (subtract weights before upload) | `field.py` | Verified |
| Checkpoint streaming and ddf_shifting match check | `checkpoint.py` | Implemented |
### 3. Inlet knowns repair generalization (partial)
The `repair_zou_he_west_knowns_d2q9` function was moved from Zou-He-only to all west inlet schemes in `inlet_outlet.cuh`. This fixes free-slip y-wall contamination of ghost-node populations. However, this alone was insufficient to fix the regularized+shifting issue.
### 4. EsoPull curved boundary (from Round 2, documented here for posterity)
Verified against Kan99b K2: **bit-identical metrics** between double_buffer and esopull streaming.
Key architectural decisions:
- `streaming/esopull_semantic_helpers.cuh` -- single source of truth for physical-value semantics
- `MacroscopicEsoPullKernel` -- GPU-side diagnostics (not host raw decode)
- `Prepare + Apply` two-phase curved boundary
## Current compatibility matrix
### Verified (passes K2/Sah04 benchmarks)
| Config | Details |
|--------|---------|
| FP32 + MRT + double_buffer | Full validation (all Kan99b, Sah04) |
| FP32 + MRT + esopull | K2 bit-identical to double_buffer |
| FP16S + MRT + double_buffer | Sah04 S2 passes |
| ddf_shifting + MRT + zou_he_local | K2 amp_CL recovered, full validation pending |
### Known limitations
| Issue | Severity | Status |
|-------|----------|--------|
| FP16S K2 St deviation (0.170 vs 0.142) | Medium -- quantization noise in curved region | Documented, acceptable for low-Re research |
| FP16S S4 divergence at step 71420 | Medium -- high-blockage quantization + wall-gap | Use FP32 for high-blockage |
| ddf_shifting + regularized inlet + MRT | High -- suppressed shedding even after inlet repair | Regularized in shifting needs root cause. Use zou_he_local for now. |
| D3Q19 MRT shifting patch incomplete | Medium -- shifted feq applied to unshifted g | Not in 2D scope, TODO noted in code |
| ddf_shifting + esopull combined | Not verified | Both paths validated separately but not together |
## Key lessons recorded
1. **SRT/TRT are shift-invariant; MRT is NOT.** The weight vector w has non-zero moment space projection. Always shift/unshift around MRT.
2. **Repair_zou_he_west_knowns is NOT Zou-He-specific.** Every west inlet scheme using `west_velocity_rho_closure_d2q9()` needs it under free-slip y-walls.
3. **FP16S failure modes are specific:** Low-blockage (S2) is fine; rotating cylinder (K2) shows quantization sensitivity; high-blockage (S4) can diverge. Test all three regimes before claiming FP16S works.
4. **`compute_feq` in shifting mode returns `feq - w`, not `feq`.** This is correct for SRT/TRT (NEQ terms cancel w), but causes a bias when paired with an unshifted `g` (D3Q19 MRT case).
5. **Host DDF path is not symmetric under shifting.** `download_ddf()` adds back w; `upload_ddf()` (before fix) did not subtract w. This breaks host-side initialization, snapshot/restore, and add_vortex under shifting.
+43
View File
@@ -0,0 +1,43 @@
[build-system]
requires = ["setuptools>=61.0", "wheel"]
build-backend = "setuptools.build_meta"
[project]
name = "CelerisLab"
version = "0.5.1"
description = "GPU-accelerated Lattice Boltzmann Method (LBM) CFD solver using CUDA"
readme = "README.md"
requires-python = ">=3.10"
license = {text = "MIT"}
authors = [
{name = "Frank14f"}
]
keywords = ["cfd", "lattice-boltzmann", "cuda", "gpu", "fluid-dynamics", "lbm"]
classifiers = [
"Development Status :: 3 - Alpha",
"Intended Audience :: Science/Research",
"Topic :: Scientific/Engineering :: Physics",
"License :: OSI Approved :: MIT License",
"Programming Language :: Python :: 3",
"Programming Language :: Python :: 3.10",
"Programming Language :: Python :: 3.11",
]
dependencies = [
"pycuda>=2020.1",
"numpy>=1.19.0",
"scipy>=1.5.0",
]
[project.urls]
Homepage = "https://github.com/frank14f/CelerisLab"
Repository = "https://github.com/frank14f/CelerisLab.git"
[tool.setuptools]
package-dir = {"" = "src"}
[tool.setuptools.packages.find]
where = ["src"]
[tool.setuptools.package-data]
"CelerisLab" = ["lbm/kernels/**/*.cu", "lbm/kernels/**/*.cuh", "lbm/kernels/**/*.h", "configs/*.json"]
@@ -0,0 +1,389 @@
{
"head": "6e3756c587ec08ab6a55c4a1a5f4671822d3f0a0",
"status": " M pyproject.toml\n M setup.py\n M src/CelerisLab/__init__.py\n M src/CelerisLab/body/__init__.py\n M src/CelerisLab/body/ddf_patch.py\n M src/CelerisLab/body/manager.py\n M src/CelerisLab/body/objects.py\n M src/CelerisLab/body/preprocess/flag_overlay.py\n M src/CelerisLab/common/__init__.py\n M src/CelerisLab/common/checkpoint.py\n M src/CelerisLab/config.py\n M src/CelerisLab/configs/CONFIG.md\n M src/CelerisLab/cuda/__init__.py\n M src/CelerisLab/cuda/compiler_v2.py\n M src/CelerisLab/cuda/context.py\n M src/CelerisLab/lbm/__init__.py\n M src/CelerisLab/lbm/curved_links.py\n M src/CelerisLab/lbm/field.py\n M src/CelerisLab/lbm/initializers.py\n M src/CelerisLab/lbm/kernels/boundary/bounce_back.cuh\n M src/CelerisLab/lbm/kernels/boundary/curved_boundary.cuh\n M src/CelerisLab/lbm/kernels/boundary/inlet/common.cuh\n M src/CelerisLab/lbm/kernels/boundary/inlet/zou_he_local.cuh\n M src/CelerisLab/lbm/kernels/boundary/inlet_outlet.cuh\n M src/CelerisLab/lbm/kernels/config/config_grid.h\n M src/CelerisLab/lbm/kernels/config/config_method.h\n M src/CelerisLab/lbm/kernels/config/config_objects.h\n M src/CelerisLab/lbm/kernels/config/config_physics.h\n M src/CelerisLab/lbm/kernels/kernel_v2.cu\n M src/CelerisLab/lbm/kernels/operators/collision_mrt.cuh\n M src/CelerisLab/lbm/kernels/operators/collision_trt.cuh\n M src/CelerisLab/lbm/kernels/operators/forcing_guo.cuh\n M src/CelerisLab/lbm/kernels/step/aux_kernels.cu\n M src/CelerisLab/lbm/kernels/step/esopull_sync.cu\n M src/CelerisLab/lbm/kernels/step/init_flow.cu\n M src/CelerisLab/lbm/kernels/step/one_step_double.cu\n M src/CelerisLab/lbm/kernels/step/one_step_esopull.cu\n M src/CelerisLab/lbm/kernels/streaming/esopull_semantic_helpers.cuh\n M src/CelerisLab/lbm/stepper.py\n M src/CelerisLab/simulation.py\n M tests/integration/test_body_sync_e2e.py\n M tests/integration/test_ddf_patch.py\n M tests/integration/test_sync_bodies_skeleton.py\n M tests/integration/test_unified_obs.py\n M tests/postproc/experiment.ipynb\n M tests/validation/run_kan99b_rotating_cylinder.py\n M tests/validation/run_sah04_st_matrix.py\n M tests/validation/test_sensor_accuracy.py\n?? docs/design/\n?? docs/multilevel_grid_architecture_analysis.md\n?? examples/\n?? research/\n?? src/CelerisLab/lbm/kernels/boundary/planar_velocity.cuh\n?? src/CelerisLab/lbm/kernels/refinement.cu\n?? src/CelerisLab/lbm/refinement.py\n?? src/CelerisLab/lbm/refinement_stepper.py\n?? \"tests/audit/body\\345\\210\\240\\345\\207\\217\\345\\212\\237\\350\\203\\275.md\"\n?? tests/integration/_cases.py\n?? tests/integration/test_numerical_gpu.py\n?? tests/integration/test_runtime_contracts_gpu.py\n?? tests/integration/test_state_gpu.py\n?? tests/integration/test_surface_actuation_gpu.py\n?? tests/unit/cpp/\n?? tests/unit/test_build_contracts.py\n?? tests/unit/test_context_ownership.py\n?? tests/unit/test_initializers.py\n?? tests/unit/test_numerical_operators.py\n?? tests/unit/test_planar_velocity.py\n?? tests/unit/test_refinement.py\n?? tests/unit/test_reservoir.py\n?? tests/unit/test_simulation_lifecycle.py\n?? tests/unit/test_slot_velocity.py\n?? tests/unit/test_state_regressions.py\n?? tests/unit/test_surface_actuation.py\n?? tests/validation/analyze_j3_saved_frames.py\n?? tests/validation/diagnose_j3_lags.py\n?? tests/validation/multigrid/\n?? tests/validation/run_j1.py\n?? tests/validation/run_j2_slot.py\n?? tests/validation/run_j3_coverage.py\n?? tests/validation/run_j3_reservoir.py\n?? tests/validation/run_poiseuille.py\n",
"copy_dir": "/tmp/celeris-fine-surface-baseline-z98oi6ps",
"hashes": {
"src/CelerisLab.egg-info/PKG-INFO": "0b9a8a4e8d60bc531473688723ddef0aab02c7ccc4997e31c9b6a6c35011ca77",
"src/CelerisLab.egg-info/top_level.txt": "cd51958ca03afabbaa9618c60b8280e486f8cc0b0359b839e10f886e7c3948f8",
"src/CelerisLab.egg-info/dependency_links.txt": "01ba4719c80b6fe911b091a7c05124b64eeece964e09c058ef8f9805daca546b",
"src/CelerisLab.egg-info/requires.txt": "36e1404178e5ea590b2fc04e8ba4d748ec9a82e7693136ccf0dfd204fe265c04",
"src/CelerisLab.egg-info/SOURCES.txt": "f36b29c1b34c4bd6b2acc3ccdd21c24ee5077df7e2a20a652d9fae77eedb8e21",
"src/CelerisLab/simulation.py": "c9d903f53fe356d7af281bea07943de1a62494127fb69848d7053fd46f7dec3e",
"src/CelerisLab/config.py": "2f1bba7515f5bc08cb3a8d140bcafe7fa0689e01b3b06494697bb2956a71530e",
"src/CelerisLab/__init__.py": "21cc469bd6e970a1f9ff5970c8eea4602065e41fc881854759ee565ee55c10c6",
"src/CelerisLab/cuda/compiler_v2.py": "c4cc3ec4445c8d75e6a253dd87963877117a722bc73b9d4811806fc6045d08c1",
"src/CelerisLab/cuda/obs_layout.py": "5ffb2c3aeeaaaaeb64f2cd8febfbcf4ad9919e5414020ad753cfade0683b21c2",
"src/CelerisLab/cuda/context.py": "013dd4ec6d01d2fbd11afdfb103eac6a273bd9f798d663d761b851eeb27885e9",
"src/CelerisLab/cuda/__init__.py": "0d01dff9f0399c8baba822aab5ca0122a135f011008ed8a499ebd9f7e5b06aea",
"src/CelerisLab/lbm/refinement_stepper.py": "ad57a6a3887b007488b4954b24ff06cd8cde2b12674bdafb97bfda1961ae1da4",
"src/CelerisLab/lbm/field.py": "0e727eacc3706add4d8d15c418e9b631050871f831698d3ac689dd5f2c701b9b",
"src/CelerisLab/lbm/equilibrium.py": "2fb2f2bb7ff326d23abce80fc2a4c0907b17740ea3e29fe6ae079c5044783826",
"src/CelerisLab/lbm/descriptors.py": "c9f025dfc14da43b989047b84cc22bd05d5cc92c9ec695c1da68fdfb788e3f2b",
"src/CelerisLab/lbm/initializers.py": "dacf9586963e862d6d0a98ef1a066036be6f91e9d423720661d8ef2c1fb2df6a",
"src/CelerisLab/lbm/curved_links.py": "00d9c29d660b41190f32dd737b12f60e10ce4214b6c9a6ab2a63438813faa594",
"src/CelerisLab/lbm/stepper.py": "d2ef351aa2de441ec123deb55ce35603064130222f5490b154d41756b755cd73",
"src/CelerisLab/lbm/__init__.py": "7f60fb3aaae81501b510d08c2fedff44fcb05657260eb10b6f5cc91e7204306b",
"src/CelerisLab/lbm/refinement.py": "554735c5613129eb29f339c6aeeb4f3a3bbc5aba67558be51fbf7c2fb6ac442a",
"src/CelerisLab/lbm/kernels/kernel_v2.cu": "c7bd3fb705b77261ba2441c52a24a7e6a7865c165cba088a1b75201c4d29c408",
"src/CelerisLab/lbm/kernels/refinement.cu": "025c59dc9c207a831e78e1635cb3f14fe60b64c021004a0d66e5d01fda8554b5",
"src/CelerisLab/lbm/kernels/config.h": "7d1124125e0b354558297934460e64c760fb68cdd7bf6d01a1238bb2eaab8c37",
"src/CelerisLab/lbm/kernels/kernel_v2.ptx": "a599ee30ae66800f4d4220eb79dfed35ff32991661260f01ea58023ef780f0ca",
"src/CelerisLab/lbm/kernels/operators/turbulence_smag.cuh": "ff7f000297ee0817e255ad9fcb6a13b647e3ddd5b206518d35f38d2895a9f501",
"src/CelerisLab/lbm/kernels/operators/collision_mrt.cuh": "aee444eb60c47a3fd518dca975d1af05425a0818a0ec6c3fb3f6150f60c2cb44",
"src/CelerisLab/lbm/kernels/operators/collision_trt.cuh": "9725b9840b9ad8b4ec7be61ff5d06d3151e86d1a87585c13f2fbf934d0d2c5f6",
"src/CelerisLab/lbm/kernels/operators/collision_srt.cuh": "6b7ff842f392c8f853d2d1a97cc69bfe50f21283f73e659404da07cf6c95f5e1",
"src/CelerisLab/lbm/kernels/operators/forcing_guo.cuh": "969a430c1af03f32e3bd0df95d805e64f56334717c44dd4ba208ba503062a24b",
"src/CelerisLab/lbm/kernels/operators/macro.cuh": "e27c1c410dc857be98da4596568e405eeaf88701d291ac0e398aa9cd23dee740",
"src/CelerisLab/lbm/kernels/operators/helpers.cuh": "0b3a4d95d7d19f5fec09e5423b8f4cc99f8a226b541967425967330da5a051ec",
"src/CelerisLab/lbm/kernels/core/precision.cuh": "849df14b4cce50af52399e4b8f3e997196f3ae5f1163f68e28df3e6b2507a8c4",
"src/CelerisLab/lbm/kernels/core/descriptors.cuh": "8440bc14857da9007982650f828a23608eec9f7cc4bf772e8c8dc1239cb45356",
"src/CelerisLab/lbm/kernels/core/obs.cuh": "b742b77c9f61e1f020fe9922c3838ae9d855e17b381154958b58f10a22938922",
"src/CelerisLab/lbm/kernels/core/params.cuh": "6e18bf730d936d940e3d85452f0714a2eaae31bf41002f9fd520ec5b372878dd",
"src/CelerisLab/lbm/kernels/core/flags.cuh": "0025705f24710330d9d9195f713879bfb650a85a3449baef0e196b831af104ab",
"src/CelerisLab/lbm/kernels/core/layout.cuh": "1fbd820021c89ac3efcde24145996cb0147769e607e498e61f308ed3e0b13706",
"src/CelerisLab/lbm/kernels/boundary/ibm_kernels.cuh": "e6909b547dc8d64cdd8a76a90660243a8f5fee535caa161b52b4dd8b7c29934b",
"src/CelerisLab/lbm/kernels/boundary/planar_velocity.cuh": "0b2f9e0bd483c199637e5672dc0ffc460bc383dd1804805befbeb4c5d8c708d1",
"src/CelerisLab/lbm/kernels/boundary/inlet_outlet.cuh": "de8b213a6da42c2e5e9f8966199fc66ea4541b85144a90f3f5dbad3c6ab63b97",
"src/CelerisLab/lbm/kernels/boundary/curved_boundary.cuh": "7bccf7e7091c012d7a3d4874a881d4d46699021faedd83d125933fbdaa562711",
"src/CelerisLab/lbm/kernels/boundary/bounce_back.cuh": "aba3748c564ed91b161d268ef8b737b7c7be96a823063d201f3da684dd845233",
"src/CelerisLab/lbm/kernels/boundary/esopull_curved_helpers.cuh": "b9b474bc4edaff05681c5443235472d04072d0d775fc0eb9c5967faef52b0258",
"src/CelerisLab/lbm/kernels/boundary/inlet/equilibrium.cuh": "f0964c811b2c41a5aaa1c6d99c490b06e850c634eb8749f1f05ef61f93c2de1d",
"src/CelerisLab/lbm/kernels/boundary/inlet/channel_stabilized.cuh": "efe077afcbb6b731256a987c2fd79a1dbc470c902f87070d60421ea6cb13d4e2",
"src/CelerisLab/lbm/kernels/boundary/inlet/common.cuh": "f3cec54c8873c65b3dca4375605d2c89a8727765884d3954c235242fdff9c6ba",
"src/CelerisLab/lbm/kernels/boundary/inlet/zou_he_local.cuh": "e73e66b853b1e4e0e30d8f4185d832aa414ce670a1813ce2b5459f2887f71f89",
"src/CelerisLab/lbm/kernels/boundary/inlet/regularized.cuh": "943d4a571818bacb89c70bccfaac202691121e3e385803ce6309123a0a03ddaf",
"src/CelerisLab/lbm/kernels/boundary/outlet/pressure_neq.cuh": "c8b2adc66d12fe602076ddc9693c5c208711fcaddb58aa9a31401a269f51c4c4",
"src/CelerisLab/lbm/kernels/streaming/esopull_single_buffer.cuh": "77ed4ab9a0ebc5ff62a91a7c39066ef395391ae36e9040a69fb2bd8b1626dc79",
"src/CelerisLab/lbm/kernels/streaming/pull_double_buffer.cuh": "b65d741ed78b7b62f99531ba0c0ce1936663d8dc9640e7d7d16c707f1baf6549",
"src/CelerisLab/lbm/kernels/streaming/esopull_semantic_helpers.cuh": "dd5a9091628b079efd97e53fd49e52d09dcee88529235db77a5648e02937af6e",
"src/CelerisLab/lbm/kernels/step/esopull_sync.cu": "c0ff3e72900c3ab89a05dd03684e96d3b740cf1672d565727fc2af165933d087",
"src/CelerisLab/lbm/kernels/step/init_flow.cu": "305be3bb12fc0d039acec1701baabcf0e8a35e683c49c34f2af8ca9867d2b29c",
"src/CelerisLab/lbm/kernels/step/esopull_macro.cu": "c73116020ca217ede1e4de27c8269c31f9d91e33433ac8252a21e9b14187c50f",
"src/CelerisLab/lbm/kernels/step/aux_kernels.cu": "e163257b9cbbcdd289bf2a76b5b147ed9512dd04825ddfc9518fb626c8cff00e",
"src/CelerisLab/lbm/kernels/step/one_step_esopull.cu": "aa223b2744ae6c9125673df311a96ce588032c1ba58bebb11fd33ecb990f8ed4",
"src/CelerisLab/lbm/kernels/step/one_step_double.cu": "f9f8242b38e8e0cf8425b75e2b0215bc15363c62eaa0fb43c761b8e0931bfdc9",
"src/CelerisLab/lbm/kernels/config/config_physics.h": "26df33c2960ba36f3283e19b55b4ea92e50e4efda705f9ebfbf3f875a4092c59",
"src/CelerisLab/lbm/kernels/config/config_method.h": "3db4e16ef2c6b22349d04e6aa8ab04bdfe0eb784f9f3a98277e15dbed1835d81",
"src/CelerisLab/lbm/kernels/config/config_grid.h": "8be3a7cf74ba30d7fd3074fed79e63dbda7311c4d03b454ea641bf298ffeaa8d",
"src/CelerisLab/lbm/kernels/config/config_objects.h": "dbb93c063586da278c15d95e23f84c12e728f4f5f1bbc3980fe9cedaa6fff90e",
"src/CelerisLab/lbm/kernels/config/config_obs.h": "c11e2249359145b5c4cbaaf0487506fa77c1f4b82c7c169ddc574aa0babcd727",
"src/CelerisLab/common/checkpoint.py": "b2f960aecd5ac27a3a7130b809ffad4709c44d522edef0359ab952654625410b",
"src/CelerisLab/common/_types.py": "aad2ff1a9033d4fd68783ad7123afb47201ddc58785cb6dc0246947037072a5f",
"src/CelerisLab/common/pathline.py": "a1b6efcc0a076d0f1dc8d49a595779426d7d5626b00072a59bac710ff02ad046",
"src/CelerisLab/common/__init__.py": "d4dbde78bc97fccc9eabac9abae8f0f15c112c10ff8e9b45bd9401d4723df1ef",
"src/CelerisLab/common/preprocess.py": "7fc78a08857cf8e98519500b094a1d896af189b6b15658ff9b388ed51bed4515",
"src/CelerisLab/common/render.py": "0e055476257eb2bcd11e733766e52195de02f8fad228f570a3511a7c831bdc29",
"src/CelerisLab/common/streakline/_render.py": "236cd637414ee318c4d66f9aed32110d8dc42a100d65fde06172f7cd0ba62c65",
"src/CelerisLab/common/streakline/_integrate.py": "3fbd4368b2c8d0e7fda40dc65aac5df02b085008b4c68acd83cb7ae45d33a13b",
"src/CelerisLab/common/streakline/_streakline.py": "1a3e08daa706b5f83cdeb337e9a945a36ddf7583c40af1d0bb9d825ac954df37",
"src/CelerisLab/common/streakline/__init__.py": "13ff1cfa416fdd721a08a659e76b5a5a99b8d3201add10a83b7b0bc654bc1eec",
"src/CelerisLab/common/streakline/_config.py": "a9185ef68e9c7b5d5a1dc0b04a28341e2ad91d13c145a7c106636a878cf0a605",
"src/CelerisLab/configs/config_lbm.json": "17e4311f1f250c6ece59177a8b6ff856b69a016c7c10267e774b030a0a390865",
"src/CelerisLab/configs/CONFIG.md": "41cafdbe525366c08aa9d0416ea026ccf0026ba7123b8a9b65f968a80d928e3a",
"src/CelerisLab/configs/config_lbm_three_cylinder_triangle.json": "eeb8e7149dbe4aa6b3a9562802735aa950750dfbe2d972a0727e788573afa817",
"src/CelerisLab/configs/config_lbm_flume_trt_regularized.json": "f4bba8e6a4339fc3c4eb14f6e2f57c4b22993c73703c773d853edfbe34736e56",
"src/CelerisLab/configs/config_body.json": "055f261f0828ca1d4f2bb694bd15b72bbcabe31d552326208f28e37f761adab1",
"src/CelerisLab/configs/config_lbm_flume_mrt_zouhe.json": "8f593321db05a563a42931603a228d61cbcba06dfbe113262d5cd0ad93c0fe79",
"src/CelerisLab/body/objects.py": "d1cf7054cc8379a83c39acc66a7c88ae62fa004f110bb0c1def2ee57137401c5",
"src/CelerisLab/body/action_smoother.py": "b1a23ee6bbd4850b172cb8738c5c3546ee465a54189e6af9d8044f023d4687dc",
"src/CelerisLab/body/registry.py": "fbb7327780adbdc6da15ebdb799980daf32df22ee974af0893d7409f177bbb68",
"src/CelerisLab/body/manager.py": "6a40be708c71ef6f3b5f5f0aa9c92cfafc51f2ec2a958f99656cccb850986c16",
"src/CelerisLab/body/ddf_patch.py": "60fcfb7441e73bf290bcff41ca3a83da3e7ddad765d7247464e8f02e3043b4e2",
"src/CelerisLab/body/sync_plan.py": "a73ac9ee361b2120d0b7bbebeaa2ccbf924ba27bd95d4dd4b383c10a39b2a409",
"src/CelerisLab/body/__init__.py": "91d1155080b3ade83d13c84c39693046df122e4bed5ef583de2df1f9453c1b76",
"src/CelerisLab/body/preprocess/flag_overlay.py": "831fc9e9736b758847759a085ff133eb49ec91318ace4fda76f85960138ee300",
"src/CelerisLab/body/preprocess/__init__.py": "dfd9d58bc07f626ab23a70053e31b88a6d9165d2e4c76a4e9f48abe674d3d2ec",
"src/CelerisLab/body/geometry/base.py": "cceca14361ca2f34d34a3e43730e1a79b8ca81be00f0dd62e884db32b479419f",
"src/CelerisLab/body/geometry/__init__.py": "ada88980ab672959aca9aa3a4c4aade3219524b2ab68110cd2a2f41e3e0ca90a",
"src/CelerisLab/body/geometry/circle.py": "7605ca7c21103f1d801ac73ab8dd18dffbdac425b2dee7b8858b283628a9e436",
"src/CelerisLab/body/coupling/soa_packer.py": "8ec26fd55ef74801bbd5ab6bd3d0a7dabc750cbd498aaac2ca4c61a0108ad3c9",
"src/CelerisLab/body/coupling/__init__.py": "c931f7eb318d48408c3e2febcc6917c88c8dcc1697cbf4329b1f340d94c35763",
"tests/conftest.py": "fa0ec26667872c9c1011d608310d2551fd24719b5d216f06d923ff4c74c73237",
"tests/specs/exp_ctrl_matrix.md": "5d9dd2e703582572eb68afe3a7096ea43ec82aa03418d20ed283c5365031e433",
"tests/specs/Sah04_validation.md": "1d122d29e281b7f50801b148f3314a0e35fdc27ee7d757c0a661243aa6185fb0",
"tests/specs/sah04.md": "33dbe5e0fd63738abd055c4aa403c191b6de04e6efdbc568f1942c6d23c7459f",
"tests/specs/Kan99b_validation.md": "0d8bf74f2361f863809af1979bf8807adaa423f98321e1104a3d86d8c7a863cf",
"tests/specs/kan99b.md": "b7e0669f0a6b677d902204f3427d1b3ac254bfe70c37d9cf995fb3e8f1fedfb1",
"tests/specs/streakline_notes.md": "cd342d214c07eb608ac2e5b8697322c44c31dbf4d27dfdb5409de46ef474df4b",
"tests/validation/run_perf_baseline.py": "93dde2eb1132f45ea69e1e285ff421dc97a83651a22c79571f299c1909650721",
"tests/validation/run_j1.py": "51b758a271ff358f931b3140a80082294a67e66c2fec0f8c19319e37f92aadc4",
"tests/validation/run_kan99b_rotating_cylinder.py": "323186429a100f36b41ab9b81ade2da6a47e93be3ccb7034a3a6b97f4ee8eb00",
"tests/validation/run_j2_slot.py": "b7d2d3aa06fcafc3ac62ed4a50892afbdb7f86e5720ce75a39ce317b6f571dad",
"tests/validation/run_j3_coverage.py": "329869519b7078e854d96241a7aad8ef93f35ac9be83f0be502c3a93523c3b13",
"tests/validation/run_sah04_st_matrix.py": "9b9c0ce063e07a316846635ee769b837ed26be6bf039f78f4219c10b516f8006",
"tests/validation/analyze_j3_saved_frames.py": "438f67dac682b94c4950626f8de4fdcde48c3a4e9ecf8fdf1b0ada4b6e0e781a",
"tests/validation/diagnose_j3_lags.py": "286fcd65b3261667a847b9b26e213d0af92cf459faa6bbd774f78c8479ce31d7",
"tests/validation/run_j3_reservoir.py": "47535bc3569ce68c888d38978bc4f9077fd763a17829c20c081be52bb18a2903",
"tests/validation/run_poiseuille.py": "e529288e2ffa8e00d281a9006723954d60a96ae4d025e8f28656c09287d4ff46",
"tests/validation/test_sensor_accuracy.py": "c6038a9e7a597a1738814bd15e6ecf357cfd271cdc2a132d47943c5280ac0ef9",
"tests/validation/multigrid/test_cpu_reference.py": "ade5d4827f971aed7174b59d83769e7aa542338e625a9fc8db1e8b1805cb74ca",
"tests/validation/multigrid/cpu_reference.py": "bba2a06a9f6517b32079ffff15e4060d8c3b7ed35f16ca134e1877226c9e4e1e",
"tests/validation/multigrid/cpu_reference_v0.2.py": "b6adbad7da625ef6a6b97958ea9625030ed92676d0cada48e061c87bcf7ca8c9",
"tests/validation/multigrid/test_open_corner_negative_control.py": "59a6f8ca80cdd63cb7827fbebf9b4b555c3793f19dd6bca801544ec10b5cbe1b",
"tests/validation/multigrid/test_refinement_followup.py": "6643e26cd877bf0d0f030e974f00a1d1c0f0350cc76d1c8affed3e8ba2f4393b",
"tests/validation/multigrid/local_stress_observable_v1.py": "0e2777990359a7cf2bb29884173b7b01de37c49bcf49e1f29fc59fe83d62b456",
"tests/validation/multigrid/test_refinement_gpu.py": "0021a39b3a131347196845cff6507c90c387b46b772fe1319d634178c5e13354",
"tests/validation/multigrid/shear_diagnostic_v0_2.py": "a8b1cf2f7abd00efc4d068bbd27bb2317144a6ca4c545d9b2e0dcf421eadebc6",
"tests/validation/multigrid/test_tron_additions.py": "8e7a6a90b85e64c7326719e7b8bca2f6d34fb4c80690f0685f7e291ab93bd2a4",
"tests/validation/multigrid/MULTIGRID_VERIFICATION_STRATEGY.md": "d4f3473da44abee6031a0e1bd4d0ca589077a18f15d2461836e4d2ebb98e458a",
"tests/validation/multigrid/shear_v0_2_evidence/stdout_horsea.txt": "0577df5b3f5cb3c7b6e1ef2de71344f8fd3e6d959117487a06cbaf7f2afa3dea",
"tests/validation/multigrid/shear_v0_2_evidence/stdout_grok.txt": "28ddd1267ca91a772f5a6bfc65d949c9a4ea7dac5c9ba3a0bdb168492810b670",
"tests/validation/multigrid/shear_v0_2_evidence/run_once.py": "6698a2e040c56be949b809387d4518eb0ba82d34cc9d99640da4f8bf3c35c23f",
"tests/validation/multigrid/shear_v0_2_evidence/source_manifest.json": "56fbd0259ff3d4dbd14ace52f64e249a435e9df91732b0e4027def2c344c2e6a",
"tests/validation/multigrid/shear_v0_2_evidence/results_horsea.json": "c2d7ce8d16a0f47baff0788a153353dcf67088da974d9cd3d521b04ecd91ee05",
"tests/validation/multigrid/shear_v0_2_evidence/comparison.json": "41c00372099dd04b6d323785e9eaf4fec09da1753d3d150ffa230800f904142f",
"tests/validation/multigrid/shear_v0_2_evidence/baseline.json": "98a7853341ea732762c7506694e3a867a7259bf110e9e461ea84f741fd9ab829",
"tests/validation/multigrid/shear_v0_2_evidence/manifest.json": "e42aa19e91608164698bea42da88fbbfab8b0f87cc37b27c5baf165453a4fdb0",
"tests/validation/multigrid/shear_v0_2_evidence/README.txt": "4306a34b6896bd6e7a5c2ca71d68e18450359239d0c7ad7a67a4e83e7155959a",
"tests/validation/multigrid/shear_v0_2_evidence/joint_report.md": "1860b8082108c8b8a87998af90cd0b81dce1c04e9f6c67b41e0912f9fef6cc9c",
"tests/validation/multigrid/local_stress_v1_evidence/stdout_horsea.txt": "882f2cfb1dbdf82cce63c011397e7c2e6307bbcfec42a3510648d328cd6ddcfe",
"tests/validation/multigrid/local_stress_v1_evidence/run_once.py": "e629800291ef65ffea8555f66ec80bf15200552540b2a493a677bfb53d0830b3",
"tests/validation/multigrid/local_stress_v1_evidence/source_manifest.json": "d2cf90b73458f493c665c9a281d06aef0c190cf0d143639fb77ab838c78f020c",
"tests/validation/multigrid/local_stress_v1_evidence/results_horsea.json": "f17b4644d19eb75d55deb7021ab679cb9e7922a2b46f1cacf8b6da6bfb9a2690",
"tests/validation/multigrid/local_stress_v1_evidence/comparison.json": "be236671a501c31c06f7e266f6e0c0c2a89aede321a483452050ff37bf84c84a",
"tests/validation/multigrid/local_stress_v1_evidence/baseline.json": "64f6541447afbd15b1b15d802ad6f1b5042aaf84e7d4d2414e4ed4c52cf70507",
"tests/validation/multigrid/local_stress_v1_evidence/manifest.json": "3a9fa8c7d691c1b8c24f05940eb724d30b890dd8ed636551068d2633d7db2f70",
"tests/validation/multigrid/local_stress_v1_evidence/README.txt": "4f62314876047ee437bb9ecbf84798d2a9f6e85f6a3aef260277b85bcdb35fae",
"tests/validation/multigrid/local_stress_v1_evidence/stdout_local_stress_observable_v1.txt": "6a826e5ad729ce45af6879a07a1c659d8b4a21403fde5b9c6d9696cc6a5b09d4",
"tests/validation/multigrid/local_stress_v1_evidence/TABLE_local_stress_observable_v1.md": "d8ff0568d9c473a4bb09396a8948ddc8dc5af2f0f3a23ac84d238814fc779501",
"tests/validation/multigrid/cpuref_0_3_evidence/stdout_horsea.txt": "457f1d2173496554c87ca6e61df518c0b8f1e0a28cdfd94b94ebbb61bc459d70",
"tests/validation/multigrid/cpuref_0_3_evidence/stdout_grok.txt": "73e4ef01138842981daaa534390f1463839e63833c11f4e8872f94f8eaadc717",
"tests/validation/multigrid/cpuref_0_3_evidence/results_horsea.json": "914389afc39752bcd4132aa21fc8d5cbcf0ca75b1efd6a49becab15c2fa3361b",
"tests/validation/multigrid/cpuref_0_3_evidence/baseline.json": "0daaccee41cabeb17a00e2405e2c7fd0b80d36f2d01778eb39c9fd22b13d2d47",
"tests/validation/multigrid/cpuref_0_3_evidence/manifest.json": "2850ecaf2e19d010ba35eb54162371d82cc1a092831e08a03b6adf75a614988b",
"tests/validation/multigrid/cpuref_0_3_evidence/README.txt": "1947ee0232b88b3cc2c506d0b0af5ba051ecc94aa8f7f09228ef3939cc95919b",
"tests/validation/multigrid/cpuref_0_3_evidence/README_grok.md": "065947e15b2242bce7d3eb05a3acdbb59939c621dcd5d31540ad4a1bd4416818",
"tests/audit/\u5ba1\u8ba1\u62a5\u544a_kernel_layer.md": "89893c98ed7c2699157bf728ec0e79b0dd6aff4008ee5c7b77eb052de24033f1",
"tests/audit/body\u91cd\u6784\u7b14\u8bb0.md": "8f978d7b01c9f49dca9eeaff0d163cec6da085e2f99ee5a5e803d72306e7a72f",
"tests/audit/\u517c\u5bb9\u6027\u6d4b\u8bd5.md": "9c1721a33b381b9c3810545772b022913da06617711b5ba13a3c2c991b81a7f7",
"tests/audit/Force_region.md": "3092080afe4a30665fe1b721803621ba9d0dd5d20ad17826984d94efc160fdac",
"tests/audit/\u5ba1\u8ba1.md": "0f14ad073a0725134e6391f961c324fd0013c7791fd410713e94ed1ad40b7385",
"tests/audit/Force_region_validation.md": "279a4484d1bfca0fd67aed4de3282d547aa048f89389420d8e5f2fd86db54fc2",
"tests/audit/body\u5220\u51cf\u529f\u80fd.md": "e9f308a8cd0f0e7df5441c32a15f84c0bae50bc0e56b8728f6c6f2cf78596673",
"tests/unit/test_initializers.py": "8b4e3358d925614984265ae73c142006b48fd1c3918cf84901f18afd9fe68c3a",
"tests/unit/test_simulation_lifecycle.py": "77abdc33218c35e9c8b62dbd99ceddbaccd8417e7f0b539ea8859ea0175c663a",
"tests/unit/test_numerical_operators.py": "6d1d560ef553a2af7adac7db3e325d96d7fe39073d5fe3e0e982439537385b27",
"tests/unit/test_sync_plan.py": "983313ef783143231fa5a392f85f3bac011184773ccaf5d946504c206cabb721",
"tests/unit/test_surface_actuation.py": "89be6f54c4eba6c2bdca0d287a5b9fa6db143de2bcd9a671d4fb8445921303ed",
"tests/unit/test_state_regressions.py": "0f69cfeb83428192f95688c76abcae7e5b9cf5f27c52bca4ac20c7f320044374",
"tests/unit/test_equilibrium.py": "1ecbcc4547b1c846b75320463d828d6a36b6aae73208084fae476b1001c1bb50",
"tests/unit/__init__.py": "17f57920d9c1ff46096ceb2af008eb38c4b98dc81ffa3c3d310e758e80ca1cd4",
"tests/unit/test_pending_edits.py": "905a0dff23b123e8e38aaf364984c810fe51c39acd64aa271e343a4701d3d024",
"tests/unit/test_planar_velocity.py": "b656da0880b4234b1db805544edbe0d2473cbcc7c2c869c71d8251337f62a982",
"tests/unit/test_body_flags.py": "ac6409157924e15a13a3d2cc2f1a09014b8b0198ba17c824f412ff20b19e2aac",
"tests/unit/test_build_contracts.py": "7bb237425e8bb481f312fa4841c484e280731e13c7cbb9a53dad3e7f98984ac3",
"tests/unit/test_context_ownership.py": "299fed30dd0f9bd4dadd8b27f50df2a6367bdb0ab2ca3f391f215fde7241f35a",
"tests/unit/test_reservoir.py": "e718c78a53c3941aba7feb8ae4e8bb0b1726c1145de84febf91220c1917991c9",
"tests/unit/test_refinement.py": "90751142f920f1c5e988577a45afa94871a6617009cdc78323a87fc7795f4634",
"tests/unit/test_slot_velocity.py": "6a9494de9a32c350389ccbed58af48951f6b25a21a258537d2e8b73eb67cb11d",
"tests/unit/cpp/semantic_regression.cpp": "99dba074c0c0a32ea76026e7d54fc60af8e6d3dc5315c8900c470b4518878f39",
"tests/unit/cpp/reservoir.cpp": "c3eacaf0271400eb45ad559b571a8f7faa2a809d5f1857ffeb5592addce2cd0c",
"tests/unit/cpp/collision_regression.cpp": "f17acdff74ab82a62dc5402b42e3f6a149c262e89b140494164d6ebd630f5e14",
"tests/unit/cpp/slot_profile.cpp": "31ac58ccab175bf79fa59fc46d4c0842df18ab0a5e5916be84760d9da2b75788",
"tests/unit/cpp/planar_velocity.cpp": "8dea266984edc69d4e0e68007e038d7a587e99f84e33478d6656a66a56680933",
"tests/integration/test_body_sync_e2e.py": "d29f01771f3512a4b3ad06fae4ee952327d7fd9f0476942402fe92e9e327fcec",
"tests/integration/test_sync_bodies_skeleton.py": "65f55a0980659b49ae0027f0642a27e2ebaead226ef083f233e878150884b07c",
"tests/integration/test_numerical_gpu.py": "002a6745929bd5ee86a9491ea9bc3f97602fb825ea17262ea190c9311881100e",
"tests/integration/test_ddf_patch.py": "dda2abba32ca13e17098232f2831a0b1b66439c35f8931d9997a0257250c1281",
"tests/integration/_cases.py": "ab76ca1096d2d10fb05b3539aa8ed3c7e549619bae6900ac98723f6c3c908f2d",
"tests/integration/test_surface_actuation_gpu.py": "3c2b4dda70db1d6493ecd92bd9b0dad6d8b438cdf6dca46410018217f8beb4da",
"tests/integration/__init__.py": "c354e43ba09b55a8013a2df2069438740b5f48b5917d855e52e33ab5d7da5a6c",
"tests/integration/test_state_gpu.py": "dde0948941e8abbc5ea10a3acb3a35abbaea576f36ecee0f1120fbcf7454d60b",
"tests/integration/test_runtime_contracts_gpu.py": "775e578e2e8072af32fc740b2698abbb79454235a0f3ee929ac4c75d747f8db5",
"tests/integration/test_unified_obs.py": "4a681536099741d92bdc258525fe3374cbdbeba0d49996e53808381a1b6a13fa",
"tests/output/exp_ctrl_matrix_streak_ny300/summary_C4_deceit_f1p5.json": "11dab8440d8c4f385061d2536403f4313c6f026b4e0b7672681327a9f4f37ebb",
"tests/output/exp_ctrl_matrix_streak_ny300/summary_C6_deceit_f2.json": "e0c4e8bcc55da5dc8de1e2fe88029aa3e67453734faa44451f5a6dfa9131557f",
"tests/output/exp_ctrl_matrix_streak_ny300/streakline_C6_deceit_f2.png": "e0a66708ce2a29c4c6b854d2596b3ffca181dc6e35d99cc94e08af3e2d8c024e",
"tests/output/exp_ctrl_matrix_streak_ny300/summary_C3_deceit_multi.json": "24c8e433aab6d207dab67546c4079868c4244c2948c32c94cd08e4f331991807",
"tests/output/exp_ctrl_matrix_streak_ny300/summary_C0_no_ctrl.json": "cf3af733a08f081cc5f879e8da79d7c60104099f4452af5b2a4a96c0e6bd5889",
"tests/output/exp_ctrl_matrix_streak_ny300/summary_C5_deceit_multi_f1p5.json": "a4cb4ff4481b39b9ee61b1d7209416237a7fe86b22c5068d713ccec9c3f7afe4",
"tests/output/exp_ctrl_matrix_streak_ny300/manifest.json": "d8a20dacc92321d98354684976f771a9ca8989fc63ddcd78e15c7768c6617671",
"tests/output/exp_ctrl_matrix_streak_ny300/streakline_C3_deceit_multi.png": "c6fed617cc6ffe6677157a9b58811d5f4613725eb98a5aec830fd07dc1aac38e",
"tests/output/exp_ctrl_matrix_streak_ny300/summary_C2_deceit.json": "7526a6b20a158461b85b1a64070b46c2b21be1e01c5ee025e6746fcf47ea3397",
"tests/output/exp_ctrl_matrix_streak_ny300/summary_C1_stealth.json": "63d34a0ab33e9fa8fe7311363efbd1b2875691f5b4958bb645b8c7ac38f1ad6b",
"tests/output/exp_ctrl_matrix_streak_ny300/streakline_C0_no_ctrl.png": "0cfd7ce8f9d743bf22a7a694b4e5a3616557cb8f1db2f4ddf49cc4bef96efef2",
"tests/output/exp_ctrl_matrix_streak_ny300/streakline_C4_deceit_f1p5.png": "4dcfc186928dcb83d28e9eb4cb2ecb4b163eb6f121d57036b4c05ab162be0951",
"tests/output/exp_ctrl_matrix_streak_ny300/streakline_C1_stealth.png": "5e3cbbefda06fcef243d7d06d74a473972350cfa4ae88bdfdb349dce13943151",
"tests/output/exp_ctrl_matrix_streak_ny300/streakline_C2_deceit.png": "22f1db77499bdbd1b3cd35f5b58b1a884dd94a86fdcfef07abd4157e6aaf8d19",
"tests/output/exp_ctrl_matrix_streak_ny300/streakline_C5_deceit_multi_f1p5.png": "823e475cc901af3d6f4d0c56eb07822b3e73a2b9d0aa23e20e3741023fe90092",
"tests/output/kan99b_validation_esopull/summary_runs.json": "fe3294a953580204319fb1143434e15096d8455b6073100dfe0d5491b76af394",
"tests/output/kan99b_validation_esopull/summary_runs.csv": "1a44bb27ee0a7fe0270905248c37364834248cdc8710bd68142a6a79bbdad82b",
"tests/output/kan99b_validation_esopull/force_csv/k2_k2_inlet_control_domM_re100_a1p000_zou_he_local_mrt.csv": "9fbc7d507c129ed85c68a9a313e3eb3431470d091bd7723e63f8afd8a3d2b737",
"tests/output/kan99b_validation_esopull/force_csv/k2_baseline_domM_re100_a1p000_regularized_mrt.csv": "8faac43f42d6e0c70085c6e616bfff4df8de897e315fc0d2b4aa8bd635c3fa05",
"tests/output/exp_ctrl_matrix_vort_nx1500/summary_C4_deceit_f1p5.json": "b613ae55fcfbd45a1a922d6d529e5274ba9d2987fdf5620fe866b889b931e48c",
"tests/output/exp_ctrl_matrix_vort_nx1500/summary_C6_deceit_f2.json": "dbf54f9a183072547b22fa14334f0167e6eefb21c1208c4e8584bc196545a399",
"tests/output/exp_ctrl_matrix_vort_nx1500/summary_C3_deceit_multi.json": "2100c6cc5c358a249804ce8f6f98531f3bc868e27af6d21a9d441b1b6a9e479e",
"tests/output/exp_ctrl_matrix_vort_nx1500/summary_C0_no_ctrl.json": "a8b4697b7c0caeb958f80e282e32d673deac8c914008d64e6b38f7883eacc57e",
"tests/output/exp_ctrl_matrix_vort_nx1500/state_C6_deceit_f2.h5": "8d0c28566d2230b422691b738cc453705496bd150be038a576c0c0fba218fc1f",
"tests/output/exp_ctrl_matrix_vort_nx1500/state_C5_deceit_multi_f1p5.h5": "608767ca11d104fa4506b57204a0c8dbd739688224ebd924fe517ce9e21db823",
"tests/output/exp_ctrl_matrix_vort_nx1500/state_C1_stealth.h5": "a83c988cc8b1173a7b2f13b132ed7243e98304dccab2965aa16cf4d32f8df007",
"tests/output/exp_ctrl_matrix_vort_nx1500/summary_C5_deceit_multi_f1p5.json": "6f6b9300782178e0ac9308a677bd9cb1565a383a78dff4cd52dea0bd464db31d",
"tests/output/exp_ctrl_matrix_vort_nx1500/vorticity_C6_deceit_f2.png": "21bbe2dac1ab06ca1b172ec62d00daa7bcd65d99adac0ed03c5e30bed59e871a",
"tests/output/exp_ctrl_matrix_vort_nx1500/vorticity_C5_deceit_multi_f1p5.png": "602a6586277699968b4cb167b134c8c406577038af088aa70baff682691398c4",
"tests/output/exp_ctrl_matrix_vort_nx1500/vorticity_C1_stealth.png": "c1e1d04f266deac5fb2815a8283da80f9139ffaccbec2219d98544296bf3152c",
"tests/output/exp_ctrl_matrix_vort_nx1500/vorticity_C4_deceit_f1p5.png": "96dee924e89b90091192a8d7b43321f109a5491511b8a83da77cfc611ae0d93b",
"tests/output/exp_ctrl_matrix_vort_nx1500/state_C2_deceit.h5": "aa5800a0cd594eeb7cf5449d6469d55e0c9033ced0ee0a3b5d59152e68c7e263",
"tests/output/exp_ctrl_matrix_vort_nx1500/manifest.json": "5d28f0f5428d7f0341e20d5d1f19c17bbc6f0f9b2a441d3c95f5422f3f2b4bd4",
"tests/output/exp_ctrl_matrix_vort_nx1500/vorticity_C2_deceit.png": "1dcb6fb959f944d7ad89c4abaaef4d1fd4a77db8901804530e86fb336b883eb5",
"tests/output/exp_ctrl_matrix_vort_nx1500/summary_C2_deceit.json": "b88ff5049aef59876b349d105f1c3467c17c9ba9022a48a77a6984f20da34345",
"tests/output/exp_ctrl_matrix_vort_nx1500/summary_C1_stealth.json": "515689cbfaa30a9e39d9907939ee194a4836b644a5e9124586e6b7221d2b394b",
"tests/output/exp_ctrl_matrix_vort_nx1500/vorticity_C3_deceit_multi.png": "d69694a1a1b2f2ea0adc7b74b7526504e2ad0b5d6317bac9b3159b2e7e88cf90",
"tests/output/exp_ctrl_matrix_vort_nx1500/state_C0_no_ctrl.h5": "3a858d6be0a946e1d26bbfa192c2f0ca3910c0f140b42575ec9d9529dd99155a",
"tests/output/exp_ctrl_matrix_vort_nx1500/state_C4_deceit_f1p5.h5": "660e4619ea530dcd18c3afb2e7fa22cafd9cdba1be7888e31ab5b76a0902d2fc",
"tests/output/exp_ctrl_matrix_vort_nx1500/vorticity_C0_no_ctrl.png": "6d4d3934f1c8b20c2a5c742ae080a7143f0c139741966adf009a227c27e9bb1f",
"tests/output/exp_ctrl_matrix_vort_nx1500/state_C3_deceit_multi.h5": "1e72126f11b2995437cecb8cc0eeffb8807efbfa43d8f346f28711fea98ddc90",
"tests/output/kan99b_validation_ref/summary_runs.json": "449316c30585a8de9997538dead5d4e35a59bf00a2ac22d01b101ab600a4bc06",
"tests/output/kan99b_validation_ref/summary_runs.csv": "e8b9620f3772e5e421026103e456e6e844a91292f40affb96174c9dbde9b6e4e",
"tests/output/kan99b_validation_ref/force_csv/k2_k2_inlet_control_domM_re100_a1p000_zou_he_local_mrt.csv": "4391f41d17ebeea1092f13b901923ced4ee2a1c5b346b79ef791d692847286b5",
"tests/output/kan99b_validation_ref/force_csv/k2_baseline_domM_re100_a1p000_regularized_mrt.csv": "105c6eb21f1943d9d935246eab1602ff2016c415a139e24fee2793e88e006ead",
"tests/output/exp_ctrl_matrix_vort_ny300/summary_C4_deceit_f1p5.json": "0085a679a423621003eea81d4ac83bfe2edef2879eed7809d2a3675a212f791a",
"tests/output/exp_ctrl_matrix_vort_ny300/summary_C6_deceit_f2.json": "e820cf73f0e90bf93c34b24416e7692a6c2e51352ccf490fa6714d0812331ca2",
"tests/output/exp_ctrl_matrix_vort_ny300/summary_C3_deceit_multi.json": "571370c74ad9af589f3dc214669bff3d857efe6fc4fa13815b5d793d12b53770",
"tests/output/exp_ctrl_matrix_vort_ny300/summary_C0_no_ctrl.json": "ec5b89961033d8ebe0d66ce1ec7940dc2faf98130c38319bc9984ef654e60b50",
"tests/output/exp_ctrl_matrix_vort_ny300/state_C6_deceit_f2.h5": "2792be74d8564fa29fd0636fc8493630fba2779c165b44330197095b3e296b18",
"tests/output/exp_ctrl_matrix_vort_ny300/state_C5_deceit_multi_f1p5.h5": "2c64ee6c7a4ea2c42ed8f3d274402bec62de0e02ea0340e16022f0cdc92af724",
"tests/output/exp_ctrl_matrix_vort_ny300/state_C1_stealth.h5": "100727d94fe6c2e46d7807eed0442555bdd1e26ec9b04b4c457171a2bbba3255",
"tests/output/exp_ctrl_matrix_vort_ny300/summary_C5_deceit_multi_f1p5.json": "f86166f121b4eeb6d74d8176c9265e7a3ccfe2540d040f554b6f96e6a6222c16",
"tests/output/exp_ctrl_matrix_vort_ny300/vorticity_C6_deceit_f2.png": "fef4de0e3ac8203742f35c16a02445b19c3f556b11f73abd5d8e3ca05ca33d78",
"tests/output/exp_ctrl_matrix_vort_ny300/vorticity_C5_deceit_multi_f1p5.png": "9136448e6d7565ca5af3666f9cf6e154342d8a3475076abfdbdd1ff9faec34f3",
"tests/output/exp_ctrl_matrix_vort_ny300/vorticity_C1_stealth.png": "544537a9c500a05937fd3be17c25e7d887461d9b83a15564f9ab7063208f40f6",
"tests/output/exp_ctrl_matrix_vort_ny300/vorticity_C4_deceit_f1p5.png": "51e7056db99dd653affbe913d52fa41df6ec0db921109384e3c679bda06b5a83",
"tests/output/exp_ctrl_matrix_vort_ny300/state_C2_deceit.h5": "39d6c162085acae1612650da37d2314757715931e83a854e08bb01407d0f8efc",
"tests/output/exp_ctrl_matrix_vort_ny300/manifest.json": "05fbc2e7bbad4267a38e1094bbdd6bee6ad270412bdb5e92b0dfc9fa56969517",
"tests/output/exp_ctrl_matrix_vort_ny300/vorticity_C2_deceit.png": "07fc5817eba30371272b87ee2e023c0a1144077d1bef77efb2fd5dc284badcb7",
"tests/output/exp_ctrl_matrix_vort_ny300/summary_C2_deceit.json": "b1fcf76039c91a9080b830352dee2e95316d754b968cc27a8f68c51527661e76",
"tests/output/exp_ctrl_matrix_vort_ny300/summary_C1_stealth.json": "b78851637b9b7b93070524a2933cae1dab6d682f8894579b2849c64921e6c29e",
"tests/output/exp_ctrl_matrix_vort_ny300/vorticity_C3_deceit_multi.png": "2658f0747ed7287f7912fe15cc58a086e01ba284277cb98689bac01ecb6ec12b",
"tests/output/exp_ctrl_matrix_vort_ny300/state_C0_no_ctrl.h5": "57f73f5f8dc4b32b156bc82300b1efd1e4eddadd9b8dc51cb7e6b41fa5c966bd",
"tests/output/exp_ctrl_matrix_vort_ny300/state_C4_deceit_f1p5.h5": "2864b9dd086709ee8b8c3f262118a5130b0d40c86838f3ca0deab5bb898dafa8",
"tests/output/exp_ctrl_matrix_vort_ny300/vorticity_C0_no_ctrl.png": "2c7f3a8be2ee540afdfb66299e43a65583434bee84bde590124524a82868c900",
"tests/output/exp_ctrl_matrix_vort_ny300/state_C3_deceit_multi.h5": "39e0d9b032dfff8cf057b410a98973729285e7d03e89f9a6a002aaf7de3d7519",
"tests/output/stealth_sweep_fix_check/summary_stealth_s150_w0.02709.json": "8b1032e13975bb05c6a810fde175c8da51bacdb3dc745fd11c1049ca63bbf136",
"tests/output/stealth_sweep_fix_check/summary_stealth_s050_w0.00903.json": "fa7da24d5dab9fd3a3c2dea6b50d0224c7a99cd9141796e137304a6040b1ac8a",
"tests/output/stealth_sweep_fix_check/streakline_stealth_s050_w0.00903.png": "640928f7eb159e7caea32036123f86c281723d083cca46839ba86bce8361ada7",
"tests/output/stealth_sweep_fix_check/state_stealth_s050_w0.00903.h5": "187ac365f9f7370c888c4c65570c47e42465b2fccd432056c176528d45cf0c2f",
"tests/output/stealth_sweep_fix_check/manifest.json": "83a3f12a942fb644e470bd07a72f24921f2147d7df429110268c5c96a9953d1a",
"tests/output/stealth_sweep_fix_check/state_stealth_s150_w0.02709.h5": "e057e9db26b2546c0704e2c959cc7d2aac91e6a49b4c7ee75a409597a5db8716",
"tests/output/stealth_sweep_fix_check/vorticity_stealth_s150_w0.02709.png": "d2d202088624cf30868228f9c913ee30e1b386aaa2c22b0ea89be43dedc0712d",
"tests/output/stealth_sweep_fix_check/streakline_stealth_s150_w0.02709.png": "0edc7caa9caaffb754490bf1f6ac7ad7180e45a991439a3f4f83ed949a082a1a",
"tests/output/stealth_sweep_fix_check/vorticity_stealth_s050_w0.00903.png": "4088359b17c46ed4d7c8401d244808fe67723273b1d16d0671b69f9478c68c1a",
"tests/output/final_validation_round/validation_summary_report.md": "881cb7052e5a555afc87168a37268ee66e8e3fba172533706e858d996fabc7b9",
"tests/output/final_validation_round/sah04_mixed/s2_d48.json": "83c6c01201d90aae5c49e73ebeca88d1c7ded6cc83c13f4892a9188e6289483f",
"tests/output/final_validation_round/sah04_mixed/s4_reg_d96.json": "b32f03e6b347fc709cea2ecd488df0f85849c733bf6a4b9cf65ea69401c93a1d",
"tests/output/final_validation_round/sah04_mixed/s1_d48.json": "120e8e878f5712dc89b7cf78c7f8d0e3368d34ad5ef7494977e083b188a54c18",
"tests/output/final_validation_round/sah04_mixed/s3_stablecfg.json": "b38a3d197a188e65c163d974113af18f332b3abed083e2654e998d9980f6be9f",
"tests/output/final_validation_round/sah04_mixed/vorticity/s3_mrt_laststep.png": "dc96fcd05d458684cfb40d4cb741172213083e2f2665e2bae7e1f0267bb3575d",
"tests/output/final_validation_round/sah04_mixed/vorticity/s1_mrt_laststep.png": "73a3580ba3c7fe6ffeee4676a9a51b5bf678d6fb523456a61e185598389ea1e1",
"tests/output/final_validation_round/sah04_mixed/vorticity/s4_mrt_laststep.png": "57f2a82761f2de1a9fc2b78ee86159ca542c966494b9c704deb451da857da778",
"tests/output/final_validation_round/sah04_mixed/vorticity/s2_mrt_laststep.png": "786f492b96ed932254b5452e2d06ff088727f2d88c7e7c7b47d386eddfe07862",
"tests/output/final_validation_round/kan99b/full_summary_runs.json": "8c4a11cbf555e08a66698439170b850c57d537d8e75e4dd75beb767bbf7e38cf",
"tests/output/final_validation_round/kan99b/summary_runs.csv": "3fa92fdd3114f0472de44bc03006af1d4b694dfc69b06704c1667cd3627b6dab",
"tests/output/final_validation_round/kan99b/force_csv/k5_baseline_domM_re160_a2p000_regularized_mrt.csv": "de05e9699146f2adffc9d7c9991f9e48396aacd142afc3c08b2b64727c83c69a",
"tests/output/final_validation_round/kan99b/force_csv/k3_baseline_domM_re60_a1p600_regularized_mrt.csv": "53cd0dc47328b7b370eced1130508655e6815a29b727bf1fe4e4e125e4918905",
"tests/output/final_validation_round/kan99b/force_csv/k2_k2_inlet_control_domM_re100_a1p000_zou_he_local_mrt.csv": "4cac1ccfdb7451de3e26d921a6406cc55d1d4630e10ec0d7ec9350a4abd49404",
"tests/output/final_validation_round/kan99b/force_csv/k4_baseline_domM_re100_a2p000_regularized_mrt.csv": "392c98de52011ddb344a5761c4520e870f4e49bbba3e144e5a02818ba2f9250b",
"tests/output/final_validation_round/kan99b/force_csv/k1_baseline_domM_re100_a0p500_regularized_mrt.csv": "9e83c5175aec644c0b97c081e610deefa731b87aef04da6297abf662a71c0702",
"tests/output/final_validation_round/kan99b/force_csv/k2_baseline_domM_re100_a1p000_regularized_mrt.csv": "55b071f278e153aa353aa2bef85f0bce35b910a7b08103032023fe3a28169b89",
"tests/output/final_validation_round/kan99b/vorticity/k2_k2_inlet_control_domM_re100_a1p000_zou_he_local_mrt.png": "b91b332e7deb787975d3f08fa3325facd4a972b536694fcda52e6c01943c42cb",
"tests/output/final_validation_round/kan99b/vorticity/k1_baseline_domM_re100_a0p500_regularized_mrt.png": "6e7c3f6567c0ff0d00d75da8373031f5ba2a17a624cb8c5d5d6ae4f8749c33c0",
"tests/output/final_validation_round/kan99b/vorticity/k5_baseline_domM_re160_a2p000_regularized_mrt.png": "c4d232df2e6f7466acca711191d976aa9411ec0ade81572b531463f42a7d633a",
"tests/output/final_validation_round/kan99b/vorticity/k3_baseline_domM_re60_a1p600_regularized_mrt.png": "b2314c60491d20933422e1697998555dec2436d39545c71f990e9906884685b2",
"tests/output/final_validation_round/kan99b/vorticity/k2_baseline_domM_re100_a1p000_regularized_mrt.png": "2b2797b8f53170d04d1a70d1cdf898f7e41b3a76b9f3c1f276dfec952520ab04",
"tests/output/final_validation_round/kan99b/vorticity/k4_baseline_domM_re100_a2p000_regularized_mrt.png": "8135f470404fe11ac97968fa580ee35232e90dcace3c6ad94de17ef7aace24d6",
"tests/output/kan99b_validation/summary_runs.json": "d7239aac64884202558741074f2d644ade9e2365d94d0b7556fba68dac94868d",
"tests/output/kan99b_validation/summary_runs.csv": "c44da69563d58b917291a9fd402d1f57055861bffab6f9e32d7db91297428d45",
"tests/output/kan99b_validation/force_csv/k5_baseline_domM_re160_a2p000_regularized_mrt.csv": "27b64460923d235d34b760f2a2371ad01611a70e38edb03d6fd6a2fe7a7de6e0",
"tests/output/kan99b_validation/force_csv/k3_baseline_domM_re60_a1p600_regularized_mrt.csv": "76ff52f4494b7ef7650c05968732a8caaba94d2b151234c02cf624f5b3a712ab",
"tests/output/kan99b_validation/force_csv/k2_k2_inlet_control_domM_re100_a1p000_zou_he_local_mrt.csv": "28a83436ca8bdad38865ba21ce1bda679562a5ae1cfc6ee8fc6e86ff760ec66d",
"tests/output/kan99b_validation/force_csv/k4_baseline_domM_re100_a2p000_regularized_mrt.csv": "823ae04870fd951879024a18169ac5cba8db4b3201726f6a00f320f1958d04c6",
"tests/output/kan99b_validation/force_csv/k1_baseline_domM_re100_a0p500_regularized_mrt.csv": "a591daf2cdecd6ac3689fa2a2aba917b23053ad26e3ef1f635c81aecc451475f",
"tests/output/kan99b_validation/force_csv/k0_baseline_domM_re100_a0p000_regularized_mrt.csv": "e95c27c646c0c9baf8f455f876c115c8dbdb23cef9d9d550f455098bf0c03b55",
"tests/output/kan99b_validation/force_csv/k2_baseline_domM_re100_a1p000_regularized_mrt.csv": "3c2ea79a0e27f561215febee2e165d24b3617a648bf908981c068ba59d549c51",
"tests/output/stealth_steady_sweep_nx1500/streakline_stealth_s125_w0.02257.png": "a892f18c74fe13efd839bfd5068097ca0ae07acebf6c06eed89e1b867e41fcb2",
"tests/output/stealth_steady_sweep_nx1500/summary_stealth_s125_w0.02257.json": "7e542f59746429022ce1794854c6fb36e8ac658dd0aea3bc1140a45e83a3f1c9",
"tests/output/stealth_steady_sweep_nx1500/summary_stealth_s100_w0.01806.json": "b76216e0fbee00ef754edbafe5790a99ce7d53638af629947ddd9615598e4c08",
"tests/output/stealth_steady_sweep_nx1500/summary_stealth_s150_w0.02709.json": "42cb241d9cfb01308ce28e129756b6cb3fe2a8e9679518da84bcb8b607fe92ac",
"tests/output/stealth_steady_sweep_nx1500/state_stealth_s075_w0.01354.h5": "558be308dbf334832bc1d29419ba5be142969117a11b124864f6b221c8fee509",
"tests/output/stealth_steady_sweep_nx1500/summary_stealth_s050_w0.00903.json": "53b579811a0b651ba7cc466c230c115b9f88486c6675e0465d0715d3377a75cd",
"tests/output/stealth_steady_sweep_nx1500/streakline_stealth_s075_w0.01354.png": "9f4a7d89b2471becaf31e84c14402441c5fd96fc7190cea5e8a9fdd06ee62002",
"tests/output/stealth_steady_sweep_nx1500/streakline_stealth_s050_w0.00903.png": "5f18f56b0ff2af3350216b65540a2bc664c569520624cfc6cc2439a3c5369560",
"tests/output/stealth_steady_sweep_nx1500/state_stealth_s100_w0.01806.h5": "30776f333959e0e9eb5ca96b269e6a8052c5b94941a4e3b36d8a6af8076920ce",
"tests/output/stealth_steady_sweep_nx1500/vorticity_stealth_s075_w0.01354.png": "b5393474d99191e88dafea4144b6a8eccfbdf75107125ce4b05383b17007d06a",
"tests/output/stealth_steady_sweep_nx1500/state_stealth_s125_w0.02257.h5": "4ed9d8587f75ad4625ec5501fa99fb733cde037180ac53f92a210ffbb08375de",
"tests/output/stealth_steady_sweep_nx1500/summary_stealth_s075_w0.01354.json": "ff1c1cc649e589b5425787493c2b0d04b6c39b43043b1968d65509cb0a426e82",
"tests/output/stealth_steady_sweep_nx1500/state_stealth_s050_w0.00903.h5": "4de51584b24095f8cf4480b8941593a5f913332f9396061ed077c9d49eb2ee11",
"tests/output/stealth_steady_sweep_nx1500/manifest.json": "0dfbb2c1b5bf9093fef169e4dc6319edb5c87a1e967e8d558613e2c64a2ca734",
"tests/output/stealth_steady_sweep_nx1500/vorticity_stealth_s100_w0.01806.png": "60824cbdf21170cb4ffd8af0a49e8522c2d79cb2694690ab67995ee973265efa",
"tests/output/stealth_steady_sweep_nx1500/state_stealth_s150_w0.02709.h5": "b22d54a05cbd3138a1fe585a825246989fcff7c00f51aa9312a4185d963db933",
"tests/output/stealth_steady_sweep_nx1500/vorticity_stealth_s125_w0.02257.png": "c1e1d04f266deac5fb2815a8283da80f9139ffaccbec2219d98544296bf3152c",
"tests/output/stealth_steady_sweep_nx1500/vorticity_stealth_s150_w0.02709.png": "bcf098083a73798dc3906807218058cc571435a010234a5a350b585ba9915c78",
"tests/output/stealth_steady_sweep_nx1500/streakline_stealth_s150_w0.02709.png": "3bac21cc75a01429399cec308d6bf5fc8918917def1bf5d7fec1cb6003390a41",
"tests/output/stealth_steady_sweep_nx1500/vorticity_stealth_s050_w0.00903.png": "a675f41df763f0a1ac0a06386315806b24f2571f5dabc8693fcd871a13ed22ba",
"tests/output/stealth_steady_sweep_nx1500/streakline_stealth_s100_w0.01806.png": "92515588596596cc1d691c643fa48cf828492c2eaed96355dcec58109de4b5aa",
"tests/output/exp_ctrl_matrix_streak_nx1500/summary_C4_deceit_f1p5.json": "0393661f08b748428fc366eeecec3b34b9d9a013aa6b151a15b33c7e3c0e1818",
"tests/output/exp_ctrl_matrix_streak_nx1500/streakline_C5_deceit_multi_f1p5_step080000.png": "bffef412087e426b614d8c05e59bd7580ee49bb77319279ddc4c1bf825678c49",
"tests/output/exp_ctrl_matrix_streak_nx1500/summary_C6_deceit_f2.json": "de067f01ef5c11249d67bbe5e02db6f2b4c5590214de02609bca115edf8dee64",
"tests/output/exp_ctrl_matrix_streak_nx1500/streakline_C6_deceit_f2.png": "846badbae81b75f765d89e5a7c4f88aeb5d57f2387511e4f2f84c72a192ea9f2",
"tests/output/exp_ctrl_matrix_streak_nx1500/summary_C3_deceit_multi.json": "eb21d1c69e51f01c1a6be1ce59fe86763089ea5aa667b8872d0186af035b24b2",
"tests/output/exp_ctrl_matrix_streak_nx1500/summary_C0_no_ctrl.json": "780a0d329cb86990a17a088f49084410abb1fad24f659255918e5ddda6b3dabd",
"tests/output/exp_ctrl_matrix_streak_nx1500/streakline_C3_deceit_multi_step080000.png": "ff7836b8229d9a5dd3900f499fe3e7f0c73a61c7109b6e6e79b11a0fb459bb63",
"tests/output/exp_ctrl_matrix_streak_nx1500/streakline_C0_no_ctrl_step040000.png": "f2b56a7e30bcc363ed69fc19705403181ac5de90800eef03039a389a65869e30",
"tests/output/exp_ctrl_matrix_streak_nx1500/summary_C5_deceit_multi_f1p5.json": "261b698723f19526a447679a2be8666c8d0cbf6df81b0c9de6d051960d77308b",
"tests/output/exp_ctrl_matrix_streak_nx1500/streakline_C0_no_ctrl_step060000.png": "0697e0ae06a01154afdcf00330ba870bd8f36d21561a33846ad7ba63fb731179",
"tests/output/exp_ctrl_matrix_streak_nx1500/streakline_C1_stealth_step040000.png": "1de3d7f54e91c5d5850f4358d1872e16fefb36d32a1b6293facb54524e32315c",
"tests/output/exp_ctrl_matrix_streak_nx1500/streakline_C0_no_ctrl_step100000.png": "91f0bf6ed3e854f7f83623a3f19bb12c83b4aac239e3eaa849fbe50e7baddff5",
"tests/output/exp_ctrl_matrix_streak_nx1500/streakline_C0_no_ctrl_step080000.png": "303c1d2d4c49b4a7495365c8cb2bcbfe9bdda7cbc0a7c7dd1f01e8aa62b3573b",
"tests/output/exp_ctrl_matrix_streak_nx1500/streakline_C5_deceit_multi_f1p5_step040000.png": "dd5945458a35d81b31a0e2f3a693a5023d6960474263e7dc86c22367a56cc13c",
"tests/output/exp_ctrl_matrix_streak_nx1500/manifest.json": "0d97efed02f775c25dd8a2d7439f310b715d142ff8d603c9da6ddab197570ce8",
"tests/output/exp_ctrl_matrix_streak_nx1500/streakline_C3_deceit_multi.png": "69022ef9175acf910374ec73848640548b85fc7beb7e6950843f52c10ed7d61b",
"tests/output/exp_ctrl_matrix_streak_nx1500/streakline_C4_deceit_f1p5_step060000.png": "16ba30b8cca0d49e6b76be0bb4f0d14bbf276ca6ec47ebf56907c7534e15c4e0",
"tests/output/exp_ctrl_matrix_streak_nx1500/streakline_C5_deceit_multi_f1p5_step100000.png": "8548b6dff635cf9c92e2baa119866277e3994366eb31aeb30641b03b3d80ee9f",
"tests/output/exp_ctrl_matrix_streak_nx1500/streakline_C2_deceit_step060000.png": "56100f169c3e378b84bfc89c5477d2c142ca043d9f28eaa70bc5448c49c7f4d5",
"tests/output/exp_ctrl_matrix_streak_nx1500/summary_C2_deceit.json": "587cd42d81b1325bbc766d9ca6c1fd3d076bf5a772efd45d056c2c4e3db742b6",
"tests/output/exp_ctrl_matrix_streak_nx1500/streakline_C1_stealth_step060000.png": "e43e95e7126de8cb857154353f161914c225f8c9f17eb44b1ff744249368a4d5",
"tests/output/exp_ctrl_matrix_streak_nx1500/streakline_C6_deceit_f2_step080000.png": "676d21ffc7180d34a6725a8bf49503ce59f48d65500450c3975d01e65162899e",
"tests/output/exp_ctrl_matrix_streak_nx1500/summary_C1_stealth.json": "73040aeb7ef07c538d4687b101c599210e660202eb1c2c3e0894dfbde682d137",
"tests/output/exp_ctrl_matrix_streak_nx1500/streakline_C4_deceit_f1p5_step100000.png": "e22171ef86979c4398c45ada9cd0f5e4c4e5b034f271df5fa8ac9a762a8554cd",
"tests/output/exp_ctrl_matrix_streak_nx1500/streakline_C2_deceit_step100000.png": "0d73042be73b0de8d0a591e56c01e3c802483aa22a97f27e0300cba82c708066",
"tests/output/exp_ctrl_matrix_streak_nx1500/streakline_C4_deceit_f1p5_step040000.png": "a6e95fd5c24052db20d5ece200edcfe5e261c00950ca964c89df9f7335579634",
"tests/output/exp_ctrl_matrix_streak_nx1500/streakline_C0_no_ctrl.png": "d74061347ac3505fad878e330f6cb04d23bdb13082bfa1afa2fda0872f80f388",
"tests/output/exp_ctrl_matrix_streak_nx1500/streakline_C4_deceit_f1p5.png": "3156400eb59fae0638556c2711345f12ca49d951ff09e6464a2271249409a6a7",
"tests/output/exp_ctrl_matrix_streak_nx1500/streakline_C1_stealth_step100000.png": "d69e34c82da98b28eef7f1af29f5d11f400e90f628049f6f5f4a3a419a4a4340",
"tests/output/exp_ctrl_matrix_streak_nx1500/streakline_C6_deceit_f2_step040000.png": "ce1f372b517dd52fc3f3eb066145e04ab6841e43b67cb0f6bfbdb42a6738eca6",
"tests/output/exp_ctrl_matrix_streak_nx1500/streakline_C3_deceit_multi_step100000.png": "07cce6c99dfa7b56dd4d3aa452873a676a5a00e9f046555fa9dda30f16dde488",
"tests/output/exp_ctrl_matrix_streak_nx1500/streakline_C1_stealth.png": "a892f18c74fe13efd839bfd5068097ca0ae07acebf6c06eed89e1b867e41fcb2",
"tests/output/exp_ctrl_matrix_streak_nx1500/streakline_C6_deceit_f2_step060000.png": "80b63bd309ef11a3ebb2f1ef301b49cd8f09bcc25562097d382f859306c9fe6d",
"tests/output/exp_ctrl_matrix_streak_nx1500/streakline_C2_deceit.png": "1edb30dc35e29ad991695353f4b84e0507792935ec75ae9a7904ebdc007a471a",
"tests/output/exp_ctrl_matrix_streak_nx1500/streakline_C5_deceit_multi_f1p5_step060000.png": "93ab8e09e58a64c5dd2eedfdafd27cf4dcfe4e8fae1af64ac71eac509e6ffdaf",
"tests/output/exp_ctrl_matrix_streak_nx1500/streakline_C3_deceit_multi_step060000.png": "f773bdef1c8d718d01b6d6d7735182c04564dd8b5692b359e1dd2f721c774b1a",
"tests/output/exp_ctrl_matrix_streak_nx1500/streakline_C4_deceit_f1p5_step080000.png": "5570fe6a25c92e5c6aa9a5129aa1797ba8ee7418170c7a351f9e35b931a366c7",
"tests/output/exp_ctrl_matrix_streak_nx1500/streakline_C1_stealth_step080000.png": "32d3e700286eb4b46b3bcf757669481affd6ff6b53792d730b5a21da92cc57d6",
"tests/output/exp_ctrl_matrix_streak_nx1500/streakline_C6_deceit_f2_step100000.png": "5acfe36694bb4e628309ff8ae1e839ca0a1f684607165bbc2883436b85208bf4",
"tests/output/exp_ctrl_matrix_streak_nx1500/streakline_C2_deceit_step040000.png": "2c6f2b8d61cc2aaa63631eb6c98d3de26dcef705fa6b66c823ce7b9eef50e00c",
"tests/output/exp_ctrl_matrix_streak_nx1500/streakline_C5_deceit_multi_f1p5.png": "adbefd0021e2c981d026718de8c63594b9c8e5971901d1dc40835cb69d95b93e",
"tests/output/exp_ctrl_matrix_streak_nx1500/streakline_C2_deceit_step080000.png": "ce8b18e4dd976ed590fcc44075f3fb058ca7b23e15a1624726c181c4dd0c11da",
"tests/output/exp_ctrl_matrix_streak_nx1500/streakline_C3_deceit_multi_step040000.png": "168d21ef24ae198fbfd642f8ca315faad4c7bff2e2c09e16ff7c97e7360ea883",
"tests/output/screening/screening_summary.csv": "3a23c4f2bd54ed5ee9bdb5b6dcdc58eed04519fcf1b4790e0abd1e6c5288fb96",
"tests/output/screening/screening_summary.json": "caf64530f152b6b8ccec82a3c7ba44fa0b3aeb0e0221ef6121857bf62c031ecd",
"tests/output/screening/B1/force_hist.csv": "854bfebe63fb2d140823fc5dbc434a70c317c6ab0bedbd5220cec45665b524c8",
"tests/output/screening/B1/summary.json": "35b4d958bc0fdd6ab6c9c0d1ed50e85d89b04f7be3e34632d6c3ea95b89acb47",
"tests/output/screening/custom/force_hist.csv": "06da0f67b564d5c114332ef3b39167b1ba222fc50045f95303c75c14755b51d5",
"tests/output/screening/custom/summary.json": "1701ed75e5e9ca16127f495ccff1d87de245d81df581e94114c8fca6fbbe77fd",
"tests/output/screening/MR1/force_hist.csv": "f70fbfa748fd0709e225523aaaa72b761db56df4f1d48f105384b94cbc44b31f",
"tests/output/screening/MR1/summary.json": "3d9a0fc19710820e3634ab2143b913b282beb159336567ab9ebf3de2092947bd",
"tests/output/screening/MR2/force_hist.csv": "c947b3c16b8e8f8f85a203cea8cd912bdfc07f96985c1c24a470b644170195ea",
"tests/output/screening/MR2/summary.json": "d2344e9e2517ec76c8b56bfbe3763dd465e24721856992401c57c414763481bb",
"tests/output/screening/MR3/force_hist.csv": "7df1536c83ee466b7195d9c521d3d3b1309acaf142f2855bba51fb279c7612e4",
"tests/output/screening/MR3/summary.json": "ad188eb1b271a6cd0fb4025b456eccac5450776f60db58466f804fc5a0e0ec61",
"tests/postproc/run_exp_ctrl_matrix_vorticity.py": "b7e0c4113111b9b677f321750c0055656ccfa4f45c25fe7846f3ed22f30d1467",
"tests/postproc/vorticity_triangle_clean.png": "f831b8143b50f038d5920a0658469622655f34176d30cf7216feff108aa2ecaf",
"tests/postproc/run_kan99b_streakline.py": "a2bbf3fc629ea170d2d4879317dbf2b81c43378a328100ac1f2ee8d9895666cb",
"tests/postproc/streakline_triangle_clean.png": "aa6669de7af6f82e98af25698a15f494e9cea20cb911ad9a30fe52597d33bb79",
"tests/postproc/experiment.ipynb": "c6b45db1c57200f0777213ef8d44cb4996c1aa7a5fb42b968b77e56f51b4fca4",
"tests/postproc/run_stealth_steady_sweep.py": "3c32c4dede7da77fd6cfbd3f7b1ff43bb11390aaba621883ec96c6c7fdad5af7",
"tests/postproc/run_exp_ctrl_matrix_streakline.py": "529d5f31a3862080f890c65177502b589710b2d960ddf131abaf7dc2f9e2a96f",
"tests/screening/run_config_sweep.py": "5030c99923815ed6ad39110cb56f748c579ff4c66c7c1a368ad1a6008017e2ff",
"examples/fixed_periodic_patch.py": "6732e440a47c237ea341703f2d80717903d34c68fd061bdc97189e5d877be46c",
"examples/fixed_patch_jet.py": "9d58ac3f32478603e8e798efcdaf6ea16e9cc92346eb4780a60e438d331abced"
}
}
@@ -0,0 +1 @@
PYTHONPATH=/home/frank14f/CelerisLab/src CUDA_VISIBLE_DEVICES='' /home/frank14f/anaconda3/envs/pycuda_3_10/bin/python -m pytest tests/validation/multigrid/test_fine_surface_gpu.py::test_missing_surface_device_buffer_rejects_before_launch -q
@@ -0,0 +1 @@
0
@@ -0,0 +1,2 @@
.. [100%]
2 passed in 0.09s
@@ -0,0 +1,30 @@
[
{
"name": "cpu_maps",
"command": [
"/home/frank14f/anaconda3/envs/pycuda_3_10/bin/python",
"-m",
"pytest",
"-q",
"-p",
"no:cacheprovider",
"tests/unit/test_refinement.py"
],
"exit_code": 0,
"seconds": 1.8799934879643843
},
{
"name": "cpu_shared_kernel",
"command": [
"/home/frank14f/anaconda3/envs/pycuda_3_10/bin/python",
"-m",
"pytest",
"-q",
"-p",
"no:cacheprovider",
"tests/unit/test_numerical_operators.py::test_actual_semantic_and_auxiliary_kernels[0-0-0]"
],
"exit_code": 0,
"seconds": 2.1572919980389997
}
]
@@ -0,0 +1,14 @@
{
"command": [
"/home/frank14f/anaconda3/envs/pycuda_3_10/bin/python",
"-m",
"pytest",
"-q",
"-p",
"no:cacheprovider",
"tests/unit/test_fine_surface.py"
],
"exit_code": 0,
"seconds": 1.947228622972034,
"note": "Final CPU recheck after preflight aperture inputs were aligned with packed FP32 lever arms. No kernel/math or uploaded-array changes."
}
@@ -0,0 +1,2 @@
............... [100%]
15 passed in 0.59s
@@ -0,0 +1,14 @@
{
"command": [
"/home/frank14f/anaconda3/envs/pycuda_3_10/bin/python",
"-m",
"pytest",
"-q",
"-p",
"no:cacheprovider",
"tests/validation/multigrid/test_refinement_followup.py::FaultGuardsCPU",
"tests/validation/multigrid/test_refinement_gpu.py::CoupledGPU::test_cleanup_attempts_every_allocation"
],
"exit_code": 0,
"seconds": 1.620646678027697
}
@@ -0,0 +1,2 @@
..... [100%]
5 passed, 5 subtests passed in 0.25s
@@ -0,0 +1,2 @@
......... [100%]
9 passed, 23 subtests passed in 0.12s
@@ -0,0 +1,14 @@
{
"command": [
"/home/frank14f/anaconda3/envs/pycuda_3_10/bin/python",
"-m",
"pytest",
"-q",
"-p",
"no:cacheprovider",
"tests/validation/multigrid/test_fine_surface_gpu.py::test_cross_interface_donor_rejects_before_cuda"
],
"exit_code": 0,
"seconds": 1.665132363094017,
"CUDA_VISIBLE_DEVICES": ""
}
@@ -0,0 +1,2 @@
. [100%]
1 passed in 0.09s
@@ -0,0 +1,2 @@
. [100%]
1 passed in 0.63s
@@ -0,0 +1 @@
PYTHONPATH=src /home/frank14f/anaconda3/envs/pycuda_3_10/bin/python -m pytest tests/unit/test_fine_surface.py -q
@@ -0,0 +1 @@
0
@@ -0,0 +1 @@
PYTHONPATH=src /home/frank14f/anaconda3/envs/pycuda_3_10/bin/python -m pytest tests/unit/test_fine_surface.py -q -k 'projection_uses_cell_center or transfer_dependencies'
@@ -0,0 +1 @@
0
@@ -0,0 +1,2 @@
... [100%]
3 passed, 12 deselected in 0.40s
@@ -0,0 +1,2 @@
............... [100%]
15 passed in 0.59s
@@ -0,0 +1,290 @@
"""CPU preparation for one fixed D2Q9 2:1 patch and optional interior circles.
Cell indices use y*nx+x; population slots use q*(nx*ny)+cell, matching
core/layout.cuh. Bounds are half-open (x0, y0, x1, y1) in coarse cells.
The four fine halo cells implement the pinned CPUREF volumetric geometry.
Base topology is independent of boundaries; prepare_fine_boundary checks them.
"""
from dataclasses import dataclass, replace
from numbers import Integral
import numpy as np
from ..config import LBMConfig
from .descriptors import D2Q9_EX, D2Q9_EY, FLUID, SOLID
ACTIVE, INNER_GHOST, OUTER_GHOST = 0, 1, 2
HALO = 4
def _readonly(values, dtype):
array = np.ascontiguousarray(values, dtype=dtype)
array.setflags(write=False)
return array
@dataclass(frozen=True, eq=False)
class FixedPatch2D:
"""Layer metadata and compact exchange tables, constructed by from_config.
Shapes are (ny, nx), including the fine halo. ``fine_origin`` is its lower
cell edge in coarse physical units, with coarse dx=dt=1 and fine dx=dt=.5.
``ghost_fine`` and ``ghost_coarse`` pair fine cells with coarse donors.
``coalesce_coarse`` contains incoming population slots; each corresponding
row of ``coalesce_fine`` contains four fine slots in (dy, dx) row order.
Weights are all 1/4. Closed corner links are included even when the coarse
donor is uncovered. These tables contain no DDF data and allocate no GPU.
This is preparation, not permission to advance these levels with OneStep:
its channel boundaries and fused collision do not implement patch coupling.
"""
coarse_shape: tuple[int, int]
bounds: tuple[int, int, int, int]
tau_coarse: float
tau_fine: float
fine_kind: np.ndarray
ghost_fine: np.ndarray
ghost_coarse: np.ndarray
coalesce_coarse: np.ndarray
coalesce_fine: np.ndarray
@classmethod
def from_config(cls, cfg: LBMConfig, bounds) -> "FixedPatch2D":
"""Prepare maps without changing cfg or allocating coarse-sized tables.
The initial backend contract is D2Q9/SRT/FP32/unshifted/double_buffer,
without LES. Two coarse cells of margin keep all halo donors in bounds;
this does NOT certify that those donors are fluid or periodic.
"""
checked = replace(cfg)
checked.validate()
if (not checked.is_d2q9 or checked.collision != "SRT"
or checked.streaming != "double_buffer"
or checked.store_precision != "FP32"
or checked.ddf_shifting or checked.les_enabled):
raise ValueError("FixedPatch2D requires D2Q9/SRT/FP32/unshifted/double_buffer without LES")
bounds = tuple(bounds)
if len(bounds) != 4 or any(isinstance(v, (bool, np.bool_))
or not isinstance(v, Integral) for v in bounds):
raise ValueError("bounds must be four integers: (x0, y0, x1, y1)")
x0, y0, x1, y1 = bounds = tuple(map(int, bounds))
nx, ny = checked.nx, checked.ny
if not (2 <= x0 < x1 <= nx - 2 and 2 <= y0 < y1 <= ny - 2):
raise ValueError("patch must be nonempty with a two-coarse-cell margin")
fx, fy = 2 * (x1 - x0) + 2 * HALO, 2 * (y1 - y0) + 2 * HALO
if max(nx * ny, fx * fy) > np.iinfo(np.uint32).max:
raise ValueError("layer cell counts exceed uint32 indexing")
tau_c = 3.0 * checked.viscosity + 0.5
tau_f = 6.0 * checked.viscosity + 0.5
if not checked.omega_min <= 1.0 / tau_f <= checked.omega_max:
raise ValueError("fine relaxation rate lies outside configured omega guards")
kind = np.full((fy, fx), OUTER_GHOST, dtype=np.uint8)
kind[2:-2, 2:-2] = INNER_GHOST
kind[HALO:-HALO, HALO:-HALO] = ACTIVE
gy, gx = np.nonzero(kind != ACTIVE)
ghost_fine = gy * fx + gx
ghost_coarse = (y0 + (gy - HALO) // 2) * nx + x0 + (gx - HALO) // 2
targets, sources = [], []
# Only the outside ring can receive fine-to-coarse populations.
# Integer doubled midpoints include all eight diagonal corner passes.
for y in range(y0 - 1, y1 + 1):
xs = range(x0 - 1, x1 + 1) if y in (y0 - 1, y1) else (x0 - 1, x1)
for x in xs:
for q in range(1, 9):
mx, my = 2 * x + 1 - D2Q9_EX[q], 2 * y + 1 - D2Q9_EY[q]
if 2 * x0 <= mx <= 2 * x1 and 2 * y0 <= my <= 2 * y1:
targets.append(q * nx * ny + y * nx + x)
a, b = HALO + 2 * (x - x0), HALO + 2 * (y - y0)
sources.append([q * fx * fy + (b + dy) * fx + a + dx
for dy in (0, 1) for dx in (0, 1)])
return cls((ny, nx), bounds, tau_c, tau_f,
_readonly(kind, np.uint8),
_readonly(ghost_fine, np.uint32),
_readonly(ghost_coarse, np.uint32),
_readonly(targets, np.uint64),
_readonly(sources, np.uint64).reshape(-1, 4))
@property
def fine_shape(self) -> tuple[int, int]:
return self.fine_kind.shape
@property
def fine_origin(self) -> tuple[float, float]:
return self.bounds[0] - HALO / 2, self.bounds[1] - HALO / 2
@property
def table_bytes(self) -> int:
return sum(a.nbytes for a in (self.fine_kind, self.ghost_fine,
self.ghost_coarse, self.coalesce_coarse,
self.coalesce_fine))
def check_synchronization(self, coarse_steps: int, fine_steps: int, *, phase: str) -> None:
"""Check a proposed backend handoff; does not convert or collide data.
Production storage is g=C(f), while CPUREF returns arrival_f. A future
g-to-g coarse step must collide coarse cells once and fine cells twice;
fine halo ghosts never collide. Coalescence must precede coarse collision.
Converting reference f to g for comparison is an observation operation,
not an additional production collision. Counts here are completed steps.
"""
if phase != "postcollision_g":
raise ValueError("patch backend handoff requires postcollision_g")
for value in (coarse_steps, fine_steps):
if isinstance(value, (bool, np.bool_)) or not isinstance(value, Integral) or value < 0:
raise ValueError("step counts must be nonnegative integers")
if fine_steps != 2 * coarse_steps:
raise ValueError("levels are not synchronized: fine_steps must equal 2*coarse_steps")
@dataclass(frozen=True, eq=False)
class FineBoundary2D:
"""Fixed local projection plus auditable, finite transfer dependency sets.
transfer_reads rows are (hop, direction, cell), traced from coalescence at
hop 2 back to exploded G at hop 0. No previous coarse interval is traversed.
Cell footprints also include the whole explosion write/donor tables.
"""
objects: tuple
flags: np.ndarray
curved_host: tuple
boundary_cells: np.ndarray
transfer_fine_cells: np.ndarray
transfer_coarse_cells: np.ndarray
transfer_reads: np.ndarray
def _transfer_footprint(patch):
ny, nx = patch.fine_shape
cells = nx * ny
pending = [(2, *divmod(int(slot), cells)) for slot in patch.coalesce_fine.ravel()]
reads = set()
while pending:
hop, q, k = pending.pop()
if (hop, q, k) in reads:
continue
reads.add((hop, q, k))
if hop == 0:
continue
y, x = divmod(k, nx)
kind = patch.fine_kind[y, x]
if kind == OUTER_GHOST:
raise ValueError("Transfer reads an invalid post-hop outer ghost")
# A collided output depends on all nine arrivals; ghosts only stream.
for direction in (range(9) if kind == ACTIVE else (q,)):
sx, sy = x - D2Q9_EX[direction], y - D2Q9_EY[direction]
if not (0 <= sx < nx and 0 <= sy < ny):
raise ValueError("Transfer dependency leaves the fine allocation")
pending.append((hop - 1, direction, sy * nx + sx))
fine = set(map(int, patch.ghost_fine)) | {k for _, _, k in reads}
coarse = set(map(int, patch.ghost_coarse)) | set(map(
int, patch.coalesce_coarse % np.prod(patch.coarse_shape)))
return fine, coarse, _readonly(sorted(reads), np.int64)
def prepare_fine_boundary(cfg, patch, objects, *, wall_aware=False):
"""Project fixed circles and reject boundary/transfer overlap before CUDA.
Input centers/radii are in coarse physical coordinates (dx=dt=1).
SurfaceActuation retains its lattice-velocity meaning: input coarse units
are converted into independent fine-local objects with dx=dt=.5.
Original objects are not retained or mutated. No runtime geometry updates.
"""
if not objects:
return None
checked = replace(cfg)
checked.validate()
if (patch.coarse_shape != (cfg.ny, cfg.nx) or not checked.is_d2q9
or checked.collision != "SRT" or checked.streaming != "double_buffer"
or checked.store_precision != "FP32" or checked.ddf_shifting or checked.les_enabled
or patch.tau_coarse != 3*checked.viscosity+.5):
raise ValueError("Fine boundary requires the matching fixed-patch configuration")
from ..body.geometry.circle import CircleGeometry
from ..body.objects import SimObject
from ..body.coupling.soa_packer import pack_cut_links_to_soa
ny, nx = patch.fine_shape
fine_cfg = replace(cfg, nx=nx, ny=ny, viscosity=2 * cfg.viscosity)
flags = np.full(nx * ny, FLUID, np.uint16)
active = patch.fine_kind.ravel() == ACTIVE
local, links = [], []
x0, y0, x1, y1 = patch.bounds
dx = dt = .5
for bid, obj in enumerate(objects):
if (type(obj.geometry) is not CircleGeometry or obj.is_sensor or obj.is_force_region
or any(getattr(obj.state, name) != 0 for name in ("vx", "vy", "omega"))
or any(vars(obj.control).values())):
raise ValueError("Fine boundaries require stationary circles without other roles")
cx, cy = obj.geometry.center
radius = obj.geometry._radius
if (not np.isfinite([cx, cy, radius]).all() or radius <= 0
or cx-radius < x0 or cx+radius > x1 or cy-radius < y0 or cy+radius > y1):
raise ValueError("Entire fine circle must lie inside the physical patch")
center = tuple((v-o)/dx-.5 for v, o in zip((cx, cy), patch.fine_origin))
spec = obj.surface_actuation
if spec is not None:
spec = replace(spec, normal_velocity=spec.normal_velocity * dt / dx)
item = SimObject(bid, geometry=CircleGeometry(*center, radius/dx),
center=center, radius=radius/dx, surface_actuation=spec)
item.validate_surface_actuation(fine_cfg)
mask = item.get_flag_mask(nx, ny)
solid = (mask & SOLID) != 0
if not solid.any() or np.any(solid & ~active) or np.any(flags[solid] & SOLID):
raise ValueError("Fine solids must be resolved, disjoint and entirely active")
flags[solid] = mask[solid]
local.append(item)
for item in local:
cut = item.geometry.build_cut_links(nx, ny, domain_flags=flags)
if not cut:
raise ValueError("Fine circle has no resolved cut links")
if item.surface_actuation is not None:
_, aperture = item.surface_actuation.project(
np.array([link.rx for link in cut]), np.array([link.ry for link in cut]))
if not aperture.any():
raise ValueError("Surface aperture hits no resolved cut links")
for link in cut:
link.body_id = item.obj_id
links.extend(cut)
boundary, writers, receivers = set(), set(), set()
for link in links:
r, q = link.fluid_idx, link.dir
y, x = divmod(r, nx)
sx, sy = x + D2Q9_EX[q], y + D2Q9_EY[q]
s = sy * nx + sx
if not (active[r] and flags[r] & FLUID and active[s] and flags[s] & SOLID):
raise ValueError("Cut-link receiver/source must be active fluid/solid")
writer = (s, q+1 if q % 2 else q-1)
if writer in writers:
raise ValueError("Duplicate fine boundary writer")
writers.add(writer)
receivers.add((r, q))
boundary.update((r, s))
if link.q < .5:
dx_, dy_ = x - D2Q9_EX[q], y - D2Q9_EY[q]
if not (0 <= dx_ < nx and 0 <= dy_ < ny and active[dy_*nx+dx_]):
raise ValueError("q<.5 donor crosses the fine active interface; fallback cannot hide it")
boundary.add(dy_*nx+dx_)
# Reverse coverage: every fluid pull across a solid neighbor needs a writer.
required = set()
for r in np.flatnonzero(active & ((flags & FLUID) != 0)):
for q in range(1, 9):
if flags[r + D2Q9_EX[q] + nx*D2Q9_EY[q]] & SOLID:
required.add((int(r), q))
if required != receivers:
raise ValueError("Fine solid pull coverage does not match the cut links")
fine, coarse, reads = _transfer_footprint(patch)
if fine & (boundary | set(map(int, np.flatnonzero(flags & SOLID)))):
raise ValueError("Boundary stencil overlaps the two-hop transfer footprint")
for k in coarse:
y, x = divmod(k, cfg.nx)
if x0 <= x < x1 and y0 <= y < y1:
raise ValueError("Transfer coarse donor/target is not an uncovered bulk cell")
if wall_aware and (y <= 2 or y >= cfg.ny-3):
raise ValueError("Transfer footprint touches the coarse wall reconstruction stencil")
return FineBoundary2D(tuple(local), _readonly(flags, np.uint16),
tuple(_readonly(a, a.dtype) for a in pack_cut_links_to_soa(links)),
_readonly(sorted(boundary), np.uint32),
_readonly(sorted(fine), np.uint32),
_readonly(sorted(coarse), np.uint32), reads)
@@ -0,0 +1,48 @@
{
"start_utc": "2026-10-14T05:08:55.958692+00:00",
"preflight_gpu": "0, GPU-e8853ae7-a302-6a17-bcfa-aa767e9ed20c, Tesla V100-SXM2-16GB, 5, 16140, 0\n1, GPU-f1c9fd5a-e917-56e0-21fb-24035ba44a36, Tesla V100-SXM2-16GB, 5, 16140, 0\n2, GPU-b8c11c01-c91f-aa0b-abf6-dad35085cc76, Tesla V100-SXM2-16GB, 5, 16140, 0\n3, GPU-8b71b032-1b75-2891-935c-ce106a53034a, Tesla V100-SXM2-16GB, 5, 16140, 0",
"preflight_apps": "",
"preflight_ram_bytes": 64091750400,
"physical_gpu_uuid": "GPU-e8853ae7-a302-6a17-bcfa-aa767e9ed20c",
"command": [
"/home/frank14f/anaconda3/envs/pycuda_3_10/bin/python",
"-c",
"import CelerisLab,pytest; print('SOURCE', CelerisLab.__file__, flush=True); assert CelerisLab.__file__.startswith('/home/frank14f/CelerisLab/src/'); raise SystemExit(pytest.main(['-q', '-s', '-p', 'no:cacheprovider', 'tests/validation/multigrid/test_fine_surface_gpu.py', 'tests/validation/multigrid/test_refinement_followup.py::NormalBuildGPU::test_offcenter_rectangle_margin_two_one_step', 'tests/validation/multigrid/test_refinement_followup.py::NormalBuildGPU::test_slot_reservoir_eight_steps']))"
],
"cwd": "/home/frank14f/CelerisLab",
"env": {
"PYTHONPATH": "/home/frank14f/CelerisLab/src",
"PYTHONNOUSERSITE": "1",
"PYTHONDONTWRITEBYTECODE": "1",
"OPENBLAS_NUM_THREADS": "1",
"CUDA_VISIBLE_DEVICES": "GPU-e8853ae7-a302-6a17-bcfa-aa767e9ed20c",
"CUDA_CACHE_DISABLE": "1",
"TMPDIR": "/tmp/celeris-fine-surface-gpu-e9g3hz7z"
},
"preflight_temp_bytes": 1637890,
"limits": {
"wall_seconds": 120,
"temp_bytes": 2000000000,
"ram_reserve_bytes": 6409175040,
"vram_reserve_MiB": 1614
},
"note": "Sampled own process group; no fixed RSS/address-space cap.",
"exit_code": 1,
"elapsed_seconds": 25.39498820400331,
"peak_group_rss_bytes": 386883584,
"peak_temp_bytes": 3585985,
"min_ram_bytes": 63638339584,
"min_vram_free_MiB": 15826,
"termination_reason": null,
"scratch_removed": true,
"source_hashes_captured_during_run": {
"src/CelerisLab/lbm/kernels/refinement.cu": "129f3d91da93b4324f88a0da73a4da1e5390f72c14cce574ee63306712da9895",
"src/CelerisLab/lbm/kernels/step/aux_kernels.cu": "578a5b20a157241ee678547059abb1372dd5a589ad06bb2c15b987eb01ca1013",
"src/CelerisLab/lbm/kernels/step/curved_double.cu": "bfa7a1df1e939020314d49755045f7a85fe4a19cc1c68dbe62653c66c5e7c2b3",
"src/CelerisLab/lbm/refinement.py": "b3fe9e58118369adb1bdfc618fbfbd917d508a563beaf2555f656b59aeff4425",
"src/CelerisLab/lbm/refinement_stepper.py": "9178224089ee6584420b79f10cf1d91441645b668e8b6898641d19eac757687b",
"src/CelerisLab/lbm/stepper.py": "0dcb7cd7ae87e33e3dc67a38b6aa43042fbe673e37d9ad165342ee1d695933ce",
"tests/unit/test_fine_surface.py": "b232b55e75eef52480f06a35c401d72b6145892bb8b79d1d1b3cfed965b3506c",
"tests/validation/multigrid/test_fine_surface_gpu.py": "3dd0658f63a4e7a1c41eecf433842c872f8fecb391ea4b44d0b48947643d5189"
}
}
@@ -0,0 +1,79 @@
SOURCE /home/frank14f/CelerisLab/src/CelerisLab/__init__.py
speed=0.0 audit=True BFL=7.4505806e-09 ledger=[1.604948192834854e-05, -5.038455128669739e-07, -6.919726729393005e-07] budget=0.00221051117 boundary=[4.0978193283081055e-08, 0.0, 0.0] transfer=[0.0, 0.0, 0.0] drive_mass=+4.09781933e-08; counts=PASS
speed=None audit=False BFL=7.4505806e-09 ledger=[1.604948192834854e-05, -5.038455128669739e-07, -6.919726729393005e-07] budget=0.00221051117 boundary=[4.0978193283081055e-08, 0.0, 0.0] transfer=[0.0, 0.0, 0.0] drive_mass=+4.09781933e-08; counts=normal build
.speed=0.002 audit=True BFL=9.73073444e-09 ledger=[1.597730442881584e-05, -5.154870450496674e-07, -7.622875273227692e-07] budget=0.00221052543 boundary=[0.0071802823804318905, 0.003110995050519705, 0.0026390845887362957] transfer=[0.0, 0.0, 0.0] drive_mass=+0.00620033871; counts=PASS
.speed=-0.002 audit=True BFL=7.4505806e-09 ledger=[1.66366808116436e-05, -5.881302058696747e-07, -7.147900760173798e-07] budget=0.00221049693 boundary=[-0.007164992857724428, -0.0030983122996985912, -0.00262861093506217] transfer=[0.0, 0.0, 0.0] drive_mass=-0.00618575338; counts=PASS
.FF.normal rectangle 17x13 bounds=(2, 2, 6, 5) fine=16x14 steps=1: max_population=1.14050047e-07 device_arrays=35288; halo/stride PASS
host_peak_rss=279.887 MiB
.slot/reservoir steps=8 max_population=1.78241457e-07 max_BC_error=2.21654773e-07 discrete_leaf_mass_change=+0.0309633738 final_sum_rho_v_bottom=0.00426894613 top=0.000960694626; raw halos/corners/fine BC isolation PASS
host_peak_rss=279.887 MiB
.
=================================== FAILURES ===================================
_ test_missing_surface_device_buffer_rejects_before_launch[surface_velocity_gpu] _
missing = 'surface_velocity_gpu'
@pytest.mark.parametrize("missing", ["surface_velocity_gpu", "link_exchange_gpu"])
def test_missing_surface_device_buffer_rejects_before_launch(missing):
backend = implementation.FixedPatchStepper.__new__(implementation.FixedPatchStepper)
backend.fine_boundary = SimpleNamespace(objects=[object_spec(.002)])
backend._fine_curved = SimpleNamespace(surface_velocity_gpu=object(), link_exchange_gpu=object())
setattr(backend._fine_curved, missing, None)
backend._curved = Mock()
with pytest.raises(RuntimeError, match="Surface boundary device buffers are missing"):
> backend._apply_fine_boundary(object())
tests/validation/multigrid/test_fine_surface_gpu.py:289:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self = <CelerisLab.lbm.refinement_stepper.FixedPatchStepper object at 0x761fb9325480>
buffer = <object object at 0x761fb937c570>, kw = {}
cl = namespace(surface_velocity_gpu=None, link_exchange_gpu=<object object at 0x761fb937c630>)
def _apply_fine_boundary(self, buffer, **kw):
"""Stage solid source slots; exchange buffer holds this fine substep only."""
cl = self._fine_curved
if cl is None:
if self.fine_boundary is not None:
raise RuntimeError("Fine boundary device buffers are missing")
return
> if self._curved is None or cl.fluid_idx_gpu is None:
E AttributeError: 'types.SimpleNamespace' object has no attribute 'fluid_idx_gpu'
src/CelerisLab/lbm/refinement_stepper.py:195: AttributeError
_ test_missing_surface_device_buffer_rejects_before_launch[link_exchange_gpu] __
missing = 'link_exchange_gpu'
@pytest.mark.parametrize("missing", ["surface_velocity_gpu", "link_exchange_gpu"])
def test_missing_surface_device_buffer_rejects_before_launch(missing):
backend = implementation.FixedPatchStepper.__new__(implementation.FixedPatchStepper)
backend.fine_boundary = SimpleNamespace(objects=[object_spec(.002)])
backend._fine_curved = SimpleNamespace(surface_velocity_gpu=object(), link_exchange_gpu=object())
setattr(backend._fine_curved, missing, None)
backend._curved = Mock()
with pytest.raises(RuntimeError, match="Surface boundary device buffers are missing"):
> backend._apply_fine_boundary(object())
tests/validation/multigrid/test_fine_surface_gpu.py:289:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self = <CelerisLab.lbm.refinement_stepper.FixedPatchStepper object at 0x761fb92299c0>
buffer = <object object at 0x761fb937f700>, kw = {}
cl = namespace(surface_velocity_gpu=<object object at 0x761fb937f710>, link_exchange_gpu=None)
def _apply_fine_boundary(self, buffer, **kw):
"""Stage solid source slots; exchange buffer holds this fine substep only."""
cl = self._fine_curved
if cl is None:
if self.fine_boundary is not None:
raise RuntimeError("Fine boundary device buffers are missing")
return
> if self._curved is None or cl.fluid_idx_gpu is None:
E AttributeError: 'types.SimpleNamespace' object has no attribute 'fluid_idx_gpu'
src/CelerisLab/lbm/refinement_stepper.py:195: AttributeError
=========================== short test summary info ============================
FAILED tests/validation/multigrid/test_fine_surface_gpu.py::test_missing_surface_device_buffer_rejects_before_launch[surface_velocity_gpu]
FAILED tests/validation/multigrid/test_fine_surface_gpu.py::test_missing_surface_device_buffer_rejects_before_launch[link_exchange_gpu]
2 failed, 6 passed in 23.73s
@@ -0,0 +1,316 @@
"""Two coarse/four fine steps: isolated fine circle, no flux-accuracy claim.
Run only through the bounded GPU runner after a fresh resource check. The test
hooks read actual kernel inputs/outputs; they never change the stepping order.
"""
import importlib.util
from contextlib import nullcontext
from pathlib import Path
from threading import RLock
from types import SimpleNamespace
from unittest.mock import Mock, patch
import numpy as np
import pycuda.driver as cuda
import pytest
import CelerisLab
from CelerisLab.body.geometry.circle import CircleGeometry
from CelerisLab.body.objects import SimObject
from CelerisLab.config import LBMConfig
from CelerisLab.cuda import compiler_v2 as compiler
from CelerisLab.cuda.context import CudaContext
from CelerisLab.lbm import refinement_stepper as implementation
from CelerisLab.lbm.descriptors import FLUID, SOLID
ROOT = Path(__file__).resolve().parents[3]
CX = np.array([0, 1, -1, 0, 0, 1, -1, 1, -1])
CY = np.array([0, 0, 0, 1, -1, 1, -1, -1, 1])
OPP = np.array([0, 2, 1, 4, 3, 6, 5, 8, 7])
W = np.array([4/9]+[1/9]*4+[1/36]*4)
MOMENTS = np.stack((np.ones(9), CX, CY))
GEOMETRY = ("fluid_idx", "dir", "q", "body_id", "rx", "ry", "rz", "fallback_class")
BOUNDS = (4, 4, 20, 20)
def read(pointer, shape, dtype=np.float32):
values = np.empty(shape, dtype)
cuda.memcpy_dtoh(values, pointer)
return values
def rest(shape):
return np.broadcast_to(W[:, None, None], (9, *shape)).astype(np.float32).copy()
def surface(speed):
return None if speed is None else dict(angle=.7, half_width=.85, normal_velocity=speed)
def object_spec(speed):
return SimObject(0, CircleGeometry(12.25, 12.25, 2.15), center=(12.25, 12.25),
radius=2.15, surface_actuation=surface(speed))
def audit_compiler(original):
def compile_private(*args, **kwargs):
entry = Path(kwargs["build_dir"])/"fine_surface_audit.cu"
entry.write_text('#define CELERIS_REFINEMENT_AUDIT\n#include "refinement.cu"\n')
kwargs["source"] = entry.name
return original(*args, **kwargs)
return compile_private
def reflection_oracle(before, cl, speed, *, verify_projection=True):
"""FP64 BFL from frozen spatial populations, independent arc projection."""
flat = before.astype(float).reshape(9, -1)
radius = np.hypot(cl.rx.astype(float), cl.ry.astype(float))
delta = (np.arctan2(cl.ry.astype(float), cl.rx.astype(float))-.7+np.pi) % (2*np.pi)-np.pi
amplitude = 0 if speed is None else speed
strength = amplitude*np.maximum(0, 1-(delta/.85)**2)**2
velocity = strength[:, None]*np.column_stack((cl.rx, cl.ry))/radius[:, None]
if verify_projection and cl.surface_velocity is not None:
np.testing.assert_allclose(cl.surface_velocity, velocity, atol=3e-9, rtol=0)
incoming = []
for i, (k, d, q, fallback) in enumerate(zip(cl.fluid_idx, cl.dir, cl.q, cl.fallback_class)):
k, d, q = int(k), int(d), float(q)
rho = flat[:, k].sum()
dot = CX[d]*velocity[i, 0]+CY[d]*velocity[i, 1]
if fallback:
value = flat[d, k]-6*W[d]*rho*dot
elif q < .5:
value = 2*q*flat[d, k]+(1-2*q)*flat[d, k-CX[d]-40*CY[d]]-6*W[d]*rho*dot
else:
value = flat[d, k]/(2*q)+(1-1/(2*q))*flat[OPP[d], k]-3*W[d]*rho*dot/q
incoming.append(value)
return np.array(incoming)
def fine_flux(before, staged, active, solid):
"""Population ledger across the fine leaf boundary: solid versus halo.
Internal fluid-to-fluid streaming cancels pairwise; solid and halo packets
are counted in their actual direction, before any collision.
"""
boundary, transfer = np.zeros(9), np.zeros(9)
magnitude = 0.0
for d, (cx, cy) in enumerate(zip(CX, CY)):
incoming = active & ~np.roll(active, (cy, cx), (0, 1))
outgoing = active & ~np.roll(active, (-cy, -cx), (0, 1))
from_solid = np.roll(solid, (cy, cx), (0, 1))
into_solid = np.roll(solid, (-cy, -cx), (0, 1))
received = np.roll(staged[d], (cy, cx), (0, 1)).astype(float)
sent = before[d].astype(float)
for vector, inc, out in ((boundary, incoming & from_solid, outgoing & into_solid),
(transfer, incoming & ~from_solid, outgoing & ~into_solid)):
assert np.isfinite(received[inc]).all() and np.isfinite(sent[out]).all()
vector[d] = received[inc].sum()-sent[out].sum()
magnitude += np.abs(received[inc]).sum()+np.abs(sent[out]).sum()
return boundary, transfer, magnitude
def coarse_flux(before, fine, active):
"""Derive every replacement from physical midpoints, not production tables."""
x0, y0, x1, y1 = BOUNDS
incoming = np.stack([np.roll(before[d], (CY[d], CX[d]), (0, 1)) for d in range(9)]).astype(float)
magnitude = 0.0
for y, x in np.argwhere(active):
for d in range(1, 9):
if x0 <= x+.5-CX[d]/2 <= x1 and y0 <= y+.5-CY[d]/2 <= y1:
a, b = 4+2*(x-x0), 4+2*(y-y0)
children = fine[d, b:b+2, a:a+2].astype(float)
assert children.shape == (2, 2) and np.isfinite(children).all()
incoming[d, y, x] = children.sum()/4
magnitude += np.abs(children).sum()/4
assert np.isfinite(incoming[:, active]).all()
# This retains the eight grazing-corner replacements of uncovered donors.
flux = (incoming[:, active]-before[:, active].astype(float)).sum(axis=1)
magnitude += np.abs(incoming[:, active]).sum()+np.abs(before[:, active]).sum(dtype=float)
return flux, magnitude
def run_patch(speed, *, audit=True):
cfg = LBMConfig(nx=24, ny=24, viscosity=.05, velocity=0, rho=1)
coarse_active = np.ones((24, 24), bool)
coarse_active[4:20, 4:20] = False
source = object_spec(speed)
state = vars(source.state).copy()
with CudaContext(0) as context:
build = (patch.object(compiler, "compile_kernel", audit_compiler(compiler.compile_kernel))
if audit else nullcontext())
with build:
backend = implementation.FixedPatchStepper(cfg, BOUNDS, context=context, fine_objects=[source])
with backend, context.activate():
c, f = backend._levels
cl = backend._fine_curved
geometry = {name: getattr(cl, name).copy() for name in GEOMETRY}
flags = backend.fine_boundary.flags.reshape(40, 40)
solid = (flags & SOLID) != 0
active = np.zeros((40, 40), bool)
active[4:-4, 4:-4] = True
active &= (flags & FLUID) != 0
active &= ~solid
local = backend.fine_boundary.objects[0]
assert local.center == (20., 20.) and local.radius == 4.3
assert source.center == (12.25, 12.25) and source.radius == 2.15
yy, xx = np.mgrid[:40, :40]
roi = active & ((xx-20)**2+(yy-20)**2 <= 9**2)
backend.initialize(rest((24, 24)), rest((40, 40)))
if audit:
for level in backend._levels:
for name in ("collision_counts", "explosion_counts", "incoming_counts"):
pointer, size = level.module.get_global(name)
cuda.memset_d8(pointer, 0, size)
initial = backend.download()
initial_pop = initial[0][:, coarse_active].sum(axis=1, dtype=float)
initial_pop += .25*initial[1][:, active].sum(axis=1, dtype=float)
boundary, fine_transfer, coarse_transfer = np.zeros(9), np.zeros(9), np.zeros(9)
budget_sum, reflection_error, drive_mass = 0., 0., 0.
traces = []
original_curved, original_fine, original_coarse = backend._curved, f.kernel, c.kernel
def curved(*args, **kwargs):
nonlocal boundary, fine_transfer, budget_sum, reflection_error, drive_mass
backend._stream.synchronize()
before = read(args[0], f.shape)
expected = reflection_oracle(before, cl, speed)
original_curved(*args, **kwargs)
backend._stream.synchronize()
staged = read(args[0], f.shape)
d, k = cl.dir.astype(int), cl.fluid_idx.astype(int)
values = staged.reshape(9, -1)[OPP[d], k+CX[d]+40*CY[d]]
passive = reflection_oracle(before, cl, None, verify_projection=False)
drive_mass += .25*float(np.sum(values-passive))
error = float(np.max(np.abs(values-expected)))
reflection_error = max(reflection_error, error)
assert error <= 1e-7
np.testing.assert_array_equal(staged[:, active], before[:, active])
b, transfer, magnitude = fine_flux(before, staged, active, solid)
boundary += .25*b
fine_transfer += .25*transfer
budget_sum += .25*magnitude
def fine(*args, **kwargs):
nonlocal budget_sum
backend._stream.synchronize()
staged = read(args[0], f.shape)
original_fine(*args, **kwargs)
backend._stream.synchronize()
advanced = read(args[1], f.shape)
assert np.isfinite(advanced[:, active]).all()
assert np.isnan(advanced[:, solid]).all()
# Include actual collision operands in the FP32 rounding budget.
budget_sum += .25*np.abs(staged[:, active]).sum(dtype=float)
traces.append(advanced[:, roi].copy())
def coarse(*args, **kwargs):
nonlocal coarse_transfer, budget_sum
backend._stream.synchronize()
before, fine_values = read(args[0], c.shape), read(args[2], f.shape)
transfer, magnitude = coarse_flux(before, fine_values, coarse_active)
coarse_transfer += transfer
budget_sum += magnitude
return original_coarse(*args, **kwargs)
with patch.object(backend, "_curved", curved), patch.object(f, "kernel", fine), \
patch.object(c, "kernel", coarse):
backend.step(2)
actual = backend.download()
population = actual[0][:, coarse_active].sum(axis=1, dtype=float)
population += .25*actual[1][:, active].sum(axis=1, dtype=float)
ledger = boundary+fine_transfer+coarse_transfer
error = MOMENTS@(population-initial_pop-ledger)
budget = 8*np.finfo(np.float32).eps*budget_sum
assert np.isfinite(budget_sum) and budget_sum > 0
assert np.max(np.abs(error)) <= budget
if speed:
assert speed*drive_mass > 0
assert len(traces) == 4 and backend.step_count == 2
if audit:
for level, mask, count in ((c, coarse_active, 2), (f, active, 4)):
pointer, size = level.module.get_global("collision_counts")
counts = read(pointer, mask.shape, np.uint32)
assert size == counts.nbytes
np.testing.assert_array_equal(counts, count*mask)
for name, values in geometry.items():
np.testing.assert_array_equal(getattr(cl, name), values)
assert vars(source.state) == state and source.geometry.center == source.center
print(f"speed={speed} audit={audit} BFL={reflection_error:.9g} ledger={error.tolist()} "
f"budget={budget:.9g} boundary={list(MOMENTS@boundary)} "
f"transfer={list(MOMENTS@(fine_transfer+coarse_transfer))} "
f"drive_mass={drive_mass:+.9g}; counts={'PASS' if audit else 'normal build'}", flush=True)
return traces, roi, actual
def uniform_reference(speed, roi):
# Reuse the existing explicit config helper without importing unrelated tests.
spec = importlib.util.spec_from_file_location("fine_surface_cases", ROOT/"tests/integration/_cases.py")
cases = importlib.util.module_from_spec(spec)
spec.loader.exec_module(cases)
with cases.make_sim(nx=48, ny=48, viscosity=.1, velocity=0, rho=1) as sim:
sim.add_body("circle", center=(24, 24), radius=4.3, surface_actuation=surface(speed))
sim.initialize()
# Uniform 48^2 has the same dx=dt=.5 representation. Its distant channel
# boundaries cannot influence the circle ROI within these four hops.
traces = []
for _ in range(4):
sim.run(1)
traces.append(sim.get_ddf().reshape(9, 48, 48)[:, 4:44, 4:44][:, roi].copy())
return traces
@pytest.mark.parametrize("speed", [0., .002, -.002])
def test_fine_surface_four_hops(speed):
assert Path(CelerisLab.__file__).resolve() == ROOT/"src/CelerisLab/__init__.py"
assert Path(compiler._KERNEL_DIR).resolve() == ROOT/"src/CelerisLab/lbm/kernels"
assert Path(implementation.__file__).resolve() == ROOT/"src/CelerisLab/lbm/refinement_stepper.py"
actual, roi, final = run_patch(speed)
reference = uniform_reference(speed, roi)
for got, wanted in zip(actual, reference):
np.testing.assert_allclose(got, wanted, atol=3e-6, rtol=0)
np.testing.assert_allclose(MOMENTS@got.astype(float), MOMENTS@wanted.astype(float),
atol=2e-5, rtol=0)
if speed == 0:
passive, passive_roi, passive_final = run_patch(None, audit=False)
np.testing.assert_array_equal(passive_roi, roi)
for got, wanted in zip(actual+list(final), passive+list(passive_final)):
np.testing.assert_array_equal(got, wanted)
@pytest.mark.parametrize("missing", ["surface_velocity_gpu", "link_exchange_gpu"])
def test_missing_surface_device_buffer_rejects_before_launch(missing):
backend = implementation.FixedPatchStepper.__new__(implementation.FixedPatchStepper)
backend.fine_boundary = SimpleNamespace(objects=[object_spec(.002)])
backend._fine_curved = SimpleNamespace(surface_velocity_gpu=object(), link_exchange_gpu=object())
setattr(backend._fine_curved, missing, None)
backend._curved = Mock()
with pytest.raises(RuntimeError, match="Surface boundary device buffers are missing"):
backend._apply_fine_boundary(object())
backend._curved.assert_not_called()
def test_close_frees_fine_boundary_after_stream_failure_once():
backend = implementation.FixedPatchStepper.__new__(implementation.FixedPatchStepper)
backend.ctx = SimpleNamespace(activate=nullcontext)
backend._lock = RLock()
backend._status = "ready"
stream, soa, first, second = Mock(), Mock(), Mock(), Mock()
stream.synchronize.side_effect = RuntimeError("stream synchronization failed")
backend._stream = stream
backend._fine_curved = soa
backend._fine_flags = first
backend._curved = Mock()
backend._levels = [object(), object()]
backend._allocations = [first, second]
with pytest.raises(RuntimeError, match="stream synchronization failed"):
backend.close()
assert backend._status == "closed"
assert backend._levels == [] and backend._allocations == []
assert backend._fine_curved is None and backend._fine_flags is None
assert backend._curved is None and backend._stream is None
backend.close()
stream.synchronize.assert_called_once_with()
soa.free.assert_called_once_with()
first.free.assert_called_once_with()
second.free.assert_called_once_with()
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,102 @@
{
"head": "6e3756c587ec08ab6a55c4a1a5f4671822d3f0a0",
"changes": [
{
"path": "src/CelerisLab/lbm/kernels/refinement.cu",
"added": 10,
"removed": 2,
"sha256": "129f3d91da93b4324f88a0da73a4da1e5390f72c14cce574ee63306712da9895",
"characters": 4482
},
{
"path": "src/CelerisLab/lbm/kernels/step/aux_kernels.cu",
"added": 1,
"removed": 55,
"sha256": "578a5b20a157241ee678547059abb1372dd5a589ad06bb2c15b987eb01ca1013",
"characters": 10982
},
{
"path": "src/CelerisLab/lbm/kernels/step/curved_double.cu",
"added": 61,
"removed": 0,
"sha256": "bfa7a1df1e939020314d49755045f7a85fe4a19cc1c68dbe62653c66c5e7c2b3",
"characters": 2153
},
{
"path": "src/CelerisLab/lbm/refinement.py",
"added": 157,
"removed": 3,
"sha256": "8935b070ec9e7020897919c15f43f7fa6293f02e2ff64a19a3e3d99bc444dbcc",
"characters": 14161
},
{
"path": "src/CelerisLab/lbm/refinement_stepper.py",
"added": 66,
"removed": 10,
"sha256": "9178224089ee6584420b79f10cf1d91441645b668e8b6898641d19eac757687b",
"characters": 14875
},
{
"path": "src/CelerisLab/lbm/stepper.py",
"added": 5,
"removed": 1,
"sha256": "0dcb7cd7ae87e33e3dc67a38b6aa43042fbe673e37d9ad165342ee1d695933ce",
"characters": 7724
},
{
"path": "tests/unit/test_fine_surface.py",
"added": 215,
"removed": 0,
"sha256": "b232b55e75eef52480f06a35c401d72b6145892bb8b79d1d1b3cfed965b3506c",
"characters": 10596
},
{
"path": "tests/validation/multigrid/test_fine_surface_gpu.py",
"added": 330,
"removed": 0,
"sha256": "d45ca48fc4e77d021fcc5461329b094ae11b257c036bb23634d326fbbedb7700",
"characters": 16204
}
],
"unchanged_baseline_files": 377,
"baseline_file_count": 382,
"post_status": " M pyproject.toml\n M setup.py\n M src/CelerisLab/__init__.py\n M src/CelerisLab/body/__init__.py\n M src/CelerisLab/body/ddf_patch.py\n M src/CelerisLab/body/manager.py\n M src/CelerisLab/body/objects.py\n M src/CelerisLab/body/preprocess/flag_overlay.py\n M src/CelerisLab/common/__init__.py\n M src/CelerisLab/common/checkpoint.py\n M src/CelerisLab/config.py\n M src/CelerisLab/configs/CONFIG.md\n M src/CelerisLab/cuda/__init__.py\n M src/CelerisLab/cuda/compiler_v2.py\n M src/CelerisLab/cuda/context.py\n M src/CelerisLab/lbm/__init__.py\n M src/CelerisLab/lbm/curved_links.py\n M src/CelerisLab/lbm/field.py\n M src/CelerisLab/lbm/initializers.py\n M src/CelerisLab/lbm/kernels/boundary/bounce_back.cuh\n M src/CelerisLab/lbm/kernels/boundary/curved_boundary.cuh\n M src/CelerisLab/lbm/kernels/boundary/inlet/common.cuh\n M src/CelerisLab/lbm/kernels/boundary/inlet/zou_he_local.cuh\n M src/CelerisLab/lbm/kernels/boundary/inlet_outlet.cuh\n M src/CelerisLab/lbm/kernels/config/config_grid.h\n M src/CelerisLab/lbm/kernels/config/config_method.h\n M src/CelerisLab/lbm/kernels/config/config_objects.h\n M src/CelerisLab/lbm/kernels/config/config_physics.h\n M src/CelerisLab/lbm/kernels/kernel_v2.cu\n M src/CelerisLab/lbm/kernels/operators/collision_mrt.cuh\n M src/CelerisLab/lbm/kernels/operators/collision_trt.cuh\n M src/CelerisLab/lbm/kernels/operators/forcing_guo.cuh\n M src/CelerisLab/lbm/kernels/step/aux_kernels.cu\n M src/CelerisLab/lbm/kernels/step/esopull_sync.cu\n M src/CelerisLab/lbm/kernels/step/init_flow.cu\n M src/CelerisLab/lbm/kernels/step/one_step_double.cu\n M src/CelerisLab/lbm/kernels/step/one_step_esopull.cu\n M src/CelerisLab/lbm/kernels/streaming/esopull_semantic_helpers.cuh\n M src/CelerisLab/lbm/stepper.py\n M src/CelerisLab/simulation.py\n M tests/integration/test_body_sync_e2e.py\n M tests/integration/test_ddf_patch.py\n M tests/integration/test_sync_bodies_skeleton.py\n M tests/integration/test_unified_obs.py\n M tests/postproc/experiment.ipynb\n M tests/validation/run_kan99b_rotating_cylinder.py\n M tests/validation/run_sah04_st_matrix.py\n M tests/validation/test_sensor_accuracy.py\n?? docs/design/\n?? docs/multilevel_grid_architecture_analysis.md\n?? examples/\n?? research/\n?? src/CelerisLab/lbm/kernels/boundary/planar_velocity.cuh\n?? src/CelerisLab/lbm/kernels/refinement.cu\n?? src/CelerisLab/lbm/kernels/step/curved_double.cu\n?? src/CelerisLab/lbm/refinement.py\n?? src/CelerisLab/lbm/refinement_stepper.py\n?? \"tests/audit/body\\345\\210\\240\\345\\207\\217\\345\\212\\237\\350\\203\\275.md\"\n?? tests/integration/_cases.py\n?? tests/integration/test_numerical_gpu.py\n?? tests/integration/test_runtime_contracts_gpu.py\n?? tests/integration/test_state_gpu.py\n?? tests/integration/test_surface_actuation_gpu.py\n?? tests/unit/cpp/\n?? tests/unit/test_build_contracts.py\n?? tests/unit/test_context_ownership.py\n?? tests/unit/test_fine_surface.py\n?? tests/unit/test_initializers.py\n?? tests/unit/test_numerical_operators.py\n?? tests/unit/test_planar_velocity.py\n?? tests/unit/test_refinement.py\n?? tests/unit/test_reservoir.py\n?? tests/unit/test_simulation_lifecycle.py\n?? tests/unit/test_slot_velocity.py\n?? tests/unit/test_state_regressions.py\n?? tests/unit/test_surface_actuation.py\n?? tests/validation/analyze_j3_saved_frames.py\n?? tests/validation/diagnose_j3_lags.py\n?? tests/validation/multigrid/\n?? tests/validation/run_j1.py\n?? tests/validation/run_j2_slot.py\n?? tests/validation/run_j3_coverage.py\n?? tests/validation/run_j3_reservoir.py\n?? tests/validation/run_poiseuille.py\n",
"patch_sha256": "9cf8b5cc4ea037c865762ba7069f0c1daabcb4383d4333167d279f8b7704e5b0",
"cleanup": {
"baseline_copy_dir": "/tmp/celeris-fine-surface-baseline-z98oi6ps",
"baseline_copy_bytes": 1581541,
"runner": "/tmp/celeris-fine-surface-gpu-run.py",
"baseline_copies_removed": true,
"runner_removed": true,
"gpu_scratch_removed": true
},
"shared_kernel_exact_extraction": true,
"diff_reverse_check": "passed",
"evidence_hashes": {
"cpu_surface_projection_command.txt": "b1783e26e92737106a5614fff01452c8ea0364372d9bdbc44c7d15c19d9b13f5",
"cpu_surface_projection_exit.txt": "9a271f2a916b0b6ee6cecb2426f0b3206ef074578be55d9bc94f6f3fe3ab86aa",
"report.txt": "ad8af2be7239f8fe728ac7a8db340d4458e6ec1bbb30b14e614c1072dd9804ec",
"cpu_existing_runs.json": "523b3179b976c2198112c7b49c6c8a75cf7d3332663a8b8a0646c94a39abd1b4",
"gpu_run.json": "8c4b4d7c53e17c30ce4c7d2fb92466e0704f39966e89016dbf82d36cf96e35bf",
"gpu_stdout.txt": "02d1f6fea194d1185a49b7bcdde58642f1d6b9634fe55e4bcda2f020414eb35d",
"cpu_device_guard_cmd.txt": "43a0fb0e20c4adcf1930f145796378294558060d5fd5303402e0538674b68c0a",
"cpu_surface_command.txt": "2b8f2a3c9ddfd1e877efa2a50a935eeb937e2b3ea92515610cd334d80703d6ce",
"baseline.json": "dc9dfa88e69d2b7cf93b0c572961c0bc7849ea1608a0b14b1a6dca1429abf87c",
"cpu_lifecycle_stdout.txt": "af52542989b4a2bf597e020c12064e7083e136f15b938ed5382b616a16f70e38",
"cpu_surface_projection_stdout.txt": "96ea3e4ca948962b6eb92aaf215efb6c598a3c4b296f6fd26094df353ded5722",
"cpu_lifecycle_run.json": "2a3b09ad2f9c86e43892d643a510c9e936d6153e2ae1f6a9eab90c3067f0473d",
"cpu_shared_kernel_stdout.txt": "1ab9905d8b0f34f6d791ff7da4efa2de0f7f3e282a078758cc0496cc0230c0f0",
"cpu_device_guard_stdout.txt": "f4c61c0ac8f55c6c9a2d6c593731bf5f8c4a6c5bebbe514284fd4f899818f9e0",
"gpu_test_run1.py": "3dd0658f63a4e7a1c41eecf433842c872f8fecb391ea4b44d0b48947643d5189",
"gpu_preparation_run1.py": "b3fe9e58118369adb1bdfc618fbfbd917d508a563beaf2555f656b59aeff4425",
"cpu_surface_exit.txt": "9a271f2a916b0b6ee6cecb2426f0b3206ef074578be55d9bc94f6f3fe3ab86aa",
"cpu_surface_stdout.txt": "bdb786f2d289eaeab4e53d0fdccb998525c217efaa778496cf7a97ccca9e1597",
"cpu_preallocation_run.json": "363106050ba00d9a1c5c948c36926e8510ed7fdd75d28cfeca59f593fd0f1c50",
"cpu_final_stdout.txt": "bdb786f2d289eaeab4e53d0fdccb998525c217efaa778496cf7a97ccca9e1597",
"cpu_maps_stdout.txt": "7886fd4e2fa8a63e9cecf02bdf650e5447ba149704ac75f51da6964d8e77ba6b",
"cpu_device_guard_exit.txt": "9a271f2a916b0b6ee6cecb2426f0b3206ef074578be55d9bc94f6f3fe3ab86aa",
"cpu_preallocation_stdout.txt": "59907462a8d5fd93406cdf4c7d1eb2f7b7a96664ae85c4ec202693d419cd019e",
"incremental.diff": "9cf8b5cc4ea037c865762ba7069f0c1daabcb4383d4333167d279f8b7704e5b0",
"cpu_final_run.json": "020a9ef12904c2d18185613d68a58dd7ff9b1b22197ac1f95bba61f2f593eaac"
}
}
+115
View File
@@ -0,0 +1,115 @@
2026-10-14 — 固定加密区内静止圆表面吹吸:受限整合交付
状态:当前代码与验证完成,停在独立审查点。A 的单层静止圆功能保持;本次只
把完整边界 stencil 位于 fine active 的圆接入 FixedPatchStepper。未增加
checkpoint、forcing、运动刚体、喷嘴内部、墙穿接口、blockforest 或临时 ledger。
所有 B 反例与既有证据保留。
入口与单位
FixedPatchStepper(cfg, bounds, context=context, fine_objects=[obj])。
obj 是现有 SimObject/CircleGeometry;中心/半径用 coarse 物理坐标,速度沿用
coarse lattice 单位(当前 dx=dt=1)。构造独立 fine-local 副本,不修改调用方对象。
C_local=(C_phys-origin)/dx-.5,R_local=R_phys/dx,U_local=U_phys*dt/dx。
真实 hit 反变换为 origin+dx*(hit_local+.5),lever arm 乘 dx,角度/q 不变。
维持 D2Q9/SRT/FP32/unshifted/double_buffer、无 LES/forcing 的原 backend 范围。
生产改动:5 个现有文件 + 1 个共享文件,+300/−71,净 +229 行。
- refinement.py:FineBoundary2D、prepare_fine_boundary;纯 CPU 建图和拒绝检查。
- refinement_stepper.py:固定 fine 对象、flags/SoA 管理、两个 BFL 子步、solid
叶掩码、初始化与释放;不接完整 Simulation/ObjectManager。
- aux_kernels.cu → step/curved_double.cu:原 action_omega/CurvedBoundaryKernel
代码块逐字相同,只抽取共享位置并增加 include guard,已比对确认。
- refinement.cu:包含共享 BFL,PatchFineStep 接 flags;solid 不 pull/collide,
输出 NaN;所有 Python launch 传完整参数。
- 原 lbm/stepper.py:allocation 显式 is not None;驱动缓冲缺失报错。
数据/所有权
explosion → BFL(current) → fine pull+collision → BFL(spare) → fine pull+collision
→ coarse pull/coalescence+collision。active fluid 每 coarse 步碰撞两次;solid
与 ghost 不碰撞。BFL 只填当前输入的 solid source 反射槽,下一子步重新填充。
下载仅发布流体叶节点,coarse covered、fine solid/ghost 均 NaN。
flags/level/transfer arrays 归 stepper._allocations;SoA 的列及速度/交换缓冲只
归 SoA,未重复登记。initialize 清空最新交换缓存。无对象不创建这些新缓冲。
内部交换缓冲仅代表最后一个 fine 子步,未新增公共 coarse 累计诊断。
测试账本分别读取四个 fine 子步的实际 population,按面积 1/4 求和;不是用
latest 值冒称区间总量,也不是喷嘴总推力。
有限依赖规则
plan.transfer_reads 保存 (hop, direction, cell),从实际 coalesce_fine 的 hop 2
源槽反向两次 pull;遇 active collision 展开全部 9 个输入,hop 0 停止。
transfer_fine_cells 加入全部 ghost_fine/explosion 写集;coarse 集合包含实际
ghost_coarse donors 与 coalesce_coarse targets。ghost 可以合法参与运输;
outer ghost 的各阶段有效性仍按原 kernel 判断。
逐条检查 r active fluid、s=r+c active solid、反射写槽唯一、q<.5 的 r−c
仍在 active;不可用 fallback 掩盖跨层 donor。同层真实 solid 阻挡的原 fallback
语义不改。逆查所有 active-fluid→solid 邻接,确保与 cut links 完全一致。
整个 solid 集合及 r/s/donor stencil 均不得碰到上述 transfer footprint。
coarse donors/targets 必须 uncovered bulk;slot 模式另外拒绝其真实壁面
reconstruction pull stencil。无对象旧 slot 模式保持原规则。
CPU 结果(原始 command/stdout/exit 见同目录)
- 新建图/单位/边界覆盖/拒绝检查:15 passed,最终代码复测 15 passed,exit 0。
同行补充的非对角圆心、origin=(2,2)、四子格平均等于 coarse I+.5 也通过。
- 旧 maps:9 passed、23 subtests;共享 actual CUDA-header CPU 回归:1 passed。
- 旧生命周期/边界模式:5 passed、5 subtests。
- 新缺失驱动缓冲拒绝:2 passed,exit 0;同步失败后释放且不重复释放:通过。
- 指定 donor 反例通过构造器检查,context.activate/mem_alloc 均未调用:1 passed。
真实 GPU 结果与首次批次失败说明
使用现有 pycuda_3_10、显式 PYTHONPATH=/home/frank14f/CelerisLab/src;stdout
首先打印并断言实际包来源。设备 0 UUID GPU-e8853ae7-a302-6a17-bcfa-aa767e9ed20c,
开始时占用 5 MiB、util=0、无计算进程;未用其他设备。
运行批次真实 exit=1:5 项 GPU 检查和 1 项 CPU cleanup 检查通过,另 2 项 CPU
缺失缓冲夹具失败,因为夹具未提供新增前置检查所需的 fluid_idx_gpu 字段。
仅补齐夹具后,定向 CPU 重测这 2 项 exit=0;原日志/exit=1 保留,未重跑 GPU。
5 项 GPU 检查:
1–3. speed=0,+.002,−.002 的批准小案例,各 2 coarse/4 fine 步。
coarse24²,patch[4,20)²,fine40²,origin(2,2),dx=dt=.5;物理圆心
(12.25,12.25)、R2.15 → local(20,20)、R4.3;angle.7/half_width.85;
nu_phys=.05,tau_c=.65/tau_f=.8,rho1/u0/G=feq。
三个驱动使用私有 audit build 验证 fine fluid 碰撞4次、coarse fluid2次,
solid/ghost0次。零驱动另与正常 production build 的 same-solid/no-actuation
路径逐元素相等。参考采用正常 A build 的48²、dx=dt=.5、circle local(24,24),
对齐真实物理位置与时间(4 fine步=物理时间2),不是跨分辨率逐元素比较。
4. 旧无对象 periodic 非居中矩形 normal build:1 coarse步,最大人口误差
1.14050047e−7,通过。
5. 旧无对象 slot/reservoir normal build:8 coarse步,最大人口误差
1.78241457e−7、最大BC误差2.21654773e−7,通过。
主要数值:
speed max |BFL误差| max |累计质量/动量账本残差| 预定FP32预算
0 7.4505806e−9 1.6049482e−5 0.00221051117
+.002 9.7307344e−9 1.5977304e−5 0.00221052543
−.002 7.4505806e−9 1.6636681e−5 0.00221049693
BFL阈值1e−7;同细分辨率、未触接口的圆周ROI人口atol3e−6、局部矩2e−5均通过。
账本预算为8*eps32*实际参与加权population绝对值总和,未放宽。喷吸附加质量
分别约+0.00620033871/−0.00618575338,符号正确。该短例净transfer项为0;
仍逐项统计真实非零出入人口,但喷吸扰动尚未触达接口。
拒绝证据
- physical C=(5.05,12.25),R=.7 → fine C=(5.6,20),R=1.4:r=(4,20),c=(1,0),
hit=(4.2,20),q≈.2,donor=(3,20)为ghost,构造在任何CUDA调用前拒绝。
- physical C=(6.05,12.25),R=.7:全部直接r/s/donor都active,仍因与真实
两hop transfer footprint相交而拒绝。说明通过边界检查不能仅靠包围盒或边距。
资源与记录
GPU批次外部耗时25.395s;进程组RSS峰值386883584 bytes,RAM最小空闲
63638339584 bytes,VRAM最小空闲15826 MiB,相关临时空间采样峰值3585985 bytes。
按实际余量保护,无固定RSS/AS上限;120s与2GB本次临时量约束未触发。监测是
采样方式,不是OS硬资源隔离。编译临时目录已清理;不会清理其他任务或旧证据。
baseline.json保存382个src/tests/examples文件哈希;其中377个保持不变。
manifest.json和incremental.diff只描述本轮;共享kernel抽取相等与反向patch检查通过。
GPU执行后仅将建图时的孔口预检输入改成与实际八列完全一致的FP32 lever arm,
避免极窄孔口在分配前后得到不同覆盖判断;最终CPU15项复测通过。GPU算子、上传
数组生成方式、步序和测试数值部分未变。gpu_test_run1.py/gpu_preparation_run1.py
是按GPU运行中已记录的SHA256逐项核对后的执行版快照,保留首次运行的精确来源。
参考与边界
直接复用A已接受BFL。ref/OpenLB/src/boundary/defineU2D.hh:74–79用于真实hit
速度投影对照,offBoundaryPostProcessors2D.hh:115–127用于两分支stencil对照;
OpenLB commit fb62326f260bf0c5ec2666fc5e055c0813ff50a9,仅算法对照、未复制代码。
现有CPUREF-0.3与实际refinement kernel的ghost不碰撞、两hop/每层tau、incoming
替换后coarse碰撞保持不变,未移植任何B候选。
不声称喷流穿粗细接口精度、长时稳定性、空间收敛或性能已验证。设备free()自身
抛错时沿用既有close限制,不保证完整释放或重试;上下文激活失败可保留资源重试。
@@ -0,0 +1,182 @@
{
"src/CelerisLab.egg-info/PKG-INFO": "0b9a8a4e8d60bc531473688723ddef0aab02c7ccc4997e31c9b6a6c35011ca77",
"src/CelerisLab.egg-info/top_level.txt": "cd51958ca03afabbaa9618c60b8280e486f8cc0b0359b839e10f886e7c3948f8",
"src/CelerisLab.egg-info/dependency_links.txt": "01ba4719c80b6fe911b091a7c05124b64eeece964e09c058ef8f9805daca546b",
"src/CelerisLab.egg-info/requires.txt": "36e1404178e5ea590b2fc04e8ba4d748ec9a82e7693136ccf0dfd204fe265c04",
"src/CelerisLab.egg-info/SOURCES.txt": "f36b29c1b34c4bd6b2acc3ccdd21c24ee5077df7e2a20a652d9fae77eedb8e21",
"src/CelerisLab/simulation.py": "c9d903f53fe356d7af281bea07943de1a62494127fb69848d7053fd46f7dec3e",
"src/CelerisLab/config.py": "2f1bba7515f5bc08cb3a8d140bcafe7fa0689e01b3b06494697bb2956a71530e",
"src/CelerisLab/__init__.py": "21cc469bd6e970a1f9ff5970c8eea4602065e41fc881854759ee565ee55c10c6",
"src/CelerisLab/cuda/compiler_v2.py": "c4cc3ec4445c8d75e6a253dd87963877117a722bc73b9d4811806fc6045d08c1",
"src/CelerisLab/cuda/obs_layout.py": "5ffb2c3aeeaaaaeb64f2cd8febfbcf4ad9919e5414020ad753cfade0683b21c2",
"src/CelerisLab/cuda/context.py": "013dd4ec6d01d2fbd11afdfb103eac6a273bd9f798d663d761b851eeb27885e9",
"src/CelerisLab/cuda/__init__.py": "0d01dff9f0399c8baba822aab5ca0122a135f011008ed8a499ebd9f7e5b06aea",
"src/CelerisLab/lbm/refinement_stepper.py": "9178224089ee6584420b79f10cf1d91441645b668e8b6898641d19eac757687b",
"src/CelerisLab/lbm/field.py": "0e727eacc3706add4d8d15c418e9b631050871f831698d3ac689dd5f2c701b9b",
"src/CelerisLab/lbm/equilibrium.py": "2fb2f2bb7ff326d23abce80fc2a4c0907b17740ea3e29fe6ae079c5044783826",
"src/CelerisLab/lbm/descriptors.py": "c9f025dfc14da43b989047b84cc22bd05d5cc92c9ec695c1da68fdfb788e3f2b",
"src/CelerisLab/lbm/initializers.py": "dacf9586963e862d6d0a98ef1a066036be6f91e9d423720661d8ef2c1fb2df6a",
"src/CelerisLab/lbm/curved_links.py": "00d9c29d660b41190f32dd737b12f60e10ce4214b6c9a6ab2a63438813faa594",
"src/CelerisLab/lbm/stepper.py": "0dcb7cd7ae87e33e3dc67a38b6aa43042fbe673e37d9ad165342ee1d695933ce",
"src/CelerisLab/lbm/__init__.py": "7f60fb3aaae81501b510d08c2fedff44fcb05657260eb10b6f5cc91e7204306b",
"src/CelerisLab/lbm/refinement.py": "8935b070ec9e7020897919c15f43f7fa6293f02e2ff64a19a3e3d99bc444dbcc",
"src/CelerisLab/lbm/kernels/kernel_v2.cu": "c7bd3fb705b77261ba2441c52a24a7e6a7865c165cba088a1b75201c4d29c408",
"src/CelerisLab/lbm/kernels/refinement.cu": "129f3d91da93b4324f88a0da73a4da1e5390f72c14cce574ee63306712da9895",
"src/CelerisLab/lbm/kernels/config.h": "7d1124125e0b354558297934460e64c760fb68cdd7bf6d01a1238bb2eaab8c37",
"src/CelerisLab/lbm/kernels/kernel_v2.ptx": "a599ee30ae66800f4d4220eb79dfed35ff32991661260f01ea58023ef780f0ca",
"src/CelerisLab/lbm/kernels/operators/turbulence_smag.cuh": "ff7f000297ee0817e255ad9fcb6a13b647e3ddd5b206518d35f38d2895a9f501",
"src/CelerisLab/lbm/kernels/operators/collision_mrt.cuh": "aee444eb60c47a3fd518dca975d1af05425a0818a0ec6c3fb3f6150f60c2cb44",
"src/CelerisLab/lbm/kernels/operators/collision_trt.cuh": "9725b9840b9ad8b4ec7be61ff5d06d3151e86d1a87585c13f2fbf934d0d2c5f6",
"src/CelerisLab/lbm/kernels/operators/collision_srt.cuh": "6b7ff842f392c8f853d2d1a97cc69bfe50f21283f73e659404da07cf6c95f5e1",
"src/CelerisLab/lbm/kernels/operators/forcing_guo.cuh": "969a430c1af03f32e3bd0df95d805e64f56334717c44dd4ba208ba503062a24b",
"src/CelerisLab/lbm/kernels/operators/macro.cuh": "e27c1c410dc857be98da4596568e405eeaf88701d291ac0e398aa9cd23dee740",
"src/CelerisLab/lbm/kernels/operators/helpers.cuh": "0b3a4d95d7d19f5fec09e5423b8f4cc99f8a226b541967425967330da5a051ec",
"src/CelerisLab/lbm/kernels/core/precision.cuh": "849df14b4cce50af52399e4b8f3e997196f3ae5f1163f68e28df3e6b2507a8c4",
"src/CelerisLab/lbm/kernels/core/descriptors.cuh": "8440bc14857da9007982650f828a23608eec9f7cc4bf772e8c8dc1239cb45356",
"src/CelerisLab/lbm/kernels/core/obs.cuh": "b742b77c9f61e1f020fe9922c3838ae9d855e17b381154958b58f10a22938922",
"src/CelerisLab/lbm/kernels/core/params.cuh": "6e18bf730d936d940e3d85452f0714a2eaae31bf41002f9fd520ec5b372878dd",
"src/CelerisLab/lbm/kernels/core/flags.cuh": "0025705f24710330d9d9195f713879bfb650a85a3449baef0e196b831af104ab",
"src/CelerisLab/lbm/kernels/core/layout.cuh": "1fbd820021c89ac3efcde24145996cb0147769e607e498e61f308ed3e0b13706",
"src/CelerisLab/lbm/kernels/boundary/ibm_kernels.cuh": "e6909b547dc8d64cdd8a76a90660243a8f5fee535caa161b52b4dd8b7c29934b",
"src/CelerisLab/lbm/kernels/boundary/planar_velocity.cuh": "0b2f9e0bd483c199637e5672dc0ffc460bc383dd1804805befbeb4c5d8c708d1",
"src/CelerisLab/lbm/kernels/boundary/inlet_outlet.cuh": "de8b213a6da42c2e5e9f8966199fc66ea4541b85144a90f3f5dbad3c6ab63b97",
"src/CelerisLab/lbm/kernels/boundary/curved_boundary.cuh": "7bccf7e7091c012d7a3d4874a881d4d46699021faedd83d125933fbdaa562711",
"src/CelerisLab/lbm/kernels/boundary/bounce_back.cuh": "aba3748c564ed91b161d268ef8b737b7c7be96a823063d201f3da684dd845233",
"src/CelerisLab/lbm/kernels/boundary/esopull_curved_helpers.cuh": "b9b474bc4edaff05681c5443235472d04072d0d775fc0eb9c5967faef52b0258",
"src/CelerisLab/lbm/kernels/boundary/inlet/equilibrium.cuh": "f0964c811b2c41a5aaa1c6d99c490b06e850c634eb8749f1f05ef61f93c2de1d",
"src/CelerisLab/lbm/kernels/boundary/inlet/channel_stabilized.cuh": "efe077afcbb6b731256a987c2fd79a1dbc470c902f87070d60421ea6cb13d4e2",
"src/CelerisLab/lbm/kernels/boundary/inlet/common.cuh": "f3cec54c8873c65b3dca4375605d2c89a8727765884d3954c235242fdff9c6ba",
"src/CelerisLab/lbm/kernels/boundary/inlet/zou_he_local.cuh": "e73e66b853b1e4e0e30d8f4185d832aa414ce670a1813ce2b5459f2887f71f89",
"src/CelerisLab/lbm/kernels/boundary/inlet/regularized.cuh": "943d4a571818bacb89c70bccfaac202691121e3e385803ce6309123a0a03ddaf",
"src/CelerisLab/lbm/kernels/boundary/outlet/pressure_neq.cuh": "c8b2adc66d12fe602076ddc9693c5c208711fcaddb58aa9a31401a269f51c4c4",
"src/CelerisLab/lbm/kernels/streaming/esopull_single_buffer.cuh": "77ed4ab9a0ebc5ff62a91a7c39066ef395391ae36e9040a69fb2bd8b1626dc79",
"src/CelerisLab/lbm/kernels/streaming/pull_double_buffer.cuh": "b65d741ed78b7b62f99531ba0c0ce1936663d8dc9640e7d7d16c707f1baf6549",
"src/CelerisLab/lbm/kernels/streaming/esopull_semantic_helpers.cuh": "dd5a9091628b079efd97e53fd49e52d09dcee88529235db77a5648e02937af6e",
"src/CelerisLab/lbm/kernels/step/curved_double.cu": "bfa7a1df1e939020314d49755045f7a85fe4a19cc1c68dbe62653c66c5e7c2b3",
"src/CelerisLab/lbm/kernels/step/esopull_sync.cu": "c0ff3e72900c3ab89a05dd03684e96d3b740cf1672d565727fc2af165933d087",
"src/CelerisLab/lbm/kernels/step/init_flow.cu": "305be3bb12fc0d039acec1701baabcf0e8a35e683c49c34f2af8ca9867d2b29c",
"src/CelerisLab/lbm/kernels/step/esopull_macro.cu": "c73116020ca217ede1e4de27c8269c31f9d91e33433ac8252a21e9b14187c50f",
"src/CelerisLab/lbm/kernels/step/aux_kernels.cu": "578a5b20a157241ee678547059abb1372dd5a589ad06bb2c15b987eb01ca1013",
"src/CelerisLab/lbm/kernels/step/one_step_esopull.cu": "aa223b2744ae6c9125673df311a96ce588032c1ba58bebb11fd33ecb990f8ed4",
"src/CelerisLab/lbm/kernels/step/one_step_double.cu": "f9f8242b38e8e0cf8425b75e2b0215bc15363c62eaa0fb43c761b8e0931bfdc9",
"src/CelerisLab/lbm/kernels/config/config_physics.h": "26df33c2960ba36f3283e19b55b4ea92e50e4efda705f9ebfbf3f875a4092c59",
"src/CelerisLab/lbm/kernels/config/config_method.h": "3db4e16ef2c6b22349d04e6aa8ab04bdfe0eb784f9f3a98277e15dbed1835d81",
"src/CelerisLab/lbm/kernels/config/config_grid.h": "8be3a7cf74ba30d7fd3074fed79e63dbda7311c4d03b454ea641bf298ffeaa8d",
"src/CelerisLab/lbm/kernels/config/config_objects.h": "dbb93c063586da278c15d95e23f84c12e728f4f5f1bbc3980fe9cedaa6fff90e",
"src/CelerisLab/lbm/kernels/config/config_obs.h": "c11e2249359145b5c4cbaaf0487506fa77c1f4b82c7c169ddc574aa0babcd727",
"src/CelerisLab/common/checkpoint.py": "b2f960aecd5ac27a3a7130b809ffad4709c44d522edef0359ab952654625410b",
"src/CelerisLab/common/_types.py": "aad2ff1a9033d4fd68783ad7123afb47201ddc58785cb6dc0246947037072a5f",
"src/CelerisLab/common/pathline.py": "a1b6efcc0a076d0f1dc8d49a595779426d7d5626b00072a59bac710ff02ad046",
"src/CelerisLab/common/__init__.py": "d4dbde78bc97fccc9eabac9abae8f0f15c112c10ff8e9b45bd9401d4723df1ef",
"src/CelerisLab/common/preprocess.py": "7fc78a08857cf8e98519500b094a1d896af189b6b15658ff9b388ed51bed4515",
"src/CelerisLab/common/render.py": "0e055476257eb2bcd11e733766e52195de02f8fad228f570a3511a7c831bdc29",
"src/CelerisLab/common/streakline/_render.py": "236cd637414ee318c4d66f9aed32110d8dc42a100d65fde06172f7cd0ba62c65",
"src/CelerisLab/common/streakline/_integrate.py": "3fbd4368b2c8d0e7fda40dc65aac5df02b085008b4c68acd83cb7ae45d33a13b",
"src/CelerisLab/common/streakline/_streakline.py": "1a3e08daa706b5f83cdeb337e9a945a36ddf7583c40af1d0bb9d825ac954df37",
"src/CelerisLab/common/streakline/__init__.py": "13ff1cfa416fdd721a08a659e76b5a5a99b8d3201add10a83b7b0bc654bc1eec",
"src/CelerisLab/common/streakline/_config.py": "a9185ef68e9c7b5d5a1dc0b04a28341e2ad91d13c145a7c106636a878cf0a605",
"src/CelerisLab/configs/config_lbm.json": "17e4311f1f250c6ece59177a8b6ff856b69a016c7c10267e774b030a0a390865",
"src/CelerisLab/configs/CONFIG.md": "41cafdbe525366c08aa9d0416ea026ccf0026ba7123b8a9b65f968a80d928e3a",
"src/CelerisLab/configs/config_lbm_three_cylinder_triangle.json": "eeb8e7149dbe4aa6b3a9562802735aa950750dfbe2d972a0727e788573afa817",
"src/CelerisLab/configs/config_lbm_flume_trt_regularized.json": "f4bba8e6a4339fc3c4eb14f6e2f57c4b22993c73703c773d853edfbe34736e56",
"src/CelerisLab/configs/config_body.json": "055f261f0828ca1d4f2bb694bd15b72bbcabe31d552326208f28e37f761adab1",
"src/CelerisLab/configs/config_lbm_flume_mrt_zouhe.json": "8f593321db05a563a42931603a228d61cbcba06dfbe113262d5cd0ad93c0fe79",
"src/CelerisLab/body/objects.py": "d1cf7054cc8379a83c39acc66a7c88ae62fa004f110bb0c1def2ee57137401c5",
"src/CelerisLab/body/action_smoother.py": "b1a23ee6bbd4850b172cb8738c5c3546ee465a54189e6af9d8044f023d4687dc",
"src/CelerisLab/body/registry.py": "fbb7327780adbdc6da15ebdb799980daf32df22ee974af0893d7409f177bbb68",
"src/CelerisLab/body/manager.py": "6a40be708c71ef6f3b5f5f0aa9c92cfafc51f2ec2a958f99656cccb850986c16",
"src/CelerisLab/body/ddf_patch.py": "60fcfb7441e73bf290bcff41ca3a83da3e7ddad765d7247464e8f02e3043b4e2",
"src/CelerisLab/body/sync_plan.py": "a73ac9ee361b2120d0b7bbebeaa2ccbf924ba27bd95d4dd4b383c10a39b2a409",
"src/CelerisLab/body/__init__.py": "91d1155080b3ade83d13c84c39693046df122e4bed5ef583de2df1f9453c1b76",
"src/CelerisLab/body/preprocess/flag_overlay.py": "831fc9e9736b758847759a085ff133eb49ec91318ace4fda76f85960138ee300",
"src/CelerisLab/body/preprocess/__init__.py": "dfd9d58bc07f626ab23a70053e31b88a6d9165d2e4c76a4e9f48abe674d3d2ec",
"src/CelerisLab/body/geometry/base.py": "cceca14361ca2f34d34a3e43730e1a79b8ca81be00f0dd62e884db32b479419f",
"src/CelerisLab/body/geometry/__init__.py": "ada88980ab672959aca9aa3a4c4aade3219524b2ab68110cd2a2f41e3e0ca90a",
"src/CelerisLab/body/geometry/circle.py": "7605ca7c21103f1d801ac73ab8dd18dffbdac425b2dee7b8858b283628a9e436",
"src/CelerisLab/body/coupling/soa_packer.py": "8ec26fd55ef74801bbd5ab6bd3d0a7dabc750cbd498aaac2ca4c61a0108ad3c9",
"src/CelerisLab/body/coupling/__init__.py": "c931f7eb318d48408c3e2febcc6917c88c8dcc1697cbf4329b1f340d94c35763",
"tests/conftest.py": "fa0ec26667872c9c1011d608310d2551fd24719b5d216f06d923ff4c74c73237",
"tests/specs/exp_ctrl_matrix.md": "5d9dd2e703582572eb68afe3a7096ea43ec82aa03418d20ed283c5365031e433",
"tests/specs/Sah04_validation.md": "1d122d29e281b7f50801b148f3314a0e35fdc27ee7d757c0a661243aa6185fb0",
"tests/specs/sah04.md": "33dbe5e0fd63738abd055c4aa403c191b6de04e6efdbc568f1942c6d23c7459f",
"tests/specs/Kan99b_validation.md": "0d8bf74f2361f863809af1979bf8807adaa423f98321e1104a3d86d8c7a863cf",
"tests/specs/kan99b.md": "b7e0669f0a6b677d902204f3427d1b3ac254bfe70c37d9cf995fb3e8f1fedfb1",
"tests/specs/streakline_notes.md": "cd342d214c07eb608ac2e5b8697322c44c31dbf4d27dfdb5409de46ef474df4b",
"tests/validation/run_perf_baseline.py": "93dde2eb1132f45ea69e1e285ff421dc97a83651a22c79571f299c1909650721",
"tests/validation/run_j1.py": "51b758a271ff358f931b3140a80082294a67e66c2fec0f8c19319e37f92aadc4",
"tests/validation/run_kan99b_rotating_cylinder.py": "323186429a100f36b41ab9b81ade2da6a47e93be3ccb7034a3a6b97f4ee8eb00",
"tests/validation/run_j2_slot.py": "b7d2d3aa06fcafc3ac62ed4a50892afbdb7f86e5720ce75a39ce317b6f571dad",
"tests/validation/run_j3_coverage.py": "329869519b7078e854d96241a7aad8ef93f35ac9be83f0be502c3a93523c3b13",
"tests/validation/run_sah04_st_matrix.py": "9b9c0ce063e07a316846635ee769b837ed26be6bf039f78f4219c10b516f8006",
"tests/validation/analyze_j3_saved_frames.py": "438f67dac682b94c4950626f8de4fdcde48c3a4e9ecf8fdf1b0ada4b6e0e781a",
"tests/validation/diagnose_j3_lags.py": "286fcd65b3261667a847b9b26e213d0af92cf459faa6bbd774f78c8479ce31d7",
"tests/validation/run_j3_reservoir.py": "47535bc3569ce68c888d38978bc4f9077fd763a17829c20c081be52bb18a2903",
"tests/validation/run_poiseuille.py": "e529288e2ffa8e00d281a9006723954d60a96ae4d025e8f28656c09287d4ff46",
"tests/validation/test_sensor_accuracy.py": "c6038a9e7a597a1738814bd15e6ecf357cfd271cdc2a132d47943c5280ac0ef9",
"tests/validation/multigrid/test_cpu_reference.py": "ade5d4827f971aed7174b59d83769e7aa542338e625a9fc8db1e8b1805cb74ca",
"tests/validation/multigrid/cpu_reference.py": "bba2a06a9f6517b32079ffff15e4060d8c3b7ed35f16ca134e1877226c9e4e1e",
"tests/validation/multigrid/test_fine_surface_gpu.py": "d45ca48fc4e77d021fcc5461329b094ae11b257c036bb23634d326fbbedb7700",
"tests/validation/multigrid/cpu_reference_v0.2.py": "b6adbad7da625ef6a6b97958ea9625030ed92676d0cada48e061c87bcf7ca8c9",
"tests/validation/multigrid/test_open_corner_negative_control.py": "59a6f8ca80cdd63cb7827fbebf9b4b555c3793f19dd6bca801544ec10b5cbe1b",
"tests/validation/multigrid/test_refinement_followup.py": "6643e26cd877bf0d0f030e974f00a1d1c0f0350cc76d1c8affed3e8ba2f4393b",
"tests/validation/multigrid/local_stress_observable_v1.py": "0e2777990359a7cf2bb29884173b7b01de37c49bcf49e1f29fc59fe83d62b456",
"tests/validation/multigrid/test_refinement_gpu.py": "0021a39b3a131347196845cff6507c90c387b46b772fe1319d634178c5e13354",
"tests/validation/multigrid/shear_diagnostic_v0_2.py": "a8b1cf2f7abd00efc4d068bbd27bb2317144a6ca4c545d9b2e0dcf421eadebc6",
"tests/validation/multigrid/test_tron_additions.py": "8e7a6a90b85e64c7326719e7b8bca2f6d34fb4c80690f0685f7e291ab93bd2a4",
"tests/validation/multigrid/MULTIGRID_VERIFICATION_STRATEGY.md": "d4f3473da44abee6031a0e1bd4d0ca589077a18f15d2461836e4d2ebb98e458a",
"tests/validation/multigrid/shear_v0_2_evidence/stdout_horsea.txt": "0577df5b3f5cb3c7b6e1ef2de71344f8fd3e6d959117487a06cbaf7f2afa3dea",
"tests/validation/multigrid/shear_v0_2_evidence/stdout_grok.txt": "28ddd1267ca91a772f5a6bfc65d949c9a4ea7dac5c9ba3a0bdb168492810b670",
"tests/validation/multigrid/shear_v0_2_evidence/run_once.py": "6698a2e040c56be949b809387d4518eb0ba82d34cc9d99640da4f8bf3c35c23f",
"tests/validation/multigrid/shear_v0_2_evidence/source_manifest.json": "56fbd0259ff3d4dbd14ace52f64e249a435e9df91732b0e4027def2c344c2e6a",
"tests/validation/multigrid/shear_v0_2_evidence/results_horsea.json": "c2d7ce8d16a0f47baff0788a153353dcf67088da974d9cd3d521b04ecd91ee05",
"tests/validation/multigrid/shear_v0_2_evidence/comparison.json": "41c00372099dd04b6d323785e9eaf4fec09da1753d3d150ffa230800f904142f",
"tests/validation/multigrid/shear_v0_2_evidence/baseline.json": "98a7853341ea732762c7506694e3a867a7259bf110e9e461ea84f741fd9ab829",
"tests/validation/multigrid/shear_v0_2_evidence/manifest.json": "e42aa19e91608164698bea42da88fbbfab8b0f87cc37b27c5baf165453a4fdb0",
"tests/validation/multigrid/shear_v0_2_evidence/README.txt": "4306a34b6896bd6e7a5c2ca71d68e18450359239d0c7ad7a67a4e83e7155959a",
"tests/validation/multigrid/shear_v0_2_evidence/joint_report.md": "1860b8082108c8b8a87998af90cd0b81dce1c04e9f6c67b41e0912f9fef6cc9c",
"tests/validation/multigrid/local_stress_v1_evidence/stdout_horsea.txt": "882f2cfb1dbdf82cce63c011397e7c2e6307bbcfec42a3510648d328cd6ddcfe",
"tests/validation/multigrid/local_stress_v1_evidence/run_once.py": "e629800291ef65ffea8555f66ec80bf15200552540b2a493a677bfb53d0830b3",
"tests/validation/multigrid/local_stress_v1_evidence/source_manifest.json": "d2cf90b73458f493c665c9a281d06aef0c190cf0d143639fb77ab838c78f020c",
"tests/validation/multigrid/local_stress_v1_evidence/results_horsea.json": "f17b4644d19eb75d55deb7021ab679cb9e7922a2b46f1cacf8b6da6bfb9a2690",
"tests/validation/multigrid/local_stress_v1_evidence/comparison.json": "be236671a501c31c06f7e266f6e0c0c2a89aede321a483452050ff37bf84c84a",
"tests/validation/multigrid/local_stress_v1_evidence/baseline.json": "64f6541447afbd15b1b15d802ad6f1b5042aaf84e7d4d2414e4ed4c52cf70507",
"tests/validation/multigrid/local_stress_v1_evidence/manifest.json": "3a9fa8c7d691c1b8c24f05940eb724d30b890dd8ed636551068d2633d7db2f70",
"tests/validation/multigrid/local_stress_v1_evidence/README.txt": "4f62314876047ee437bb9ecbf84798d2a9f6e85f6a3aef260277b85bcdb35fae",
"tests/validation/multigrid/local_stress_v1_evidence/stdout_local_stress_observable_v1.txt": "6a826e5ad729ce45af6879a07a1c659d8b4a21403fde5b9c6d9696cc6a5b09d4",
"tests/validation/multigrid/local_stress_v1_evidence/TABLE_local_stress_observable_v1.md": "d8ff0568d9c473a4bb09396a8948ddc8dc5af2f0f3a23ac84d238814fc779501",
"tests/validation/multigrid/cpuref_0_3_evidence/stdout_horsea.txt": "457f1d2173496554c87ca6e61df518c0b8f1e0a28cdfd94b94ebbb61bc459d70",
"tests/validation/multigrid/cpuref_0_3_evidence/stdout_grok.txt": "73e4ef01138842981daaa534390f1463839e63833c11f4e8872f94f8eaadc717",
"tests/validation/multigrid/cpuref_0_3_evidence/results_horsea.json": "914389afc39752bcd4132aa21fc8d5cbcf0ca75b1efd6a49becab15c2fa3361b",
"tests/validation/multigrid/cpuref_0_3_evidence/baseline.json": "0daaccee41cabeb17a00e2405e2c7fd0b80d36f2d01778eb39c9fd22b13d2d47",
"tests/validation/multigrid/cpuref_0_3_evidence/manifest.json": "2850ecaf2e19d010ba35eb54162371d82cc1a092831e08a03b6adf75a614988b",
"tests/validation/multigrid/cpuref_0_3_evidence/README.txt": "1947ee0232b88b3cc2c506d0b0af5ba051ecc94aa8f7f09228ef3939cc95919b",
"tests/validation/multigrid/cpuref_0_3_evidence/README_grok.md": "065947e15b2242bce7d3eb05a3acdbb59939c621dcd5d31540ad4a1bd4416818",
"tests/audit/\u5ba1\u8ba1\u62a5\u544a_kernel_layer.md": "89893c98ed7c2699157bf728ec0e79b0dd6aff4008ee5c7b77eb052de24033f1",
"tests/audit/body\u91cd\u6784\u7b14\u8bb0.md": "8f978d7b01c9f49dca9eeaff0d163cec6da085e2f99ee5a5e803d72306e7a72f",
"tests/audit/\u517c\u5bb9\u6027\u6d4b\u8bd5.md": "9c1721a33b381b9c3810545772b022913da06617711b5ba13a3c2c991b81a7f7",
"tests/audit/Force_region.md": "3092080afe4a30665fe1b721803621ba9d0dd5d20ad17826984d94efc160fdac",
"tests/audit/\u5ba1\u8ba1.md": "0f14ad073a0725134e6391f961c324fd0013c7791fd410713e94ed1ad40b7385",
"tests/audit/Force_region_validation.md": "279a4484d1bfca0fd67aed4de3282d547aa048f89389420d8e5f2fd86db54fc2",
"tests/audit/body\u5220\u51cf\u529f\u80fd.md": "e9f308a8cd0f0e7df5441c32a15f84c0bae50bc0e56b8728f6c6f2cf78596673",
"tests/unit/test_initializers.py": "8b4e3358d925614984265ae73c142006b48fd1c3918cf84901f18afd9fe68c3a",
"tests/unit/test_simulation_lifecycle.py": "77abdc33218c35e9c8b62dbd99ceddbaccd8417e7f0b539ea8859ea0175c663a",
"tests/unit/test_numerical_operators.py": "6d1d560ef553a2af7adac7db3e325d96d7fe39073d5fe3e0e982439537385b27",
"tests/unit/test_fine_surface.py": "b232b55e75eef52480f06a35c401d72b6145892bb8b79d1d1b3cfed965b3506c",
"tests/unit/test_sync_plan.py": "983313ef783143231fa5a392f85f3bac011184773ccaf5d946504c206cabb721",
"tests/unit/test_surface_actuation.py": "89be6f54c4eba6c2bdca0d287a5b9fa6db143de2bcd9a671d4fb8445921303ed",
"tests/unit/test_state_regressions.py": "0f69cfeb83428192f95688c76abcae7e5b9cf5f27c52bca4ac20c7f320044374",
"tests/unit/test_equilibrium.py": "1ecbcc4547b1c846b75320463d828d6a36b6aae73208084fae476b1001c1bb50",
"tests/unit/__init__.py": "17f57920d9c1ff46096ceb2af008eb38c4b98dc81ffa3c3d310e758e80ca1cd4",
"tests/unit/test_pending_edits.py": "905a0dff23b123e8e38aaf364984c810fe51c39acd64aa271e343a4701d3d024",
"tests/unit/test_planar_velocity.py": "b656da0880b4234b1db805544edbe0d2473cbcc7c2c869c71d8251337f62a982",
"tests/unit/test_body_flags.py": "ac6409157924e15a13a3d2cc2f1a09014b8b0198ba17c824f412ff20b19e2aac",
"tests/unit/test_build_contracts.py": "7bb237425e8bb481f312fa4841c484e280731e13c7cbb9a53dad3e7f98984ac3",
"tests/unit/test_context_ownership.py": "299fed30dd0f9bd4dadd8b27f50df2a6367bdb0ab2ca3f391f215fde7241f35a",
"tests/unit/test_reservoir.py": "e718c78a53c3941aba7feb8ae4e8bb0b1726c1145de84febf91220c1917991c9",
"tests/unit/test_refinement.py": "90751142f920f1c5e988577a45afa94871a6617009cdc78323a87fc7795f4634",
"tests/unit/test_slot_velocity.py": "6a9494de9a32c350389ccbed58af48951f6b25a21a258537d2e8b73eb67cb11d",
"tests/unit/cpp/semantic_regression.cpp": "99dba074c0c0a32ea76026e7d54fc60af8e6d3dc5315c8900c470b4518878f39",
"tests/unit/cpp/reservoir.cpp": "c3eacaf0271400eb45ad559b571a8f7faa2a809d5f1857ffeb5592addce2cd0c",
"tests/unit/cpp/collision_regression.cpp": "f17acdff74ab82a62dc5402b42e3f6a149c262e89b140494164d6ebd630f5e14",
"tests/unit/cpp/slot_profile.cpp": "31ac58ccab175bf79fa59fc46d4c0842df18ab0a5e5916be84760d9da2b75788"
}
@@ -0,0 +1,182 @@
{
"tests/unit/cpp/planar_velocity.cpp": "8dea266984edc69d4e0e68007e038d7a587e99f84e33478d6656a66a56680933",
"tests/integration/test_body_sync_e2e.py": "d29f01771f3512a4b3ad06fae4ee952327d7fd9f0476942402fe92e9e327fcec",
"tests/integration/test_sync_bodies_skeleton.py": "65f55a0980659b49ae0027f0642a27e2ebaead226ef083f233e878150884b07c",
"tests/integration/test_numerical_gpu.py": "002a6745929bd5ee86a9491ea9bc3f97602fb825ea17262ea190c9311881100e",
"tests/integration/test_ddf_patch.py": "dda2abba32ca13e17098232f2831a0b1b66439c35f8931d9997a0257250c1281",
"tests/integration/_cases.py": "ab76ca1096d2d10fb05b3539aa8ed3c7e549619bae6900ac98723f6c3c908f2d",
"tests/integration/test_surface_actuation_gpu.py": "3c2b4dda70db1d6493ecd92bd9b0dad6d8b438cdf6dca46410018217f8beb4da",
"tests/integration/__init__.py": "c354e43ba09b55a8013a2df2069438740b5f48b5917d855e52e33ab5d7da5a6c",
"tests/integration/test_state_gpu.py": "dde0948941e8abbc5ea10a3acb3a35abbaea576f36ecee0f1120fbcf7454d60b",
"tests/integration/test_runtime_contracts_gpu.py": "775e578e2e8072af32fc740b2698abbb79454235a0f3ee929ac4c75d747f8db5",
"tests/integration/test_unified_obs.py": "4a681536099741d92bdc258525fe3374cbdbeba0d49996e53808381a1b6a13fa",
"tests/output/exp_ctrl_matrix_streak_ny300/summary_C4_deceit_f1p5.json": "11dab8440d8c4f385061d2536403f4313c6f026b4e0b7672681327a9f4f37ebb",
"tests/output/exp_ctrl_matrix_streak_ny300/summary_C6_deceit_f2.json": "e0c4e8bcc55da5dc8de1e2fe88029aa3e67453734faa44451f5a6dfa9131557f",
"tests/output/exp_ctrl_matrix_streak_ny300/streakline_C6_deceit_f2.png": "e0a66708ce2a29c4c6b854d2596b3ffca181dc6e35d99cc94e08af3e2d8c024e",
"tests/output/exp_ctrl_matrix_streak_ny300/summary_C3_deceit_multi.json": "24c8e433aab6d207dab67546c4079868c4244c2948c32c94cd08e4f331991807",
"tests/output/exp_ctrl_matrix_streak_ny300/summary_C0_no_ctrl.json": "cf3af733a08f081cc5f879e8da79d7c60104099f4452af5b2a4a96c0e6bd5889",
"tests/output/exp_ctrl_matrix_streak_ny300/summary_C5_deceit_multi_f1p5.json": "a4cb4ff4481b39b9ee61b1d7209416237a7fe86b22c5068d713ccec9c3f7afe4",
"tests/output/exp_ctrl_matrix_streak_ny300/manifest.json": "d8a20dacc92321d98354684976f771a9ca8989fc63ddcd78e15c7768c6617671",
"tests/output/exp_ctrl_matrix_streak_ny300/streakline_C3_deceit_multi.png": "c6fed617cc6ffe6677157a9b58811d5f4613725eb98a5aec830fd07dc1aac38e",
"tests/output/exp_ctrl_matrix_streak_ny300/summary_C2_deceit.json": "7526a6b20a158461b85b1a64070b46c2b21be1e01c5ee025e6746fcf47ea3397",
"tests/output/exp_ctrl_matrix_streak_ny300/summary_C1_stealth.json": "63d34a0ab33e9fa8fe7311363efbd1b2875691f5b4958bb645b8c7ac38f1ad6b",
"tests/output/exp_ctrl_matrix_streak_ny300/streakline_C0_no_ctrl.png": "0cfd7ce8f9d743bf22a7a694b4e5a3616557cb8f1db2f4ddf49cc4bef96efef2",
"tests/output/exp_ctrl_matrix_streak_ny300/streakline_C4_deceit_f1p5.png": "4dcfc186928dcb83d28e9eb4cb2ecb4b163eb6f121d57036b4c05ab162be0951",
"tests/output/exp_ctrl_matrix_streak_ny300/streakline_C1_stealth.png": "5e3cbbefda06fcef243d7d06d74a473972350cfa4ae88bdfdb349dce13943151",
"tests/output/exp_ctrl_matrix_streak_ny300/streakline_C2_deceit.png": "22f1db77499bdbd1b3cd35f5b58b1a884dd94a86fdcfef07abd4157e6aaf8d19",
"tests/output/exp_ctrl_matrix_streak_ny300/streakline_C5_deceit_multi_f1p5.png": "823e475cc901af3d6f4d0c56eb07822b3e73a2b9d0aa23e20e3741023fe90092",
"tests/output/kan99b_validation_esopull/summary_runs.json": "fe3294a953580204319fb1143434e15096d8455b6073100dfe0d5491b76af394",
"tests/output/kan99b_validation_esopull/summary_runs.csv": "1a44bb27ee0a7fe0270905248c37364834248cdc8710bd68142a6a79bbdad82b",
"tests/output/kan99b_validation_esopull/force_csv/k2_k2_inlet_control_domM_re100_a1p000_zou_he_local_mrt.csv": "9fbc7d507c129ed85c68a9a313e3eb3431470d091bd7723e63f8afd8a3d2b737",
"tests/output/kan99b_validation_esopull/force_csv/k2_baseline_domM_re100_a1p000_regularized_mrt.csv": "8faac43f42d6e0c70085c6e616bfff4df8de897e315fc0d2b4aa8bd635c3fa05",
"tests/output/exp_ctrl_matrix_vort_nx1500/summary_C4_deceit_f1p5.json": "b613ae55fcfbd45a1a922d6d529e5274ba9d2987fdf5620fe866b889b931e48c",
"tests/output/exp_ctrl_matrix_vort_nx1500/summary_C6_deceit_f2.json": "dbf54f9a183072547b22fa14334f0167e6eefb21c1208c4e8584bc196545a399",
"tests/output/exp_ctrl_matrix_vort_nx1500/summary_C3_deceit_multi.json": "2100c6cc5c358a249804ce8f6f98531f3bc868e27af6d21a9d441b1b6a9e479e",
"tests/output/exp_ctrl_matrix_vort_nx1500/summary_C0_no_ctrl.json": "a8b4697b7c0caeb958f80e282e32d673deac8c914008d64e6b38f7883eacc57e",
"tests/output/exp_ctrl_matrix_vort_nx1500/state_C6_deceit_f2.h5": "8d0c28566d2230b422691b738cc453705496bd150be038a576c0c0fba218fc1f",
"tests/output/exp_ctrl_matrix_vort_nx1500/state_C5_deceit_multi_f1p5.h5": "608767ca11d104fa4506b57204a0c8dbd739688224ebd924fe517ce9e21db823",
"tests/output/exp_ctrl_matrix_vort_nx1500/state_C1_stealth.h5": "a83c988cc8b1173a7b2f13b132ed7243e98304dccab2965aa16cf4d32f8df007",
"tests/output/exp_ctrl_matrix_vort_nx1500/summary_C5_deceit_multi_f1p5.json": "6f6b9300782178e0ac9308a677bd9cb1565a383a78dff4cd52dea0bd464db31d",
"tests/output/exp_ctrl_matrix_vort_nx1500/vorticity_C6_deceit_f2.png": "21bbe2dac1ab06ca1b172ec62d00daa7bcd65d99adac0ed03c5e30bed59e871a",
"tests/output/exp_ctrl_matrix_vort_nx1500/vorticity_C5_deceit_multi_f1p5.png": "602a6586277699968b4cb167b134c8c406577038af088aa70baff682691398c4",
"tests/output/exp_ctrl_matrix_vort_nx1500/vorticity_C1_stealth.png": "c1e1d04f266deac5fb2815a8283da80f9139ffaccbec2219d98544296bf3152c",
"tests/output/exp_ctrl_matrix_vort_nx1500/vorticity_C4_deceit_f1p5.png": "96dee924e89b90091192a8d7b43321f109a5491511b8a83da77cfc611ae0d93b",
"tests/output/exp_ctrl_matrix_vort_nx1500/state_C2_deceit.h5": "aa5800a0cd594eeb7cf5449d6469d55e0c9033ced0ee0a3b5d59152e68c7e263",
"tests/output/exp_ctrl_matrix_vort_nx1500/manifest.json": "5d28f0f5428d7f0341e20d5d1f19c17bbc6f0f9b2a441d3c95f5422f3f2b4bd4",
"tests/output/exp_ctrl_matrix_vort_nx1500/vorticity_C2_deceit.png": "1dcb6fb959f944d7ad89c4abaaef4d1fd4a77db8901804530e86fb336b883eb5",
"tests/output/exp_ctrl_matrix_vort_nx1500/summary_C2_deceit.json": "b88ff5049aef59876b349d105f1c3467c17c9ba9022a48a77a6984f20da34345",
"tests/output/exp_ctrl_matrix_vort_nx1500/summary_C1_stealth.json": "515689cbfaa30a9e39d9907939ee194a4836b644a5e9124586e6b7221d2b394b",
"tests/output/exp_ctrl_matrix_vort_nx1500/vorticity_C3_deceit_multi.png": "d69694a1a1b2f2ea0adc7b74b7526504e2ad0b5d6317bac9b3159b2e7e88cf90",
"tests/output/exp_ctrl_matrix_vort_nx1500/state_C0_no_ctrl.h5": "3a858d6be0a946e1d26bbfa192c2f0ca3910c0f140b42575ec9d9529dd99155a",
"tests/output/exp_ctrl_matrix_vort_nx1500/state_C4_deceit_f1p5.h5": "660e4619ea530dcd18c3afb2e7fa22cafd9cdba1be7888e31ab5b76a0902d2fc",
"tests/output/exp_ctrl_matrix_vort_nx1500/vorticity_C0_no_ctrl.png": "6d4d3934f1c8b20c2a5c742ae080a7143f0c139741966adf009a227c27e9bb1f",
"tests/output/exp_ctrl_matrix_vort_nx1500/state_C3_deceit_multi.h5": "1e72126f11b2995437cecb8cc0eeffb8807efbfa43d8f346f28711fea98ddc90",
"tests/output/kan99b_validation_ref/summary_runs.json": "449316c30585a8de9997538dead5d4e35a59bf00a2ac22d01b101ab600a4bc06",
"tests/output/kan99b_validation_ref/summary_runs.csv": "e8b9620f3772e5e421026103e456e6e844a91292f40affb96174c9dbde9b6e4e",
"tests/output/kan99b_validation_ref/force_csv/k2_k2_inlet_control_domM_re100_a1p000_zou_he_local_mrt.csv": "4391f41d17ebeea1092f13b901923ced4ee2a1c5b346b79ef791d692847286b5",
"tests/output/kan99b_validation_ref/force_csv/k2_baseline_domM_re100_a1p000_regularized_mrt.csv": "105c6eb21f1943d9d935246eab1602ff2016c415a139e24fee2793e88e006ead",
"tests/output/exp_ctrl_matrix_vort_ny300/summary_C4_deceit_f1p5.json": "0085a679a423621003eea81d4ac83bfe2edef2879eed7809d2a3675a212f791a",
"tests/output/exp_ctrl_matrix_vort_ny300/summary_C6_deceit_f2.json": "e820cf73f0e90bf93c34b24416e7692a6c2e51352ccf490fa6714d0812331ca2",
"tests/output/exp_ctrl_matrix_vort_ny300/summary_C3_deceit_multi.json": "571370c74ad9af589f3dc214669bff3d857efe6fc4fa13815b5d793d12b53770",
"tests/output/exp_ctrl_matrix_vort_ny300/summary_C0_no_ctrl.json": "ec5b89961033d8ebe0d66ce1ec7940dc2faf98130c38319bc9984ef654e60b50",
"tests/output/exp_ctrl_matrix_vort_ny300/state_C6_deceit_f2.h5": "2792be74d8564fa29fd0636fc8493630fba2779c165b44330197095b3e296b18",
"tests/output/exp_ctrl_matrix_vort_ny300/state_C5_deceit_multi_f1p5.h5": "2c64ee6c7a4ea2c42ed8f3d274402bec62de0e02ea0340e16022f0cdc92af724",
"tests/output/exp_ctrl_matrix_vort_ny300/state_C1_stealth.h5": "100727d94fe6c2e46d7807eed0442555bdd1e26ec9b04b4c457171a2bbba3255",
"tests/output/exp_ctrl_matrix_vort_ny300/summary_C5_deceit_multi_f1p5.json": "f86166f121b4eeb6d74d8176c9265e7a3ccfe2540d040f554b6f96e6a6222c16",
"tests/output/exp_ctrl_matrix_vort_ny300/vorticity_C6_deceit_f2.png": "fef4de0e3ac8203742f35c16a02445b19c3f556b11f73abd5d8e3ca05ca33d78",
"tests/output/exp_ctrl_matrix_vort_ny300/vorticity_C5_deceit_multi_f1p5.png": "9136448e6d7565ca5af3666f9cf6e154342d8a3475076abfdbdd1ff9faec34f3",
"tests/output/exp_ctrl_matrix_vort_ny300/vorticity_C1_stealth.png": "544537a9c500a05937fd3be17c25e7d887461d9b83a15564f9ab7063208f40f6",
"tests/output/exp_ctrl_matrix_vort_ny300/vorticity_C4_deceit_f1p5.png": "51e7056db99dd653affbe913d52fa41df6ec0db921109384e3c679bda06b5a83",
"tests/output/exp_ctrl_matrix_vort_ny300/state_C2_deceit.h5": "39d6c162085acae1612650da37d2314757715931e83a854e08bb01407d0f8efc",
"tests/output/exp_ctrl_matrix_vort_ny300/manifest.json": "05fbc2e7bbad4267a38e1094bbdd6bee6ad270412bdb5e92b0dfc9fa56969517",
"tests/output/exp_ctrl_matrix_vort_ny300/vorticity_C2_deceit.png": "07fc5817eba30371272b87ee2e023c0a1144077d1bef77efb2fd5dc284badcb7",
"tests/output/exp_ctrl_matrix_vort_ny300/summary_C2_deceit.json": "b1fcf76039c91a9080b830352dee2e95316d754b968cc27a8f68c51527661e76",
"tests/output/exp_ctrl_matrix_vort_ny300/summary_C1_stealth.json": "b78851637b9b7b93070524a2933cae1dab6d682f8894579b2849c64921e6c29e",
"tests/output/exp_ctrl_matrix_vort_ny300/vorticity_C3_deceit_multi.png": "2658f0747ed7287f7912fe15cc58a086e01ba284277cb98689bac01ecb6ec12b",
"tests/output/exp_ctrl_matrix_vort_ny300/state_C0_no_ctrl.h5": "57f73f5f8dc4b32b156bc82300b1efd1e4eddadd9b8dc51cb7e6b41fa5c966bd",
"tests/output/exp_ctrl_matrix_vort_ny300/state_C4_deceit_f1p5.h5": "2864b9dd086709ee8b8c3f262118a5130b0d40c86838f3ca0deab5bb898dafa8",
"tests/output/exp_ctrl_matrix_vort_ny300/vorticity_C0_no_ctrl.png": "2c7f3a8be2ee540afdfb66299e43a65583434bee84bde590124524a82868c900",
"tests/output/exp_ctrl_matrix_vort_ny300/state_C3_deceit_multi.h5": "39e0d9b032dfff8cf057b410a98973729285e7d03e89f9a6a002aaf7de3d7519",
"tests/output/stealth_sweep_fix_check/summary_stealth_s150_w0.02709.json": "8b1032e13975bb05c6a810fde175c8da51bacdb3dc745fd11c1049ca63bbf136",
"tests/output/stealth_sweep_fix_check/summary_stealth_s050_w0.00903.json": "fa7da24d5dab9fd3a3c2dea6b50d0224c7a99cd9141796e137304a6040b1ac8a",
"tests/output/stealth_sweep_fix_check/streakline_stealth_s050_w0.00903.png": "640928f7eb159e7caea32036123f86c281723d083cca46839ba86bce8361ada7",
"tests/output/stealth_sweep_fix_check/state_stealth_s050_w0.00903.h5": "187ac365f9f7370c888c4c65570c47e42465b2fccd432056c176528d45cf0c2f",
"tests/output/stealth_sweep_fix_check/manifest.json": "83a3f12a942fb644e470bd07a72f24921f2147d7df429110268c5c96a9953d1a",
"tests/output/stealth_sweep_fix_check/state_stealth_s150_w0.02709.h5": "e057e9db26b2546c0704e2c959cc7d2aac91e6a49b4c7ee75a409597a5db8716",
"tests/output/stealth_sweep_fix_check/vorticity_stealth_s150_w0.02709.png": "d2d202088624cf30868228f9c913ee30e1b386aaa2c22b0ea89be43dedc0712d",
"tests/output/stealth_sweep_fix_check/streakline_stealth_s150_w0.02709.png": "0edc7caa9caaffb754490bf1f6ac7ad7180e45a991439a3f4f83ed949a082a1a",
"tests/output/stealth_sweep_fix_check/vorticity_stealth_s050_w0.00903.png": "4088359b17c46ed4d7c8401d244808fe67723273b1d16d0671b69f9478c68c1a",
"tests/output/final_validation_round/validation_summary_report.md": "881cb7052e5a555afc87168a37268ee66e8e3fba172533706e858d996fabc7b9",
"tests/output/final_validation_round/sah04_mixed/s2_d48.json": "83c6c01201d90aae5c49e73ebeca88d1c7ded6cc83c13f4892a9188e6289483f",
"tests/output/final_validation_round/sah04_mixed/s4_reg_d96.json": "b32f03e6b347fc709cea2ecd488df0f85849c733bf6a4b9cf65ea69401c93a1d",
"tests/output/final_validation_round/sah04_mixed/s1_d48.json": "120e8e878f5712dc89b7cf78c7f8d0e3368d34ad5ef7494977e083b188a54c18",
"tests/output/final_validation_round/sah04_mixed/s3_stablecfg.json": "b38a3d197a188e65c163d974113af18f332b3abed083e2654e998d9980f6be9f",
"tests/output/final_validation_round/sah04_mixed/vorticity/s3_mrt_laststep.png": "dc96fcd05d458684cfb40d4cb741172213083e2f2665e2bae7e1f0267bb3575d",
"tests/output/final_validation_round/sah04_mixed/vorticity/s1_mrt_laststep.png": "73a3580ba3c7fe6ffeee4676a9a51b5bf678d6fb523456a61e185598389ea1e1",
"tests/output/final_validation_round/sah04_mixed/vorticity/s4_mrt_laststep.png": "57f2a82761f2de1a9fc2b78ee86159ca542c966494b9c704deb451da857da778",
"tests/output/final_validation_round/sah04_mixed/vorticity/s2_mrt_laststep.png": "786f492b96ed932254b5452e2d06ff088727f2d88c7e7c7b47d386eddfe07862",
"tests/output/final_validation_round/kan99b/full_summary_runs.json": "8c4a11cbf555e08a66698439170b850c57d537d8e75e4dd75beb767bbf7e38cf",
"tests/output/final_validation_round/kan99b/summary_runs.csv": "3fa92fdd3114f0472de44bc03006af1d4b694dfc69b06704c1667cd3627b6dab",
"tests/output/final_validation_round/kan99b/force_csv/k5_baseline_domM_re160_a2p000_regularized_mrt.csv": "de05e9699146f2adffc9d7c9991f9e48396aacd142afc3c08b2b64727c83c69a",
"tests/output/final_validation_round/kan99b/force_csv/k3_baseline_domM_re60_a1p600_regularized_mrt.csv": "53cd0dc47328b7b370eced1130508655e6815a29b727bf1fe4e4e125e4918905",
"tests/output/final_validation_round/kan99b/force_csv/k2_k2_inlet_control_domM_re100_a1p000_zou_he_local_mrt.csv": "4cac1ccfdb7451de3e26d921a6406cc55d1d4630e10ec0d7ec9350a4abd49404",
"tests/output/final_validation_round/kan99b/force_csv/k4_baseline_domM_re100_a2p000_regularized_mrt.csv": "392c98de52011ddb344a5761c4520e870f4e49bbba3e144e5a02818ba2f9250b",
"tests/output/final_validation_round/kan99b/force_csv/k1_baseline_domM_re100_a0p500_regularized_mrt.csv": "9e83c5175aec644c0b97c081e610deefa731b87aef04da6297abf662a71c0702",
"tests/output/final_validation_round/kan99b/force_csv/k2_baseline_domM_re100_a1p000_regularized_mrt.csv": "55b071f278e153aa353aa2bef85f0bce35b910a7b08103032023fe3a28169b89",
"tests/output/final_validation_round/kan99b/vorticity/k2_k2_inlet_control_domM_re100_a1p000_zou_he_local_mrt.png": "b91b332e7deb787975d3f08fa3325facd4a972b536694fcda52e6c01943c42cb",
"tests/output/final_validation_round/kan99b/vorticity/k1_baseline_domM_re100_a0p500_regularized_mrt.png": "6e7c3f6567c0ff0d00d75da8373031f5ba2a17a624cb8c5d5d6ae4f8749c33c0",
"tests/output/final_validation_round/kan99b/vorticity/k5_baseline_domM_re160_a2p000_regularized_mrt.png": "c4d232df2e6f7466acca711191d976aa9411ec0ade81572b531463f42a7d633a",
"tests/output/final_validation_round/kan99b/vorticity/k3_baseline_domM_re60_a1p600_regularized_mrt.png": "b2314c60491d20933422e1697998555dec2436d39545c71f990e9906884685b2",
"tests/output/final_validation_round/kan99b/vorticity/k2_baseline_domM_re100_a1p000_regularized_mrt.png": "2b2797b8f53170d04d1a70d1cdf898f7e41b3a76b9f3c1f276dfec952520ab04",
"tests/output/final_validation_round/kan99b/vorticity/k4_baseline_domM_re100_a2p000_regularized_mrt.png": "8135f470404fe11ac97968fa580ee35232e90dcace3c6ad94de17ef7aace24d6",
"tests/output/kan99b_validation/summary_runs.json": "d7239aac64884202558741074f2d644ade9e2365d94d0b7556fba68dac94868d",
"tests/output/kan99b_validation/summary_runs.csv": "c44da69563d58b917291a9fd402d1f57055861bffab6f9e32d7db91297428d45",
"tests/output/kan99b_validation/force_csv/k5_baseline_domM_re160_a2p000_regularized_mrt.csv": "27b64460923d235d34b760f2a2371ad01611a70e38edb03d6fd6a2fe7a7de6e0",
"tests/output/kan99b_validation/force_csv/k3_baseline_domM_re60_a1p600_regularized_mrt.csv": "76ff52f4494b7ef7650c05968732a8caaba94d2b151234c02cf624f5b3a712ab",
"tests/output/kan99b_validation/force_csv/k2_k2_inlet_control_domM_re100_a1p000_zou_he_local_mrt.csv": "28a83436ca8bdad38865ba21ce1bda679562a5ae1cfc6ee8fc6e86ff760ec66d",
"tests/output/kan99b_validation/force_csv/k4_baseline_domM_re100_a2p000_regularized_mrt.csv": "823ae04870fd951879024a18169ac5cba8db4b3201726f6a00f320f1958d04c6",
"tests/output/kan99b_validation/force_csv/k1_baseline_domM_re100_a0p500_regularized_mrt.csv": "a591daf2cdecd6ac3689fa2a2aba917b23053ad26e3ef1f635c81aecc451475f",
"tests/output/kan99b_validation/force_csv/k0_baseline_domM_re100_a0p000_regularized_mrt.csv": "e95c27c646c0c9baf8f455f876c115c8dbdb23cef9d9d550f455098bf0c03b55",
"tests/output/kan99b_validation/force_csv/k2_baseline_domM_re100_a1p000_regularized_mrt.csv": "3c2ea79a0e27f561215febee2e165d24b3617a648bf908981c068ba59d549c51",
"tests/output/stealth_steady_sweep_nx1500/streakline_stealth_s125_w0.02257.png": "a892f18c74fe13efd839bfd5068097ca0ae07acebf6c06eed89e1b867e41fcb2",
"tests/output/stealth_steady_sweep_nx1500/summary_stealth_s125_w0.02257.json": "7e542f59746429022ce1794854c6fb36e8ac658dd0aea3bc1140a45e83a3f1c9",
"tests/output/stealth_steady_sweep_nx1500/summary_stealth_s100_w0.01806.json": "b76216e0fbee00ef754edbafe5790a99ce7d53638af629947ddd9615598e4c08",
"tests/output/stealth_steady_sweep_nx1500/summary_stealth_s150_w0.02709.json": "42cb241d9cfb01308ce28e129756b6cb3fe2a8e9679518da84bcb8b607fe92ac",
"tests/output/stealth_steady_sweep_nx1500/state_stealth_s075_w0.01354.h5": "558be308dbf334832bc1d29419ba5be142969117a11b124864f6b221c8fee509",
"tests/output/stealth_steady_sweep_nx1500/summary_stealth_s050_w0.00903.json": "53b579811a0b651ba7cc466c230c115b9f88486c6675e0465d0715d3377a75cd",
"tests/output/stealth_steady_sweep_nx1500/streakline_stealth_s075_w0.01354.png": "9f4a7d89b2471becaf31e84c14402441c5fd96fc7190cea5e8a9fdd06ee62002",
"tests/output/stealth_steady_sweep_nx1500/streakline_stealth_s050_w0.00903.png": "5f18f56b0ff2af3350216b65540a2bc664c569520624cfc6cc2439a3c5369560",
"tests/output/stealth_steady_sweep_nx1500/state_stealth_s100_w0.01806.h5": "30776f333959e0e9eb5ca96b269e6a8052c5b94941a4e3b36d8a6af8076920ce",
"tests/output/stealth_steady_sweep_nx1500/vorticity_stealth_s075_w0.01354.png": "b5393474d99191e88dafea4144b6a8eccfbdf75107125ce4b05383b17007d06a",
"tests/output/stealth_steady_sweep_nx1500/state_stealth_s125_w0.02257.h5": "4ed9d8587f75ad4625ec5501fa99fb733cde037180ac53f92a210ffbb08375de",
"tests/output/stealth_steady_sweep_nx1500/summary_stealth_s075_w0.01354.json": "ff1c1cc649e589b5425787493c2b0d04b6c39b43043b1968d65509cb0a426e82",
"tests/output/stealth_steady_sweep_nx1500/state_stealth_s050_w0.00903.h5": "4de51584b24095f8cf4480b8941593a5f913332f9396061ed077c9d49eb2ee11",
"tests/output/stealth_steady_sweep_nx1500/manifest.json": "0dfbb2c1b5bf9093fef169e4dc6319edb5c87a1e967e8d558613e2c64a2ca734",
"tests/output/stealth_steady_sweep_nx1500/vorticity_stealth_s100_w0.01806.png": "60824cbdf21170cb4ffd8af0a49e8522c2d79cb2694690ab67995ee973265efa",
"tests/output/stealth_steady_sweep_nx1500/state_stealth_s150_w0.02709.h5": "b22d54a05cbd3138a1fe585a825246989fcff7c00f51aa9312a4185d963db933",
"tests/output/stealth_steady_sweep_nx1500/vorticity_stealth_s125_w0.02257.png": "c1e1d04f266deac5fb2815a8283da80f9139ffaccbec2219d98544296bf3152c",
"tests/output/stealth_steady_sweep_nx1500/vorticity_stealth_s150_w0.02709.png": "bcf098083a73798dc3906807218058cc571435a010234a5a350b585ba9915c78",
"tests/output/stealth_steady_sweep_nx1500/streakline_stealth_s150_w0.02709.png": "3bac21cc75a01429399cec308d6bf5fc8918917def1bf5d7fec1cb6003390a41",
"tests/output/stealth_steady_sweep_nx1500/vorticity_stealth_s050_w0.00903.png": "a675f41df763f0a1ac0a06386315806b24f2571f5dabc8693fcd871a13ed22ba",
"tests/output/stealth_steady_sweep_nx1500/streakline_stealth_s100_w0.01806.png": "92515588596596cc1d691c643fa48cf828492c2eaed96355dcec58109de4b5aa",
"tests/output/exp_ctrl_matrix_streak_nx1500/summary_C4_deceit_f1p5.json": "0393661f08b748428fc366eeecec3b34b9d9a013aa6b151a15b33c7e3c0e1818",
"tests/output/exp_ctrl_matrix_streak_nx1500/streakline_C5_deceit_multi_f1p5_step080000.png": "bffef412087e426b614d8c05e59bd7580ee49bb77319279ddc4c1bf825678c49",
"tests/output/exp_ctrl_matrix_streak_nx1500/summary_C6_deceit_f2.json": "de067f01ef5c11249d67bbe5e02db6f2b4c5590214de02609bca115edf8dee64",
"tests/output/exp_ctrl_matrix_streak_nx1500/streakline_C6_deceit_f2.png": "846badbae81b75f765d89e5a7c4f88aeb5d57f2387511e4f2f84c72a192ea9f2",
"tests/output/exp_ctrl_matrix_streak_nx1500/summary_C3_deceit_multi.json": "eb21d1c69e51f01c1a6be1ce59fe86763089ea5aa667b8872d0186af035b24b2",
"tests/output/exp_ctrl_matrix_streak_nx1500/summary_C0_no_ctrl.json": "780a0d329cb86990a17a088f49084410abb1fad24f659255918e5ddda6b3dabd",
"tests/output/exp_ctrl_matrix_streak_nx1500/streakline_C3_deceit_multi_step080000.png": "ff7836b8229d9a5dd3900f499fe3e7f0c73a61c7109b6e6e79b11a0fb459bb63",
"tests/output/exp_ctrl_matrix_streak_nx1500/streakline_C0_no_ctrl_step040000.png": "f2b56a7e30bcc363ed69fc19705403181ac5de90800eef03039a389a65869e30",
"tests/output/exp_ctrl_matrix_streak_nx1500/summary_C5_deceit_multi_f1p5.json": "261b698723f19526a447679a2be8666c8d0cbf6df81b0c9de6d051960d77308b",
"tests/output/exp_ctrl_matrix_streak_nx1500/streakline_C0_no_ctrl_step060000.png": "0697e0ae06a01154afdcf00330ba870bd8f36d21561a33846ad7ba63fb731179",
"tests/output/exp_ctrl_matrix_streak_nx1500/streakline_C1_stealth_step040000.png": "1de3d7f54e91c5d5850f4358d1872e16fefb36d32a1b6293facb54524e32315c",
"tests/output/exp_ctrl_matrix_streak_nx1500/streakline_C0_no_ctrl_step100000.png": "91f0bf6ed3e854f7f83623a3f19bb12c83b4aac239e3eaa849fbe50e7baddff5",
"tests/output/exp_ctrl_matrix_streak_nx1500/streakline_C0_no_ctrl_step080000.png": "303c1d2d4c49b4a7495365c8cb2bcbfe9bdda7cbc0a7c7dd1f01e8aa62b3573b",
"tests/output/exp_ctrl_matrix_streak_nx1500/streakline_C5_deceit_multi_f1p5_step040000.png": "dd5945458a35d81b31a0e2f3a693a5023d6960474263e7dc86c22367a56cc13c",
"tests/output/exp_ctrl_matrix_streak_nx1500/manifest.json": "0d97efed02f775c25dd8a2d7439f310b715d142ff8d603c9da6ddab197570ce8",
"tests/output/exp_ctrl_matrix_streak_nx1500/streakline_C3_deceit_multi.png": "69022ef9175acf910374ec73848640548b85fc7beb7e6950843f52c10ed7d61b",
"tests/output/exp_ctrl_matrix_streak_nx1500/streakline_C4_deceit_f1p5_step060000.png": "16ba30b8cca0d49e6b76be0bb4f0d14bbf276ca6ec47ebf56907c7534e15c4e0",
"tests/output/exp_ctrl_matrix_streak_nx1500/streakline_C5_deceit_multi_f1p5_step100000.png": "8548b6dff635cf9c92e2baa119866277e3994366eb31aeb30641b03b3d80ee9f",
"tests/output/exp_ctrl_matrix_streak_nx1500/streakline_C2_deceit_step060000.png": "56100f169c3e378b84bfc89c5477d2c142ca043d9f28eaa70bc5448c49c7f4d5",
"tests/output/exp_ctrl_matrix_streak_nx1500/summary_C2_deceit.json": "587cd42d81b1325bbc766d9ca6c1fd3d076bf5a772efd45d056c2c4e3db742b6",
"tests/output/exp_ctrl_matrix_streak_nx1500/streakline_C1_stealth_step060000.png": "e43e95e7126de8cb857154353f161914c225f8c9f17eb44b1ff744249368a4d5",
"tests/output/exp_ctrl_matrix_streak_nx1500/streakline_C6_deceit_f2_step080000.png": "676d21ffc7180d34a6725a8bf49503ce59f48d65500450c3975d01e65162899e",
"tests/output/exp_ctrl_matrix_streak_nx1500/summary_C1_stealth.json": "73040aeb7ef07c538d4687b101c599210e660202eb1c2c3e0894dfbde682d137",
"tests/output/exp_ctrl_matrix_streak_nx1500/streakline_C4_deceit_f1p5_step100000.png": "e22171ef86979c4398c45ada9cd0f5e4c4e5b034f271df5fa8ac9a762a8554cd",
"tests/output/exp_ctrl_matrix_streak_nx1500/streakline_C2_deceit_step100000.png": "0d73042be73b0de8d0a591e56c01e3c802483aa22a97f27e0300cba82c708066",
"tests/output/exp_ctrl_matrix_streak_nx1500/streakline_C4_deceit_f1p5_step040000.png": "a6e95fd5c24052db20d5ece200edcfe5e261c00950ca964c89df9f7335579634",
"tests/output/exp_ctrl_matrix_streak_nx1500/streakline_C0_no_ctrl.png": "d74061347ac3505fad878e330f6cb04d23bdb13082bfa1afa2fda0872f80f388",
"tests/output/exp_ctrl_matrix_streak_nx1500/streakline_C4_deceit_f1p5.png": "3156400eb59fae0638556c2711345f12ca49d951ff09e6464a2271249409a6a7",
"tests/output/exp_ctrl_matrix_streak_nx1500/streakline_C1_stealth_step100000.png": "d69e34c82da98b28eef7f1af29f5d11f400e90f628049f6f5f4a3a419a4a4340",
"tests/output/exp_ctrl_matrix_streak_nx1500/streakline_C6_deceit_f2_step040000.png": "ce1f372b517dd52fc3f3eb066145e04ab6841e43b67cb0f6bfbdb42a6738eca6",
"tests/output/exp_ctrl_matrix_streak_nx1500/streakline_C3_deceit_multi_step100000.png": "07cce6c99dfa7b56dd4d3aa452873a676a5a00e9f046555fa9dda30f16dde488",
"tests/output/exp_ctrl_matrix_streak_nx1500/streakline_C1_stealth.png": "a892f18c74fe13efd839bfd5068097ca0ae07acebf6c06eed89e1b867e41fcb2",
"tests/output/exp_ctrl_matrix_streak_nx1500/streakline_C6_deceit_f2_step060000.png": "80b63bd309ef11a3ebb2f1ef301b49cd8f09bcc25562097d382f859306c9fe6d",
"tests/output/exp_ctrl_matrix_streak_nx1500/streakline_C2_deceit.png": "1edb30dc35e29ad991695353f4b84e0507792935ec75ae9a7904ebdc007a471a",
"tests/output/exp_ctrl_matrix_streak_nx1500/streakline_C5_deceit_multi_f1p5_step060000.png": "93ab8e09e58a64c5dd2eedfdafd27cf4dcfe4e8fae1af64ac71eac509e6ffdaf",
"tests/output/exp_ctrl_matrix_streak_nx1500/streakline_C3_deceit_multi_step060000.png": "f773bdef1c8d718d01b6d6d7735182c04564dd8b5692b359e1dd2f721c774b1a",
"tests/output/exp_ctrl_matrix_streak_nx1500/streakline_C4_deceit_f1p5_step080000.png": "5570fe6a25c92e5c6aa9a5129aa1797ba8ee7418170c7a351f9e35b931a366c7",
"tests/output/exp_ctrl_matrix_streak_nx1500/streakline_C1_stealth_step080000.png": "32d3e700286eb4b46b3bcf757669481affd6ff6b53792d730b5a21da92cc57d6",
"tests/output/exp_ctrl_matrix_streak_nx1500/streakline_C6_deceit_f2_step100000.png": "5acfe36694bb4e628309ff8ae1e839ca0a1f684607165bbc2883436b85208bf4",
"tests/output/exp_ctrl_matrix_streak_nx1500/streakline_C2_deceit_step040000.png": "2c6f2b8d61cc2aaa63631eb6c98d3de26dcef705fa6b66c823ce7b9eef50e00c"
}
@@ -0,0 +1,182 @@
{
"tests/output/exp_ctrl_matrix_streak_nx1500/streakline_C5_deceit_multi_f1p5.png": "adbefd0021e2c981d026718de8c63594b9c8e5971901d1dc40835cb69d95b93e",
"tests/output/exp_ctrl_matrix_streak_nx1500/streakline_C2_deceit_step080000.png": "ce8b18e4dd976ed590fcc44075f3fb058ca7b23e15a1624726c181c4dd0c11da",
"tests/output/exp_ctrl_matrix_streak_nx1500/streakline_C3_deceit_multi_step040000.png": "168d21ef24ae198fbfd642f8ca315faad4c7bff2e2c09e16ff7c97e7360ea883",
"tests/output/screening/screening_summary.csv": "3a23c4f2bd54ed5ee9bdb5b6dcdc58eed04519fcf1b4790e0abd1e6c5288fb96",
"tests/output/screening/screening_summary.json": "caf64530f152b6b8ccec82a3c7ba44fa0b3aeb0e0221ef6121857bf62c031ecd",
"tests/output/screening/B1/force_hist.csv": "854bfebe63fb2d140823fc5dbc434a70c317c6ab0bedbd5220cec45665b524c8",
"tests/output/screening/B1/summary.json": "35b4d958bc0fdd6ab6c9c0d1ed50e85d89b04f7be3e34632d6c3ea95b89acb47",
"tests/output/screening/custom/force_hist.csv": "06da0f67b564d5c114332ef3b39167b1ba222fc50045f95303c75c14755b51d5",
"tests/output/screening/custom/summary.json": "1701ed75e5e9ca16127f495ccff1d87de245d81df581e94114c8fca6fbbe77fd",
"tests/output/screening/MR1/force_hist.csv": "f70fbfa748fd0709e225523aaaa72b761db56df4f1d48f105384b94cbc44b31f",
"tests/output/screening/MR1/summary.json": "3d9a0fc19710820e3634ab2143b913b282beb159336567ab9ebf3de2092947bd",
"tests/output/screening/MR2/force_hist.csv": "c947b3c16b8e8f8f85a203cea8cd912bdfc07f96985c1c24a470b644170195ea",
"tests/output/screening/MR2/summary.json": "d2344e9e2517ec76c8b56bfbe3763dd465e24721856992401c57c414763481bb",
"tests/output/screening/MR3/force_hist.csv": "7df1536c83ee466b7195d9c521d3d3b1309acaf142f2855bba51fb279c7612e4",
"tests/output/screening/MR3/summary.json": "ad188eb1b271a6cd0fb4025b456eccac5450776f60db58466f804fc5a0e0ec61",
"tests/postproc/run_exp_ctrl_matrix_vorticity.py": "b7e0c4113111b9b677f321750c0055656ccfa4f45c25fe7846f3ed22f30d1467",
"tests/postproc/vorticity_triangle_clean.png": "f831b8143b50f038d5920a0658469622655f34176d30cf7216feff108aa2ecaf",
"tests/postproc/run_kan99b_streakline.py": "a2bbf3fc629ea170d2d4879317dbf2b81c43378a328100ac1f2ee8d9895666cb",
"tests/postproc/streakline_triangle_clean.png": "aa6669de7af6f82e98af25698a15f494e9cea20cb911ad9a30fe52597d33bb79",
"tests/postproc/experiment.ipynb": "c6b45db1c57200f0777213ef8d44cb4996c1aa7a5fb42b968b77e56f51b4fca4",
"tests/postproc/run_stealth_steady_sweep.py": "3c32c4dede7da77fd6cfbd3f7b1ff43bb11390aaba621883ec96c6c7fdad5af7",
"tests/postproc/run_exp_ctrl_matrix_streakline.py": "529d5f31a3862080f890c65177502b589710b2d960ddf131abaf7dc2f9e2a96f",
"tests/screening/run_config_sweep.py": "5030c99923815ed6ad39110cb56f748c579ff4c66c7c1a368ad1a6008017e2ff",
"examples/fixed_periodic_patch.py": "6732e440a47c237ea341703f2d80717903d34c68fd061bdc97189e5d877be46c",
"examples/fixed_patch_jet.py": "9d58ac3f32478603e8e798efcdaf6ea16e9cc92346eb4780a60e438d331abced",
"research/j3-lag-2026-10-12/host-check.log": "b2b6d262934b3abf9e0f0bdbde14b339cb977f7bffe391c17b51b5d067862dda",
"research/j3-lag-2026-10-12/REVIEW.md": "f388b64b0cc0413dc9865afda90ed24de666dda0d6cdb821b4363ce1b73631b3",
"research/j3-lag-2026-10-12/trajectory.h5": "2b51f8ec5e0cc8ca72c73ac1b51dd611158368e6d6de791d85150fa111ea1986",
"research/j3-lag-2026-10-12/baseline-status.txt": "e0b69879084f54afac1a3bc3701f1de9819068190c815ae84421f02f83cad9f7",
"research/j3-lag-2026-10-12/baseline.json": "5e9a920813fe3d775110af85af92970d5245a7040ace804445e432353b77e489",
"research/j3-lag-2026-10-12/gpu-diagnostic.log": "97956b517072b7c34e2e29e2a23f87eafb19b9eda786a4b8149e4a2eaed76ee9",
"research/j3-lag-2026-10-12/gpu-availability.log": "b227a519b8286849cfdf842573bd451803da048c6b27af9517f6b8964cd3aa39",
"research/j3-lag-2026-10-12/results.json": "00435ac7e402943e55e702fac1beb5af8cafe71967999658bcde2b29077b1fa8",
"research/j3-lag-2026-10-12/incremental.diff": "ebdf66c72daf17b926482f79a1a30bf0eb2d27fc930a7bb62e5449ebcf72fcc7",
"research/j3-lag-2026-10-12/end-21280.h5": "19a94e9e8db6dd9ac981effe06032c351992250b58768d9c090409193893d588",
"research/j3-lag-2026-10-12/start-20760.h5": "6c4cba5928c77566c2afc32231311a3986831c18fea766faadebb101243399e2",
"research/fine_surface_20261014/cpu_surface_projection_command.txt": "b1783e26e92737106a5614fff01452c8ea0364372d9bdbc44c7d15c19d9b13f5",
"research/fine_surface_20261014/cpu_surface_projection_exit.txt": "9a271f2a916b0b6ee6cecb2426f0b3206ef074578be55d9bc94f6f3fe3ab86aa",
"research/fine_surface_20261014/report.txt": "ad8af2be7239f8fe728ac7a8db340d4458e6ec1bbb30b14e614c1072dd9804ec",
"research/fine_surface_20261014/cpu_existing_runs.json": "523b3179b976c2198112c7b49c6c8a75cf7d3332663a8b8a0646c94a39abd1b4",
"research/fine_surface_20261014/gpu_run.json": "8c4b4d7c53e17c30ce4c7d2fb92466e0704f39966e89016dbf82d36cf96e35bf",
"research/fine_surface_20261014/gpu_stdout.txt": "02d1f6fea194d1185a49b7bcdde58642f1d6b9634fe55e4bcda2f020414eb35d",
"research/fine_surface_20261014/cpu_device_guard_cmd.txt": "43a0fb0e20c4adcf1930f145796378294558060d5fd5303402e0538674b68c0a",
"research/fine_surface_20261014/cpu_surface_command.txt": "2b8f2a3c9ddfd1e877efa2a50a935eeb937e2b3ea92515610cd334d80703d6ce",
"research/fine_surface_20261014/baseline.json": "dc9dfa88e69d2b7cf93b0c572961c0bc7849ea1608a0b14b1a6dca1429abf87c",
"research/fine_surface_20261014/cpu_lifecycle_stdout.txt": "af52542989b4a2bf597e020c12064e7083e136f15b938ed5382b616a16f70e38",
"research/fine_surface_20261014/cpu_surface_projection_stdout.txt": "96ea3e4ca948962b6eb92aaf215efb6c598a3c4b296f6fd26094df353ded5722",
"research/fine_surface_20261014/cpu_lifecycle_run.json": "2a3b09ad2f9c86e43892d643a510c9e936d6153e2ae1f6a9eab90c3067f0473d",
"research/fine_surface_20261014/cpu_shared_kernel_stdout.txt": "1ab9905d8b0f34f6d791ff7da4efa2de0f7f3e282a078758cc0496cc0230c0f0",
"research/fine_surface_20261014/manifest.json": "19747021257f2bc5fa012763521a1733c7303a07f319f013253ca2b9ebb3ad35",
"research/fine_surface_20261014/cpu_device_guard_stdout.txt": "f4c61c0ac8f55c6c9a2d6c593731bf5f8c4a6c5bebbe514284fd4f899818f9e0",
"research/fine_surface_20261014/gpu_test_run1.py": "3dd0658f63a4e7a1c41eecf433842c872f8fecb391ea4b44d0b48947643d5189",
"research/fine_surface_20261014/gpu_preparation_run1.py": "b3fe9e58118369adb1bdfc618fbfbd917d508a563beaf2555f656b59aeff4425",
"research/fine_surface_20261014/cpu_surface_exit.txt": "9a271f2a916b0b6ee6cecb2426f0b3206ef074578be55d9bc94f6f3fe3ab86aa",
"research/fine_surface_20261014/cpu_surface_stdout.txt": "bdb786f2d289eaeab4e53d0fdccb998525c217efaa778496cf7a97ccca9e1597",
"research/fine_surface_20261014/cpu_preallocation_run.json": "363106050ba00d9a1c5c948c36926e8510ed7fdd75d28cfeca59f593fd0f1c50",
"research/fine_surface_20261014/cpu_final_stdout.txt": "bdb786f2d289eaeab4e53d0fdccb998525c217efaa778496cf7a97ccca9e1597",
"research/fine_surface_20261014/cpu_maps_stdout.txt": "7886fd4e2fa8a63e9cecf02bdf650e5447ba149704ac75f51da6964d8e77ba6b",
"research/fine_surface_20261014/cpu_device_guard_exit.txt": "9a271f2a916b0b6ee6cecb2426f0b3206ef074578be55d9bc94f6f3fe3ab86aa",
"research/fine_surface_20261014/cpu_preallocation_stdout.txt": "59907462a8d5fd93406cdf4c7d1eb2f7b7a96664ae85c4ec202693d419cd019e",
"research/fine_surface_20261014/incremental.diff": "9cf8b5cc4ea037c865762ba7069f0c1daabcb4383d4333167d279f8b7704e5b0",
"research/fine_surface_20261014/cpu_final_run.json": "020a9ef12904c2d18185613d68a58dd7ff9b1b22197ac1f95bba61f2f593eaac",
"research/refinement_slot_20261013/incremental.patch": "2daca4c9751190df27e18ea79e46685a8fe3cbb6d42b34135b1219b8f53ea3fc",
"research/refinement_slot_20261013/baseline.json": "17b1a8cb7e8232979cd1fc9976cb6b78aa58a7005449526ec15cc0bfd45f8139",
"research/refinement_slot_20261013/manifest.json": "9f28f275533e8a1a761ec748152170b40845612058236ce331c47ae6c5d68713",
"research/refinement_slot_20261013/before.json": "482b02da26207ce32deb9368b6eb63f9de7b4ab670078c02f458f512fb182b53",
"research/refinement_slot_20261013/notes.txt": "8c70efe2acef9f179c453d297b27047b7632a2d55e0739fff4bccf74e0867511",
"research/refinement_slot_20261013/stdout.txt": "1cabbc8a87a2a237ffa649feac0b1b8e0ae8d769af8c298e600e249d2a525f58",
"research/refinement_slot_20261013/results.json": "6245de38106d7a7b0bfea0aa5100b9c9e393ab5436fc594ce0295b4526964b8f",
"research/refinement_slot_20261013/cpu_results.json": "2a891c1adcb3b25390ee7967e5171396aedb9cb4da5ae85f7444450d758671d5",
"research/refinement_slot_followup_20261013/planar_velocity.sha256": "326639a3e66b2b8dbd21ecd76b32a331f3194a82d1b5888219eee4a1782f6366",
"research/refinement_slot_followup_20261013/incremental.patch": "b734b4b540ece11a037a0f119a9846c39c09c8247d3cc89877880a27c3d082c4",
"research/refinement_slot_followup_20261013/planar_velocity.cuh": "0b2f9e0bd483c199637e5672dc0ffc460bc383dd1804805befbeb4c5d8c708d1",
"research/refinement_slot_followup_20261013/baseline.json": "7ee505b7371a5258db7cb197c999be8859d14641915e3085f1969deb465880a4",
"research/refinement_slot_followup_20261013/manifest.json": "b11c1fb42abccc4b5638b974d1ea00b0687d8fad72b492eab3c8435bf485fd13",
"research/refinement_slot_followup_20261013/before.json": "809c4a6f330d4a29e92415fd0eb820f34dec38484e3560a8b9287b09553c2d87",
"research/refinement_slot_followup_20261013/notes.txt": "c04644a287aa936c9c6de0ca9d8bd83cee2d80aab9544ca284c9f7c029bfeff9",
"research/refinement_slot_followup_20261013/stdout.txt": "acb72f2b14e1abfe750330d84a38afe9bbe944bf028dde9700a291d5edff4be4",
"research/refinement_slot_followup_20261013/results.json": "dc38c3f5f88fac2ebf49be11df84e9f3da9d25504d400b6a506240a91735e4e1",
"research/refinement_prepare_20261013/incremental.patch": "df01345b8e2c33ebf6cdcbbb5104f02c4d7c239a6e6cafab1833228791bfa9a7",
"research/refinement_prepare_20261013/baseline.json": "5cc3c35faac9bb43a0017d83ddfca330d7da93f1e6407391da56b2e9df3b28b6",
"research/refinement_prepare_20261013/manifest.json": "5d479557cd01d61d8b652a3cf456fa57665bf624ce3b4a42c747523b74dec548",
"research/refinement_prepare_20261013/README.txt": "eee46f01add6ed7a5da76da76c98da628e13b930cfc49785399d7afbedbfd95f",
"research/refinement_prepare_20261013/validation.json": "945f4c3604ae0eae91c29741a39588207cfff3e05646e03a12d074a299956c2f",
"research/refinement_prepare_20261013/validation.txt": "5b5a8e9d455d37064c6709dcfd14e89ba66f51f09a11a9863b5cab67ac651d42",
"research/refinement_followup_20261013/gpu_rectangle_before.json": "aeab9314117b7eaa0950566094d20ecb5a304cc55b85887b6281694d3a6b8660",
"research/refinement_followup_20261013/gpu_before.json": "236cc69740cb40640cf4cd96cd94ff80644c2cf07c471b276092303edd3003e1",
"research/refinement_followup_20261013/gpu_rectangle_before_no_launch_1791886104981638567.json": "831b08511b78e8e631a17a638212b1c511e6f3fdb86019d7a77cc0f44d4015d2",
"research/refinement_followup_20261013/gpu_stdout.txt": "3147d3ab0b58ac9aa67c495491979ebb455db0fc2e89e7004facbd8c55c67b4e",
"research/refinement_followup_20261013/cpu_results_attempt1.json": "a91976e3ff92f7fe458a4432dae31d6b751bee92450d9a07e1dd5ee1cf5e915a",
"research/refinement_followup_20261013/incremental.patch": "b638544a02cbf7dd7acfcad545fcac50dc9640e193a9672f27916275c134253f",
"research/refinement_followup_20261013/baseline.json": "77694a29bbea2e61eb69eb5fe37eca7a8d5e82114bd59c7ff23e89d3db53a019",
"research/refinement_followup_20261013/gpu_seed1_before.json": "4dc6de02770a8e985f62d902ab9067cf5910084e4506ece059979640adb5575f",
"research/refinement_followup_20261013/gpu_seed1_stdout.txt": "8453a1b7221085691b39439428e39aaf52215abbbe9b1f84fc54c4a695260a9e",
"research/refinement_followup_20261013/cleanup.json": "ce1fb34fcbf2fadf7786234a8dd5dd9d0e520d9353a08b5df4c6777a35beed88",
"research/refinement_followup_20261013/manifest.json": "5f4c3b56a9ff8dfb422c37e0777af90536e94585ae7573caa05410e3cea294f5",
"research/refinement_followup_20261013/README.txt": "c553e889c6d66bb81d17d2691150cadf6fecdaa336de941281e7c85a6ff1eb12",
"research/refinement_followup_20261013/cpu_stdout.txt": "f9bcee3a2b43599e99c2e3b3a250aa4d4f4db1a73d1bf7cf1db0ab1fa585c54b",
"research/refinement_followup_20261013/gpu_before_no_launch.json": "396664d587d2e7791e972def03c7199845f7a162ab4626733fae1e54e1262da5",
"research/refinement_followup_20261013/gpu_rectangle_results.json": "9a06af9ec07de80d049889f321b7ea5f03036f4e461af2a43cdfb76d02ee1d6a",
"research/refinement_followup_20261013/gpu_rectangle_stdout.txt": "fea29f48685d84966b51d41b33e59bc01bef7d9dbc5e75b3d7c316de761f5bd5",
"research/refinement_followup_20261013/gpu_seed1_results.json": "ac54f5071b6e6095437078d4f8ed1cbc851a4b727ce6336281c1f27472f3dbe4",
"research/refinement_followup_20261013/run_gpu.py": "16b1520adbfee1651539f04dd694f5f02e9dc8ae4f4fc55d374a0ac06b50b4b8",
"research/refinement_followup_20261013/cpu_results.json": "a1a57b35c0839a82a7b653a062e852edf693d2c318da77dc1cb79373661bc780",
"research/refinement_followup_20261013/gpu_results.json": "be369bb072139b3fbfac4cbb3ab5eade7d2fb1ab67549ae2e4e0d0f48f640dfc",
"research/refinement_followup_20261013/cpu_stdout_attempt1.txt": "6ac5f889a9f6b6ecfa8abb74e98b07deaadc71c7f5488112eca26e4ed255e7ba",
"research/refinement_step_20261013/gpu_failure_validation.txt": "d6ec00e0e8c69015565135a67fac6de47701e9eebc3cbacc379abf8166ac61be",
"research/refinement_step_20261013/cpu_validation.json": "cf7200fc4b763f5a2133d8affeea306578a247179bb82ce2f5ae0d8e244c576b",
"research/refinement_step_20261013/incremental.patch": "c3d2d813b64f8a2305f54153508d71b546d86af7be1005cff96e0ef8c91297bb",
"research/refinement_step_20261013/baseline.json": "68bd37982acb433bea235a94f211c907be483e905742f98166235929f79ba95d",
"research/refinement_step_20261013/manifest.json": "a60a40ffa9073a8047f3b9f5af3c1256179603641083c3a20dda6cfa6e050146",
"research/refinement_step_20261013/README.txt": "922d6fc6c742203f69e174a12cac6b19e8ae15be74257134c08d72990b16d517",
"research/refinement_step_20261013/gpu_validation.json": "2f0218854a2a307dd15a891a781fa3c2b7e865c201630a36ca180134b1ee6436",
"research/refinement_step_20261013/gpu_validation.txt": "1714ee85e6235528bf29dac85bca1298a673bdb9bf0c9c364961bf364a83f0d2",
"research/refinement_step_20261013/gpu_failure_validation.json": "5e7d58863659af3c29f10aac11ff43516fedd39a30a40e5ead62732ba80fcbd3",
"research/repair-2026-10-10/simplification-checks.log": "c9f15e870d02003480adf1a7f2fe4a9aca66c1934c4477619f05c8a4798ba85b",
"research/repair-2026-10-10/repair-state.md": "4d4aa1ec0c11a87d2c8380912e7ed74cf5c910ae42e5cc529effde36c9020969",
"research/repair-2026-10-10/TRON_HANDOFF.md": "f8aaa3d99cd133c2055d4adf396a0a57d14f6006aea19e87611bd1c2c1b53a88",
"research/repair-2026-10-10/final-gpu.log": "988bb97256d17b88c14f3793b15880d727ecb285abe62e7d2ae27a16729651c3",
"research/repair-2026-10-10/baseline-status.txt": "074088d793014e3b8154c58718058c7d300fb45595f5129fa957ef1e4cec38e2",
"research/repair-2026-10-10/repair-architecture.md": "49be42ff5c994017f3175e17efda14d84f0b68f8ecd239f66ccee38415b60c5a",
"research/repair-2026-10-10/classic-results.json": "a5d15305f516fd378b54cf9029102be58a83a55a7bad4b8e058fcfe0cc9898f4",
"research/repair-2026-10-10/checkpoint-domain-2026-10-12.diff": "292b4bafe7a62d4fbbf7c165eb99929336edfcaa16b15f34f72ab71fcd928391",
"research/repair-2026-10-10/repair-numerical.md": "0272ebfa8c519aad161c520542cf53156574661609b91fd5ccad7955fdf2bd7b",
"research/repair-2026-10-10/provenance.json": "a81b7e32ecf7182c9617df1b39bbb063a05ef89290ad501bac4573cd5e8a6832",
"research/repair-2026-10-10/classic-signals.npz": "820c9a0b0713d7455f0a5839ac2cd5ee706086d1a26461225dcdb095673421e2",
"research/repair-2026-10-10/baseline-hashes.json": "d6a7d5f9ec5bceb0e7927d55603d9c5e70105982cd945723454659b19ab476e6",
"research/repair-2026-10-10/final-unit.log": "a892a39ecf88125558538cadce2cb5dc46d106b993b164e03da4ebb0eee68cef",
"research/repair-2026-10-10/original-user-files/tests/postproc/experiment.ipynb": "c6b45db1c57200f0777213ef8d44cb4996c1aa7a5fb42b968b77e56f51b4fca4",
"research/repair-2026-10-10/original-user-files/src/CelerisLab/lbm/kernels/config/config_physics.h": "26df33c2960ba36f3283e19b55b4ea92e50e4efda705f9ebfbf3f875a4092c59",
"research/repair-2026-10-10/original-user-files/src/CelerisLab/lbm/kernels/config/config_method.h": "3db4e16ef2c6b22349d04e6aa8ab04bdfe0eb784f9f3a98277e15dbed1835d81",
"research/repair-2026-10-10/original-user-files/src/CelerisLab/lbm/kernels/config/config_grid.h": "8be3a7cf74ba30d7fd3074fed79e63dbda7311c4d03b454ea641bf298ffeaa8d",
"research/repair-2026-10-10/original-user-files/src/CelerisLab/lbm/kernels/config/config_objects.h": "dbb93c063586da278c15d95e23f84c12e728f4f5f1bbc3980fe9cedaa6fff90e",
"research/surface_actuation_20261014/report.txt": "128dd731124542be4ba50fe18d24ceb0a5b37f0329bcf32cdda4de3f1514b0c7",
"research/surface_actuation_20261014/gpu_run.json": "e06268a9acdb3c6ced30e58d684c427aeaaa427b7098da55e60f9a4854a8aa58",
"research/surface_actuation_20261014/gpu_stdout.txt": "bc882fe06353f12ab2b85bc5c9b7e6a23adf705d9e2ab6a529ca8afa49a5166a",
"research/surface_actuation_20261014/cpu_surface_command.txt": "7204f2326b37ce0b4bf05e806935974fb91246922f7e3760dbab0627d94f07ef",
"research/surface_actuation_20261014/baseline.json": "4456d6718db2ad3335c372368e3e1a0a384d78319855a0a9d4cdfca02f28a4c7",
"research/surface_actuation_20261014/cpu_initial.txt": "2c19cce736bac1da5ccacf06b0c71b0e1affcd385e1346d2ab9a0cab5567842a",
"research/surface_actuation_20261014/manifest.json": "9a4e768bd10e8609cd722af8f3904aed27df7debaf2389aa20692c67fe05050f",
"research/surface_actuation_20261014/cpu_surface_exit.txt": "9a271f2a916b0b6ee6cecb2426f0b3206ef074578be55d9bc94f6f3fe3ab86aa",
"research/surface_actuation_20261014/cpu_surface_stdout.txt": "8e47fbdb3f81736adfbb0df2621df4953cf20f2e49cf63a9518b32e6a524fc20",
"research/surface_actuation_20261014/incremental.diff": "9511a0f105edd655f08fbbb22b0330729ee6b610b15febfa38403c4ec506c88b",
"research/surface_actuation_20261014/cpu_checkpoint_stdout.txt": "d740f1038fb46c8c49a0677d9b0d3677ef461bc14cf58f92eb8bd9ad3b1c97f9",
"research/surface_actuation_20261014/cpu_checkpoint_run.json": "8970cd51e65172d47ed3dd16fd118923708dbb2309b213fb819a4c9e3f2e67d0",
"research/j1-2026-10-12/REVIEW.md": "13004a4f140acdcf59acb57e9e2dda1bb95763d30060f822a7c206c94b813a9f",
"research/j1-2026-10-12/gpu.log": "8659a78ea52bbf8eb923d46ea71636ce63cd322352d5c98a74f631e666dd8cfb",
"research/j1-2026-10-12/baseline-status.txt": "ac398360e05b746b89ae0c3acfe202b5122e650a3bb1ff234ab26f874a303e64",
"research/j1-2026-10-12/baseline.json": "ad7afdf7b3913d11c07343e971fe2f43c2d1a2b99e3d5904a6ba89e3bb0b24fb",
"research/j1-2026-10-12/checkpoint-gpu.log": "adfe3d77d2e6c6f6184dccc0267b4404b20a7709505d5ff5affed0ed4a618083",
"research/j1-2026-10-12/cpu.log": "60cac097f7c4f11401df2aacb43a248640555e7628d2829c4680c71db34e9640",
"research/j1-2026-10-12/gpu-validation.log": "d1e9f2aea17a85eddcd94b81c700738ce073214857b55c28abd1219ff1edbed7",
"research/j1-2026-10-12/results.json": "449f8a17dacac0fc6d2489c4b10bac330dbbbdb38fad3ce54f739ac8c6d48e85",
"research/j1-2026-10-12/incremental.diff": "a454c23da7b0011645949c0fbf64d0c41ecfdab5642b1b7c5119868005d3c721",
"research/j3-coverage-2026-10-12/restart-21280.h5": "3e89c12c16f91f76ca9acd909e0fa7d42df6fbb5e870b299aa08ca42bc3e3dc9",
"research/j3-coverage-2026-10-12/REVIEW.md": "7293f3f3442855c8521698605aab504e026915a7bf1e77f5a24710d89a812443",
"research/j3-coverage-2026-10-12/restart-reference-21296.h5": "7192f510dd7820675aa1de130f55514136fba782cf77f92545189918a7e0c328",
"research/j3-coverage-2026-10-12/negative-end-20760.h5": "bd0bd063579d625e358762b1fdde5ac11bfcf739646a847fb77a4a2031011b9b",
"research/j3-coverage-2026-10-12/baseline-status.txt": "31c949b11b20d7cd4202dba16882b5712aa1653da0cb2da2f0ebd69bf488040e",
"research/j3-coverage-2026-10-12/baseline.json": "d8844104f2665a25bfc417ee29becf89ab3955fac9105b5ddb12cfb1fe2a55b0",
"research/j3-coverage-2026-10-12/verification.json": "205986efd2b41635721b7fd20288be982348c765180102c7102750ba088f3a28",
"research/j3-coverage-2026-10-12/negative-budget-20744.h5": "c09d75fc4a2cff68039a0956bd9d32b79b9cd3a6b386c72b4db54c214b110cd8",
"research/j3-coverage-2026-10-12/gpu-validation.log": "505cd5a5db46d7984aefb2a614151c25c4ace0e7d2a52e02c3e4f9792fd8eb95",
"research/j3-coverage-2026-10-12/results.json": "02460981ad49c9cc13b4246abad1d8afd2599c61bfb545a6e32da9bbcd5c0db1",
"research/j3-coverage-2026-10-12/incremental.diff": "98aa7855d5d6b91b4509a924c8a5aabab4339ba29c7e7dc2d91262c48e3848ca",
"research/fixed_patch_jet_20261013/incremental.patch": "dd95a98f03b7ce06d024a1d1d1f454dd206ad10a573a8060f728bad71941d6e8",
"research/fixed_patch_jet_20261013/baseline.json": "d2a83d490ca545589a7a7fc0e3fd187f4801e22e5c8d2d18ddb519097d3281b9",
"research/fixed_patch_jet_20261013/manifest.json": "3efaf5af8d6a4f6c3460d8023466af611ff90bc9fc79c3e7db6f591d172d1182",
"research/fixed_patch_jet_20261013/before.json": "dd47f1e25a807a3eafef7d12429f034117f945a4ebfeb98eb1688d1752c3d30d",
"research/fixed_patch_jet_20261013/notes.txt": "155be36e201c9c8a043a87fc7a7d0064b703990b2aad86853767603fe38a256d",
"research/fixed_patch_jet_20261013/stdout.txt": "925abb3038095560d71a4e7733b38d93672397640cc88197c733a8a39e2f9f51",
"research/fixed_patch_jet_20261013/results.json": "fcd944b8dec61b399874b5386d6e00880f0dbc34d248ad371a6af8781fddaa93",
"research/fixed_patch_jet_20261013/fixed_patch_jet.py": "f27cd067fd7b9a7c6d7fab19fa471fe0617ee67889ae3931048557cc5659181b",
"research/fixed_patch_jet_20261013/output/summary.json": "a9a4ab5975684a386f05746f570ec4d7b1c5ee3be413400445122448f534eca3",
"research/fixed_patch_jet_20261013/output/velocity.png": "0f8ffc3a7b36ffefa5c0cd8550309fe89d9de72cd5476f354a27fac89cb39b0a",
"research/fixed_patch_jet_20261013/output/layout.png": "cfc354c0192a5a9727a8056ff6c5bc4571f916143853e4da2dc16da965e10173",
"research/audit-2026-10-09/numerical_semantics_results.json": "b95b065b594aa2911740dab216f87936c9bf7f7fa25acfda93b5738443564035",
"research/audit-2026-10-09/REVIEW.zh-CN.md": "2841fd3aa7a6baedbe1079d90915c8b05212b133824ed6abccaa1f09656eaefe",
"research/audit-2026-10-09/root-initializers-report.md": "ca448457c444949d5d0e1e10fa7121064510b77fc4c3512580900f0299219867",
"research/audit-2026-10-09/numerical-report.md": "970330b3a593f79f09866ce6ae82bc0ddd81226230d0a6ff06ae8ae756ee80da"
}
@@ -0,0 +1,72 @@
{
"research/audit-2026-10-09/numerical_collision_results.json": "51e5c263bb8cde82cedef2ccfdbf5ef657742a80218d7896b1ff877516e59693",
"research/audit-2026-10-09/architecture-cpu-results.json": "e1b809210005c8765b13fddbb5ed710d15f6fcbb4c5788a4064f3e88808433ef",
"research/audit-2026-10-09/numerical_compile_results.json": "c3b0ae02072a2ec408ada7513b542ec255f6855cb743a3ed7f91bd8f31504f44",
"research/audit-2026-10-09/state_results.json": "da9170df3e11231c73f20e5e79ed68e08966673d1dd52004ea6b6a279afc0dcd",
"research/audit-2026-10-09/architecture-report.md": "861079dc3f4ced9fdc41bfb22002d32e190c0d630d3ba2f138f9dc7a949b8371",
"research/audit-2026-10-09/state-report.md": "f8708807efc2e109810c5955f7c1884a932668c0b3cb2963c2df3b09f2a3d5c4",
"research/fixed_patch_jet_closure_20261013/incremental.patch": "18b30ecc0703bcb4cb6577255d12a5b0d95dfea99d02d761bbc1b5b231bba1d3",
"research/fixed_patch_jet_closure_20261013/baseline.json": "ccf88409836657aebbf091f06c41141c81d20169c2cac0fd8e2a16b40df36882",
"research/fixed_patch_jet_closure_20261013/manifest.json": "7a2a079be7b6146b3bc2f5494f98ca2f935805ca4c6aa1eb1b9067fdeb3ae3c5",
"research/fixed_patch_jet_closure_20261013/notes.txt": "bc3c939659ef0cbda506024d79b896707f4dc4af94bb088924e139f81a9e885f",
"research/fixed_patch_jet_closure_20261013/cpu_stdout.txt": "4e1f371a568eb1c2a7912cb5ea564c8c23f0106dbc41a68f179bbcafdff2cdff",
"research/fixed_patch_jet_closure_20261013/layout_uncropped.png": "0ef6709c02ed5beba5707e033d9f6f9795a9bbfe3d7fc23341fa7dab6e85288c",
"research/fixed_patch_jet_closure_20261013/cpu_results.json": "6bae91721db9051f18bbf89dacca40b80410f84f037e7732cb1af4eadc24aaf8",
"research/j3-offline-2026-10-12/REVIEW.md": "d9902c58498e73c29e054b23adb968f7e1e14421cba5c58d03bbc5a50159ae79",
"research/j3-offline-2026-10-12/lags.csv": "fbd9addd413f24c47f4411317e872265bb774e8e1724fe169412befa860ae94d",
"research/j3-offline-2026-10-12/localization.png": "a72907638e32b0ecfc2205bea438e7b408f40aad86217ce6ad9b4877840c9cfc",
"research/j3-offline-2026-10-12/results.json": "cdb857bea6f4e06ed15acf773505ce6d5147f8cb8ce0a53cc368ee267cde6361",
"research/j3-offline-2026-10-12/cpu-analysis.log": "bc02a9b197fc15ae1b503ca54655a7622d4361f9b45b7848ff9c387ea3665f11",
"research/j3-offline-2026-10-12/regions.csv": "3a8fc640b61d70e3b7f73d2bf8ac2bd3f720adf39a90dfda6180430e0489efae",
"research/fixed_patch_jet_records_20261013/incremental.patch": "63485fb4eee8e2e89b683961aee32a6ca00ef5e607a362efb3290f3a08809222",
"research/fixed_patch_jet_records_20261013/baseline.json": "d73ddb2a6629f03655aa05fae08bb4bbc9474c686af56dbe29c99d6491b7508e",
"research/fixed_patch_jet_records_20261013/manifest.json": "97a2fbf139985a19cb6c0e0818646571fa1bcfb23e36424998a64777db641592",
"research/fixed_patch_jet_records_20261013/before.json": "68ec7ef820d5f826b6e24c6afdef71c76bd22400393815321ac3a1905c437796",
"research/fixed_patch_jet_records_20261013/notes.txt": "6d55a6395833fa02883357752ab3d8ea43df516fbcb40e4006fb1756757b1e99",
"research/fixed_patch_jet_records_20261013/stdout.txt": "6e579eff0c1762ba31d8b1cee709e0cdba2e3f408432b71fe374b2d9f450665c",
"research/fixed_patch_jet_records_20261013/results.json": "7997ee1626ad0640a9d362499c8e0eeefe9d71913fef5f2280112d5bdc9b50d4",
"research/fixed_patch_jet_records_20261013/fixed_patch_jet.py": "7d6370fe6d8b723b1b3e1492e89fcc72562383c0dc030c25a254ac3fc899845a",
"research/fixed_patch_jet_records_20261013/output/summary.json": "a448c2e66a56ee48071315d6f73d0ec1afccc29d680ab3a40d51d1df62dd973a",
"research/fixed_patch_jet_records_20261013/output/velocity.png": "7c67c5f64a4bec94547c0ac7833e6d47eeaae9696904c1465a9d5d969008b79d",
"research/fixed_patch_jet_records_20261013/output/layout.png": "678ba19a51c112960ace2a4b8d9d94e43287d97c3a6ef892684630ab37b70255",
"research/j2-slot-2026-10-12/REVIEW.md": "10c4a94ffc32e0a2c4e0f6593b7cfc28479b5869f279f0b9d0b708fa3a47d1e6",
"research/j2-slot-2026-10-12/gpu-serialization-failure.log": "df804e53b35e7ddaad79a17842b4b5fd9d834e29ca2d56edb00e835848d09200",
"research/j2-slot-2026-10-12/baseline-status.txt": "812616e2d941efcf854e1b37d6e662dda1aaf2b69074fcc04017133e13b72166",
"research/j2-slot-2026-10-12/baseline.json": "e82a1844145fd0cbc585c581b29f80b56193f122cfe1dfa7578f26904a720285",
"research/j2-slot-2026-10-12/cli.log": "9482ad7101d501f27f92e204b2f3ae5c6d91bd887b525aa31cb4a2a188f3cb92",
"research/j2-slot-2026-10-12/cpu.log": "91aba5961006909fbbb860429a9d3cfc930112a0d74c7788bc51c0a5897b47e5",
"research/j2-slot-2026-10-12/gpu-validation.log": "223351b52c70fa4523289f3a1b3db435a11286379253280470900ffe397580a6",
"research/j2-slot-2026-10-12/results.json": "7d35ca7989aed5380e0a45de7f583972566fc516a051da63c53b35514e267494",
"research/j2-slot-2026-10-12/incremental.diff": "c9e391bc91438cd912c1ed5a419705d4388522f672c67a066cfc055e814e699f",
"research/design-2026-10-09/math-and-history.md": "64f8c82e4949d6f58b46faa09800958714859c36cad20bbeeae8b449ae7a6099",
"research/design-2026-10-09/math-checks.json": "94750381954317cde8d649db26beaed8ea945666572a05030ca2b4d97d384011",
"research/design-2026-10-09/Contracts.lean": "2442d9a778ef20e8af3fecf23be6fea6d73c6299ff744c9664b652bc5ee3f034",
"research/design-2026-10-09/jet-study.md": "a362142ef04a5ad5dbb4c9db9d221b1199dccec53780c8f2da49a15201cfe529",
"research/design-2026-10-09/PLAN.zh-CN.md": "0341dd7ee306a040340c8e5dedb07a109e931c27dbf3c994d072aa78e3b6bc67",
"research/design-2026-10-09/jet_closure_results.json": "12cf7d400a206f9f9ec9ea6ad251fe6bb0232e27bcbed22fbc1ead2c0fc7d249",
"research/design-2026-10-09/grid-study.md": "4435dc1275ec5e15b118becc6ac391f306195d1e5beaa58037b1aff3bb2465c7",
"research/design-2026-10-09/jet_closure_check.py": "fde45d0f8518740ef5c0bf0fe7635d6adaf9a2e789927dd4e68e991c138ddc30",
"research/design-2026-10-09/api-architecture-study.md": "d6fb45ec784f0e1db55fb9f34e137b9f551db0b9b39fd4f0ef247a78fc34eedf",
"research/design-2026-10-09/math_checks.py": "4254983a783fe4bad8888b3d7c243c87d991c7bbf242edb0f56f25cbaefee890",
"research/wall_seam_pulse_20261014/analyze.py": "2b174826ffaee96c147bd247ef5e322cb51d55ce506f330bac021afd012560f7",
"research/wall_seam_pulse_20261014/stdout.txt": "4a555ab2412d6b6974ba42f213fa394c6b438a3762981a135cbddfeff5598ae2",
"research/wall_seam_pulse_20261014/run.json": "4466aafbea16f9af46d70a5da4c8ce69ea7d5fcd256181f083cc728d1c35bfe9",
"research/wall_seam_pulse_20261014/interpretation.txt": "9785c6814a25cddbf5e74b4cb1ba421287c920d97a502425d6739667185a24c6",
"research/wall_seam_pulse_20261014/results.json": "29b7588e4cc86750d63567315fd430c9de20be5419bb45f8bca4a5259f6473aa",
"research/wall_seam_pulse_20261014/sources.csv": "765f6e8b7545304675688295153ee6c94deacfbfb52571c831021ca03f4bb98d",
"research/refinement_example_20261013/incremental.patch": "6acd05df6669ccdcf234ac1680c6e76c75a2587974adb6728f7edda6fd625b69",
"research/refinement_example_20261013/baseline.json": "ae0af15ddb40709d1e348655a665264984a240ded1e28af816a8000d08e784be",
"research/refinement_example_20261013/manifest.json": "6da85ac513065dcf49200bc0872bec38b6c7ba61f7d82036c2189cabe5ac29ce",
"research/refinement_example_20261013/before.json": "d95cd518f080eab92af5e53e1e9b6b6fad626eae51990e510d2d2f2ae9d0ec7b",
"research/refinement_example_20261013/notes.txt": "f111f8cba94b43d1127945fa41615037e1740efcfc529e802338dd8c4ff02795",
"research/refinement_example_20261013/stdout.txt": "9c59fb315a5552cce4ceab171003e425bf64d747137c89bd86d8779a34adcbd1",
"research/refinement_example_20261013/results.json": "8ab13bbc022f2a66898aa07ed94f43cb6716570e7a360a809b7fcd097316db7e",
"research/j3-reservoir-2026-10-12/gpu-availability-sandbox.log": "1d58470512e583a0acfabf6896ee5f31e5b493b8231aed54b864f64eb275b02c",
"research/j3-reservoir-2026-10-12/REVIEW.md": "1ea5f860728584ea6cbe40ba3994e40471102d8e2cf6d93e28fe47222cba0cab",
"research/j3-reservoir-2026-10-12/baseline-status.txt": "0ef1a8c9878c4053ebc1a7d4bace6d4ec38bf27ace167b4239ddbb1c6c897e20",
"research/j3-reservoir-2026-10-12/baseline.json": "847fefd1eae971985d34d04d89ee6d6f1c91f6940c54fe351d112faba7bc6838",
"research/j3-reservoir-2026-10-12/cpu.log": "b33f6c1a1b0ee67968c4cff85d491e46e30e0d6c796b552629714ab8b5dcead0",
"research/j3-reservoir-2026-10-12/gpu-validation.log": "ff04024db197e332f37c912a96413e3251fd0186947348ffbc33af6f4a899f2c",
"research/j3-reservoir-2026-10-12/results.json": "49685de7679a14860258abf1753aaa6d116ad709b868d907ddb40e74c9b845ea",
"research/j3-reservoir-2026-10-12/incremental.diff": "fae312831d71e46dd477a640b06ed927853a9e735d26bf9f5868927fa31cfa56"
}
@@ -0,0 +1,49 @@
step,substep,time,bfl_error,drive_mass,latest_body_impulse_x,latest_body_impulse_y,latest_body_angular_impulse,boundary_m,boundary_px,boundary_py,fine_transfer_m,fine_transfer_px,fine_transfer_py
1,1,0.5,3.7331066016221826e-09,0.0015482567250728607,-0.0010669911280274391,-0.0009111231192946434,-1.3296011179275702e-05,0.0015482567250728607,0.0010669846087694168,0.0009111212566494942,0.0,0.0,0.0
1,2,1.0,7.450580596923828e-09,0.00155003224242226,-0.0005924226716160774,-0.0005089053884148598,-6.828160713734377e-06,0.0018995041027665138,0.0005924198776483536,0.0005089100450277328,-3.557652235031128e-07,0.0,0.0
2,1,1.5,9.730734440438482e-09,0.0015509553987416245,-0.0007510213181376457,-0.0006337100639939308,-6.453869729639017e-06,0.0018004681915044785,0.0007510194554924965,0.0006337091326713562,-8.530914783477783e-07,-7.450580596923828e-09,-1.6763806343078613e-07
2,2,2.0,7.450580596923828e-09,0.0015510943465718227,-0.0007005799561738968,-0.0005853474140167236,9.16537625561542e-06,0.0019320533610880375,0.0007005711086094379,0.0005853441543877125,-1.3401731848716736e-06,2.7939677238464355e-09,-9.313225746154785e-10
3,1,2.5,8.252825436927402e-09,0.0015511169589478664,-0.0007204441353678703,-0.0006065750494599342,-1.9204094044988906e-06,0.0019155647605657578,0.0007204404100775719,0.0006065657362341881,-1.6577541828155518e-06,1.5832483768463135e-07,1.5832483768463135e-07
3,2,3.0,9.915552157124807e-09,0.0015509250112041078,-0.0006797974929213524,-0.0005730642005801201,2.2820092603348385e-06,0.0019676131196320057,0.0006797960959374905,0.0005730544216930866,-1.982320100069046e-06,3.1152740120887756e-07,3.096647560596466e-07
4,1,3.5,9.13659503609665e-09,0.0015507420136590903,-0.0006570117548108101,-0.0005553392693400383,-3.1137037854733762e-06,0.00195569870993495,0.0006570047698915005,0.0005553369410336018,-3.2121315598487854e-06,3.5297125577926636e-07,3.762543201446533e-07
4,2,4.0,7.450580596923828e-09,0.0015504969629409936,-0.0006134528666734695,-0.0005185604095458984,-2.5563305094955524e-07,0.001978149637579918,0.0006134519353508949,0.0005185585469007492,-3.698747605085373e-06,-3.585591912269592e-08,1.909211277961731e-08
5,1,4.5,7.450580596923828e-09,0.0015502991826538432,-0.0005827639251947403,-0.0004925131797790527,-2.496779667127136e-06,0.001968016382306814,0.0005827643908560276,0.0004925071261823177,-3.6563724279403687e-06,5.550682544708252e-07,2.4121254682540894e-07
5,2,5.0,7.450580596923828e-09,0.0015500768212474217,-0.0005441568791866302,-0.00045982934534549713,-6.621178455512577e-07,0.0019786693155765533,0.0005441587418317795,0.00045982934534549713,-3.6312267184257507e-06,5.122274160385132e-07,2.2258609533309937e-07
6,1,5.5,7.450580596923828e-09,0.001549918623869907,-0.0005141962319612503,-0.00043411366641521454,-1.9021591811663185e-06,0.0019702534191310406,0.000514195766299963,0.00043410947546362877,-2.8940849006175995e-06,5.164183676242828e-07,3.213062882423401e-08
6,2,6.0,7.450580596923828e-09,0.0015497499199425297,-0.0004802681505680084,-0.0004054997116327286,-7.309877421146638e-07,0.0019760499708354473,0.0004802667535841465,0.00040551135316491127,-3.33273783326149e-06,-3.0687078833580017e-07,-2.1746382117271423e-07
7,1,6.5,6.764444948625936e-09,0.0015496176481223653,-0.0004520462825894356,-0.0003813067451119423,-1.5892076227208562e-06,0.001969610806554556,0.00045204488560557365,0.00038131000474095345,-7.304362952709198e-06,-2.8349459171295166e-06,-1.5050172805786133e-06
7,2,7.0,8.109305865700023e-09,0.0015494958415757888,-0.00042206887155771255,-0.0003560921177268028,-7.75549964804334e-07,0.0019731801003217697,0.0004220716655254364,0.00035608746111392975,-1.9578728824853897e-05,-1.0931398719549179e-05,-6.151851266622543e-06
8,1,7.5,7.94549828708746e-09,0.0015493981799709084,-0.00039640720933675766,-0.000333922915160656,-1.3677983846660524e-06,0.001968265976756811,0.00039641233161091805,0.0003339252434670925,-5.536805838346481e-05,-2.580694854259491e-05,-1.5653669834136963e-05
8,2,8.0,8.57936799381065e-09,0.0015493020071895578,-0.00037000514566898346,-0.00031171925365924835,-8.318499384873945e-07,0.0019705859012901783,0.00037001678720116615,0.0003117159940302372,-0.00011411821469664574,-6.15590251982212e-05,-3.886828199028969e-05
9,1,8.5,8.998468456478115e-09,0.0015492362139466068,-0.0003468478098511696,-0.0002919333055615425,-1.3410125925261696e-06,0.0019667870365083218,0.0003468613140285015,0.0002919272519648075,-0.00023686187341809273,-9.644916281104088e-05,-6.473483517765999e-05
9,2,9.0,1.0769307515201554e-08,0.0015491672233875443,-0.0003237603232264519,-0.00027247238904237747,-8.826204219714029e-07,0.0019684722647070885,0.0003237677738070488,0.0002724668011069298,-0.0003811251372098923,-0.00018009915947914124,-0.00012547895312309265
10,1,9.5,6.5991891951000525e-09,0.001549105281009374,-0.00030333735048770905,-0.00025494955480098724,-1.3582019926516864e-06,0.0019654426723718643,0.0003033336251974106,0.000254947692155838,-0.0006271977908909321,-0.00022491207346320152,-0.00016344105824828148
10,2,10.0,6.118484829897852e-09,0.001549051989981235,-0.0002833334729075432,-0.00023819785565137863,-9.026330124450865e-07,0.001966737676411867,0.0002833292819559574,0.0002382085658609867,-0.0008610719814896584,-0.0003546644002199173,-0.00026744231581687927
11,1,10.5,6.552038911422642e-09,0.00154901751549866,-0.0002655861899256706,-0.0002231122925877571,-1.2630542108871268e-06,0.001964384224265814,0.00026558665558695793,0.00022311368957161903,-0.0011930274777114391,-0.00039019854739308357,-0.0003034067340195179
11,2,11.0,9.802380018797408e-09,0.0015489874147144294,-0.00024848151952028275,-0.00020880158990621567,-9.786817930512726e-07,0.0019654412753880024,0.00024848291650414467,0.00020880764350295067,-0.001470054965466261,-0.0005364310927689075,-0.0004325839690864086
12,1,11.5,1.0565094576975298e-08,0.0015489509835935602,-0.00023323949426412582,-0.0001959698274731636,-1.174757736199794e-06,0.0019635832868516445,0.00023323623463511467,0.000195962842553854,-0.0017936332151293755,-0.0005537522956728935,-0.0004546362906694412
12,2,12.0,1.0153207108398732e-08,0.0015489143609847475,-0.00021865405142307281,-0.00018392689526081085,-9.567065110127615e-07,0.001964456867426634,0.00021865731105208397,0.0001839236356317997,-0.00204546470195055,-0.0006773108616471291,-0.0005757706239819527
13,1,12.5,6.847925559938517e-09,0.0015489000506591615,-0.00020564347505569458,-0.00017303228378295898,-1.229019973680856e-06,0.0019629797898232937,0.0002056504599750042,0.00017301971092820168,-0.002280890941619873,-0.00067916139960289,-0.000582011416554451
13,2,13.0,1.1770799335231175e-08,0.0015488750333560626,-0.0001933462917804718,-0.00016286037862300873,-9.379367493789204e-07,0.0019637630321085453,0.00019335513934493065,0.00016285711899399757,-0.002459546085447073,-0.0007534711621701717,-0.0006643435917794704
14,1,13.5,8.936060558184522e-09,0.0015488612668431816,-0.00018239393830299377,-0.00015359185636043549,-1.2376870923702654e-06,0.001962530892342329,0.000182389747351408,0.00015358394011855125,-0.002583651803433895,-0.0007450981065630913,-0.0006575053557753563
14,2,14.0,1.2725840020655355e-08,0.0015488343418273527,-0.0001720944419503212,-0.00014511216431856155,-8.9041709272486e-07,0.001963145099580288,0.00017209816724061966,0.00014511402696371078,-0.002680632285773754,-0.0007635904476046562,-0.0006860606372356415
15,1,14.5,9.446215296082805e-09,0.0015488229734234565,-0.0001630391925573349,-0.00013743527233600616,-1.146773010329838e-06,0.001962078735232353,0.00016304105520248413,0.00013743527233600616,-0.0027179024182260036,-0.0007485975511372089,-0.000670840498059988
15,2,15.0,9.313422921763959e-09,0.001548801691143042,-0.00015463586896657944,-0.00013038236647844315,-9.957984490327476e-07,0.0019625588320195675,0.0001546279527246952,0.0001303856261074543,-0.002754406537860632,-0.0007191230542957783,-0.000647230539470911
16,1,15.5,7.756034481332108e-09,0.001548795055197433,-0.00014728587120771408,-0.00012414250522851944,-1.19767199602272e-06,0.001961618661880493,0.0001472746953368187,0.00012414157390594482,-0.0027457624673843384,-0.000701194629073143,-0.0006282757967710495
16,2,16.0,4.9820187697502405e-09,0.0015487817877766277,-0.0001406259834766388,-0.00011855922639369965,-1.0063548837591085e-06,0.001962041947990656,0.0001406143419444561,0.00011856527999043465,-0.00275089917704463,-0.0006374767981469631,-0.0005653253756463528
17,1,16.5,7.659630707479437e-09,0.0015487774975968425,-0.0001347297802567482,-0.00011365208774805069,-1.1021201878902431e-06,0.0019611907191574574,0.00013471907004714012,0.00011365814134478569,-0.0027269930578768253,-0.0006199139170348644,-0.0005475492216646671
17,2,17.0,8.840773640939048e-09,0.001548763244042896,-0.00012935884296894073,-0.00010930560529232025,-1.016784981322516e-06,0.0019615269266068935,0.0001293686218559742,0.00010931165888905525,-0.002721673808991909,-0.0005361568182706833,-0.00046241283416748047
18,1,17.5,1.2304882210378842e-08,0.0015487567261606326,-0.00012471340596675873,-0.000105343759059906,-1.0469923481526422e-06,0.001960811670869589,0.0001247120089828968,0.00010533956810832024,-0.0026941243559122086,-0.0005193613469600677,-0.00044766347855329514
18,2,18.0,7.418095471223296e-09,0.0015487429170055658,-0.00012026354670524597,-0.00010176189243793488,-9.512738775585561e-07,0.001961167436093092,0.00012026121839880943,0.00010176049545407295,-0.0026859669014811516,-0.0004291580989956856,-0.00035731401294469833
19,1,18.5,7.707569693593541e-09,0.0015487447557849957,-0.0001163184642791748,-9.842775762081146e-05,-1.1155910571991612e-06,0.001960610970854759,0.00011632218956947327,9.842775762081146e-05,-0.0026490092277526855,-0.00040957890450954437,-0.00034233927726745605
19,2,19.0,9.897528907565345e-09,0.001548736220618044,-0.00011231936514377594,-9.525753557682037e-05,-8.746676823934152e-07,0.0019609862938523293,0.00011232960969209671,9.52649861574173e-05,-0.0026348931714892387,-0.0003248099237680435,-0.00026043038815259933
20,1,19.5,7.458307527130614e-09,0.0015487257938516241,-0.00010872259736061096,-9.228847920894623e-05,-1.117876357703551e-06,0.001960530411452055,0.00010872026905417442,9.2280562967062e-05,-0.0025746123865246773,-0.000293082557618618,-0.0002375887706875801
20,2,20.0,7.1616321761780455e-09,0.0015487109979796746,-0.00010512489825487137,-8.937250822782516e-05,-9.404776560861805e-07,0.0019608777947723866,0.00010512815788388252,8.937017992138863e-05,-0.002546322997659445,-0.00022387364879250526,-0.00017382996156811714
21,1,20.5,1.2005225979994094e-08,0.0015487181439359362,-0.00010188575834035873,-8.659716695547104e-05,-1.0574914846017691e-06,0.0019605131819844246,0.00010188296437263489,8.659809827804565e-05,-0.002445746213197708,-0.00016940850764513016,-0.00013363640755414963
21,2,21.0,7.5469843707765e-09,0.001548692199227755,-9.881984442472458e-05,-8.39056447148323e-05,-9.763081801894558e-07,0.0019607869908213615,9.881611913442612e-05,8.391123265028e-05,-0.0023945574648678303,-0.0001229965128004551,-9.305356070399284e-05
22,1,21.5,6.037053218443944e-09,0.0015486938404374378,-9.613670408725739e-05,-8.161552250385284e-05,-1.0525385535364862e-06,0.00196036696434021,9.6137635409832e-05,8.160900324583054e-05,-0.002243565861135721,-3.6747660487890244e-05,-2.6164110749959946e-05
22,2,22.0,9.586391680471706e-09,0.001548693360520578,-9.382795542478561e-05,-7.957685738801956e-05,-9.683724135900462e-07,0.001960549969226122,9.383400902152061e-05,7.956428453326225e-05,-0.0021634772419929504,-1.710653305053711e-05,-1.1105090379714966e-05
23,1,22.5,9.489836569342991e-09,0.0015486823349255578,-9.185541421175003e-05,-7.787439972162247e-05,-1.0168454692704998e-06,0.0019601034000515938,9.18535515666008e-05,7.786881178617477e-05,-0.0019649858586490154,0.00010295165702700615,8.555082604289055e-05
23,2,23.0,6.585969006267511e-09,0.0015486694330888832,-9.038113057613373e-05,-7.635168731212616e-05,-9.023735720870008e-07,0.0019602179527282715,9.038485586643219e-05,7.635634392499924e-05,-0.001856005284935236,9.549083188176155e-05,7.625715807080269e-05
24,1,23.5,6.188236104098799e-09,0.0015486604639943502,-8.921325206756592e-05,-7.526762783527374e-05,-1.0200224049849993e-06,0.001959813293069601,8.920999243855476e-05,7.527368143200874e-05,-0.0016284165903925896,0.0002412758767604828,0.00019868742674589157
24,2,24.0,9.620717680847157e-09,0.0015486650695279314,-8.823629468679428e-05,-7.427390664815903e-05,-9.335468453830487e-07,0.0019598701037466526,8.823955431580544e-05,7.426505908370018e-05,-0.0014977920800447464,0.0002111736685037613,0.00016872771084308624
1 step substep time bfl_error drive_mass latest_body_impulse_x latest_body_impulse_y latest_body_angular_impulse boundary_m boundary_px boundary_py fine_transfer_m fine_transfer_px fine_transfer_py
2 1 1 0.5 3.7331066016221826e-09 0.0015482567250728607 -0.0010669911280274391 -0.0009111231192946434 -1.3296011179275702e-05 0.0015482567250728607 0.0010669846087694168 0.0009111212566494942 0.0 0.0 0.0
3 1 2 1.0 7.450580596923828e-09 0.00155003224242226 -0.0005924226716160774 -0.0005089053884148598 -6.828160713734377e-06 0.0018995041027665138 0.0005924198776483536 0.0005089100450277328 -3.557652235031128e-07 0.0 0.0
4 2 1 1.5 9.730734440438482e-09 0.0015509553987416245 -0.0007510213181376457 -0.0006337100639939308 -6.453869729639017e-06 0.0018004681915044785 0.0007510194554924965 0.0006337091326713562 -8.530914783477783e-07 -7.450580596923828e-09 -1.6763806343078613e-07
5 2 2 2.0 7.450580596923828e-09 0.0015510943465718227 -0.0007005799561738968 -0.0005853474140167236 9.16537625561542e-06 0.0019320533610880375 0.0007005711086094379 0.0005853441543877125 -1.3401731848716736e-06 2.7939677238464355e-09 -9.313225746154785e-10
6 3 1 2.5 8.252825436927402e-09 0.0015511169589478664 -0.0007204441353678703 -0.0006065750494599342 -1.9204094044988906e-06 0.0019155647605657578 0.0007204404100775719 0.0006065657362341881 -1.6577541828155518e-06 1.5832483768463135e-07 1.5832483768463135e-07
7 3 2 3.0 9.915552157124807e-09 0.0015509250112041078 -0.0006797974929213524 -0.0005730642005801201 2.2820092603348385e-06 0.0019676131196320057 0.0006797960959374905 0.0005730544216930866 -1.982320100069046e-06 3.1152740120887756e-07 3.096647560596466e-07
8 4 1 3.5 9.13659503609665e-09 0.0015507420136590903 -0.0006570117548108101 -0.0005553392693400383 -3.1137037854733762e-06 0.00195569870993495 0.0006570047698915005 0.0005553369410336018 -3.2121315598487854e-06 3.5297125577926636e-07 3.762543201446533e-07
9 4 2 4.0 7.450580596923828e-09 0.0015504969629409936 -0.0006134528666734695 -0.0005185604095458984 -2.5563305094955524e-07 0.001978149637579918 0.0006134519353508949 0.0005185585469007492 -3.698747605085373e-06 -3.585591912269592e-08 1.909211277961731e-08
10 5 1 4.5 7.450580596923828e-09 0.0015502991826538432 -0.0005827639251947403 -0.0004925131797790527 -2.496779667127136e-06 0.001968016382306814 0.0005827643908560276 0.0004925071261823177 -3.6563724279403687e-06 5.550682544708252e-07 2.4121254682540894e-07
11 5 2 5.0 7.450580596923828e-09 0.0015500768212474217 -0.0005441568791866302 -0.00045982934534549713 -6.621178455512577e-07 0.0019786693155765533 0.0005441587418317795 0.00045982934534549713 -3.6312267184257507e-06 5.122274160385132e-07 2.2258609533309937e-07
12 6 1 5.5 7.450580596923828e-09 0.001549918623869907 -0.0005141962319612503 -0.00043411366641521454 -1.9021591811663185e-06 0.0019702534191310406 0.000514195766299963 0.00043410947546362877 -2.8940849006175995e-06 5.164183676242828e-07 3.213062882423401e-08
13 6 2 6.0 7.450580596923828e-09 0.0015497499199425297 -0.0004802681505680084 -0.0004054997116327286 -7.309877421146638e-07 0.0019760499708354473 0.0004802667535841465 0.00040551135316491127 -3.33273783326149e-06 -3.0687078833580017e-07 -2.1746382117271423e-07
14 7 1 6.5 6.764444948625936e-09 0.0015496176481223653 -0.0004520462825894356 -0.0003813067451119423 -1.5892076227208562e-06 0.001969610806554556 0.00045204488560557365 0.00038131000474095345 -7.304362952709198e-06 -2.8349459171295166e-06 -1.5050172805786133e-06
15 7 2 7.0 8.109305865700023e-09 0.0015494958415757888 -0.00042206887155771255 -0.0003560921177268028 -7.75549964804334e-07 0.0019731801003217697 0.0004220716655254364 0.00035608746111392975 -1.9578728824853897e-05 -1.0931398719549179e-05 -6.151851266622543e-06
16 8 1 7.5 7.94549828708746e-09 0.0015493981799709084 -0.00039640720933675766 -0.000333922915160656 -1.3677983846660524e-06 0.001968265976756811 0.00039641233161091805 0.0003339252434670925 -5.536805838346481e-05 -2.580694854259491e-05 -1.5653669834136963e-05
17 8 2 8.0 8.57936799381065e-09 0.0015493020071895578 -0.00037000514566898346 -0.00031171925365924835 -8.318499384873945e-07 0.0019705859012901783 0.00037001678720116615 0.0003117159940302372 -0.00011411821469664574 -6.15590251982212e-05 -3.886828199028969e-05
18 9 1 8.5 8.998468456478115e-09 0.0015492362139466068 -0.0003468478098511696 -0.0002919333055615425 -1.3410125925261696e-06 0.0019667870365083218 0.0003468613140285015 0.0002919272519648075 -0.00023686187341809273 -9.644916281104088e-05 -6.473483517765999e-05
19 9 2 9.0 1.0769307515201554e-08 0.0015491672233875443 -0.0003237603232264519 -0.00027247238904237747 -8.826204219714029e-07 0.0019684722647070885 0.0003237677738070488 0.0002724668011069298 -0.0003811251372098923 -0.00018009915947914124 -0.00012547895312309265
20 10 1 9.5 6.5991891951000525e-09 0.001549105281009374 -0.00030333735048770905 -0.00025494955480098724 -1.3582019926516864e-06 0.0019654426723718643 0.0003033336251974106 0.000254947692155838 -0.0006271977908909321 -0.00022491207346320152 -0.00016344105824828148
21 10 2 10.0 6.118484829897852e-09 0.001549051989981235 -0.0002833334729075432 -0.00023819785565137863 -9.026330124450865e-07 0.001966737676411867 0.0002833292819559574 0.0002382085658609867 -0.0008610719814896584 -0.0003546644002199173 -0.00026744231581687927
22 11 1 10.5 6.552038911422642e-09 0.00154901751549866 -0.0002655861899256706 -0.0002231122925877571 -1.2630542108871268e-06 0.001964384224265814 0.00026558665558695793 0.00022311368957161903 -0.0011930274777114391 -0.00039019854739308357 -0.0003034067340195179
23 11 2 11.0 9.802380018797408e-09 0.0015489874147144294 -0.00024848151952028275 -0.00020880158990621567 -9.786817930512726e-07 0.0019654412753880024 0.00024848291650414467 0.00020880764350295067 -0.001470054965466261 -0.0005364310927689075 -0.0004325839690864086
24 12 1 11.5 1.0565094576975298e-08 0.0015489509835935602 -0.00023323949426412582 -0.0001959698274731636 -1.174757736199794e-06 0.0019635832868516445 0.00023323623463511467 0.000195962842553854 -0.0017936332151293755 -0.0005537522956728935 -0.0004546362906694412
25 12 2 12.0 1.0153207108398732e-08 0.0015489143609847475 -0.00021865405142307281 -0.00018392689526081085 -9.567065110127615e-07 0.001964456867426634 0.00021865731105208397 0.0001839236356317997 -0.00204546470195055 -0.0006773108616471291 -0.0005757706239819527
26 13 1 12.5 6.847925559938517e-09 0.0015489000506591615 -0.00020564347505569458 -0.00017303228378295898 -1.229019973680856e-06 0.0019629797898232937 0.0002056504599750042 0.00017301971092820168 -0.002280890941619873 -0.00067916139960289 -0.000582011416554451
27 13 2 13.0 1.1770799335231175e-08 0.0015488750333560626 -0.0001933462917804718 -0.00016286037862300873 -9.379367493789204e-07 0.0019637630321085453 0.00019335513934493065 0.00016285711899399757 -0.002459546085447073 -0.0007534711621701717 -0.0006643435917794704
28 14 1 13.5 8.936060558184522e-09 0.0015488612668431816 -0.00018239393830299377 -0.00015359185636043549 -1.2376870923702654e-06 0.001962530892342329 0.000182389747351408 0.00015358394011855125 -0.002583651803433895 -0.0007450981065630913 -0.0006575053557753563
29 14 2 14.0 1.2725840020655355e-08 0.0015488343418273527 -0.0001720944419503212 -0.00014511216431856155 -8.9041709272486e-07 0.001963145099580288 0.00017209816724061966 0.00014511402696371078 -0.002680632285773754 -0.0007635904476046562 -0.0006860606372356415
30 15 1 14.5 9.446215296082805e-09 0.0015488229734234565 -0.0001630391925573349 -0.00013743527233600616 -1.146773010329838e-06 0.001962078735232353 0.00016304105520248413 0.00013743527233600616 -0.0027179024182260036 -0.0007485975511372089 -0.000670840498059988
31 15 2 15.0 9.313422921763959e-09 0.001548801691143042 -0.00015463586896657944 -0.00013038236647844315 -9.957984490327476e-07 0.0019625588320195675 0.0001546279527246952 0.0001303856261074543 -0.002754406537860632 -0.0007191230542957783 -0.000647230539470911
32 16 1 15.5 7.756034481332108e-09 0.001548795055197433 -0.00014728587120771408 -0.00012414250522851944 -1.19767199602272e-06 0.001961618661880493 0.0001472746953368187 0.00012414157390594482 -0.0027457624673843384 -0.000701194629073143 -0.0006282757967710495
33 16 2 16.0 4.9820187697502405e-09 0.0015487817877766277 -0.0001406259834766388 -0.00011855922639369965 -1.0063548837591085e-06 0.001962041947990656 0.0001406143419444561 0.00011856527999043465 -0.00275089917704463 -0.0006374767981469631 -0.0005653253756463528
34 17 1 16.5 7.659630707479437e-09 0.0015487774975968425 -0.0001347297802567482 -0.00011365208774805069 -1.1021201878902431e-06 0.0019611907191574574 0.00013471907004714012 0.00011365814134478569 -0.0027269930578768253 -0.0006199139170348644 -0.0005475492216646671
35 17 2 17.0 8.840773640939048e-09 0.001548763244042896 -0.00012935884296894073 -0.00010930560529232025 -1.016784981322516e-06 0.0019615269266068935 0.0001293686218559742 0.00010931165888905525 -0.002721673808991909 -0.0005361568182706833 -0.00046241283416748047
36 18 1 17.5 1.2304882210378842e-08 0.0015487567261606326 -0.00012471340596675873 -0.000105343759059906 -1.0469923481526422e-06 0.001960811670869589 0.0001247120089828968 0.00010533956810832024 -0.0026941243559122086 -0.0005193613469600677 -0.00044766347855329514
37 18 2 18.0 7.418095471223296e-09 0.0015487429170055658 -0.00012026354670524597 -0.00010176189243793488 -9.512738775585561e-07 0.001961167436093092 0.00012026121839880943 0.00010176049545407295 -0.0026859669014811516 -0.0004291580989956856 -0.00035731401294469833
38 19 1 18.5 7.707569693593541e-09 0.0015487447557849957 -0.0001163184642791748 -9.842775762081146e-05 -1.1155910571991612e-06 0.001960610970854759 0.00011632218956947327 9.842775762081146e-05 -0.0026490092277526855 -0.00040957890450954437 -0.00034233927726745605
39 19 2 19.0 9.897528907565345e-09 0.001548736220618044 -0.00011231936514377594 -9.525753557682037e-05 -8.746676823934152e-07 0.0019609862938523293 0.00011232960969209671 9.52649861574173e-05 -0.0026348931714892387 -0.0003248099237680435 -0.00026043038815259933
40 20 1 19.5 7.458307527130614e-09 0.0015487257938516241 -0.00010872259736061096 -9.228847920894623e-05 -1.117876357703551e-06 0.001960530411452055 0.00010872026905417442 9.2280562967062e-05 -0.0025746123865246773 -0.000293082557618618 -0.0002375887706875801
41 20 2 20.0 7.1616321761780455e-09 0.0015487109979796746 -0.00010512489825487137 -8.937250822782516e-05 -9.404776560861805e-07 0.0019608777947723866 0.00010512815788388252 8.937017992138863e-05 -0.002546322997659445 -0.00022387364879250526 -0.00017382996156811714
42 21 1 20.5 1.2005225979994094e-08 0.0015487181439359362 -0.00010188575834035873 -8.659716695547104e-05 -1.0574914846017691e-06 0.0019605131819844246 0.00010188296437263489 8.659809827804565e-05 -0.002445746213197708 -0.00016940850764513016 -0.00013363640755414963
43 21 2 21.0 7.5469843707765e-09 0.001548692199227755 -9.881984442472458e-05 -8.39056447148323e-05 -9.763081801894558e-07 0.0019607869908213615 9.881611913442612e-05 8.391123265028e-05 -0.0023945574648678303 -0.0001229965128004551 -9.305356070399284e-05
44 22 1 21.5 6.037053218443944e-09 0.0015486938404374378 -9.613670408725739e-05 -8.161552250385284e-05 -1.0525385535364862e-06 0.00196036696434021 9.6137635409832e-05 8.160900324583054e-05 -0.002243565861135721 -3.6747660487890244e-05 -2.6164110749959946e-05
45 22 2 22.0 9.586391680471706e-09 0.001548693360520578 -9.382795542478561e-05 -7.957685738801956e-05 -9.683724135900462e-07 0.001960549969226122 9.383400902152061e-05 7.956428453326225e-05 -0.0021634772419929504 -1.710653305053711e-05 -1.1105090379714966e-05
46 23 1 22.5 9.489836569342991e-09 0.0015486823349255578 -9.185541421175003e-05 -7.787439972162247e-05 -1.0168454692704998e-06 0.0019601034000515938 9.18535515666008e-05 7.786881178617477e-05 -0.0019649858586490154 0.00010295165702700615 8.555082604289055e-05
47 23 2 23.0 6.585969006267511e-09 0.0015486694330888832 -9.038113057613373e-05 -7.635168731212616e-05 -9.023735720870008e-07 0.0019602179527282715 9.038485586643219e-05 7.635634392499924e-05 -0.001856005284935236 9.549083188176155e-05 7.625715807080269e-05
48 24 1 23.5 6.188236104098799e-09 0.0015486604639943502 -8.921325206756592e-05 -7.526762783527374e-05 -1.0200224049849993e-06 0.001959813293069601 8.920999243855476e-05 7.527368143200874e-05 -0.0016284165903925896 0.0002412758767604828 0.00019868742674589157
49 24 2 24.0 9.620717680847157e-09 0.0015486650695279314 -8.823629468679428e-05 -7.427390664815903e-05 -9.335468453830487e-07 0.0019598701037466526 8.823955431580544e-05 7.426505908370018e-05 -0.0014977920800447464 0.0002111736685037613 0.00016872771084308624
@@ -0,0 +1,73 @@
step,level,substep,max_error,max_ratio,regime,drift_m,drift_px,drift_py,ideal_defect_m,ideal_defect_px,ideal_defect_py,measured_rounding_m,measured_rounding_px,measured_rounding_py
1,fine,1,6.200234548003891e-08,0.28965071213188953,True,1.6061589121818542e-05,1.7695128917694092e-08,6.51925802230835e-09,-3.41740524767431e-16,1.214306433183765e-17,-8.673617379884035e-18,1.6061589122160283e-05,1.7695128905551027e-08,6.519258030981967e-09
1,fine,2,9.592780092493314e-08,0.3574847775115332,True,-3.2549723982810974e-07,-1.3969838619232178e-09,-1.4435499906539917e-08,-5.4539706084710815e-15,1.3877787807814457e-17,3.469446951953614e-17,-3.2549723437413913e-07,-1.3969838758010056e-09,-1.4435499941234387e-08
1,coarse,1,1.1080350609260492e-08,0.10456730670501622,True,-1.5292316675186157e-06,-1.30385160446167e-08,-1.5832483768463135e-07,-4.288236432614667e-15,-5.551115123125783e-17,1.3877787807814457e-17,-1.5292316632303793e-06,-1.3038515989105548e-08,-1.5832483769850914e-07
2,fine,1,7.754918973645886e-08,0.34580397879479957,True,8.987262845039368e-07,-2.3283064365386963e-08,-1.9744038581848145e-07,-5.167741234934908e-15,-1.5612511283791264e-17,2.931682674400804e-16,8.98726289671678e-07,-2.328306434977445e-08,-1.974403861116497e-07
2,fine,2,1.155261522001183e-07,0.321440603069343,True,2.284534275531769e-06,-2.8870999813079834e-08,8.66129994392395e-08,-1.1794384913166311e-14,-7.112366251504909e-17,2.203098814490545e-16,2.2845342873261537e-06,-2.887099974195617e-08,8.661299921892962e-08
2,coarse,1,1.6365805183271576e-08,0.1544470929589978,True,-1.426786184310913e-06,-3.0919909477233887e-07,-3.0919909477233887e-07,-6.286637876939949e-15,-8.326672684688674e-17,-8.326672684688674e-17,-1.4267861780242752e-06,-3.0919909468907214e-07,-3.0919909468907214e-07
3,fine,1,9.149310453704373e-08,0.3150717610922152,True,4.654750227928162e-06,1.0896474123001099e-07,6.146728992462158e-08,-1.1813466871402056e-14,1.1449174941446927e-16,2.1163626406917047e-16,4.6547502397416285e-06,1.0896474111551924e-07,6.146728971298532e-08
3,fine,2,1.0172501863081607e-07,0.3828123813437159,True,7.561873644590378e-06,1.257285475730896e-08,5.168840289115906e-08,-1.7838161503469507e-14,8.673617379884035e-18,3.2786273695961654e-16,7.561873662428539e-06,1.2572854748635343e-08,5.168840256329632e-08
3,coarse,1,1.0010523732173482e-07,0.2854567053212911,True,9.115785360336304e-06,3.3155083656311035e-07,3.203749656677246e-07,-3.837208328860697e-15,1.5334955527634975e-15,1.2420620087993939e-15,9.115785364173512e-06,3.315508350296148e-07,3.203749644256626e-07
4,fine,1,1.1511500297434196e-07,0.3632811360585352,True,1.1234544217586517e-05,3.3155083656311035e-07,2.3469328880310059e-07,-2.0365653607967715e-14,2.5673907444456745e-16,2.393918396847994e-16,1.1234544237952171e-05,3.315508363063713e-07,2.3469328856370875e-07
4,fine,2,1.323716875001324e-07,0.420721981505359,True,1.0875053703784943e-05,7.171183824539185e-08,5.4016709327697754e-08,-1.6948248360293405e-14,-6.83481049534862e-16,-4.0939474033052647e-16,1.0875053720733191e-05,7.17118389288729e-08,5.4016709737092494e-08
4,coarse,1,1.2150177930436712e-07,0.37139422446265463,True,1.3064593076705933e-05,5.997717380523682e-07,5.62518835067749e-07,-1.2559397966072083e-14,-5.967448757360216e-16,-2.498001805406602e-16,1.306459308926533e-05,5.99771738649113e-07,5.625188353175492e-07
5,fine,1,1.2583242237074188e-07,0.3554646638422362,True,9.815674275159836e-06,-2.789311110973358e-07,-3.608874976634979e-07,-1.565240992373873e-14,-1.9949319973733282e-16,-3.642919299551295e-17,9.815674290812246e-06,-2.789311108978426e-07,-3.6088749762706873e-07
5,fine,2,1.2541811456046048e-07,0.3685724336736591,True,9.207520633935928e-06,-2.5192275643348694e-07,-4.0512531995773315e-08,-1.5307199952019346e-14,3.469446951953614e-17,4.3021142204224816e-16,9.207520649243128e-06,-2.519227564681814e-07,-4.051253242598474e-08
5,coarse,1,1.2532259030528792e-07,0.38942307019337585,True,1.49458646774292e-05,9.723007678985596e-07,1.2628734111785889e-06,-1.6535384173010925e-14,1.5959455978986625e-16,6.175615574477433e-16,1.4945864693964583e-05,9.72300767738965e-07,1.2628734105610273e-06
6,fine,1,1.0399005534456052e-07,0.4260869217553865,True,5.527399480342865e-06,-8.754432201385498e-08,-1.555308699607849e-07,-1.4764231504038605e-14,4.336808689942018e-17,3.86843335142828e-16,5.5273994951070965e-06,-8.754432205722307e-08,-1.5553087034762825e-07
6,fine,2,1.295425238190262e-07,0.36331211716460343,True,5.567912012338638e-06,-2.6542693376541138e-08,-2.0908191800117493e-07,-1.4812803761365956e-14,-5.186823193170653e-16,1.734723475976807e-18,5.567912027151442e-06,-2.654269285785882e-08,-2.0908191800290965e-07
6,coarse,1,1.0239773140519048e-07,0.43028837580529966,True,1.3461336493492126e-05,5.308538675308228e-07,4.2654573917388916e-07,-2.033095913844818e-14,2.0816681711721685e-16,1.2212453270876722e-15,1.3461336513823086e-05,5.308538673226559e-07,4.2654573795264383e-07
7,fine,1,1.1958961998459472e-07,0.4029625240438387,True,5.150679498910904e-06,-5.3551048040390015e-08,-7.497146725654602e-08,-1.5931700403370996e-14,-5.204170427930421e-17,-1.700029006457271e-16,5.150679514842604e-06,-5.355104798834831e-08,-7.497146708654312e-08
7,fine,2,1.265965450247819e-07,0.3851888208747954,True,3.789551556110382e-06,0.0,3.725290298461914e-09,-1.5173626244369132e-14,7.806255641895632e-17,3.903127820947816e-16,3.7895515712840083e-06,-7.806255641895632e-17,3.725289908149132e-09
7,coarse,1,1.0902046165828239e-07,0.38161058826685446,True,1.2835487723350525e-05,8.326023817062378e-07,-2.6635825634002686e-07,-2.4501234374696423e-14,-5.48172618408671e-16,-2.5673907444456745e-16,1.283548774785176e-05,8.326023822544104e-07,-2.663582560832878e-07
8,fine,1,1.2448945463372496e-07,0.3720247984466396,True,2.2617168724536896e-06,7.869675755500793e-08,3.259629011154175e-09,-1.5289852717259578e-14,7.28583859910259e-17,-2.636779683484747e-16,2.2617168877435423e-06,7.869675748214955e-08,3.259629274832143e-09
8,fine,2,1.3473279458775522e-07,0.39946262369614577,True,2.4368055164813995e-06,7.031485438346863e-08,-1.5366822481155396e-08,-1.6287318715946242e-14,4.683753385137379e-17,-1.196959198423997e-16,2.4368055327687183e-06,7.03148543366311e-08,-1.5366822361459476e-08
8,coarse,1,1.265961931951054e-07,0.38341345468786764,True,8.130446076393127e-06,7.506459951400757e-07,-5.830079317092896e-07,-2.2391810627908626e-14,-1.6861512186494565e-15,1.0408340855860843e-16,8.130446098784938e-06,7.506459968262269e-07,-5.83007931813373e-07
9,fine,1,1.3222774730703435e-07,0.3900959817916434,True,2.078711986541748e-06,8.568167686462402e-08,6.239861249923706e-08,-1.5612511283791264e-14,-2.5326962749261384e-16,2.42861286636753e-16,2.0787120021542593e-06,8.568167711789365e-08,6.239861225637577e-08
9,fine,2,1.2824470274619415e-07,0.4272642246416919,True,8.78702849149704e-07,9.266659617424011e-08,-1.3830140233039856e-07,-1.4988010832439613e-14,-1.6653345369377348e-16,-1.2836953722228372e-16,8.787028641377148e-07,9.266659634077357e-08,-1.3830140220202902e-07
9,coarse,1,1.1335454486172125e-07,0.3876201969620664,True,5.185604095458984e-06,-2.384185791015625e-07,-6.07222318649292e-07,-2.583350200424661e-14,3.122502256758253e-16,7.632783294297951e-17,5.185604121292486e-06,-2.384185794138127e-07,-6.072223187256198e-07
10,fine,1,1.2645846059200494e-07,0.3781818251482199,True,2.073124051094055e-06,6.426125764846802e-08,1.0151416063308716e-07,-1.6764367671839864e-14,2.949029909160572e-16,-2.1163626406917047e-16,2.073124067858423e-06,6.426125735356503e-08,1.0151416084472342e-07
10,fine,2,1.3663077158554415e-07,0.43888780198316496,True,1.5008263289928436e-06,7.031485438346863e-08,1.9883736968040466e-07,-1.6273440928138427e-14,-1.4051260155412137e-16,6.071532165918825e-17,1.5008263452662846e-06,7.031485452398123e-08,1.9883736961968934e-07
10,coarse,1,1.5257769281351585e-07,0.4176679708473079,True,4.520639777183533e-06,-5.904585123062134e-07,-3.166496753692627e-08,-2.443184543565735e-14,-4.649058915617843e-16,1.0408340855860843e-16,4.520639801615378e-06,-5.904585118413075e-07,-3.166496764100968e-08
11,fine,1,1.4342478449336227e-07,0.40055388671598813,True,9.159557521343231e-07,1.4388933777809143e-07,1.103617250919342e-07,-1.6368850719317152e-14,-7.979727989493313e-17,-1.3877787807814457e-17,9.159557685031738e-07,1.438893378578887e-07,1.1036172510581199e-07
11,fine,2,1.229973988214894e-07,0.44018383771634995,True,1.3504177331924438e-06,-2.7939677238464355e-08,-3.725290298461914e-09,-1.6167622796103842e-14,-1.942890293094024e-16,1.457167719820518e-16,1.3504177493600666e-06,-2.7939677044175326e-08,-3.725290444178686e-09
11,coarse,1,1.0126133054289e-07,0.37920635013850246,True,2.175569534301758e-06,-1.341104507446289e-07,1.2665987014770508e-07,-2.38073449843057e-14,9.020562075079397e-17,5.759281940243e-16,2.175569558109103e-06,-1.3411045083483453e-07,1.2665986957177688e-07
12,fine,1,1.2071681543268653e-07,0.4311470967916149,True,1.3746321201324463e-06,-2.1420419216156006e-08,1.4528632164001465e-07,-1.6273440928138427e-14,-2.237793284010081e-16,-4.0072112295064244e-16,1.3746321364058872e-06,-2.1420418992376677e-08,1.4528632204073577e-07
12,fine,2,1.371591822341145e-07,0.44227593234711177,True,1.982320100069046e-06,9.73232090473175e-08,1.448206603527069e-07,-1.6818144099595145e-14,-2.96637714392034e-16,1.214306433183765e-17,1.98232011688719e-06,9.732320934395522e-08,1.4482066034056384e-07
12,coarse,1,1.2813768046626706e-07,0.42388935775355246,True,3.3173710107803345e-06,-4.898756742477417e-07,-1.8067657947540283e-07,-2.7193525209412428e-14,-1.1171619185290638e-15,-4.649058915617843e-16,3.3173710379738597e-06,-4.898756731305798e-07,-1.8067657901049694e-07
13,fine,1,1.3950153099351326e-07,0.4396993900025004,True,1.2670643627643585e-06,2.3050233721733093e-07,1.2153759598731995e-07,-1.662038562333379e-14,3.903127820947816e-16,9.194034422677078e-17,1.2670643793847441e-06,2.3050233682701815e-07,1.215375958953796e-07
13,fine,2,1.2581214114959494e-07,0.4721292711508529,True,1.1995434761047363e-06,3.7159770727157593e-07,1.0710209608078003e-07,-1.5909148998183298e-14,-8.153200337090993e-17,9.540979117872439e-17,1.1995434920138853e-06,3.7159770735310793e-07,1.0710209598537024e-07
13,coarse,1,1.2660152992616247e-07,0.45318197065007865,True,7.878988981246948e-07,-1.210719347000122e-07,3.334134817123413e-07,-2.346040028911034e-14,-4.2327252813834093e-16,2.706168622523819e-16,7.878989215850951e-07,-1.2107193427673968e-07,3.3341348144172445e-07
14,fine,1,1.5054562552130335e-07,0.5104225030616341,True,6.658956408500671e-07,1.778826117515564e-07,-2.60770320892334e-08,-1.6335890973273592e-14,2.96637714392034e-16,3.86843335142828e-16,6.658956571859581e-07,1.7788261145491868e-07,-2.6077032476076734e-08
14,fine,2,1.3530934717120857e-07,0.4009751179733903,True,1.2051314115524292e-06,-1.955777406692505e-08,1.6205012798309326e-07,-1.6099968580540747e-14,-1.5785983631388945e-16,8.500145032286355e-17,1.2051314276523978e-06,-1.9557773909065213e-08,1.620501278980918e-07
14,coarse,1,1.3409460186686317e-07,0.39963893479139145,True,3.9692968130111694e-06,8.754432201385498e-08,2.9616057872772217e-07,-2.5528190672474693e-14,-6.245004513516506e-17,-6.314393452555578e-16,3.96929683853936e-06,8.754432207630503e-08,2.961605793591615e-07
15,fine,1,1.2702620799665e-07,0.37981873927853255,True,1.000240445137024e-06,-3.166496753692627e-08,7.729977369308472e-08,-1.607568245187707e-14,-2.1337098754514727e-16,1.4051260155412137e-16,1.0002404612127064e-06,-3.166496732355528e-08,7.729977355257212e-08
15,fine,2,1.1264902777252672e-07,0.42131603992753336,True,8.651986718177795e-07,-4.377216100692749e-08,-1.0151416063308716e-07,-1.5992415725030185e-14,4.336808689942018e-17,3.2959746043559335e-17,8.651986878101953e-07,-4.377216105029558e-08,-1.015141606660469e-07
15,coarse,1,1.305862756817433e-07,0.5086178241462508,True,1.6335397958755493e-06,-6.146728992462158e-08,2.2165477275848389e-07,-2.533390164316529e-14,-4.85722573273506e-17,2.706168622523819e-16,1.633539821209451e-06,-6.146728987604932e-08,2.2165477248786702e-07
16,fine,1,1.3092614292720128e-07,0.40502514569399495,True,9.629875421524048e-07,-9.685754776000977e-08,8.66129994392395e-08,-1.6838960781306866e-14,-9.194034422677078e-17,8.500145032286355e-17,9.629875589913656e-07,-9.685754766806942e-08,8.661299935423805e-08
16,fine,2,1.3893401662468108e-07,0.39764517507033376,True,1.5990808606147766e-06,-8.009374141693115e-08,-5.3085386753082275e-08,-1.6518036938251157e-14,3.0531133177191805e-16,3.5735303605122226e-16,1.5990808771328135e-06,-8.009374172224248e-08,-5.308538711043531e-08
16,coarse,1,1.2888908407227007e-07,0.4083972967001409,True,5.159527063369751e-06,-4.3213367462158203e-07,1.4901161193847656e-07,-2.6131874442114622e-14,7.216449660063518e-16,-3.885780586188048e-16,5.159527089501625e-06,-4.32133675343227e-07,1.4901161232705462e-07
17,fine,1,1.249536419889452e-07,0.39288318869275274,True,1.12876296043396e-06,-1.7601996660232544e-07,-2.3283064365386963e-07,-1.7957857423311907e-14,-5.551115123125783e-16,1.3530843112619095e-16,1.1287629783918174e-06,-1.7601996604721393e-07,-2.3283064378917806e-07
17,fine,2,1.3328934989065289e-07,0.46401164838116316,True,7.129274308681488e-07,-2.1373853087425232e-07,-2.6496127247810364e-07,-1.634803403760543e-14,-2.914335439641036e-16,9.71445146547012e-17,7.129274472161828e-07,-2.1373853058281878e-07,-2.6496127257524815e-07
17,coarse,1,1.246264329513025e-07,0.4613853551985751,True,5.302950739860535e-06,-2.0675361156463623e-07,1.1362135410308838e-07,-2.8373137173076657e-14,7.7021722333370235e-16,-6.869504964868156e-16,5.302950768233672e-06,-2.0675361233485345e-07,1.1362135479003888e-07
18,fine,1,1.5840482392448507e-07,0.48249679461224454,True,8.10716301202774e-07,-1.4016404747962952e-07,-2.6402994990348816e-07,-1.6878859421254333e-14,7.632783294297951e-17,2.0816681711721685e-17,8.107163180816335e-07,-1.4016404755595735e-07,-2.6402994992430484e-07
18,fine,2,1.217794476371381e-07,0.4447119430321027,True,1.4016404747962952e-07,-2.8545036911964417e-07,-8.847564458847046e-09,-1.709223040879948e-14,-1.1275702593849246e-16,1.8214596497756474e-16,1.4016406457185993e-07,-2.8545036900688714e-07,-8.847564640993011e-09
18,coarse,1,1.3857981828735433e-07,0.4519491616828685,True,5.850568413734436e-06,-1.2479722499847412e-07,-1.471489667892456e-07,-2.688821387764051e-14,-8.534839501805891e-16,9.08995101411847e-16,5.85056844062265e-06,-1.2479722414499017e-07,-1.471489676982407e-07
19,fine,1,1.4433919059975153e-07,0.3821888438774327,True,1.9441358745098114e-06,-1.3969838619232178e-09,-2.7474015951156616e-08,-1.628905343942222e-14,-3.920475055707584e-16,2.42861286636753e-17,1.944135890798865e-06,-1.3969834698757122e-09,-2.7474015975442745e-08
19,fine,2,1.4349667698532187e-07,0.4183999473130793,True,2.1490268409252167e-06,1.7834827303886414e-07,-7.869675755500793e-08,-1.678344963007561e-14,-5.204170427930421e-18,2.949029909160572e-17,2.1490268577086663e-06,1.783482730440683e-07,-7.869675758449823e-08
19,coarse,1,1.264100825126846e-07,0.5347769553832019,True,5.165114998817444e-06,3.91155481338501e-08,1.1734664440155029e-07,-2.6804947150793623e-14,-4.2327252813834093e-16,-3.8163916471489756e-16,5.165115025622391e-06,3.9115548557122626e-08,1.1734664478318946e-07
20,fine,1,1.1464598925758906e-07,0.39800949885565845,True,1.8593855202198029e-06,7.031485438346863e-08,-2.2817403078079224e-08,-1.695171780724536e-14,1.457167719820518e-16,-7.632783294297951e-17,1.8593855371715207e-06,7.031485423775186e-08,-2.281740300175139e-08
20,fine,2,1.3166252321727967e-07,0.41581763506478076,True,2.2118911147117615e-06,9.313225746154785e-10,9.033828973770142e-08,-1.7095699855751434e-14,-3.7643499428696714e-16,2.0990154059319366e-16,2.2118911318074613e-06,9.313229510504728e-10,9.033828952779988e-08
20,coarse,1,1.3024161815700097e-07,0.47356066681074566,True,4.023313522338867e-06,5.997717380523682e-07,-8.568167686462402e-08,-2.7228219678931964e-14,3.0531133177191805e-16,3.7470027081099033e-16,4.023313549567087e-06,5.997717377470568e-07,-8.56816772393243e-08
21,fine,1,1.361732063775989e-07,0.4205892378883329,True,2.439599484205246e-06,1.4854595065116882e-07,-1.327134668827057e-07,-1.6781714906599632e-14,3.885780586188048e-16,8.673617379884035e-17,2.439599500986961e-06,1.4854595026259076e-07,-1.3271346696944186e-07
21,fine,2,1.2473161092874108e-07,0.45376916235253945,True,2.2514723241329193e-06,3.5902485251426697e-07,1.9976869225502014e-07,-1.692396223162973e-14,6.938893903907228e-17,-1.457167719820518e-16,2.2514723410568815e-06,3.5902485244487803e-07,1.9976869240073691e-07
21,coarse,1,1.5484813187249813e-07,0.561763881940829,True,3.507360816001892e-06,7.431954145431519e-07,6.202608346939087e-07,-2.6131874442114622e-14,-4.579669976578771e-16,1.5265566588595902e-16,3.5073608421337665e-06,7.431954150011189e-07,6.20260834541253e-07
22,fine,1,1.1594882032284204e-07,0.46103443091228286,True,1.2228265404701233e-06,2.300366759300232e-07,1.9185245037078857e-07,-1.5529244556944377e-14,-3.469446951953614e-18,7.28583859910259e-17,1.2228265559993678e-06,2.3003667593349264e-07,1.918524502979302e-07
22,fine,2,1.4032262196650436e-07,0.41123793671363457,True,2.0829029381275177e-06,1.317821443080902e-07,1.1594966053962708e-07,-1.6656814816329302e-14,-2.42861286636753e-17,2.7755575615628914e-17,2.0829029547843325e-06,1.3178214433237634e-07,1.159496605118715e-07
22,coarse,1,1.4061314457247676e-07,0.5696050037738337,True,5.517154932022095e-06,1.6167759895324707e-06,1.0058283805847168e-06,-2.643718577388654e-14,-4.996003610813204e-16,-4.579669976578771e-16,5.5171549584592805e-06,1.616775990032071e-06,1.0058283810426838e-06
23,fine,1,1.172129048265802e-07,0.43537551205849856,True,1.8416903913021088e-06,2.230517566204071e-07,2.1746382117271423e-07,-1.620752143605131e-14,-4.735795089416683e-16,1.9081958235744878e-17,1.8416904075096302e-06,2.2305175709398661e-07,2.1746382115363228e-07
23,fine,2,1.2559042006365928e-07,0.4297035689234779,True,1.998152583837509e-06,7.031485438346863e-08,4.98257577419281e-08,-1.62231339473351e-14,3.0184188481996443e-16,-3.7816971776294395e-16,1.998152600060643e-06,7.031485408162674e-08,4.982575812009782e-08
23,coarse,1,1.5135824793510722e-07,0.4407189177218073,True,1.2038275599479675e-05,1.3243407011032104e-06,7.692724466323853e-07,-2.7304547511874944e-14,1.4502288259166107e-15,-4.371503159461554e-16,1.2038275626784223e-05,1.3243406996529816e-06,7.692724470695356e-07
24,fine,1,1.1879041472706575e-07,0.3912946498849803,True,1.0398216545581818e-06,1.62515789270401e-07,1.3737007975578308e-07,-1.705927066275592e-14,1.6306400674181987e-16,-9.020562075079397e-17,1.0398216716174524e-06,1.62515789107337e-07,1.373700798459887e-07
24,fine,2,1.4235627243674998e-07,0.4195513876580241,True,1.6004778444766998e-06,1.3830140233039856e-07,1.7927959561347961e-07,-1.668977456237286e-14,-1.9949319973733282e-16,1.2663481374630692e-16,1.6004778611664744e-06,1.3830140252989176e-07,1.792795954868448e-07
24,coarse,1,1.5865499780609582e-07,0.5231448442629695,True,9.544193744659424e-06,4.5821070671081543e-07,2.942979335784912e-07,-2.545880173343562e-14,3.8163916471489756e-16,-1.457167719820518e-16,9.544193770118226e-06,4.5821070632917626e-07,2.94297933724208e-07
1 step level substep max_error max_ratio regime drift_m drift_px drift_py ideal_defect_m ideal_defect_px ideal_defect_py measured_rounding_m measured_rounding_px measured_rounding_py
2 1 fine 1 6.200234548003891e-08 0.28965071213188953 True 1.6061589121818542e-05 1.7695128917694092e-08 6.51925802230835e-09 -3.41740524767431e-16 1.214306433183765e-17 -8.673617379884035e-18 1.6061589122160283e-05 1.7695128905551027e-08 6.519258030981967e-09
3 1 fine 2 9.592780092493314e-08 0.3574847775115332 True -3.2549723982810974e-07 -1.3969838619232178e-09 -1.4435499906539917e-08 -5.4539706084710815e-15 1.3877787807814457e-17 3.469446951953614e-17 -3.2549723437413913e-07 -1.3969838758010056e-09 -1.4435499941234387e-08
4 1 coarse 1 1.1080350609260492e-08 0.10456730670501622 True -1.5292316675186157e-06 -1.30385160446167e-08 -1.5832483768463135e-07 -4.288236432614667e-15 -5.551115123125783e-17 1.3877787807814457e-17 -1.5292316632303793e-06 -1.3038515989105548e-08 -1.5832483769850914e-07
5 2 fine 1 7.754918973645886e-08 0.34580397879479957 True 8.987262845039368e-07 -2.3283064365386963e-08 -1.9744038581848145e-07 -5.167741234934908e-15 -1.5612511283791264e-17 2.931682674400804e-16 8.98726289671678e-07 -2.328306434977445e-08 -1.974403861116497e-07
6 2 fine 2 1.155261522001183e-07 0.321440603069343 True 2.284534275531769e-06 -2.8870999813079834e-08 8.66129994392395e-08 -1.1794384913166311e-14 -7.112366251504909e-17 2.203098814490545e-16 2.2845342873261537e-06 -2.887099974195617e-08 8.661299921892962e-08
7 2 coarse 1 1.6365805183271576e-08 0.1544470929589978 True -1.426786184310913e-06 -3.0919909477233887e-07 -3.0919909477233887e-07 -6.286637876939949e-15 -8.326672684688674e-17 -8.326672684688674e-17 -1.4267861780242752e-06 -3.0919909468907214e-07 -3.0919909468907214e-07
8 3 fine 1 9.149310453704373e-08 0.3150717610922152 True 4.654750227928162e-06 1.0896474123001099e-07 6.146728992462158e-08 -1.1813466871402056e-14 1.1449174941446927e-16 2.1163626406917047e-16 4.6547502397416285e-06 1.0896474111551924e-07 6.146728971298532e-08
9 3 fine 2 1.0172501863081607e-07 0.3828123813437159 True 7.561873644590378e-06 1.257285475730896e-08 5.168840289115906e-08 -1.7838161503469507e-14 8.673617379884035e-18 3.2786273695961654e-16 7.561873662428539e-06 1.2572854748635343e-08 5.168840256329632e-08
10 3 coarse 1 1.0010523732173482e-07 0.2854567053212911 True 9.115785360336304e-06 3.3155083656311035e-07 3.203749656677246e-07 -3.837208328860697e-15 1.5334955527634975e-15 1.2420620087993939e-15 9.115785364173512e-06 3.315508350296148e-07 3.203749644256626e-07
11 4 fine 1 1.1511500297434196e-07 0.3632811360585352 True 1.1234544217586517e-05 3.3155083656311035e-07 2.3469328880310059e-07 -2.0365653607967715e-14 2.5673907444456745e-16 2.393918396847994e-16 1.1234544237952171e-05 3.315508363063713e-07 2.3469328856370875e-07
12 4 fine 2 1.323716875001324e-07 0.420721981505359 True 1.0875053703784943e-05 7.171183824539185e-08 5.4016709327697754e-08 -1.6948248360293405e-14 -6.83481049534862e-16 -4.0939474033052647e-16 1.0875053720733191e-05 7.17118389288729e-08 5.4016709737092494e-08
13 4 coarse 1 1.2150177930436712e-07 0.37139422446265463 True 1.3064593076705933e-05 5.997717380523682e-07 5.62518835067749e-07 -1.2559397966072083e-14 -5.967448757360216e-16 -2.498001805406602e-16 1.306459308926533e-05 5.99771738649113e-07 5.625188353175492e-07
14 5 fine 1 1.2583242237074188e-07 0.3554646638422362 True 9.815674275159836e-06 -2.789311110973358e-07 -3.608874976634979e-07 -1.565240992373873e-14 -1.9949319973733282e-16 -3.642919299551295e-17 9.815674290812246e-06 -2.789311108978426e-07 -3.6088749762706873e-07
15 5 fine 2 1.2541811456046048e-07 0.3685724336736591 True 9.207520633935928e-06 -2.5192275643348694e-07 -4.0512531995773315e-08 -1.5307199952019346e-14 3.469446951953614e-17 4.3021142204224816e-16 9.207520649243128e-06 -2.519227564681814e-07 -4.051253242598474e-08
16 5 coarse 1 1.2532259030528792e-07 0.38942307019337585 True 1.49458646774292e-05 9.723007678985596e-07 1.2628734111785889e-06 -1.6535384173010925e-14 1.5959455978986625e-16 6.175615574477433e-16 1.4945864693964583e-05 9.72300767738965e-07 1.2628734105610273e-06
17 6 fine 1 1.0399005534456052e-07 0.4260869217553865 True 5.527399480342865e-06 -8.754432201385498e-08 -1.555308699607849e-07 -1.4764231504038605e-14 4.336808689942018e-17 3.86843335142828e-16 5.5273994951070965e-06 -8.754432205722307e-08 -1.5553087034762825e-07
18 6 fine 2 1.295425238190262e-07 0.36331211716460343 True 5.567912012338638e-06 -2.6542693376541138e-08 -2.0908191800117493e-07 -1.4812803761365956e-14 -5.186823193170653e-16 1.734723475976807e-18 5.567912027151442e-06 -2.654269285785882e-08 -2.0908191800290965e-07
19 6 coarse 1 1.0239773140519048e-07 0.43028837580529966 True 1.3461336493492126e-05 5.308538675308228e-07 4.2654573917388916e-07 -2.033095913844818e-14 2.0816681711721685e-16 1.2212453270876722e-15 1.3461336513823086e-05 5.308538673226559e-07 4.2654573795264383e-07
20 7 fine 1 1.1958961998459472e-07 0.4029625240438387 True 5.150679498910904e-06 -5.3551048040390015e-08 -7.497146725654602e-08 -1.5931700403370996e-14 -5.204170427930421e-17 -1.700029006457271e-16 5.150679514842604e-06 -5.355104798834831e-08 -7.497146708654312e-08
21 7 fine 2 1.265965450247819e-07 0.3851888208747954 True 3.789551556110382e-06 0.0 3.725290298461914e-09 -1.5173626244369132e-14 7.806255641895632e-17 3.903127820947816e-16 3.7895515712840083e-06 -7.806255641895632e-17 3.725289908149132e-09
22 7 coarse 1 1.0902046165828239e-07 0.38161058826685446 True 1.2835487723350525e-05 8.326023817062378e-07 -2.6635825634002686e-07 -2.4501234374696423e-14 -5.48172618408671e-16 -2.5673907444456745e-16 1.283548774785176e-05 8.326023822544104e-07 -2.663582560832878e-07
23 8 fine 1 1.2448945463372496e-07 0.3720247984466396 True 2.2617168724536896e-06 7.869675755500793e-08 3.259629011154175e-09 -1.5289852717259578e-14 7.28583859910259e-17 -2.636779683484747e-16 2.2617168877435423e-06 7.869675748214955e-08 3.259629274832143e-09
24 8 fine 2 1.3473279458775522e-07 0.39946262369614577 True 2.4368055164813995e-06 7.031485438346863e-08 -1.5366822481155396e-08 -1.6287318715946242e-14 4.683753385137379e-17 -1.196959198423997e-16 2.4368055327687183e-06 7.03148543366311e-08 -1.5366822361459476e-08
25 8 coarse 1 1.265961931951054e-07 0.38341345468786764 True 8.130446076393127e-06 7.506459951400757e-07 -5.830079317092896e-07 -2.2391810627908626e-14 -1.6861512186494565e-15 1.0408340855860843e-16 8.130446098784938e-06 7.506459968262269e-07 -5.83007931813373e-07
26 9 fine 1 1.3222774730703435e-07 0.3900959817916434 True 2.078711986541748e-06 8.568167686462402e-08 6.239861249923706e-08 -1.5612511283791264e-14 -2.5326962749261384e-16 2.42861286636753e-16 2.0787120021542593e-06 8.568167711789365e-08 6.239861225637577e-08
27 9 fine 2 1.2824470274619415e-07 0.4272642246416919 True 8.78702849149704e-07 9.266659617424011e-08 -1.3830140233039856e-07 -1.4988010832439613e-14 -1.6653345369377348e-16 -1.2836953722228372e-16 8.787028641377148e-07 9.266659634077357e-08 -1.3830140220202902e-07
28 9 coarse 1 1.1335454486172125e-07 0.3876201969620664 True 5.185604095458984e-06 -2.384185791015625e-07 -6.07222318649292e-07 -2.583350200424661e-14 3.122502256758253e-16 7.632783294297951e-17 5.185604121292486e-06 -2.384185794138127e-07 -6.072223187256198e-07
29 10 fine 1 1.2645846059200494e-07 0.3781818251482199 True 2.073124051094055e-06 6.426125764846802e-08 1.0151416063308716e-07 -1.6764367671839864e-14 2.949029909160572e-16 -2.1163626406917047e-16 2.073124067858423e-06 6.426125735356503e-08 1.0151416084472342e-07
30 10 fine 2 1.3663077158554415e-07 0.43888780198316496 True 1.5008263289928436e-06 7.031485438346863e-08 1.9883736968040466e-07 -1.6273440928138427e-14 -1.4051260155412137e-16 6.071532165918825e-17 1.5008263452662846e-06 7.031485452398123e-08 1.9883736961968934e-07
31 10 coarse 1 1.5257769281351585e-07 0.4176679708473079 True 4.520639777183533e-06 -5.904585123062134e-07 -3.166496753692627e-08 -2.443184543565735e-14 -4.649058915617843e-16 1.0408340855860843e-16 4.520639801615378e-06 -5.904585118413075e-07 -3.166496764100968e-08
32 11 fine 1 1.4342478449336227e-07 0.40055388671598813 True 9.159557521343231e-07 1.4388933777809143e-07 1.103617250919342e-07 -1.6368850719317152e-14 -7.979727989493313e-17 -1.3877787807814457e-17 9.159557685031738e-07 1.438893378578887e-07 1.1036172510581199e-07
33 11 fine 2 1.229973988214894e-07 0.44018383771634995 True 1.3504177331924438e-06 -2.7939677238464355e-08 -3.725290298461914e-09 -1.6167622796103842e-14 -1.942890293094024e-16 1.457167719820518e-16 1.3504177493600666e-06 -2.7939677044175326e-08 -3.725290444178686e-09
34 11 coarse 1 1.0126133054289e-07 0.37920635013850246 True 2.175569534301758e-06 -1.341104507446289e-07 1.2665987014770508e-07 -2.38073449843057e-14 9.020562075079397e-17 5.759281940243e-16 2.175569558109103e-06 -1.3411045083483453e-07 1.2665986957177688e-07
35 12 fine 1 1.2071681543268653e-07 0.4311470967916149 True 1.3746321201324463e-06 -2.1420419216156006e-08 1.4528632164001465e-07 -1.6273440928138427e-14 -2.237793284010081e-16 -4.0072112295064244e-16 1.3746321364058872e-06 -2.1420418992376677e-08 1.4528632204073577e-07
36 12 fine 2 1.371591822341145e-07 0.44227593234711177 True 1.982320100069046e-06 9.73232090473175e-08 1.448206603527069e-07 -1.6818144099595145e-14 -2.96637714392034e-16 1.214306433183765e-17 1.98232011688719e-06 9.732320934395522e-08 1.4482066034056384e-07
37 12 coarse 1 1.2813768046626706e-07 0.42388935775355246 True 3.3173710107803345e-06 -4.898756742477417e-07 -1.8067657947540283e-07 -2.7193525209412428e-14 -1.1171619185290638e-15 -4.649058915617843e-16 3.3173710379738597e-06 -4.898756731305798e-07 -1.8067657901049694e-07
38 13 fine 1 1.3950153099351326e-07 0.4396993900025004 True 1.2670643627643585e-06 2.3050233721733093e-07 1.2153759598731995e-07 -1.662038562333379e-14 3.903127820947816e-16 9.194034422677078e-17 1.2670643793847441e-06 2.3050233682701815e-07 1.215375958953796e-07
39 13 fine 2 1.2581214114959494e-07 0.4721292711508529 True 1.1995434761047363e-06 3.7159770727157593e-07 1.0710209608078003e-07 -1.5909148998183298e-14 -8.153200337090993e-17 9.540979117872439e-17 1.1995434920138853e-06 3.7159770735310793e-07 1.0710209598537024e-07
40 13 coarse 1 1.2660152992616247e-07 0.45318197065007865 True 7.878988981246948e-07 -1.210719347000122e-07 3.334134817123413e-07 -2.346040028911034e-14 -4.2327252813834093e-16 2.706168622523819e-16 7.878989215850951e-07 -1.2107193427673968e-07 3.3341348144172445e-07
41 14 fine 1 1.5054562552130335e-07 0.5104225030616341 True 6.658956408500671e-07 1.778826117515564e-07 -2.60770320892334e-08 -1.6335890973273592e-14 2.96637714392034e-16 3.86843335142828e-16 6.658956571859581e-07 1.7788261145491868e-07 -2.6077032476076734e-08
42 14 fine 2 1.3530934717120857e-07 0.4009751179733903 True 1.2051314115524292e-06 -1.955777406692505e-08 1.6205012798309326e-07 -1.6099968580540747e-14 -1.5785983631388945e-16 8.500145032286355e-17 1.2051314276523978e-06 -1.9557773909065213e-08 1.620501278980918e-07
43 14 coarse 1 1.3409460186686317e-07 0.39963893479139145 True 3.9692968130111694e-06 8.754432201385498e-08 2.9616057872772217e-07 -2.5528190672474693e-14 -6.245004513516506e-17 -6.314393452555578e-16 3.96929683853936e-06 8.754432207630503e-08 2.961605793591615e-07
44 15 fine 1 1.2702620799665e-07 0.37981873927853255 True 1.000240445137024e-06 -3.166496753692627e-08 7.729977369308472e-08 -1.607568245187707e-14 -2.1337098754514727e-16 1.4051260155412137e-16 1.0002404612127064e-06 -3.166496732355528e-08 7.729977355257212e-08
45 15 fine 2 1.1264902777252672e-07 0.42131603992753336 True 8.651986718177795e-07 -4.377216100692749e-08 -1.0151416063308716e-07 -1.5992415725030185e-14 4.336808689942018e-17 3.2959746043559335e-17 8.651986878101953e-07 -4.377216105029558e-08 -1.015141606660469e-07
46 15 coarse 1 1.305862756817433e-07 0.5086178241462508 True 1.6335397958755493e-06 -6.146728992462158e-08 2.2165477275848389e-07 -2.533390164316529e-14 -4.85722573273506e-17 2.706168622523819e-16 1.633539821209451e-06 -6.146728987604932e-08 2.2165477248786702e-07
47 16 fine 1 1.3092614292720128e-07 0.40502514569399495 True 9.629875421524048e-07 -9.685754776000977e-08 8.66129994392395e-08 -1.6838960781306866e-14 -9.194034422677078e-17 8.500145032286355e-17 9.629875589913656e-07 -9.685754766806942e-08 8.661299935423805e-08
48 16 fine 2 1.3893401662468108e-07 0.39764517507033376 True 1.5990808606147766e-06 -8.009374141693115e-08 -5.3085386753082275e-08 -1.6518036938251157e-14 3.0531133177191805e-16 3.5735303605122226e-16 1.5990808771328135e-06 -8.009374172224248e-08 -5.308538711043531e-08
49 16 coarse 1 1.2888908407227007e-07 0.4083972967001409 True 5.159527063369751e-06 -4.3213367462158203e-07 1.4901161193847656e-07 -2.6131874442114622e-14 7.216449660063518e-16 -3.885780586188048e-16 5.159527089501625e-06 -4.32133675343227e-07 1.4901161232705462e-07
50 17 fine 1 1.249536419889452e-07 0.39288318869275274 True 1.12876296043396e-06 -1.7601996660232544e-07 -2.3283064365386963e-07 -1.7957857423311907e-14 -5.551115123125783e-16 1.3530843112619095e-16 1.1287629783918174e-06 -1.7601996604721393e-07 -2.3283064378917806e-07
51 17 fine 2 1.3328934989065289e-07 0.46401164838116316 True 7.129274308681488e-07 -2.1373853087425232e-07 -2.6496127247810364e-07 -1.634803403760543e-14 -2.914335439641036e-16 9.71445146547012e-17 7.129274472161828e-07 -2.1373853058281878e-07 -2.6496127257524815e-07
52 17 coarse 1 1.246264329513025e-07 0.4613853551985751 True 5.302950739860535e-06 -2.0675361156463623e-07 1.1362135410308838e-07 -2.8373137173076657e-14 7.7021722333370235e-16 -6.869504964868156e-16 5.302950768233672e-06 -2.0675361233485345e-07 1.1362135479003888e-07
53 18 fine 1 1.5840482392448507e-07 0.48249679461224454 True 8.10716301202774e-07 -1.4016404747962952e-07 -2.6402994990348816e-07 -1.6878859421254333e-14 7.632783294297951e-17 2.0816681711721685e-17 8.107163180816335e-07 -1.4016404755595735e-07 -2.6402994992430484e-07
54 18 fine 2 1.217794476371381e-07 0.4447119430321027 True 1.4016404747962952e-07 -2.8545036911964417e-07 -8.847564458847046e-09 -1.709223040879948e-14 -1.1275702593849246e-16 1.8214596497756474e-16 1.4016406457185993e-07 -2.8545036900688714e-07 -8.847564640993011e-09
55 18 coarse 1 1.3857981828735433e-07 0.4519491616828685 True 5.850568413734436e-06 -1.2479722499847412e-07 -1.471489667892456e-07 -2.688821387764051e-14 -8.534839501805891e-16 9.08995101411847e-16 5.85056844062265e-06 -1.2479722414499017e-07 -1.471489676982407e-07
56 19 fine 1 1.4433919059975153e-07 0.3821888438774327 True 1.9441358745098114e-06 -1.3969838619232178e-09 -2.7474015951156616e-08 -1.628905343942222e-14 -3.920475055707584e-16 2.42861286636753e-17 1.944135890798865e-06 -1.3969834698757122e-09 -2.7474015975442745e-08
57 19 fine 2 1.4349667698532187e-07 0.4183999473130793 True 2.1490268409252167e-06 1.7834827303886414e-07 -7.869675755500793e-08 -1.678344963007561e-14 -5.204170427930421e-18 2.949029909160572e-17 2.1490268577086663e-06 1.783482730440683e-07 -7.869675758449823e-08
58 19 coarse 1 1.264100825126846e-07 0.5347769553832019 True 5.165114998817444e-06 3.91155481338501e-08 1.1734664440155029e-07 -2.6804947150793623e-14 -4.2327252813834093e-16 -3.8163916471489756e-16 5.165115025622391e-06 3.9115548557122626e-08 1.1734664478318946e-07
59 20 fine 1 1.1464598925758906e-07 0.39800949885565845 True 1.8593855202198029e-06 7.031485438346863e-08 -2.2817403078079224e-08 -1.695171780724536e-14 1.457167719820518e-16 -7.632783294297951e-17 1.8593855371715207e-06 7.031485423775186e-08 -2.281740300175139e-08
60 20 fine 2 1.3166252321727967e-07 0.41581763506478076 True 2.2118911147117615e-06 9.313225746154785e-10 9.033828973770142e-08 -1.7095699855751434e-14 -3.7643499428696714e-16 2.0990154059319366e-16 2.2118911318074613e-06 9.313229510504728e-10 9.033828952779988e-08
61 20 coarse 1 1.3024161815700097e-07 0.47356066681074566 True 4.023313522338867e-06 5.997717380523682e-07 -8.568167686462402e-08 -2.7228219678931964e-14 3.0531133177191805e-16 3.7470027081099033e-16 4.023313549567087e-06 5.997717377470568e-07 -8.56816772393243e-08
62 21 fine 1 1.361732063775989e-07 0.4205892378883329 True 2.439599484205246e-06 1.4854595065116882e-07 -1.327134668827057e-07 -1.6781714906599632e-14 3.885780586188048e-16 8.673617379884035e-17 2.439599500986961e-06 1.4854595026259076e-07 -1.3271346696944186e-07
63 21 fine 2 1.2473161092874108e-07 0.45376916235253945 True 2.2514723241329193e-06 3.5902485251426697e-07 1.9976869225502014e-07 -1.692396223162973e-14 6.938893903907228e-17 -1.457167719820518e-16 2.2514723410568815e-06 3.5902485244487803e-07 1.9976869240073691e-07
64 21 coarse 1 1.5484813187249813e-07 0.561763881940829 True 3.507360816001892e-06 7.431954145431519e-07 6.202608346939087e-07 -2.6131874442114622e-14 -4.579669976578771e-16 1.5265566588595902e-16 3.5073608421337665e-06 7.431954150011189e-07 6.20260834541253e-07
65 22 fine 1 1.1594882032284204e-07 0.46103443091228286 True 1.2228265404701233e-06 2.300366759300232e-07 1.9185245037078857e-07 -1.5529244556944377e-14 -3.469446951953614e-18 7.28583859910259e-17 1.2228265559993678e-06 2.3003667593349264e-07 1.918524502979302e-07
66 22 fine 2 1.4032262196650436e-07 0.41123793671363457 True 2.0829029381275177e-06 1.317821443080902e-07 1.1594966053962708e-07 -1.6656814816329302e-14 -2.42861286636753e-17 2.7755575615628914e-17 2.0829029547843325e-06 1.3178214433237634e-07 1.159496605118715e-07
67 22 coarse 1 1.4061314457247676e-07 0.5696050037738337 True 5.517154932022095e-06 1.6167759895324707e-06 1.0058283805847168e-06 -2.643718577388654e-14 -4.996003610813204e-16 -4.579669976578771e-16 5.5171549584592805e-06 1.616775990032071e-06 1.0058283810426838e-06
68 23 fine 1 1.172129048265802e-07 0.43537551205849856 True 1.8416903913021088e-06 2.230517566204071e-07 2.1746382117271423e-07 -1.620752143605131e-14 -4.735795089416683e-16 1.9081958235744878e-17 1.8416904075096302e-06 2.2305175709398661e-07 2.1746382115363228e-07
69 23 fine 2 1.2559042006365928e-07 0.4297035689234779 True 1.998152583837509e-06 7.031485438346863e-08 4.98257577419281e-08 -1.62231339473351e-14 3.0184188481996443e-16 -3.7816971776294395e-16 1.998152600060643e-06 7.031485408162674e-08 4.982575812009782e-08
70 23 coarse 1 1.5135824793510722e-07 0.4407189177218073 True 1.2038275599479675e-05 1.3243407011032104e-06 7.692724466323853e-07 -2.7304547511874944e-14 1.4502288259166107e-15 -4.371503159461554e-16 1.2038275626784223e-05 1.3243406996529816e-06 7.692724470695356e-07
71 24 fine 1 1.1879041472706575e-07 0.3912946498849803 True 1.0398216545581818e-06 1.62515789270401e-07 1.3737007975578308e-07 -1.705927066275592e-14 1.6306400674181987e-16 -9.020562075079397e-17 1.0398216716174524e-06 1.62515789107337e-07 1.373700798459887e-07
72 24 fine 2 1.4235627243674998e-07 0.4195513876580241 True 1.6004778444766998e-06 1.3830140233039856e-07 1.7927959561347961e-07 -1.668977456237286e-14 -1.9949319973733282e-16 1.2663481374630692e-16 1.6004778611664744e-06 1.3830140252989176e-07 1.792795954868448e-07
73 24 coarse 1 1.5865499780609582e-07 0.5231448442629695 True 9.544193744659424e-06 4.5821070671081543e-07 2.942979335784912e-07 -2.545880173343562e-14 3.8163916471489756e-16 -1.457167719820518e-16 9.544193770118226e-06 4.5821070632917626e-07 2.94297933724208e-07
@@ -0,0 +1,25 @@
step,time,average_bound_ratio,leaf_m,leaf_px,leaf_py,delta_m,delta_px,delta_py,boundary_m,boundary_px,boundary_py,fine_transfer_m,fine_transfer_px,fine_transfer_py,coarse_transfer_m,coarse_transfer_px,coarse_transfer_py,raw_m,raw_px,raw_py,collision_drift_m,collision_drift_px,collision_drift_py,average_rounding_m,average_rounding_px,average_rounding_py,closure_m,closure_px,closure_py,cumulative_raw_m,cumulative_raw_px,cumulative_raw_py,cumulative_closure_m,cumulative_closure_px,cumulative_closure_py
1,1,0.28124994289828603,560.7534663206898,0.0016594058834016323,0.0014196881093084812,0.003462142776697874,0.0016594058834016323,0.0014196881093084812,0.0034477608278393745,0.0016594044864177704,0.001420031301677227,-3.557652235031128e-07,0.0,0.0,5.308538675308228e-07,-1.862645149230957e-09,-1.7695128917694092e-07,1.4206860214471817e-05,3.259629011154175e-09,-1.6624107956886292e-07,1.4206860214471817e-05,3.259629011154175e-09,-1.6624107956886292e-07,1.7508864402770996e-07,-1.862645149230957e-09,-1.7695128917694092e-07,0.0,0.0,0.0,1.4206860214471817e-05,3.259629011154175e-09,-1.6624107956886292e-07,0.0,0.0,0.0
2,2,0.37499987985940486,560.7572004375979,0.003110479563474655,0.002638322301208973,0.0037341169081628323,0.0014510736800730228,0.0012186341919004917,0.003732521552592516,0.0014515905641019344,0.0012190532870590687,-2.193264663219452e-06,-4.6566128730773926e-09,-1.685693860054016e-07,2.032145857810974e-06,-1.5087425708770752e-07,1.695007085800171e-07,1.7564743757247925e-06,-3.6135315895080566e-07,-4.200264811515808e-07,1.7564743757247925e-06,-3.6135315895080566e-07,-4.200264811515808e-07,-1.6111880540847778e-07,-1.555308699607849e-07,9.313225746154785e-10,0.0,0.0,0.0,1.596333459019661e-05,-3.580935299396515e-07,-5.862675607204437e-07,0.0,0.0,0.0
3,3,0.2812499146093721,560.7611049492843,0.004511175211519003,0.0038183839060366154,0.00390451168641448,0.0014006956480443478,0.0011800616048276424,0.0038831778801977634,0.0014002365060150623,0.0011796201579272747,-3.6400742828845978e-06,4.698522388935089e-07,4.6798959374427795e-07,3.641471266746521e-06,-4.637986421585083e-07,-4.600733518600464e-07,2.1332409232854843e-05,4.530884325504303e-07,4.3353065848350525e-07,2.1332409232854843e-05,4.530884325504303e-07,4.3353065848350525e-07,1.3969838619232178e-09,6.05359673500061e-09,7.916241884231567e-09,0.0,0.0,0.0,3.729574382305145e-05,9.499490261077881e-08,-1.5273690223693848e-07,0.0,0.0,0.0
4,4,0.37499987985940486,560.7650738614611,0.005782689433544874,0.004893188830465078,0.003968912176787853,0.0012715142220258713,0.001074804924428463,0.003933848347514868,0.0012704567052423954,0.001073895487934351,-6.910879164934158e-06,3.1711533665657043e-07,3.9534643292427063e-07,6.800517439842224e-06,-2.6263296604156494e-07,-3.371387720108032e-07,3.517419099807739e-05,1.0030344128608704e-06,8.512288331985474e-07,3.517419099807739e-05,1.0030344128608704e-06,8.512288331985474e-07,-1.103617250919342e-07,5.448237061500549e-08,5.820766091346741e-08,0.0,0.0,0.0,7.246993482112885e-05,1.0980293154716492e-06,6.984919309616089e-07,0.0,0.0,0.0
5,5,0.3749998295680158,560.7690546456724,0.006910111755132675,0.005846448242664337,0.003980784211307764,0.001127422321587801,0.0009532594121992588,0.0039466856978833675,0.001126923132687807,0.0009523364715278149,-7.287599146366119e-06,1.0672956705093384e-06,4.637986421585083e-07,7.417052984237671e-06,-1.0095536708831787e-06,-4.023313522338867e-07,3.396905958652496e-05,4.414469003677368e-07,8.614733815193176e-07,3.396905958652496e-05,4.414469003677368e-07,8.614733815193176e-07,1.2945383787155151e-07,5.774199962615967e-08,6.146728992462158e-08,0.0,0.0,0.0,0.00010643899440765381,1.539476215839386e-06,1.5599653124809265e-06,0.0,0.0,0.0
6,6,0.46874973195382685,560.7730254461057,0.007904952857643366,0.006686040665954351,0.003970800433307886,0.0009948411025106907,0.0008395924232900143,0.003946303389966488,0.0009944625198841095,0.00083962082862854,-6.226822733879089e-06,2.0954757928848267e-07,-1.8533319234848022e-07,6.167218089103699e-06,-2.477318048477173e-07,9.499490261077881e-08,2.455664798617363e-05,4.1676685214042664e-07,6.193295121192932e-08,2.455664798617363e-05,4.1676685214042664e-07,6.193295121192932e-08,-5.960464477539063e-08,-3.818422555923462e-08,-9.033828973770142e-08,0.0,0.0,0.0,0.00013099564239382744,1.9562430679798126e-06,1.6218982636928558e-06,0.0,0.0,0.0
7,7,0.4687496533735736,560.7769900038838,0.008779809810221195,0.007423080503940582,0.003964557778090239,0.0008748569525778294,0.0007370398379862309,0.003942790906876326,0.0008741165511310101,0.0007373974658548832,-2.6883091777563095e-05,-1.3766344636678696e-05,-7.656868547201157e-06,2.6874244213104248e-05,1.3727694749832153e-05,7.636845111846924e-06,2.177571877837181e-05,7.790513336658478e-07,-3.3760443329811096e-07,2.177571877837181e-05,7.790513336658478e-07,-3.3760443329811096e-07,-8.847564458847046e-09,-3.864988684654236e-08,-2.0023435354232788e-08,0.0,0.0,0.0,0.00015277136117219925,2.7352944016456604e-06,1.2842938303947449e-06,0.0,0.0,0.0
8,8,0.4687496533735736,560.7809417177923,0.009547093417495489,0.00806809077039361,0.0039517139084637165,0.0007672836072742939,0.0006450102664530277,0.0039388518780469894,0.0007664291188120842,0.0006456412374973297,-0.00016948627308011055,-8.736597374081612e-05,-5.452195182442665e-05,0.0001695193350315094,8.732080459594727e-05,5.4486095905303955e-05,1.2828968465328217e-05,8.996576070785522e-07,-5.951151251792908e-07,1.2828968465328217e-05,8.996576070785522e-07,-5.951151251792908e-07,3.306195139884949e-08,-4.516914486885071e-08,-3.585591912269592e-08,0.0,0.0,0.0,0.00016560032963752747,3.6349520087242126e-06,6.891787052154541e-07,0.0,0.0,0.0
9,9,0.4686406250816172,560.7848850805312,0.010217653587460518,0.008631827309727669,0.0039433627389371395,0.0006705601699650288,0.0005637365393340588,0.00393525930121541,0.0006706290878355503,0.0005643940530717373,-0.000617987010627985,-0.0002765483222901821,-0.00019021378830075264,0.0006179474294185638,0.00027653947472572327,0.00019023939967155457,8.143018931150436e-06,-6.007030606269836e-08,-6.831251084804535e-07,8.143018931150436e-06,-6.007030606269836e-08,-6.831251084804535e-07,-3.958120942115784e-08,-8.847564458847046e-09,2.561137080192566e-08,0.0,0.0,0.0,0.0001737433485686779,3.5748817026615143e-06,6.05359673500061e-09,0.0,0.0,0.0
10,10,0.4685945715880829,560.7888254267164,0.010803885292261839,0.00912527134642005,0.00394034618511796,0.000586231704801321,0.0004934440366923809,0.0039321803487837315,0.000586662907153368,0.0004931562580168247,-0.0014882697723805904,-0.0005795764736831188,-0.00043088337406516075,0.0014883410185575485,0.0005796011537313461,0.00043090246617794037,8.094590157270432e-06,-4.5588240027427673e-07,2.6868656277656555e-07,8.094590157270432e-06,-4.5588240027427673e-07,2.6868656277656555e-07,7.12461769580841e-08,2.468004822731018e-08,1.909211277961731e-08,0.0,0.0,0.0,0.00018183793872594833,3.1189993023872375e-06,2.7474015951156616e-07,0.0,0.0,0.0
11,11,0.37499977927664024,560.7927596913651,0.011317913420498371,0.009557455778121948,0.003934264648705721,0.0005140281282365322,0.0004321844317018986,0.003929825499653816,0.0005140695720911026,0.0004319213330745697,-0.0026630824431777,-0.0009266296401619911,-0.0007359907031059265,0.002663079649209976,0.0009266063570976257,0.0007360205054283142,4.441943019628525e-06,-1.816079020500183e-08,2.3329630494117737e-07,4.441943019628525e-06,-1.816079020500183e-08,2.3329630494117737e-07,-2.7939677238464355e-09,-2.3283064365386963e-08,2.9802322387695312e-08,0.0,0.0,0.0,0.00018627988174557686,3.1008385121822357e-06,5.080364644527435e-07,0.0,0.0,0.0
12,12,0.46874663591177923,560.7966943499632,0.011769441422075033,0.009937478695064783,0.003934658598154783,0.00045152800157666206,0.00038002291694283485,0.003928040154278278,0.00045189354568719864,0.0003798864781856537,-0.0038390979170799255,-0.0012310631573200226,-0.0010304069146513939,0.0038390420377254486,0.0012311115860939026,0.0010304339230060577,6.674323230981827e-06,-4.139728844165802e-07,1.0943040251731873e-07,6.674323230981827e-06,-4.139728844165802e-07,1.0943040251731873e-07,-5.587935447692871e-08,4.842877388000488e-08,2.7008354663848877e-08,0.0,0.0,0.0,0.00019295420497655869,2.6868656277656555e-06,6.174668669700623e-07,0.0,0.0,0.0
13,13,0.37499972898527817,560.8006243831478,0.01216893782839179,0.010273906867951155,0.0039300331845879555,0.0003994964063167572,0.0003364281728863716,0.003926742821931839,0.00039900559931993484,0.00033587682992219925,-0.004740437027066946,-0.0014326325617730618,-0.0012463550083339214,0.004740472882986069,0.0014326423406600952,0.0012463442981243134,3.2545067369937897e-06,4.810281097888947e-07,5.620531737804413e-07,3.2545067369937897e-06,4.810281097888947e-07,5.620531737804413e-07,3.585591912269592e-08,9.778887033462524e-09,-1.0710209608078003e-08,0.0,0.0,0.0,0.00019620871171355247,3.16789373755455e-06,1.1795200407505035e-06,0.0,0.0,0.0
14,14,0.4687474688530803,560.8045558938757,0.012523647397756577,0.010573056526482105,0.003931510727852583,0.00035470956936478615,0.00029914965853095055,0.003925675991922617,0.00035448791459202766,0.00029869796708226204,-0.005264284089207649,-0.0015086885541677475,-0.0013435659930109978,0.0052642785012722015,0.0015086643397808075,0.0013435855507850647,5.840323865413666e-06,2.4586915969848633e-07,4.3213367462158203e-07,5.840323865413666e-06,2.4586915969848633e-07,4.3213367462158203e-07,-5.587935447692871e-09,-2.421438694000244e-08,1.955777406692505e-08,0.0,0.0,0.0,0.00020204903557896614,3.4137628972530365e-06,1.6116537153720856e-06,0.0,0.0,0.0
15,15,0.4682317851482336,560.8084840090014,0.012841148767620325,0.010841074865311384,0.003928115125745535,0.00031750136986374855,0.00026801833882927895,0.003924637567251921,0.00031766900792717934,0.00026782089844346046,-0.005472308956086636,-0.0014677206054329872,-0.001318071037530899,0.005472287535667419,0.001467689871788025,0.001318071037530899,3.4989789128303528e-06,-1.3690441846847534e-07,1.9744038581848145e-07,3.4989789128303528e-06,-1.3690441846847534e-07,1.9744038581848145e-07,-2.1420419216156006e-08,-3.073364496231079e-08,0.0,0.0,0.0,0.0,0.0002055480144917965,3.276858478784561e-06,1.809094101190567e-06,0.0,0.0,0.0
16,16,0.4687439328019107,560.8124153451063,0.013128423597663641,0.011083992663770914,0.0039313361048698425,0.0002872748300433159,0.00024291779845952988,0.003923660609871149,0.0002878890372812748,0.00024270685389637947,-0.005496661644428968,-0.0013386714272201061,-0.0011936011724174023,0.005496615543961525,0.0013386663049459457,0.001193629577755928,7.721595466136932e-06,-6.09084963798523e-07,1.825392246246338e-07,7.721595466136932e-06,-6.09084963798523e-07,1.825392246246338e-07,-4.6100467443466187e-08,-5.122274160385132e-09,2.8405338525772095e-08,0.0,0.0,0.0,0.00021326960995793343,2.667773514986038e-06,1.991633325815201e-06,0.0,0.0,0.0
17,17,0.46873638940438433,560.8163452413864,0.013391933869570494,0.011306562926620245,0.003929896280169487,0.0002635102719068527,0.0002225702628493309,0.003922717645764351,0.0002640876919031143,0.00022296980023384094,-0.005448666866868734,-0.0011560707353055477,-0.0010099620558321476,0.005448700860142708,0.0011560898274183273,0.0010099466890096664,7.1446411311626434e-06,-5.96512109041214e-07,-3.841705620288849e-07,7.1446411311626434e-06,-5.96512109041214e-07,-3.841705620288849e-07,3.3993273973464966e-08,1.909211277961731e-08,-1.5366822481155396e-08,0.0,0.0,0.0,0.00022041425108909607,2.0712614059448242e-06,1.607462763786316e-06,0.0,0.0,0.0
18,18,0.4687180348178792,560.8202739986591,0.013636329676955938,0.011513229925185442,0.003928757272660732,0.00024439580738544464,0.000206666998565197,0.003921979106962681,0.00024497322738170624,0.0002071000635623932,-0.00538009125739336,-0.0009485194459557533,-0.0008049774914979935,0.005380067974328995,0.0009484924376010895,0.0008049644529819489,6.80144876241684e-06,-5.504116415977478e-07,-4.200264811515808e-07,6.80144876241684e-06,-5.504116415977478e-07,-4.200264811515808e-07,-2.3283064365386963e-08,-2.7008354663848877e-08,-1.30385160446167e-08,0.0,0.0,0.0,0.0002272156998515129,1.5208497643470764e-06,1.1874362826347351e-06,0.0,0.0,0.0
19,19,0.4687494647810733,560.8242048402317,0.013865197543054819,0.011706916149705648,0.003930841572582722,0.00022886786609888077,0.00019368622452020645,0.0039215972647070885,0.00022865179926156998,0.00019369274377822876,-0.005283902399241924,-0.0007343888282775879,-0.0006027696654200554,0.005283888429403305,0.0007343888282775879,0.0006027519702911377,9.258277714252472e-06,2.1606683731079102e-07,1.1175870895385742e-08,9.258277714252472e-06,2.1606683731079102e-07,1.1175870895385742e-08,-1.3969838619232178e-08,0.0,-1.7695128917694092e-08,0.0,0.0,0.0,0.00023647397756576538,1.7369166016578674e-06,1.1986121535301208e-06,0.0,0.0,0.0
20,20,0.468749291904748,560.8281343518756,0.01407972676679492,0.011888547334820032,0.003929511643946171,0.00021452922374010086,0.0001816311851143837,0.0039214082062244415,0.00021384842693805695,0.00018165074288845062,-0.005120935384184122,-0.0005169562064111233,-0.00041141873225569725,0.005120944231748581,0.0005169659852981567,0.00041141733527183533,8.094590157270432e-06,6.710179150104523e-07,-1.816079020500183e-08,8.094590157270432e-06,6.710179150104523e-07,-1.816079020500183e-08,8.847564458847046e-09,9.778887033462524e-09,-1.3969838619232178e-09,0.0,0.0,0.0,0.0002445685677230358,2.4079345166683197e-06,1.180451363325119e-06,0.0,0.0,0.0
21,21,0.4686316241476506,560.8320638332516,0.014281701296567917,0.012059765867888927,0.003929481375962496,0.0002019745297729969,0.00017121853306889534,0.003921300172805786,0.000200699083507061,0.00017050933092832565,-0.004840303678065538,-0.00029240502044558525,-0.00022668996825814247,0.004840286448597908,0.00029242970049381256,0.00022671185433864594,8.198432624340057e-06,1.2507662177085876e-06,6.873160600662231e-07,8.198432624340057e-06,1.2507662177085876e-06,6.873160600662231e-07,-1.7229467630386353e-08,2.468004822731018e-08,2.1886080503463745e-08,0.0,0.0,0.0,0.00025276700034737587,3.6587007343769073e-06,1.8677674233913422e-06,0.0,0.0,0.0
22,22,0.46868277541627273,560.835993598681,0.014473678078502417,0.012222256977111101,0.0039297654293477535,0.00019197678193449974,0.0001624911092221737,0.003920916933566332,0.00018997164443135262,0.0001611732877790928,-0.004407043103128672,-5.385419353842735e-05,-3.726920112967491e-05,0.004407068714499474,5.3880736231803894e-05,3.727339208126068e-05,8.822884410619736e-06,1.978594809770584e-06,1.3136304914951324e-06,8.822884410619736e-06,1.978594809770584e-06,1.3136304914951324e-06,2.561137080192566e-08,2.6542693376541138e-08,4.190951585769653e-09,0.0,0.0,0.0,0.0002615898847579956,5.6372955441474915e-06,3.1813979148864746e-06,0.0,0.0,0.0
23,23,0.4687343150126283,560.8399298018776,0.014657547231763601,0.01237749820575118,0.003936203196644783,0.0001838691532611847,0.0001552412286400795,0.003920321352779865,0.000182238407433033,0.000154225155711174,-0.0038209911435842514,0.0001984424889087677,0.00016180798411369324,0.00382099486887455,-0.00019842945039272308,-0.00016182847321033478,1.5878118574619293e-05,1.6177073121070862e-06,1.0365620255470276e-06,1.5878118574619293e-05,1.6177073121070862e-06,1.0365620255470276e-06,3.725290298461914e-09,1.30385160446167e-08,-2.0489096641540527e-08,0.0,0.0,0.0,0.0002774680033326149,7.255002856254578e-06,4.217959940433502e-06,0.0,0.0,0.0
24,24,0.46876041911371336,560.8438616539352,0.014835720416158438,0.012527641374617815,0.0039318520575761795,0.00017817318439483643,0.00015014316886663437,0.003919683396816254,0.0001774495467543602,0.00014953874051570892,-0.003126208670437336,0.0004524495452642441,0.0003674151375889778,0.0031261928379535675,-0.00045248493552207947,-0.0003674216568470001,1.2184493243694305e-05,7.59027898311615e-07,6.109476089477539e-07,1.2184493243694305e-05,7.59027898311615e-07,6.109476089477539e-07,-1.5832483768463135e-08,-3.5390257835388184e-08,-6.51925802230835e-09,0.0,0.0,0.0,0.0002896524965763092,8.014030754566193e-06,4.828907549381256e-06,0.0,0.0,0.0
1 step time average_bound_ratio leaf_m leaf_px leaf_py delta_m delta_px delta_py boundary_m boundary_px boundary_py fine_transfer_m fine_transfer_px fine_transfer_py coarse_transfer_m coarse_transfer_px coarse_transfer_py raw_m raw_px raw_py collision_drift_m collision_drift_px collision_drift_py average_rounding_m average_rounding_px average_rounding_py closure_m closure_px closure_py cumulative_raw_m cumulative_raw_px cumulative_raw_py cumulative_closure_m cumulative_closure_px cumulative_closure_py
2 1 1 0.28124994289828603 560.7534663206898 0.0016594058834016323 0.0014196881093084812 0.003462142776697874 0.0016594058834016323 0.0014196881093084812 0.0034477608278393745 0.0016594044864177704 0.001420031301677227 -3.557652235031128e-07 0.0 0.0 5.308538675308228e-07 -1.862645149230957e-09 -1.7695128917694092e-07 1.4206860214471817e-05 3.259629011154175e-09 -1.6624107956886292e-07 1.4206860214471817e-05 3.259629011154175e-09 -1.6624107956886292e-07 1.7508864402770996e-07 -1.862645149230957e-09 -1.7695128917694092e-07 0.0 0.0 0.0 1.4206860214471817e-05 3.259629011154175e-09 -1.6624107956886292e-07 0.0 0.0 0.0
3 2 2 0.37499987985940486 560.7572004375979 0.003110479563474655 0.002638322301208973 0.0037341169081628323 0.0014510736800730228 0.0012186341919004917 0.003732521552592516 0.0014515905641019344 0.0012190532870590687 -2.193264663219452e-06 -4.6566128730773926e-09 -1.685693860054016e-07 2.032145857810974e-06 -1.5087425708770752e-07 1.695007085800171e-07 1.7564743757247925e-06 -3.6135315895080566e-07 -4.200264811515808e-07 1.7564743757247925e-06 -3.6135315895080566e-07 -4.200264811515808e-07 -1.6111880540847778e-07 -1.555308699607849e-07 9.313225746154785e-10 0.0 0.0 0.0 1.596333459019661e-05 -3.580935299396515e-07 -5.862675607204437e-07 0.0 0.0 0.0
4 3 3 0.2812499146093721 560.7611049492843 0.004511175211519003 0.0038183839060366154 0.00390451168641448 0.0014006956480443478 0.0011800616048276424 0.0038831778801977634 0.0014002365060150623 0.0011796201579272747 -3.6400742828845978e-06 4.698522388935089e-07 4.6798959374427795e-07 3.641471266746521e-06 -4.637986421585083e-07 -4.600733518600464e-07 2.1332409232854843e-05 4.530884325504303e-07 4.3353065848350525e-07 2.1332409232854843e-05 4.530884325504303e-07 4.3353065848350525e-07 1.3969838619232178e-09 6.05359673500061e-09 7.916241884231567e-09 0.0 0.0 0.0 3.729574382305145e-05 9.499490261077881e-08 -1.5273690223693848e-07 0.0 0.0 0.0
5 4 4 0.37499987985940486 560.7650738614611 0.005782689433544874 0.004893188830465078 0.003968912176787853 0.0012715142220258713 0.001074804924428463 0.003933848347514868 0.0012704567052423954 0.001073895487934351 -6.910879164934158e-06 3.1711533665657043e-07 3.9534643292427063e-07 6.800517439842224e-06 -2.6263296604156494e-07 -3.371387720108032e-07 3.517419099807739e-05 1.0030344128608704e-06 8.512288331985474e-07 3.517419099807739e-05 1.0030344128608704e-06 8.512288331985474e-07 -1.103617250919342e-07 5.448237061500549e-08 5.820766091346741e-08 0.0 0.0 0.0 7.246993482112885e-05 1.0980293154716492e-06 6.984919309616089e-07 0.0 0.0 0.0
6 5 5 0.3749998295680158 560.7690546456724 0.006910111755132675 0.005846448242664337 0.003980784211307764 0.001127422321587801 0.0009532594121992588 0.0039466856978833675 0.001126923132687807 0.0009523364715278149 -7.287599146366119e-06 1.0672956705093384e-06 4.637986421585083e-07 7.417052984237671e-06 -1.0095536708831787e-06 -4.023313522338867e-07 3.396905958652496e-05 4.414469003677368e-07 8.614733815193176e-07 3.396905958652496e-05 4.414469003677368e-07 8.614733815193176e-07 1.2945383787155151e-07 5.774199962615967e-08 6.146728992462158e-08 0.0 0.0 0.0 0.00010643899440765381 1.539476215839386e-06 1.5599653124809265e-06 0.0 0.0 0.0
7 6 6 0.46874973195382685 560.7730254461057 0.007904952857643366 0.006686040665954351 0.003970800433307886 0.0009948411025106907 0.0008395924232900143 0.003946303389966488 0.0009944625198841095 0.00083962082862854 -6.226822733879089e-06 2.0954757928848267e-07 -1.8533319234848022e-07 6.167218089103699e-06 -2.477318048477173e-07 9.499490261077881e-08 2.455664798617363e-05 4.1676685214042664e-07 6.193295121192932e-08 2.455664798617363e-05 4.1676685214042664e-07 6.193295121192932e-08 -5.960464477539063e-08 -3.818422555923462e-08 -9.033828973770142e-08 0.0 0.0 0.0 0.00013099564239382744 1.9562430679798126e-06 1.6218982636928558e-06 0.0 0.0 0.0
8 7 7 0.4687496533735736 560.7769900038838 0.008779809810221195 0.007423080503940582 0.003964557778090239 0.0008748569525778294 0.0007370398379862309 0.003942790906876326 0.0008741165511310101 0.0007373974658548832 -2.6883091777563095e-05 -1.3766344636678696e-05 -7.656868547201157e-06 2.6874244213104248e-05 1.3727694749832153e-05 7.636845111846924e-06 2.177571877837181e-05 7.790513336658478e-07 -3.3760443329811096e-07 2.177571877837181e-05 7.790513336658478e-07 -3.3760443329811096e-07 -8.847564458847046e-09 -3.864988684654236e-08 -2.0023435354232788e-08 0.0 0.0 0.0 0.00015277136117219925 2.7352944016456604e-06 1.2842938303947449e-06 0.0 0.0 0.0
9 8 8 0.4687496533735736 560.7809417177923 0.009547093417495489 0.00806809077039361 0.0039517139084637165 0.0007672836072742939 0.0006450102664530277 0.0039388518780469894 0.0007664291188120842 0.0006456412374973297 -0.00016948627308011055 -8.736597374081612e-05 -5.452195182442665e-05 0.0001695193350315094 8.732080459594727e-05 5.4486095905303955e-05 1.2828968465328217e-05 8.996576070785522e-07 -5.951151251792908e-07 1.2828968465328217e-05 8.996576070785522e-07 -5.951151251792908e-07 3.306195139884949e-08 -4.516914486885071e-08 -3.585591912269592e-08 0.0 0.0 0.0 0.00016560032963752747 3.6349520087242126e-06 6.891787052154541e-07 0.0 0.0 0.0
10 9 9 0.4686406250816172 560.7848850805312 0.010217653587460518 0.008631827309727669 0.0039433627389371395 0.0006705601699650288 0.0005637365393340588 0.00393525930121541 0.0006706290878355503 0.0005643940530717373 -0.000617987010627985 -0.0002765483222901821 -0.00019021378830075264 0.0006179474294185638 0.00027653947472572327 0.00019023939967155457 8.143018931150436e-06 -6.007030606269836e-08 -6.831251084804535e-07 8.143018931150436e-06 -6.007030606269836e-08 -6.831251084804535e-07 -3.958120942115784e-08 -8.847564458847046e-09 2.561137080192566e-08 0.0 0.0 0.0 0.0001737433485686779 3.5748817026615143e-06 6.05359673500061e-09 0.0 0.0 0.0
11 10 10 0.4685945715880829 560.7888254267164 0.010803885292261839 0.00912527134642005 0.00394034618511796 0.000586231704801321 0.0004934440366923809 0.0039321803487837315 0.000586662907153368 0.0004931562580168247 -0.0014882697723805904 -0.0005795764736831188 -0.00043088337406516075 0.0014883410185575485 0.0005796011537313461 0.00043090246617794037 8.094590157270432e-06 -4.5588240027427673e-07 2.6868656277656555e-07 8.094590157270432e-06 -4.5588240027427673e-07 2.6868656277656555e-07 7.12461769580841e-08 2.468004822731018e-08 1.909211277961731e-08 0.0 0.0 0.0 0.00018183793872594833 3.1189993023872375e-06 2.7474015951156616e-07 0.0 0.0 0.0
12 11 11 0.37499977927664024 560.7927596913651 0.011317913420498371 0.009557455778121948 0.003934264648705721 0.0005140281282365322 0.0004321844317018986 0.003929825499653816 0.0005140695720911026 0.0004319213330745697 -0.0026630824431777 -0.0009266296401619911 -0.0007359907031059265 0.002663079649209976 0.0009266063570976257 0.0007360205054283142 4.441943019628525e-06 -1.816079020500183e-08 2.3329630494117737e-07 4.441943019628525e-06 -1.816079020500183e-08 2.3329630494117737e-07 -2.7939677238464355e-09 -2.3283064365386963e-08 2.9802322387695312e-08 0.0 0.0 0.0 0.00018627988174557686 3.1008385121822357e-06 5.080364644527435e-07 0.0 0.0 0.0
13 12 12 0.46874663591177923 560.7966943499632 0.011769441422075033 0.009937478695064783 0.003934658598154783 0.00045152800157666206 0.00038002291694283485 0.003928040154278278 0.00045189354568719864 0.0003798864781856537 -0.0038390979170799255 -0.0012310631573200226 -0.0010304069146513939 0.0038390420377254486 0.0012311115860939026 0.0010304339230060577 6.674323230981827e-06 -4.139728844165802e-07 1.0943040251731873e-07 6.674323230981827e-06 -4.139728844165802e-07 1.0943040251731873e-07 -5.587935447692871e-08 4.842877388000488e-08 2.7008354663848877e-08 0.0 0.0 0.0 0.00019295420497655869 2.6868656277656555e-06 6.174668669700623e-07 0.0 0.0 0.0
14 13 13 0.37499972898527817 560.8006243831478 0.01216893782839179 0.010273906867951155 0.0039300331845879555 0.0003994964063167572 0.0003364281728863716 0.003926742821931839 0.00039900559931993484 0.00033587682992219925 -0.004740437027066946 -0.0014326325617730618 -0.0012463550083339214 0.004740472882986069 0.0014326423406600952 0.0012463442981243134 3.2545067369937897e-06 4.810281097888947e-07 5.620531737804413e-07 3.2545067369937897e-06 4.810281097888947e-07 5.620531737804413e-07 3.585591912269592e-08 9.778887033462524e-09 -1.0710209608078003e-08 0.0 0.0 0.0 0.00019620871171355247 3.16789373755455e-06 1.1795200407505035e-06 0.0 0.0 0.0
15 14 14 0.4687474688530803 560.8045558938757 0.012523647397756577 0.010573056526482105 0.003931510727852583 0.00035470956936478615 0.00029914965853095055 0.003925675991922617 0.00035448791459202766 0.00029869796708226204 -0.005264284089207649 -0.0015086885541677475 -0.0013435659930109978 0.0052642785012722015 0.0015086643397808075 0.0013435855507850647 5.840323865413666e-06 2.4586915969848633e-07 4.3213367462158203e-07 5.840323865413666e-06 2.4586915969848633e-07 4.3213367462158203e-07 -5.587935447692871e-09 -2.421438694000244e-08 1.955777406692505e-08 0.0 0.0 0.0 0.00020204903557896614 3.4137628972530365e-06 1.6116537153720856e-06 0.0 0.0 0.0
16 15 15 0.4682317851482336 560.8084840090014 0.012841148767620325 0.010841074865311384 0.003928115125745535 0.00031750136986374855 0.00026801833882927895 0.003924637567251921 0.00031766900792717934 0.00026782089844346046 -0.005472308956086636 -0.0014677206054329872 -0.001318071037530899 0.005472287535667419 0.001467689871788025 0.001318071037530899 3.4989789128303528e-06 -1.3690441846847534e-07 1.9744038581848145e-07 3.4989789128303528e-06 -1.3690441846847534e-07 1.9744038581848145e-07 -2.1420419216156006e-08 -3.073364496231079e-08 0.0 0.0 0.0 0.0 0.0002055480144917965 3.276858478784561e-06 1.809094101190567e-06 0.0 0.0 0.0
17 16 16 0.4687439328019107 560.8124153451063 0.013128423597663641 0.011083992663770914 0.0039313361048698425 0.0002872748300433159 0.00024291779845952988 0.003923660609871149 0.0002878890372812748 0.00024270685389637947 -0.005496661644428968 -0.0013386714272201061 -0.0011936011724174023 0.005496615543961525 0.0013386663049459457 0.001193629577755928 7.721595466136932e-06 -6.09084963798523e-07 1.825392246246338e-07 7.721595466136932e-06 -6.09084963798523e-07 1.825392246246338e-07 -4.6100467443466187e-08 -5.122274160385132e-09 2.8405338525772095e-08 0.0 0.0 0.0 0.00021326960995793343 2.667773514986038e-06 1.991633325815201e-06 0.0 0.0 0.0
18 17 17 0.46873638940438433 560.8163452413864 0.013391933869570494 0.011306562926620245 0.003929896280169487 0.0002635102719068527 0.0002225702628493309 0.003922717645764351 0.0002640876919031143 0.00022296980023384094 -0.005448666866868734 -0.0011560707353055477 -0.0010099620558321476 0.005448700860142708 0.0011560898274183273 0.0010099466890096664 7.1446411311626434e-06 -5.96512109041214e-07 -3.841705620288849e-07 7.1446411311626434e-06 -5.96512109041214e-07 -3.841705620288849e-07 3.3993273973464966e-08 1.909211277961731e-08 -1.5366822481155396e-08 0.0 0.0 0.0 0.00022041425108909607 2.0712614059448242e-06 1.607462763786316e-06 0.0 0.0 0.0
19 18 18 0.4687180348178792 560.8202739986591 0.013636329676955938 0.011513229925185442 0.003928757272660732 0.00024439580738544464 0.000206666998565197 0.003921979106962681 0.00024497322738170624 0.0002071000635623932 -0.00538009125739336 -0.0009485194459557533 -0.0008049774914979935 0.005380067974328995 0.0009484924376010895 0.0008049644529819489 6.80144876241684e-06 -5.504116415977478e-07 -4.200264811515808e-07 6.80144876241684e-06 -5.504116415977478e-07 -4.200264811515808e-07 -2.3283064365386963e-08 -2.7008354663848877e-08 -1.30385160446167e-08 0.0 0.0 0.0 0.0002272156998515129 1.5208497643470764e-06 1.1874362826347351e-06 0.0 0.0 0.0
20 19 19 0.4687494647810733 560.8242048402317 0.013865197543054819 0.011706916149705648 0.003930841572582722 0.00022886786609888077 0.00019368622452020645 0.0039215972647070885 0.00022865179926156998 0.00019369274377822876 -0.005283902399241924 -0.0007343888282775879 -0.0006027696654200554 0.005283888429403305 0.0007343888282775879 0.0006027519702911377 9.258277714252472e-06 2.1606683731079102e-07 1.1175870895385742e-08 9.258277714252472e-06 2.1606683731079102e-07 1.1175870895385742e-08 -1.3969838619232178e-08 0.0 -1.7695128917694092e-08 0.0 0.0 0.0 0.00023647397756576538 1.7369166016578674e-06 1.1986121535301208e-06 0.0 0.0 0.0
21 20 20 0.468749291904748 560.8281343518756 0.01407972676679492 0.011888547334820032 0.003929511643946171 0.00021452922374010086 0.0001816311851143837 0.0039214082062244415 0.00021384842693805695 0.00018165074288845062 -0.005120935384184122 -0.0005169562064111233 -0.00041141873225569725 0.005120944231748581 0.0005169659852981567 0.00041141733527183533 8.094590157270432e-06 6.710179150104523e-07 -1.816079020500183e-08 8.094590157270432e-06 6.710179150104523e-07 -1.816079020500183e-08 8.847564458847046e-09 9.778887033462524e-09 -1.3969838619232178e-09 0.0 0.0 0.0 0.0002445685677230358 2.4079345166683197e-06 1.180451363325119e-06 0.0 0.0 0.0
22 21 21 0.4686316241476506 560.8320638332516 0.014281701296567917 0.012059765867888927 0.003929481375962496 0.0002019745297729969 0.00017121853306889534 0.003921300172805786 0.000200699083507061 0.00017050933092832565 -0.004840303678065538 -0.00029240502044558525 -0.00022668996825814247 0.004840286448597908 0.00029242970049381256 0.00022671185433864594 8.198432624340057e-06 1.2507662177085876e-06 6.873160600662231e-07 8.198432624340057e-06 1.2507662177085876e-06 6.873160600662231e-07 -1.7229467630386353e-08 2.468004822731018e-08 2.1886080503463745e-08 0.0 0.0 0.0 0.00025276700034737587 3.6587007343769073e-06 1.8677674233913422e-06 0.0 0.0 0.0
23 22 22 0.46868277541627273 560.835993598681 0.014473678078502417 0.012222256977111101 0.0039297654293477535 0.00019197678193449974 0.0001624911092221737 0.003920916933566332 0.00018997164443135262 0.0001611732877790928 -0.004407043103128672 -5.385419353842735e-05 -3.726920112967491e-05 0.004407068714499474 5.3880736231803894e-05 3.727339208126068e-05 8.822884410619736e-06 1.978594809770584e-06 1.3136304914951324e-06 8.822884410619736e-06 1.978594809770584e-06 1.3136304914951324e-06 2.561137080192566e-08 2.6542693376541138e-08 4.190951585769653e-09 0.0 0.0 0.0 0.0002615898847579956 5.6372955441474915e-06 3.1813979148864746e-06 0.0 0.0 0.0
24 23 23 0.4687343150126283 560.8399298018776 0.014657547231763601 0.01237749820575118 0.003936203196644783 0.0001838691532611847 0.0001552412286400795 0.003920321352779865 0.000182238407433033 0.000154225155711174 -0.0038209911435842514 0.0001984424889087677 0.00016180798411369324 0.00382099486887455 -0.00019842945039272308 -0.00016182847321033478 1.5878118574619293e-05 1.6177073121070862e-06 1.0365620255470276e-06 1.5878118574619293e-05 1.6177073121070862e-06 1.0365620255470276e-06 3.725290298461914e-09 1.30385160446167e-08 -2.0489096641540527e-08 0.0 0.0 0.0 0.0002774680033326149 7.255002856254578e-06 4.217959940433502e-06 0.0 0.0 0.0
25 24 24 0.46876041911371336 560.8438616539352 0.014835720416158438 0.012527641374617815 0.0039318520575761795 0.00017817318439483643 0.00015014316886663437 0.003919683396816254 0.0001774495467543602 0.00014953874051570892 -0.003126208670437336 0.0004524495452642441 0.0003674151375889778 0.0031261928379535675 -0.00045248493552207947 -0.0003674216568470001 1.2184493243694305e-05 7.59027898311615e-07 6.109476089477539e-07 1.2184493243694305e-05 7.59027898311615e-07 6.109476089477539e-07 -1.5832483768463135e-08 -3.5390257835388184e-08 -6.51925802230835e-09 0.0 0.0 0.0 0.0002896524965763092 8.014030754566193e-06 4.828907549381256e-06 0.0 0.0 0.0
@@ -0,0 +1,97 @@
metric,time,signal,baseline,absolute,any_crossed,peak_crossed,x,y,q
coarse_interface_u,1,0.0,0.0,0.0,False,False,3.5,3.5,
coarse_interface_u,2,0.0,2.63417801721126e-09,2.63417801721126e-09,False,False,3.5,3.5,
coarse_interface_u,3,0.0,2.63417801721126e-09,2.63417801721126e-09,False,False,3.5,3.5,
coarse_interface_u,4,0.0,6.585443742795605e-08,6.585443742795605e-08,False,False,3.5,3.5,
coarse_interface_u,5,0.0,1.2644051067663912e-07,1.2644051067663912e-07,False,False,3.5,3.5,
coarse_interface_u,6,2.123413592043705e-07,1.4528626697542904e-07,3.5762762617979955e-07,False,False,20.5,12.5,
coarse_interface_u,7,4.0664670353703905e-06,2.0116559817931723e-07,4.267265792606936e-06,True,True,20.5,13.5,
coarse_interface_u,8,2.316397368189694e-05,1.5646213891164667e-07,2.3320343327342335e-05,True,True,20.5,13.5,
coarse_interface_u,9,6.795742008554701e-05,1.5646213891164667e-07,6.81138583592495e-05,True,True,20.5,13.5,
coarse_interface_u,10,0.00013453387391202865,9.750014426779573e-08,0.00013463070833560589,True,True,20.5,13.5,
coarse_interface_u,11,0.00020315493961354394,1.1795114315203827e-07,0.00020326776624343072,True,True,20.5,13.5,
coarse_interface_u,12,0.0002578325145358002,7.455233297611785e-08,0.00025790659921174714,True,True,20.5,14.5,
coarse_interface_u,13,0.0002848355625376438,3.83541997932092e-08,0.0002848672209318115,True,True,20.5,14.5,
coarse_interface_u,14,0.00028850325159438407,3.003423681142711e-08,0.00028847339892346693,True,True,20.5,15.5,
coarse_interface_u,15,0.0002790426599299092,6.516592454722021e-08,0.00027900289954439403,True,True,20.5,16.5,
coarse_interface_u,16,0.0002656231695763881,1.006517304071618e-07,0.0002656687325338991,True,True,20.5,17.5,
coarse_interface_u,17,0.00025167224259872663,9.86322156278415e-08,0.00025171418857411254,True,True,20.5,18.5,
coarse_interface_u,18,0.00023917435962541014,1.0286787296380317e-07,0.00023916330914968713,True,True,20.5,19.5,
coarse_interface_u,19,0.0002264648202014007,7.783088195871973e-08,0.00022649832134267317,True,True,20.5,20.5,
coarse_interface_u,20,0.00021450009842274482,8.503127640307697e-08,0.0002145262119900782,True,True,20.5,20.5,
coarse_interface_u,21,0.00019565444290966713,7.893743237430962e-08,0.00019572665753668725,True,True,20.5,20.5,
coarse_interface_u,22,0.00017530342242023255,5.2749351285234925e-08,0.0001753561669734725,True,True,20.5,20.5,
coarse_interface_u,23,0.00016284198169591366,8.178685339035058e-08,0.00016288798599953632,True,True,20.5,14.5,
coarse_interface_u,24,0.00016001299284349154,6.715860617082587e-08,0.00016005458983486885,True,True,20.5,14.5,
coarse_bulk_u,1,0.0,0.0,0.0,False,False,0.5,0.5,
coarse_bulk_u,2,0.0,0.0,0.0,False,False,0.5,0.5,
coarse_bulk_u,3,0.0,0.0,0.0,False,False,0.5,0.5,
coarse_bulk_u,4,0.0,0.0,0.0,False,False,0.5,0.5,
coarse_bulk_u,5,0.0,0.0,0.0,False,False,0.5,0.5,
coarse_bulk_u,6,0.0,0.0,0.0,False,False,0.5,0.5,
coarse_bulk_u,7,9.685747920378016e-08,2.12341462371735e-07,3.0919894157551517e-07,False,False,21.5,12.5,
coarse_bulk_u,8,1.885523449607647e-06,2.458690369633922e-07,2.131116250194691e-06,True,False,21.5,13.5,
coarse_bulk_u,9,1.1801222962468464e-05,1.564621179284487e-07,1.1957591962850096e-05,True,True,21.5,13.5,
coarse_bulk_u,10,3.7763148161723895e-05,1.0327184058071679e-07,3.786536052602384e-05,True,True,21.5,13.5,
coarse_bulk_u,11,8.290997527773004e-05,4.214683516511236e-08,8.293984645156337e-05,True,True,21.5,13.5,
coarse_bulk_u,12,0.00013975592467875463,5.890198697622995e-09,0.00013975397806857782,True,True,21.5,13.5,
coarse_bulk_u,13,0.00019498935130707817,4.806920811870088e-08,0.00019495727755690072,True,True,21.5,14.5,
coarse_bulk_u,14,0.00023699059195898703,3.215422633434082e-08,0.00023698211801486242,True,True,21.5,14.5,
coarse_bulk_u,15,0.000255587117158192,3.434546877545681e-08,0.0002555629409290573,True,True,21.5,14.5,
coarse_bulk_u,16,0.00025699080829703886,0.0,0.00025699080829703886,True,True,21.5,15.5,
coarse_bulk_u,17,0.00024815159847585574,6.606481633104396e-08,0.0002482080995082901,True,True,21.5,16.5,
coarse_bulk_u,18,0.00023639704637690832,6.929437569595666e-08,0.00023645799303108044,True,True,21.5,17.5,
coarse_bulk_u,19,0.00022522644482484474,1.0390817551817351e-07,0.00022530812767909556,True,True,21.5,19.5,
coarse_bulk_u,20,0.0002151574621150763,1.042082306083734e-07,0.00021524519922552202,True,True,22.5,18.5,
coarse_bulk_u,21,0.00020618043430475382,9.442706670805767e-08,0.00020625960942046836,True,True,21.5,20.5,
coarse_bulk_u,22,0.0001977039381507293,5.556802130737047e-08,0.00019775833634301496,True,True,22.5,20.5,
coarse_bulk_u,23,0.00018973381549205,4.4703464263670685e-08,0.00018970107840731907,True,True,22.5,21.5,
coarse_bulk_u,24,0.00018031585591623997,9.995996742145265e-08,0.0001802207328329628,True,True,22.5,22.5,
fine_band_neq,1,0.0,3.000928300994632e-09,3.000928300994632e-09,False,False,4.25,4.25,
fine_band_neq,2,0.0,4.501393077727123e-09,4.501393077727123e-09,False,False,4.25,4.25,
fine_band_neq,3,0.0,2.069606169774474e-08,2.069606169774474e-08,False,False,4.25,4.25,
fine_band_neq,4,0.0,4.1392115429639276e-09,4.1392115429639276e-09,False,False,4.25,4.25,
fine_band_neq,5,0.0,4.1392115429639276e-09,4.1392115429639276e-09,False,False,4.25,4.25,
fine_band_neq,6,3.8661114470928126e-07,9.934099098884985e-09,3.766770456103963e-07,True,True,19.75,13.25,
fine_band_neq,7,2.0898831959437203e-06,9.934099098884985e-09,2.0799490968448353e-06,True,True,19.75,13.25,
fine_band_neq,8,5.086951299526632e-06,9.934099098884985e-09,5.077017200427747e-06,True,True,19.75,13.75,
fine_band_neq,9,7.3187303596400355e-06,1.1589783133203468e-08,7.307140576506832e-06,True,True,19.75,14.25,
fine_band_neq,10,7.498180437826019e-06,9.106256526614231e-09,7.489074181299404e-06,True,True,19.75,15.25,
fine_band_neq,11,6.85740365241605e-06,5.794905943989903e-09,6.86319855836004e-06,True,True,19.75,17.25,
fine_band_neq,12,6.20376639004494e-06,6.622735776451449e-09,6.200455026694751e-06,True,True,19.75,18.25,
fine_band_neq,13,5.366229072267803e-06,4.139212333997833e-09,5.369540443278531e-06,True,True,19.75,19.25,
fine_band_neq,14,5.300103189165295e-06,4.967056432825245e-09,5.30507024559812e-06,True,True,19.75,19.75,
fine_band_neq,15,4.0156351262532475e-06,4.553132745832578e-09,4.018946498263176e-06,True,True,19.75,19.75,
fine_band_neq,16,3.7773208383384826e-06,6.622738135675377e-09,3.783943576474158e-06,True,True,19.75,16.75,
fine_band_neq,17,3.59763095919563e-06,6.622736969941201e-09,3.598458797438031e-06,True,True,19.75,17.75,
fine_band_neq,18,3.1864885083332517e-06,1.7384672978959514e-08,3.2038731813122112e-06,True,True,19.75,18.75,
fine_band_neq,19,3.2079558324737967e-06,9.934106745546067e-09,3.2054722903795962e-06,True,True,19.75,19.75,
fine_band_neq,20,3.2478981990546885e-06,8.278412177986638e-09,3.256176611232675e-06,True,True,19.75,19.75,
fine_band_neq,21,2.8408409309954585e-06,1.1589792486832451e-08,2.83256250521724e-06,True,True,19.75,19.75,
fine_band_neq,22,2.2599308021065134e-06,1.241763983306221e-09,2.2599308009962904e-06,True,True,19.75,19.75,
fine_band_neq,23,1.7067130013148635e-06,2.0696062086322797e-09,1.7075408424993554e-06,True,True,19.75,19.75,
fine_band_neq,24,1.7691307190870198e-06,7.864502313270627e-09,1.768302879068262e-06,True,True,4.25,8.25,
transfer_neq,1,0.0,1.5004641487625925e-09,1.5004641487625925e-09,False,False,3.5,3.5,6
transfer_neq,2,0.0,3.000928290586291e-09,3.000928290586291e-09,False,False,3.5,3.5,6
transfer_neq,3,0.0,3.000928290586291e-09,3.000928290586291e-09,False,False,3.5,3.5,6
transfer_neq,4,0.0,6.881438113781613e-09,6.881438113781613e-09,False,False,3.5,3.5,6
transfer_neq,5,0.0,6.467520081987477e-09,6.467520081987477e-09,False,False,3.5,3.5,6
transfer_neq,6,4.801482146599145e-08,1.7384695072397705e-08,3.063012639359375e-08,False,False,20.5,12.5,1
transfer_neq,7,9.917490157301811e-07,1.4901174696935193e-08,9.76847841033246e-07,True,True,20.5,13.5,1
transfer_neq,8,5.3319513640959215e-06,7.450589978308386e-09,5.324500774117613e-06,True,True,20.5,13.5,1
transfer_neq,9,1.3926900000016396e-05,4.967061900673642e-09,1.3921932938115722e-05,True,True,20.5,13.5,1
transfer_neq,10,2.2683459353481372e-05,7.0366557441969846e-09,2.269049600922557e-05,True,True,20.5,13.5,1
transfer_neq,11,2.6366830318105827e-05,8.692339972804497e-09,2.6375522658078632e-05,True,True,20.5,14.5,1
transfer_neq,12,2.307753771932375e-05,1.0761948318616099e-08,2.3088299667642365e-05,True,True,20.5,14.5,1
transfer_neq,13,1.804053278801898e-05,6.6227364148296886e-09,1.804715552443381e-05,True,True,16.5,20.5,3
transfer_neq,14,1.3273871487681776e-05,3.725288785783043e-09,1.327759677646756e-05,True,True,17.5,20.5,3
transfer_neq,15,1.109810416584367e-05,1.7074248230553035e-09,1.1096396741020614e-05,True,True,20.5,20.5,5
transfer_neq,16,1.0547037354428218e-05,3.777030622292843e-09,1.0550814385050511e-05,True,True,20.5,20.5,5
transfer_neq,17,7.76073680465103e-06,1.5522043823879006e-09,7.762289009033418e-06,True,True,20.5,20.5,5
transfer_neq,18,6.477044739522375e-06,2.4835230261199825e-09,6.479528262548495e-06,True,True,16.5,3.5,4
transfer_neq,19,6.888961226400592e-06,4.553130164564045e-09,6.893514356565156e-06,True,True,16.5,3.5,4
transfer_neq,20,8.081834403372845e-06,1.6556842147297246e-09,8.080178719158115e-06,True,True,3.5,15.5,2
transfer_neq,21,9.19306995308955e-06,4.553133203799575e-09,9.19762308629335e-06,True,True,3.5,15.5,2
transfer_neq,22,9.90222802181584e-06,1.241762831449833e-09,9.90346978464729e-06,True,True,3.5,15.5,2
transfer_neq,23,9.820215213826589e-06,3.725291089495819e-09,9.823940504916084e-06,True,True,3.5,16.5,2
transfer_neq,24,9.034586770997888e-06,6.208816516473092e-09,9.028377954481415e-06,True,True,3.5,17.5,2
1 metric time signal baseline absolute any_crossed peak_crossed x y q
2 coarse_interface_u 1 0.0 0.0 0.0 False False 3.5 3.5
3 coarse_interface_u 2 0.0 2.63417801721126e-09 2.63417801721126e-09 False False 3.5 3.5
4 coarse_interface_u 3 0.0 2.63417801721126e-09 2.63417801721126e-09 False False 3.5 3.5
5 coarse_interface_u 4 0.0 6.585443742795605e-08 6.585443742795605e-08 False False 3.5 3.5
6 coarse_interface_u 5 0.0 1.2644051067663912e-07 1.2644051067663912e-07 False False 3.5 3.5
7 coarse_interface_u 6 2.123413592043705e-07 1.4528626697542904e-07 3.5762762617979955e-07 False False 20.5 12.5
8 coarse_interface_u 7 4.0664670353703905e-06 2.0116559817931723e-07 4.267265792606936e-06 True True 20.5 13.5
9 coarse_interface_u 8 2.316397368189694e-05 1.5646213891164667e-07 2.3320343327342335e-05 True True 20.5 13.5
10 coarse_interface_u 9 6.795742008554701e-05 1.5646213891164667e-07 6.81138583592495e-05 True True 20.5 13.5
11 coarse_interface_u 10 0.00013453387391202865 9.750014426779573e-08 0.00013463070833560589 True True 20.5 13.5
12 coarse_interface_u 11 0.00020315493961354394 1.1795114315203827e-07 0.00020326776624343072 True True 20.5 13.5
13 coarse_interface_u 12 0.0002578325145358002 7.455233297611785e-08 0.00025790659921174714 True True 20.5 14.5
14 coarse_interface_u 13 0.0002848355625376438 3.83541997932092e-08 0.0002848672209318115 True True 20.5 14.5
15 coarse_interface_u 14 0.00028850325159438407 3.003423681142711e-08 0.00028847339892346693 True True 20.5 15.5
16 coarse_interface_u 15 0.0002790426599299092 6.516592454722021e-08 0.00027900289954439403 True True 20.5 16.5
17 coarse_interface_u 16 0.0002656231695763881 1.006517304071618e-07 0.0002656687325338991 True True 20.5 17.5
18 coarse_interface_u 17 0.00025167224259872663 9.86322156278415e-08 0.00025171418857411254 True True 20.5 18.5
19 coarse_interface_u 18 0.00023917435962541014 1.0286787296380317e-07 0.00023916330914968713 True True 20.5 19.5
20 coarse_interface_u 19 0.0002264648202014007 7.783088195871973e-08 0.00022649832134267317 True True 20.5 20.5
21 coarse_interface_u 20 0.00021450009842274482 8.503127640307697e-08 0.0002145262119900782 True True 20.5 20.5
22 coarse_interface_u 21 0.00019565444290966713 7.893743237430962e-08 0.00019572665753668725 True True 20.5 20.5
23 coarse_interface_u 22 0.00017530342242023255 5.2749351285234925e-08 0.0001753561669734725 True True 20.5 20.5
24 coarse_interface_u 23 0.00016284198169591366 8.178685339035058e-08 0.00016288798599953632 True True 20.5 14.5
25 coarse_interface_u 24 0.00016001299284349154 6.715860617082587e-08 0.00016005458983486885 True True 20.5 14.5
26 coarse_bulk_u 1 0.0 0.0 0.0 False False 0.5 0.5
27 coarse_bulk_u 2 0.0 0.0 0.0 False False 0.5 0.5
28 coarse_bulk_u 3 0.0 0.0 0.0 False False 0.5 0.5
29 coarse_bulk_u 4 0.0 0.0 0.0 False False 0.5 0.5
30 coarse_bulk_u 5 0.0 0.0 0.0 False False 0.5 0.5
31 coarse_bulk_u 6 0.0 0.0 0.0 False False 0.5 0.5
32 coarse_bulk_u 7 9.685747920378016e-08 2.12341462371735e-07 3.0919894157551517e-07 False False 21.5 12.5
33 coarse_bulk_u 8 1.885523449607647e-06 2.458690369633922e-07 2.131116250194691e-06 True False 21.5 13.5
34 coarse_bulk_u 9 1.1801222962468464e-05 1.564621179284487e-07 1.1957591962850096e-05 True True 21.5 13.5
35 coarse_bulk_u 10 3.7763148161723895e-05 1.0327184058071679e-07 3.786536052602384e-05 True True 21.5 13.5
36 coarse_bulk_u 11 8.290997527773004e-05 4.214683516511236e-08 8.293984645156337e-05 True True 21.5 13.5
37 coarse_bulk_u 12 0.00013975592467875463 5.890198697622995e-09 0.00013975397806857782 True True 21.5 13.5
38 coarse_bulk_u 13 0.00019498935130707817 4.806920811870088e-08 0.00019495727755690072 True True 21.5 14.5
39 coarse_bulk_u 14 0.00023699059195898703 3.215422633434082e-08 0.00023698211801486242 True True 21.5 14.5
40 coarse_bulk_u 15 0.000255587117158192 3.434546877545681e-08 0.0002555629409290573 True True 21.5 14.5
41 coarse_bulk_u 16 0.00025699080829703886 0.0 0.00025699080829703886 True True 21.5 15.5
42 coarse_bulk_u 17 0.00024815159847585574 6.606481633104396e-08 0.0002482080995082901 True True 21.5 16.5
43 coarse_bulk_u 18 0.00023639704637690832 6.929437569595666e-08 0.00023645799303108044 True True 21.5 17.5
44 coarse_bulk_u 19 0.00022522644482484474 1.0390817551817351e-07 0.00022530812767909556 True True 21.5 19.5
45 coarse_bulk_u 20 0.0002151574621150763 1.042082306083734e-07 0.00021524519922552202 True True 22.5 18.5
46 coarse_bulk_u 21 0.00020618043430475382 9.442706670805767e-08 0.00020625960942046836 True True 21.5 20.5
47 coarse_bulk_u 22 0.0001977039381507293 5.556802130737047e-08 0.00019775833634301496 True True 22.5 20.5
48 coarse_bulk_u 23 0.00018973381549205 4.4703464263670685e-08 0.00018970107840731907 True True 22.5 21.5
49 coarse_bulk_u 24 0.00018031585591623997 9.995996742145265e-08 0.0001802207328329628 True True 22.5 22.5
50 fine_band_neq 1 0.0 3.000928300994632e-09 3.000928300994632e-09 False False 4.25 4.25
51 fine_band_neq 2 0.0 4.501393077727123e-09 4.501393077727123e-09 False False 4.25 4.25
52 fine_band_neq 3 0.0 2.069606169774474e-08 2.069606169774474e-08 False False 4.25 4.25
53 fine_band_neq 4 0.0 4.1392115429639276e-09 4.1392115429639276e-09 False False 4.25 4.25
54 fine_band_neq 5 0.0 4.1392115429639276e-09 4.1392115429639276e-09 False False 4.25 4.25
55 fine_band_neq 6 3.8661114470928126e-07 9.934099098884985e-09 3.766770456103963e-07 True True 19.75 13.25
56 fine_band_neq 7 2.0898831959437203e-06 9.934099098884985e-09 2.0799490968448353e-06 True True 19.75 13.25
57 fine_band_neq 8 5.086951299526632e-06 9.934099098884985e-09 5.077017200427747e-06 True True 19.75 13.75
58 fine_band_neq 9 7.3187303596400355e-06 1.1589783133203468e-08 7.307140576506832e-06 True True 19.75 14.25
59 fine_band_neq 10 7.498180437826019e-06 9.106256526614231e-09 7.489074181299404e-06 True True 19.75 15.25
60 fine_band_neq 11 6.85740365241605e-06 5.794905943989903e-09 6.86319855836004e-06 True True 19.75 17.25
61 fine_band_neq 12 6.20376639004494e-06 6.622735776451449e-09 6.200455026694751e-06 True True 19.75 18.25
62 fine_band_neq 13 5.366229072267803e-06 4.139212333997833e-09 5.369540443278531e-06 True True 19.75 19.25
63 fine_band_neq 14 5.300103189165295e-06 4.967056432825245e-09 5.30507024559812e-06 True True 19.75 19.75
64 fine_band_neq 15 4.0156351262532475e-06 4.553132745832578e-09 4.018946498263176e-06 True True 19.75 19.75
65 fine_band_neq 16 3.7773208383384826e-06 6.622738135675377e-09 3.783943576474158e-06 True True 19.75 16.75
66 fine_band_neq 17 3.59763095919563e-06 6.622736969941201e-09 3.598458797438031e-06 True True 19.75 17.75
67 fine_band_neq 18 3.1864885083332517e-06 1.7384672978959514e-08 3.2038731813122112e-06 True True 19.75 18.75
68 fine_band_neq 19 3.2079558324737967e-06 9.934106745546067e-09 3.2054722903795962e-06 True True 19.75 19.75
69 fine_band_neq 20 3.2478981990546885e-06 8.278412177986638e-09 3.256176611232675e-06 True True 19.75 19.75
70 fine_band_neq 21 2.8408409309954585e-06 1.1589792486832451e-08 2.83256250521724e-06 True True 19.75 19.75
71 fine_band_neq 22 2.2599308021065134e-06 1.241763983306221e-09 2.2599308009962904e-06 True True 19.75 19.75
72 fine_band_neq 23 1.7067130013148635e-06 2.0696062086322797e-09 1.7075408424993554e-06 True True 19.75 19.75
73 fine_band_neq 24 1.7691307190870198e-06 7.864502313270627e-09 1.768302879068262e-06 True True 4.25 8.25
74 transfer_neq 1 0.0 1.5004641487625925e-09 1.5004641487625925e-09 False False 3.5 3.5 6
75 transfer_neq 2 0.0 3.000928290586291e-09 3.000928290586291e-09 False False 3.5 3.5 6
76 transfer_neq 3 0.0 3.000928290586291e-09 3.000928290586291e-09 False False 3.5 3.5 6
77 transfer_neq 4 0.0 6.881438113781613e-09 6.881438113781613e-09 False False 3.5 3.5 6
78 transfer_neq 5 0.0 6.467520081987477e-09 6.467520081987477e-09 False False 3.5 3.5 6
79 transfer_neq 6 4.801482146599145e-08 1.7384695072397705e-08 3.063012639359375e-08 False False 20.5 12.5 1
80 transfer_neq 7 9.917490157301811e-07 1.4901174696935193e-08 9.76847841033246e-07 True True 20.5 13.5 1
81 transfer_neq 8 5.3319513640959215e-06 7.450589978308386e-09 5.324500774117613e-06 True True 20.5 13.5 1
82 transfer_neq 9 1.3926900000016396e-05 4.967061900673642e-09 1.3921932938115722e-05 True True 20.5 13.5 1
83 transfer_neq 10 2.2683459353481372e-05 7.0366557441969846e-09 2.269049600922557e-05 True True 20.5 13.5 1
84 transfer_neq 11 2.6366830318105827e-05 8.692339972804497e-09 2.6375522658078632e-05 True True 20.5 14.5 1
85 transfer_neq 12 2.307753771932375e-05 1.0761948318616099e-08 2.3088299667642365e-05 True True 20.5 14.5 1
86 transfer_neq 13 1.804053278801898e-05 6.6227364148296886e-09 1.804715552443381e-05 True True 16.5 20.5 3
87 transfer_neq 14 1.3273871487681776e-05 3.725288785783043e-09 1.327759677646756e-05 True True 17.5 20.5 3
88 transfer_neq 15 1.109810416584367e-05 1.7074248230553035e-09 1.1096396741020614e-05 True True 20.5 20.5 5
89 transfer_neq 16 1.0547037354428218e-05 3.777030622292843e-09 1.0550814385050511e-05 True True 20.5 20.5 5
90 transfer_neq 17 7.76073680465103e-06 1.5522043823879006e-09 7.762289009033418e-06 True True 20.5 20.5 5
91 transfer_neq 18 6.477044739522375e-06 2.4835230261199825e-09 6.479528262548495e-06 True True 16.5 3.5 4
92 transfer_neq 19 6.888961226400592e-06 4.553130164564045e-09 6.893514356565156e-06 True True 16.5 3.5 4
93 transfer_neq 20 8.081834403372845e-06 1.6556842147297246e-09 8.080178719158115e-06 True True 3.5 15.5 2
94 transfer_neq 21 9.19306995308955e-06 4.553133203799575e-09 9.19762308629335e-06 True True 3.5 15.5 2
95 transfer_neq 22 9.90222802181584e-06 1.241762831449833e-09 9.90346978464729e-06 True True 3.5 15.5 2
96 transfer_neq 23 9.820215213826589e-06 3.725291089495819e-09 9.823940504916084e-06 True True 3.5 16.5 2
97 transfer_neq 24 9.034586770997888e-06 6.208816516473092e-09 9.028377954481415e-06 True True 3.5 17.5 2
@@ -0,0 +1,170 @@
{
"speed": 0.002,
"initial_leaf": [
560.7500041779131,
0.0,
0.0
],
"final_leaf": [
560.8438616539352,
0.014835720416158438,
0.012527641374617815
],
"raw_residual": [
0.0002896524965763092,
8.014030754566193e-06,
4.828907549381256e-06
],
"exact_average_residual": [
0.00028958916664123535,
7.874332368373871e-06,
4.7245994210243225e-06
],
"cumulative": {
"boundary": [
0.09356788685545325,
0.014827846083790064,
0.01252291677519679
],
"fine_transfer": [
-0.0672332551330328,
-0.01191190630197525,
-0.010114157572388649
],
"coarse_transfer": [
0.06723319180309772,
0.011911766603589058,
0.010114053264260292
],
"rounding": [
0.0002896524965763092,
8.014030754566193e-06,
4.828907549381256e-06
],
"average": [
-6.332993507385254e-08,
-1.3969838619232178e-07,
-1.043081283569336e-07
]
},
"checks": {
"validity": true,
"geometry_unchanged": true,
"boundary_count": 48,
"collision_count": 72,
"local_collision": true,
"local_regime": true,
"bfl": true,
"transfer_rounding": true,
"interval_closure": true,
"cumulative_closure": true,
"propagation": true,
"drive_sign": true
},
"max_collision_ratio": 0.5696050037738337,
"max_collision_error": 1.5865499780609582e-07,
"max_bfl_error": 1.2725840020655355e-08,
"max_interval_closure": 0.0,
"drive_mass": 0.07436401406617413,
"propagation": {
"coarse_interface_u": {
"threshold": 1e-06,
"baseline_factor": 10,
"first_arrival": {
"time": 7,
"signal": 4.0664670353703905e-06,
"baseline": 2.0116559817931723e-07,
"absolute": 4.267265792606936e-06,
"x": 20.5,
"y": 13.5
},
"peak": {
"metric": "coarse_interface_u",
"time": 14,
"signal": 0.00028850325159438407,
"baseline": 3.003423681142711e-08,
"absolute": 0.00028847339892346693,
"any_crossed": true,
"peak_crossed": true,
"x": 20.5,
"y": 15.5
}
},
"coarse_bulk_u": {
"threshold": 1e-06,
"baseline_factor": 10,
"first_arrival": {
"time": 8,
"signal": 1.1069172403255332e-06,
"baseline": 1.005827957173589e-07,
"absolute": 1.2074577299858699e-06,
"x": 13.5,
"y": 21.5
},
"peak": {
"metric": "coarse_bulk_u",
"time": 16,
"signal": 0.00025699080829703886,
"baseline": 0.0,
"absolute": 0.00025699080829703886,
"any_crossed": true,
"peak_crossed": true,
"x": 21.5,
"y": 15.5
}
},
"fine_band_neq": {
"threshold": 1e-07,
"baseline_factor": 10,
"first_arrival": {
"time": 6,
"signal": 3.8661114470928126e-07,
"baseline": 9.934099098884985e-09,
"absolute": 3.766770456103963e-07,
"x": 19.75,
"y": 13.25
},
"peak": {
"metric": "fine_band_neq",
"time": 10,
"signal": 7.498180437826019e-06,
"baseline": 9.106256526614231e-09,
"absolute": 7.489074181299404e-06,
"any_crossed": true,
"peak_crossed": true,
"x": 19.75,
"y": 15.25
}
},
"transfer_neq": {
"threshold": 1e-07,
"baseline_factor": 10,
"first_arrival": {
"time": 7,
"signal": 9.917490157301811e-07,
"baseline": 1.4901174696935193e-08,
"absolute": 9.76847841033246e-07,
"q": 1,
"x": 20.5,
"y": 13.5
},
"peak": {
"metric": "transfer_neq",
"time": 11,
"signal": 2.6366830318105827e-05,
"baseline": 8.692339972804497e-09,
"absolute": 2.6375522658078632e-05,
"any_crossed": true,
"peak_crossed": true,
"q": 1,
"x": 20.5,
"y": 14.5
}
}
},
"raw_minus_zero": [
6.053410470485687e-05,
2.1085143089294434e-06,
9.126961231231689e-07
]
}
@@ -0,0 +1,2 @@
/home/frank14f/anaconda3/envs/pycuda_3_10/bin/python /home/frank14f/CelerisLab/research/fine_surface_joint_20261014/runner.py
Child command, explicit environment, fresh resource preflight and actual exit are stored in gpu_run.json.
@@ -0,0 +1,110 @@
FROZEN BEFORE GPU — bounded fine-surface/interface validation, 2026-10-14
Scope: exactly three independent trajectories speed=0,+.002,-.002, each24
coarse/48fine steps, same physical time[0,24]. No other GPU tests, extensions,
parameter sweeps or time extensions. Read-only hook instrumentation of normal
production build, no audit macro and no stepping/formula changes.
Geometry: periodic24x24 coarse domain; patch edge bounds[4,20)x[4,20);
fine40x40 including4halo; origin edge(2,2); fine dx=dt=.5; coarse dx=dt=1.
Circle physical center(12.25,12.25),radius2.15 => fine integer center(20,20),R4.3.
Stationary solid; surface angle.7rad,half_width.85rad,C1 amplitude0,+/-.002.
nu_coarse=.05,tau_coarse=.65,tau_fine=.8; unforcedD2Q9SRT,FP32,unshiftedDB.
Initial rho1,u0,Q-major postcollision equilibrium, same FP32 initial populations.
All initial sources and device omega are checked. Actual package path must be
/home/frank14f/CelerisLab/src. The preserved old tests are not changed or run.
Validity at every fine/coarse hop and publication:
All valid fluid leaves finite, density(.9,1.1) and |u|<.05 in local collision
oracle validity regime. Fine solids and outermost2halo after each fine hopNaN;
inner ghost exactly stream-only including legitimate directionalNaNs.
Published fine ghost/solid and coarse coveredNaN. Geometry and flags unchanged.
Propagation definitions (strict >; horizons and masks never adjusted):
- Fine band: fine active fluid nodes with any D2Q9 nonrest neighbor outside
geometric active patch, excluding solid boundaries.
- Coarse interface: uncovered receiver cells of actual coalescence map.
- Coarse bulk: ALL uncovered coarse fluid except that interface receiver set.
- Transfer neq: actual replaced q component of the full reconstructed coarse
incoming vector minus FP64feq(rho,u) of that same incoming vector, BEFORE
coarse collision. Do not form full macros from partly valid ghost children.
- Fine band neq: postcollision g minus FP64 equilibrium from its own macros.
- Velocities: FP64 moments of published postcollision g / rho.
- Physical coordinate coarse(I+.5,J+.5);fine(2+.5*(i+.5),2+.5*(j+.5)).
Interface transfer and publication sampled at integer physical t=1..24.
Boundary substeps at t=n-.5,n; no claim of sub-integer arrival resolution.
- At each same point/q,time,phase compare driven and ZERO trajectory:
velocity norm difference>1e-6 AND >10*zero velocity norm;
neq absolute difference>1e-7 AND >10*abs(zero neq).
Fine-band criterion uses maxq at each node for BOTH signal/baseline; this
conservatively requires excess over the largest zero neq at that node.
- For BOTH signs, all4 metrics (fine-band neq, actual-transfer neq,
coarse-interface velocity, coarse-bulk velocity) must cross by24 or FAIL.
Record each first qualified sample and global peak's time,physicallocation,
baseline,absolutevalue,signal; per-step maxima and qualifying flag retained.
These are aligned signal witnesses, not necessarily the same node/direction.
This tests startup distribution/macroscopic propagation, possibly acoustic;
not established jet advection, physical accuracy or shear-only transmission.
Ledger (M maps9populations to mass,px,py; area weights coarse1,fine1/4):
L_n=M(sum coarse leaves+1/4 sum fine fluid leaves), FP64 accumulation.
Each of48fine hops individually captures pre-BFL and staged BFL populations.
B_h=1/4 M(actual solid-to-fluid arrivals minus fluid-to-solid departures).
F_h=1/4 M(actual ghost-to-fluid arrivals minus fluid-to-ghost departures).
B_n=B_h1+B_h2; F_n=F_h1+F_h2. No using latest buffer as two-hop sum.
C_n=M(actual reconstructed coarse incoming minus previous coarse leaves),
including periodic native streaming, all replacement links and8grazingcorners.
Coarse incoming constructed from independent physical midpoint map; compare
all target/source slots to actual tables. avg32=.25*((a+b)+c+d) inFP32.
RAW_n=L_n-L_(n-1)-B_n-F_n-C_n; cumulative raw uses same initial/final leaves.
Report RAW and driven-minus-zero RAW FIRST, never call them corrected to zero.
Source-based rounding decomposition and separate fixed checks:
1. Each fine/coarse collision: reconstruct actual FP32 input using pure pull
and avg32 where applicable. Independently evaluate FP64 SRT at the actual
device FP32omega, verifying omega against tau and force=0.
Every q,node must obey |GPUout-SRT64(input)| <= 8*eps32*|input_q|.
This fixed local, near-rest acceptance bound reflects short FP32 rho/macro/
feq/FMA path and fast-math compilation; it is not a general roundoff theorem.
Report max absolute error and max normalized ratio, and fail if ratio>1.
Cround = weighted sum M(GPUout-input) measured LOCALLY, independently of L
or RAW. Record FP64 ideal moment defect and measured GPUout-ideal separately.
Arbitrary collision error cannot be excused solely by global closure.
2. Transfer Tround=M(avg32-avg64exact), computed independently from actual4
children. Require each slot <=gamma3*sum|children|/4, u=eps32/2,
gamma3=3u/(1-3u); exact power-of-two scaling in this normal positive regime.
avg32 already in C_n, so DO NOT subtract Tround a second time.
Also report RAW_exact_average=RAW+Tround to expose this source explicitly.
3. BFL local oracle abs error<=1e-7, actual active cells unchanged.
4. |RAW_n-Cround_n|<=1e-10 componentwise per interval;
|sum RAW-sum Cround|<=1e-9 cumulative. These are FP64 bookkeeping bounds,
NOT a physical-conservation/accuracy test. No broad eps*whole-domain
accumulated budget used to label raw conservation as passing.
5. Both driven cases' cumulative actual-minus-passive-oracle boundary mass
has same sign as specified normal speed. BFL passive evaluated on same
actual populations; not another trajectory and not a conservation fix.
Saved data: pertrajectory24ledger rows,72local collision rows,48fine boundary
rows; small compressed diagnostic signals for reproducible zero comparisons;
no full-field populations. Per-step link_exchange_GPU also saved separately:
latest fine Fx,Fy scaled1/4; torque scaled1/8 for physical lever length. These
body momentum diagnostics differ from fluid mass exchange and are NOT thrust
or exchange rate. A fine-hop fluid exchange rate is B_h/.5; the coarse interval
rate is (B_h1+B_h2)/1, numerically equal to interval sum only because dt_c=1.
Do not equate B_h2/latest with two-hop interval sum.
No post-result tolerance/formula/window changes, retries or added steps to
chase PASS. Preserve errors with real stdout/exit. Report precise unmet checks.
Resource guards: fresh physicalGPU0UUID/apps/VRAM/RAM, onlyGPU0ifidle; no
other task interference; 180secondwalltimeout; current available RAM reserve
max(4GiB,10%),VRAM reserve max(512MiB,10%), own temporary+evidence<=2GB.
Sample own process group RSS, no fixed address-space/RSS cap; remove only owned
scratch. Every text artifact<=40000characters. Hash criteria/script/source at
freeze then verify before launch; preserve all previous dirty/evidence.
Reference trace: accepted local tests/test_fine_surface_gpu.py BFL/flux hooks;
refinement.cu actual two fine hops and coalesce order; macro.cuh and
collision_srt.cuh actual FP32 collision path; compiler_v2.py --use_fast_math.
Previously accepted OpenLB defineU2D.hh74-79/offBoundaryPostProcessors2D.hh115-127
remain BFL hit/stencil reference; no new CFD formula or borrowed code.
Production change limited to one coordinate-frame documentation sentence.
@@ -0,0 +1,105 @@
{
"frozen_utc": "2026-10-14T05:55:03.221284+00:00",
"hashes": {
"src/CelerisLab.egg-info/PKG-INFO": "0b9a8a4e8d60bc531473688723ddef0aab02c7ccc4997e31c9b6a6c35011ca77",
"src/CelerisLab.egg-info/top_level.txt": "cd51958ca03afabbaa9618c60b8280e486f8cc0b0359b839e10f886e7c3948f8",
"src/CelerisLab.egg-info/dependency_links.txt": "01ba4719c80b6fe911b091a7c05124b64eeece964e09c058ef8f9805daca546b",
"src/CelerisLab.egg-info/requires.txt": "36e1404178e5ea590b2fc04e8ba4d748ec9a82e7693136ccf0dfd204fe265c04",
"src/CelerisLab.egg-info/SOURCES.txt": "f36b29c1b34c4bd6b2acc3ccdd21c24ee5077df7e2a20a652d9fae77eedb8e21",
"src/CelerisLab/simulation.py": "c9d903f53fe356d7af281bea07943de1a62494127fb69848d7053fd46f7dec3e",
"src/CelerisLab/config.py": "2f1bba7515f5bc08cb3a8d140bcafe7fa0689e01b3b06494697bb2956a71530e",
"src/CelerisLab/__init__.py": "21cc469bd6e970a1f9ff5970c8eea4602065e41fc881854759ee565ee55c10c6",
"src/CelerisLab/cuda/compiler_v2.py": "c4cc3ec4445c8d75e6a253dd87963877117a722bc73b9d4811806fc6045d08c1",
"src/CelerisLab/cuda/obs_layout.py": "5ffb2c3aeeaaaaeb64f2cd8febfbcf4ad9919e5414020ad753cfade0683b21c2",
"src/CelerisLab/cuda/context.py": "013dd4ec6d01d2fbd11afdfb103eac6a273bd9f798d663d761b851eeb27885e9",
"src/CelerisLab/cuda/__init__.py": "0d01dff9f0399c8baba822aab5ca0122a135f011008ed8a499ebd9f7e5b06aea",
"src/CelerisLab/lbm/refinement_stepper.py": "6aad7f66e4288e293b30b2f9712202447686f263fab41150f5d919cc64328d06",
"src/CelerisLab/lbm/field.py": "0e727eacc3706add4d8d15c418e9b631050871f831698d3ac689dd5f2c701b9b",
"src/CelerisLab/lbm/equilibrium.py": "2fb2f2bb7ff326d23abce80fc2a4c0907b17740ea3e29fe6ae079c5044783826",
"src/CelerisLab/lbm/descriptors.py": "c9f025dfc14da43b989047b84cc22bd05d5cc92c9ec695c1da68fdfb788e3f2b",
"src/CelerisLab/lbm/initializers.py": "dacf9586963e862d6d0a98ef1a066036be6f91e9d423720661d8ef2c1fb2df6a",
"src/CelerisLab/lbm/curved_links.py": "00d9c29d660b41190f32dd737b12f60e10ce4214b6c9a6ab2a63438813faa594",
"src/CelerisLab/lbm/stepper.py": "0dcb7cd7ae87e33e3dc67a38b6aa43042fbe673e37d9ad165342ee1d695933ce",
"src/CelerisLab/lbm/__init__.py": "7f60fb3aaae81501b510d08c2fedff44fcb05657260eb10b6f5cc91e7204306b",
"src/CelerisLab/lbm/refinement.py": "8935b070ec9e7020897919c15f43f7fa6293f02e2ff64a19a3e3d99bc444dbcc",
"src/CelerisLab/lbm/kernels/kernel_v2.cu": "c7bd3fb705b77261ba2441c52a24a7e6a7865c165cba088a1b75201c4d29c408",
"src/CelerisLab/lbm/kernels/refinement.cu": "129f3d91da93b4324f88a0da73a4da1e5390f72c14cce574ee63306712da9895",
"src/CelerisLab/lbm/kernels/config.h": "7d1124125e0b354558297934460e64c760fb68cdd7bf6d01a1238bb2eaab8c37",
"src/CelerisLab/lbm/kernels/kernel_v2.ptx": "a599ee30ae66800f4d4220eb79dfed35ff32991661260f01ea58023ef780f0ca",
"src/CelerisLab/lbm/kernels/operators/turbulence_smag.cuh": "ff7f000297ee0817e255ad9fcb6a13b647e3ddd5b206518d35f38d2895a9f501",
"src/CelerisLab/lbm/kernels/operators/collision_mrt.cuh": "aee444eb60c47a3fd518dca975d1af05425a0818a0ec6c3fb3f6150f60c2cb44",
"src/CelerisLab/lbm/kernels/operators/collision_trt.cuh": "9725b9840b9ad8b4ec7be61ff5d06d3151e86d1a87585c13f2fbf934d0d2c5f6",
"src/CelerisLab/lbm/kernels/operators/collision_srt.cuh": "6b7ff842f392c8f853d2d1a97cc69bfe50f21283f73e659404da07cf6c95f5e1",
"src/CelerisLab/lbm/kernels/operators/forcing_guo.cuh": "969a430c1af03f32e3bd0df95d805e64f56334717c44dd4ba208ba503062a24b",
"src/CelerisLab/lbm/kernels/operators/macro.cuh": "e27c1c410dc857be98da4596568e405eeaf88701d291ac0e398aa9cd23dee740",
"src/CelerisLab/lbm/kernels/operators/helpers.cuh": "0b3a4d95d7d19f5fec09e5423b8f4cc99f8a226b541967425967330da5a051ec",
"src/CelerisLab/lbm/kernels/core/precision.cuh": "849df14b4cce50af52399e4b8f3e997196f3ae5f1163f68e28df3e6b2507a8c4",
"src/CelerisLab/lbm/kernels/core/descriptors.cuh": "8440bc14857da9007982650f828a23608eec9f7cc4bf772e8c8dc1239cb45356",
"src/CelerisLab/lbm/kernels/core/obs.cuh": "b742b77c9f61e1f020fe9922c3838ae9d855e17b381154958b58f10a22938922",
"src/CelerisLab/lbm/kernels/core/params.cuh": "6e18bf730d936d940e3d85452f0714a2eaae31bf41002f9fd520ec5b372878dd",
"src/CelerisLab/lbm/kernels/core/flags.cuh": "0025705f24710330d9d9195f713879bfb650a85a3449baef0e196b831af104ab",
"src/CelerisLab/lbm/kernels/core/layout.cuh": "1fbd820021c89ac3efcde24145996cb0147769e607e498e61f308ed3e0b13706",
"src/CelerisLab/lbm/kernels/boundary/ibm_kernels.cuh": "e6909b547dc8d64cdd8a76a90660243a8f5fee535caa161b52b4dd8b7c29934b",
"src/CelerisLab/lbm/kernels/boundary/planar_velocity.cuh": "0b2f9e0bd483c199637e5672dc0ffc460bc383dd1804805befbeb4c5d8c708d1",
"src/CelerisLab/lbm/kernels/boundary/inlet_outlet.cuh": "de8b213a6da42c2e5e9f8966199fc66ea4541b85144a90f3f5dbad3c6ab63b97",
"src/CelerisLab/lbm/kernels/boundary/curved_boundary.cuh": "7bccf7e7091c012d7a3d4874a881d4d46699021faedd83d125933fbdaa562711",
"src/CelerisLab/lbm/kernels/boundary/bounce_back.cuh": "aba3748c564ed91b161d268ef8b737b7c7be96a823063d201f3da684dd845233",
"src/CelerisLab/lbm/kernels/boundary/esopull_curved_helpers.cuh": "b9b474bc4edaff05681c5443235472d04072d0d775fc0eb9c5967faef52b0258",
"src/CelerisLab/lbm/kernels/boundary/inlet/equilibrium.cuh": "f0964c811b2c41a5aaa1c6d99c490b06e850c634eb8749f1f05ef61f93c2de1d",
"src/CelerisLab/lbm/kernels/boundary/inlet/channel_stabilized.cuh": "efe077afcbb6b731256a987c2fd79a1dbc470c902f87070d60421ea6cb13d4e2",
"src/CelerisLab/lbm/kernels/boundary/inlet/common.cuh": "f3cec54c8873c65b3dca4375605d2c89a8727765884d3954c235242fdff9c6ba",
"src/CelerisLab/lbm/kernels/boundary/inlet/zou_he_local.cuh": "e73e66b853b1e4e0e30d8f4185d832aa414ce670a1813ce2b5459f2887f71f89",
"src/CelerisLab/lbm/kernels/boundary/inlet/regularized.cuh": "943d4a571818bacb89c70bccfaac202691121e3e385803ce6309123a0a03ddaf",
"src/CelerisLab/lbm/kernels/boundary/outlet/pressure_neq.cuh": "c8b2adc66d12fe602076ddc9693c5c208711fcaddb58aa9a31401a269f51c4c4",
"src/CelerisLab/lbm/kernels/streaming/esopull_single_buffer.cuh": "77ed4ab9a0ebc5ff62a91a7c39066ef395391ae36e9040a69fb2bd8b1626dc79",
"src/CelerisLab/lbm/kernels/streaming/pull_double_buffer.cuh": "b65d741ed78b7b62f99531ba0c0ce1936663d8dc9640e7d7d16c707f1baf6549",
"src/CelerisLab/lbm/kernels/streaming/esopull_semantic_helpers.cuh": "dd5a9091628b079efd97e53fd49e52d09dcee88529235db77a5648e02937af6e",
"src/CelerisLab/lbm/kernels/step/curved_double.cu": "bfa7a1df1e939020314d49755045f7a85fe4a19cc1c68dbe62653c66c5e7c2b3",
"src/CelerisLab/lbm/kernels/step/esopull_sync.cu": "c0ff3e72900c3ab89a05dd03684e96d3b740cf1672d565727fc2af165933d087",
"src/CelerisLab/lbm/kernels/step/init_flow.cu": "305be3bb12fc0d039acec1701baabcf0e8a35e683c49c34f2af8ca9867d2b29c",
"src/CelerisLab/lbm/kernels/step/esopull_macro.cu": "c73116020ca217ede1e4de27c8269c31f9d91e33433ac8252a21e9b14187c50f",
"src/CelerisLab/lbm/kernels/step/aux_kernels.cu": "578a5b20a157241ee678547059abb1372dd5a589ad06bb2c15b987eb01ca1013",
"src/CelerisLab/lbm/kernels/step/one_step_esopull.cu": "aa223b2744ae6c9125673df311a96ce588032c1ba58bebb11fd33ecb990f8ed4",
"src/CelerisLab/lbm/kernels/step/one_step_double.cu": "f9f8242b38e8e0cf8425b75e2b0215bc15363c62eaa0fb43c761b8e0931bfdc9",
"src/CelerisLab/lbm/kernels/config/config_physics.h": "26df33c2960ba36f3283e19b55b4ea92e50e4efda705f9ebfbf3f875a4092c59",
"src/CelerisLab/lbm/kernels/config/config_method.h": "3db4e16ef2c6b22349d04e6aa8ab04bdfe0eb784f9f3a98277e15dbed1835d81",
"src/CelerisLab/lbm/kernels/config/config_grid.h": "8be3a7cf74ba30d7fd3074fed79e63dbda7311c4d03b454ea641bf298ffeaa8d",
"src/CelerisLab/lbm/kernels/config/config_objects.h": "dbb93c063586da278c15d95e23f84c12e728f4f5f1bbc3980fe9cedaa6fff90e",
"src/CelerisLab/lbm/kernels/config/config_obs.h": "c11e2249359145b5c4cbaaf0487506fa77c1f4b82c7c169ddc574aa0babcd727",
"src/CelerisLab/common/checkpoint.py": "b2f960aecd5ac27a3a7130b809ffad4709c44d522edef0359ab952654625410b",
"src/CelerisLab/common/_types.py": "aad2ff1a9033d4fd68783ad7123afb47201ddc58785cb6dc0246947037072a5f",
"src/CelerisLab/common/pathline.py": "a1b6efcc0a076d0f1dc8d49a595779426d7d5626b00072a59bac710ff02ad046",
"src/CelerisLab/common/__init__.py": "d4dbde78bc97fccc9eabac9abae8f0f15c112c10ff8e9b45bd9401d4723df1ef",
"src/CelerisLab/common/preprocess.py": "7fc78a08857cf8e98519500b094a1d896af189b6b15658ff9b388ed51bed4515",
"src/CelerisLab/common/render.py": "0e055476257eb2bcd11e733766e52195de02f8fad228f570a3511a7c831bdc29",
"src/CelerisLab/common/streakline/_render.py": "236cd637414ee318c4d66f9aed32110d8dc42a100d65fde06172f7cd0ba62c65",
"src/CelerisLab/common/streakline/_integrate.py": "3fbd4368b2c8d0e7fda40dc65aac5df02b085008b4c68acd83cb7ae45d33a13b",
"src/CelerisLab/common/streakline/_streakline.py": "1a3e08daa706b5f83cdeb337e9a945a36ddf7583c40af1d0bb9d825ac954df37",
"src/CelerisLab/common/streakline/__init__.py": "13ff1cfa416fdd721a08a659e76b5a5a99b8d3201add10a83b7b0bc654bc1eec",
"src/CelerisLab/common/streakline/_config.py": "a9185ef68e9c7b5d5a1dc0b04a28341e2ad91d13c145a7c106636a878cf0a605",
"src/CelerisLab/configs/config_lbm.json": "17e4311f1f250c6ece59177a8b6ff856b69a016c7c10267e774b030a0a390865",
"src/CelerisLab/configs/CONFIG.md": "41cafdbe525366c08aa9d0416ea026ccf0026ba7123b8a9b65f968a80d928e3a",
"src/CelerisLab/configs/config_lbm_three_cylinder_triangle.json": "eeb8e7149dbe4aa6b3a9562802735aa950750dfbe2d972a0727e788573afa817",
"src/CelerisLab/configs/config_lbm_flume_trt_regularized.json": "f4bba8e6a4339fc3c4eb14f6e2f57c4b22993c73703c773d853edfbe34736e56",
"src/CelerisLab/configs/config_body.json": "055f261f0828ca1d4f2bb694bd15b72bbcabe31d552326208f28e37f761adab1",
"src/CelerisLab/configs/config_lbm_flume_mrt_zouhe.json": "8f593321db05a563a42931603a228d61cbcba06dfbe113262d5cd0ad93c0fe79",
"src/CelerisLab/body/objects.py": "d1cf7054cc8379a83c39acc66a7c88ae62fa004f110bb0c1def2ee57137401c5",
"src/CelerisLab/body/action_smoother.py": "b1a23ee6bbd4850b172cb8738c5c3546ee465a54189e6af9d8044f023d4687dc",
"src/CelerisLab/body/registry.py": "fbb7327780adbdc6da15ebdb799980daf32df22ee974af0893d7409f177bbb68",
"src/CelerisLab/body/manager.py": "6a40be708c71ef6f3b5f5f0aa9c92cfafc51f2ec2a958f99656cccb850986c16",
"src/CelerisLab/body/ddf_patch.py": "60fcfb7441e73bf290bcff41ca3a83da3e7ddad765d7247464e8f02e3043b4e2",
"src/CelerisLab/body/sync_plan.py": "a73ac9ee361b2120d0b7bbebeaa2ccbf924ba27bd95d4dd4b383c10a39b2a409",
"src/CelerisLab/body/__init__.py": "91d1155080b3ade83d13c84c39693046df122e4bed5ef583de2df1f9453c1b76",
"src/CelerisLab/body/preprocess/flag_overlay.py": "831fc9e9736b758847759a085ff133eb49ec91318ace4fda76f85960138ee300",
"src/CelerisLab/body/preprocess/__init__.py": "dfd9d58bc07f626ab23a70053e31b88a6d9165d2e4c76a4e9f48abe674d3d2ec",
"src/CelerisLab/body/geometry/base.py": "cceca14361ca2f34d34a3e43730e1a79b8ca81be00f0dd62e884db32b479419f",
"src/CelerisLab/body/geometry/__init__.py": "ada88980ab672959aca9aa3a4c4aade3219524b2ab68110cd2a2f41e3e0ca90a",
"src/CelerisLab/body/geometry/circle.py": "7605ca7c21103f1d801ac73ab8dd18dffbdac425b2dee7b8858b283628a9e436",
"src/CelerisLab/body/coupling/soa_packer.py": "8ec26fd55ef74801bbd5ab6bd3d0a7dabc750cbd498aaac2ca4c61a0108ad3c9",
"src/CelerisLab/body/coupling/__init__.py": "c931f7eb318d48408c3e2febcc6917c88c8dcc1697cbf4329b1f340d94c35763",
"tests/validation/multigrid/test_fine_surface_gpu.py": "d45ca48fc4e77d021fcc5461329b094ae11b257c036bb23634d326fbbedb7700",
"research/fine_surface_joint_20261014/validate.py": "346f1223daa7ce1fb376be5e921fec5ad77c3a10992806d54ececdf199e7c3ea",
"research/fine_surface_joint_20261014/runner.py": "2e52a6fd8306c07415c82d9275e17d58e0597ebd9f1f45b3be81dcdb005d4737",
"research/fine_surface_joint_20261014/criteria.txt": "d80d6f1218b3db449ea9115fa701b9173bc866929e634e2a3b17278b65f0c256"
}
}
@@ -0,0 +1,39 @@
{
"start_utc": "2026-10-14T05:55:16.773509+00:00",
"command": [
"/home/frank14f/anaconda3/envs/pycuda_3_10/bin/python",
"/home/frank14f/CelerisLab/research/fine_surface_joint_20261014/validate.py"
],
"cwd": "/home/frank14f/CelerisLab",
"physical_gpu_uuid": "GPU-e8853ae7-a302-6a17-bcfa-aa767e9ed20c",
"note": "Sampled guards, not an OS hard isolation; no fixed RSS/AS cap.",
"preflight_gpu": "0, GPU-e8853ae7-a302-6a17-bcfa-aa767e9ed20c, Tesla V100-SXM2-16GB, 5, 16140, 0\n1, GPU-f1c9fd5a-e917-56e0-21fb-24035ba44a36, Tesla V100-SXM2-16GB, 5, 16140, 0\n2, GPU-b8c11c01-c91f-aa0b-abf6-dad35085cc76, Tesla V100-SXM2-16GB, 5, 16140, 0\n3, GPU-8b71b032-1b75-2891-935c-ce106a53034a, Tesla V100-SXM2-16GB, 5, 16140, 0\n",
"preflight_apps": "",
"preflight_ram_bytes": 64120958976,
"limits": {
"wall_seconds": 180,
"temp_bytes": 2000000000,
"ram_reserve_bytes": 6412095897,
"vram_reserve_MiB": 1614
},
"env": {
"PYTHONPATH": "/home/frank14f/CelerisLab/src",
"PYTHONNOUSERSITE": "1",
"PYTHONDONTWRITEBYTECODE": "1",
"OPENBLAS_NUM_THREADS": "1",
"CUDA_VISIBLE_DEVICES": "GPU-e8853ae7-a302-6a17-bcfa-aa767e9ed20c",
"CUDA_CACHE_DISABLE": "1",
"TMPDIR": "/tmp/celeris-joint24-5efo3_mj"
},
"frozen_sha256": "68fdac18ac1b4371c2a7856456c7cc5b6f360c5dde52d282c44a68237d74028d",
"peak_group_rss_bytes": 297836544,
"peak_temp_bytes": 2081386,
"min_ram_bytes": 63740788736,
"min_vram_free_MiB": 15826,
"termination_reason": null,
"postflight_gpu": "0, GPU-e8853ae7-a302-6a17-bcfa-aa767e9ed20c, Tesla V100-SXM2-16GB, 5, 16140, 0\n1, GPU-f1c9fd5a-e917-56e0-21fb-24035ba44a36, Tesla V100-SXM2-16GB, 5, 16140, 0\n2, GPU-b8c11c01-c91f-aa0b-abf6-dad35085cc76, Tesla V100-SXM2-16GB, 5, 16140, 0\n3, GPU-8b71b032-1b75-2891-935c-ce106a53034a, Tesla V100-SXM2-16GB, 5, 16140, 0\n",
"postflight_apps": "",
"exit_code": 0,
"elapsed_seconds": 9.595732301007956,
"scratch_removed": true
}
@@ -0,0 +1,10 @@
--- a/src/CelerisLab/lbm/refinement_stepper.py
+++ b/src/CelerisLab/lbm/refinement_stepper.py
@@ -39,6 +39,7 @@
velocities are in coarse lattice units (dx=dt=1). Independent local copies
are projected at fine cell centers. Their complete stencil must be active
and disjoint from the actual two-hop transfer footprint.
+ These use the edge/cell-center frame (coarse centers I+.5), whereas ordinary Simulation objects use the integer-node frame.
``initialize(coarse_g, fine_g)`` accepts physical Q-major (9,ny,nx) arrays
already in postcollision phase. It does not collide or build channel flags.
@@ -0,0 +1,38 @@
{
"baseline_files": 610,
"changed_previous_files": [
"src/CelerisLab/lbm/refinement_stepper.py"
],
"incremental_lines_added": 1,
"incremental_lines_deleted": 0,
"frozen_hashes_unchanged": true,
"frozen_file_count": 100,
"rows": {
"zero": {
"ledger": 24,
"collisions": 72,
"boundary": 48
},
"blow": {
"ledger": 24,
"collisions": 72,
"boundary": 48
},
"suction": {
"ledger": 24,
"collisions": 72,
"boundary": 48
}
},
"regions": {
"coarse_interface": 68,
"coarse_bulk": 252,
"fine_band": 124,
"transfer_slots": 196
},
"all_text_files_within_40000_chars": true,
"scratch_removed": true,
"temporary_before_copy_removed": true,
"review_complete": true,
"total_evidence_bytes_before_manifest": 936489
}
@@ -0,0 +1,138 @@
{
"baseline_00.json": {
"bytes": 21302,
"sha256": "24564bba03c0d0563a04a8ef41c2c66f272c2e23d3992694e032c436b3272985"
},
"baseline_01.json": {
"bytes": 26191,
"sha256": "1aa54afbe77b4db806ed852aa9166c6b098de8271318f33c1aec9dbca73fee00"
},
"baseline_02.json": {
"bytes": 22440,
"sha256": "4ad20625dd7be154983bd5e834b7d9c22a9bf103fbb821198d081efab9723229"
},
"baseline_03.json": {
"bytes": 8584,
"sha256": "c0296688fdb2e19634d4c82b389d3bfb5cc1c442e465fc35139cc5b1d6d47944"
},
"blow_boundary.csv": {
"bytes": 12536,
"sha256": "136c42ab6daab369f813681a55546da96b9280d918178a4b7ff03d0fd5847c72"
},
"blow_collisions.csv": {
"bytes": 19145,
"sha256": "229245407e1eb436867a6110b7b7487effeaa8dd73540d05f25288c01f5e8670"
},
"blow_ledger.csv": {
"bytes": 15977,
"sha256": "89d9a88147b9c609d15e06c98f279daf27060cc914acd53910e74e2b46108977"
},
"blow_propagation.csv": {
"bytes": 9714,
"sha256": "4c452e4bffaec594f8b9e17dc992a9106541d5b0d283e0a2725cdc040808b257"
},
"blow_signals.npz": {
"bytes": 221114,
"sha256": "a78440514365bdb6c2af5424f729d856446adf14c2728da471606e24e5f8ce9a"
},
"blow_summary.json": {
"bytes": 4113,
"sha256": "e5b574ba02848b88487bfaa64e934b4d07c598658f4012a71f014ea6d883c351"
},
"command.txt": {
"bytes": 232,
"sha256": "99d80134c654c9eca51ba107b49bc077dfe83c7ac6f40b85378ec0b308c260a7"
},
"criteria.txt": {
"bytes": 7480,
"sha256": "d80d6f1218b3db449ea9115fa701b9173bc866929e634e2a3b17278b65f0c256"
},
"frozen.json": {
"bytes": 11972,
"sha256": "68fdac18ac1b4371c2a7856456c7cc5b6f360c5dde52d282c44a68237d74028d"
},
"gpu_run.json": {
"bytes": 1955,
"sha256": "ff90cf37cf7e198cea3a26bc00a2fd905b3eb07e6dbc5028ee58c299977b8de7"
},
"incremental.diff": {
"bytes": 625,
"sha256": "b5e3f04adf67ccc9ac79dd2e33d7871ce3247e168783df355b1224bd2c8a0941"
},
"integrity.json": {
"bytes": 826,
"sha256": "1fb4e8332dee509528b2d18edcbf733d2d8e632c9635039def62c662b7b031e0"
},
"regions.json": {
"bytes": 27525,
"sha256": "f31c6d6723a10df5dbb14bff7758bdf321b1cc5a395cf0b6a169ff5f44d3c54d"
},
"report.txt": {
"bytes": 8207,
"sha256": "8a5643409f9d1796406d190fa533a2a0058acf2b3765d83606311ee385504fae"
},
"result.json": {
"bytes": 11442,
"sha256": "846fb625d15270a906cbcfd65df4202768929ff391507856a0fe31981d611cba"
},
"review.txt": {
"bytes": 2117,
"sha256": "d2e40a8eabe9b88e514a79eff6374a3abfe5f4db2e9a98f9a483dcbaa6464a4c"
},
"runner.py": {
"bytes": 5847,
"sha256": "2e52a6fd8306c07415c82d9275e17d58e0597ebd9f1f45b3be81dcdb005d4737"
},
"stdout.txt": {
"bytes": 19940,
"sha256": "81c8de698c6e141e734545df8dee063edc51829f339afb2bd15b1efa21482deb"
},
"suction_boundary.csv": {
"bytes": 12505,
"sha256": "7a92dd8bc5e94a0262d7b06e01c03a2c2b3f808bc611e4e27820671a5bda6d32"
},
"suction_collisions.csv": {
"bytes": 19173,
"sha256": "46d0dfaad18cb6bd988169c5a91f15bc6e7ba77e8444965361b8393fd7f86c9b"
},
"suction_ledger.csv": {
"bytes": 16208,
"sha256": "12c8118a4ef769565e1f89476d0860dc4b4f96bc1bcad995ed083eaa53e36085"
},
"suction_propagation.csv": {
"bytes": 9720,
"sha256": "2991ef8dbad2fa52b8382e24974782ea533ee233ad1833e1e3bdd78c3fdd4992"
},
"suction_signals.npz": {
"bytes": 220058,
"sha256": "44f593b3c0129b575fae00ea1bc0fdb14961a4bdf9491c7db0325acc4c682f8c"
},
"suction_summary.json": {
"bytes": 4126,
"sha256": "e2aa6da27b04a5432508c5ed440179a5075dedbd52c38478596f3248f3e8b53b"
},
"validate.py": {
"bytes": 19576,
"sha256": "346f1223daa7ce1fb376be5e921fec5ad77c3a10992806d54ececdf199e7c3ea"
},
"zero_boundary.csv": {
"bytes": 11491,
"sha256": "f9785fcb1bb68064675beb6240a78e23c34f5123219eb91bbe748211c5cb1f38"
},
"zero_collisions.csv": {
"bytes": 18915,
"sha256": "2496ccaeb9a1cf3cfed81ba412d9017b7eb9e375176551abe41572b9f09931cc"
},
"zero_ledger.csv": {
"bytes": 16051,
"sha256": "b86d46933a0193dcd7e681982406cc91f89e56d55ac57be0afa514b492e827db"
},
"zero_signals.npz": {
"bytes": 127958,
"sha256": "71a833a056f7370dc929d9c0d321dc0f83b2fd8b2894d14403f2f16d372297a0"
},
"zero_summary.json": {
"bytes": 1508,
"sha256": "facbe3d1568f80643ed7af3ebe93f076f9a3e0f7b1b90cb33e4b2fb27f6c25e9"
}
}
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,110 @@
2026-10-14 — fine surface + fixed patch:24粗步短联合验证
结果:仅运行0、+.002、-.002三条同时间轨迹,各24coarse/48fine、物理时间24;
唯一GPU批次exit0,全部预设局部算子、有效性、记账与传播检查通过,已停止。
这不是严格守恒、物理精度、成熟喷流、空间收敛或长期稳定性认证。
先报告未修正累计收支残差(质量、Px、Py;实际FP32 transfer账本):
零驱动 +2.2911839187e-4 +5.9055164456e-6 +3.9162114263e-6
正吹 +2.8965249658e-4 +8.0140307546e-6 +4.8289075494e-6
负吸 +3.3393828198e-4 +2.1932646632e-7 +2.6496127248e-7
相对零驱动的原始残差差值(不是修正后的守恒量):
正吹 +6.0534104705e-5 +2.1085143089e-6 +9.1269612312e-7
负吸 +1.0481989011e-4 -5.6861899793e-6 -3.6512501538e-6
零驱动本身有FP32累计漂移,不能把bitwise非零视为传播,也不能把舍入后闭合0
说成原始残差为0。正吹/负吸的原始质量残差分别约占实际边界净质量交换的
0.310%/0.357%;扣同时间零驱动基线后的差值分别约占0.0647%/0.1122%。
这里只报告比例,没有事后以这些比例新增通过判据。
传播证据(两驱动同样的首次达标时间和物理坐标;时间以整数粗步采样):
量 首次t/位置 正吹差值 负吸差值
fine接口内侧post-G neq 6 /(19.75,13.25) 3.86611e-7 3.73349e-7
真实transfer arrival neq 7 /(20.5,13.5),q1 9.91749e-7 1.00666e-6
coarse接收圈post-G速度 7 /(20.5,13.5) 4.06647e-6 4.09198e-6
接收圈之外coarse bulk速度 8 /(13.5,21.5) 1.10692e-6 1.01799e-6
对应零驱动基线依次9.93410e-9、1.49012e-8、2.01166e-7、1.00583e-7。
预先固定速度差>1e-6,neq差>1e-7,且均>同位置/时间/阶段基线10倍;两符号均满足。
负吸bulk首次点的绝对速度9.17512e-7,差值1.01799e-6;判据本来就针对差值,
未把它改写为绝对速度超过1e-6。随后峰值处绝对速度和差值均明显非零。
峰值(相对零驱动,全部位于预设采样窗口内):
量 峰值t/位置 正吹 负吸
fine接口内侧neq 10 /(19.75,15.25) 7.49818e-6 7.38603e-6
真实transfer neq 11 /(20.5,14.5),q1 2.63668e-5 2.62411e-5
coarse接收圈速度 14 /(20.5,15.5) 2.88503e-4 2.87819e-4
接收圈之外bulk速度 16 /(21.5,15.5) 2.56991e-4 2.56441e-4
这里证明喷吸启动扰动实际到达并通过接口,可能含压力/声学传播。不同指标的
首次点是各自固定区域的检测见证,不冒称同一个流体质点的轨迹。24粗步内不能
判断成熟射流或纯剪切扰动的跨接口精度。区域及实际传递方向保存在regions.json;
每步指标、first/peak、同点基线和绝对值均有CSV/JSON;小型NPZ供离线复核。
逐步收支与舍入:
每条轨迹24行复合叶节点质量/动量账本;48行真实fine边界交换(每区间2行、
每次面积权重1/4);72行局部collision诊断(每区间fine2次、coarse1次)。
实际fluid boundary、fine transfer和coarse transfer分别统计,未用最新一帧
link_exchange代替两子步累计。最新body impulse另列,仅为该子步的动量交换;
fine rate=该子步交换/.5,coarse rate=两子步之和/1,不冒充总推力。
24区间累计(质量、Px、Py):
正吹B = (+.0935678868555, +.0148278460838, +.0125229167752)
正吹F = (-.0672332551330, -.0119119063020, -.0101141575724)
正吹C = (+.0672331918031, +.0119117666036, +.0101140532643)
负吸B = (-.0934597565793, -.0147664458491, -.0124674369581)
负吸F = (+.0670307464898, +.0118954917416, +.0100988540798)
负吸C = (-.0670307874680, -.0118956044316, -.0100990422070)
其中B为solid边界净交换,F为fine叶/halo交换,C为coarse真实incoming收支。
正吹/负吸同实际population上相对passive BFL oracle的累计附加质量分别
+.0743640140662、-.0742686590511,符号正确;这不是额外轨迹或守恒修正。
每个碰撞逐q/节点独立FP64 SRT参考:使用实际读回FP32omega并核对tau/force;
固定近静止判据|GPUout-SRT64(actual_input)|<=8*eps32*|input_q|。
三轨迹最大归一化误差分别.463942、.569605、.528511,全部<1;
最大绝对误差分别1.29143e-7、1.58655e-7、1.64771e-7。
它是本例的固定局部容差,考虑实际fast-math/FMA路径,不是一般舍入定理。
每次局部M(output-input)独立测得的累计漂移与原始账本残差吻合;逐区间和累计
剩余闭合误差在FP64计账中恰为0,满足预设1e-10/1e-9。这个零是记账分解验证,
不是离散方案的精确物理守恒结论,也未以全域大容差掩盖raw残差。
coalescence的顺序FP32四子格平均与精确FP64均值之差独立由实际children计算,
所有槽通过固定gamma3局部界限;实际transfer账本已经包含它,没有重复扣除。
累计平均舍入(质量、Px、Py):
零驱动 (-5.7183206081e-7, -1.8812716007e-7, -2.8312206268e-7)
正吹 (-6.3329935074e-8, -1.3969838619e-7, -1.0430812836e-7)
负吸 (-4.0978193283e-8, -1.1269003153e-7, -1.8812716007e-7)
采用精确平均记账的原始残差亦保存在各summary的exact_average_residual中。
BFL最大局部误差三轨迹均<=1.27259e-8,低于冻结1e-7。
未从末态差反推任何收支项,也未看到结果后改公式、阈值、窗口或步数。
有效性:每细步active流体有限、solid与最外2层halo为NaN;inner ghost按真实
逐方向stream-only(包含合法NaN)核对。每粗步发布fine全部非叶和coarse covered
均NaN;leaf finite、局部密度/速度范围达标;几何/flags/源对象不变。
coarse320叶节点,其中68接口接收节点、252外部bulk;fine963流体叶,
124接口内侧节点;实际coalescence196方向槽,包括原有8个grazing-corner槽。
执行和范围:
冻结2026-10-14 05:55:03 UTC,GPU启动05:55:16 UTC,实际耗时9.596s,exit0。
GPU0 UUID GPU-e8853ae7-a302-6a17-bcfa-aa767e9ed20c,预检5MiB/util0/无计算进程。
包来源严格为/home/frank14f/CelerisLab/src;现有pycuda_3_10环境;未安装依赖。
峰值进程组RSS297836544bytes,最少可用RAM63740788736bytes,最少可用VRAM
15826MiB,本轮临时与证据采样峰值2081386bytes,远小于2GB;无保护触发。
采样保护不是OS硬隔离;独占scratch已删除,GPU退出后5MiB且无计算进程。
生产增量只有refinement_stepper.py一行文档,+1/-0,明确fine_objects采用
edge/cell-center坐标(coarse中心I+.5),普通Simulation使用integer-node坐标。
完整610文件基线比对仅这一文件改变;既有dirty、旧审查和运行证据全部保留;
100个冻结脚本/源码哈希复核一致;不改生产公式、helper、网格或推进时序;
无提交/推送、无DynamisLab修改、无额外GPU矩阵。默认旧测试未改未重跑。
证据导航:
criteria.txt + frozen.json:运行前完整判据、时间戳、SHA256;不可事后改写。
command.txt + runner.py + gpu_run.json + stdout.txt:确切命令、环境、预检、退出。
validate.py:本次独立验证脚本,复用已接受test_fine_surface_gpu.py的只读钩子。
zero/blow/suction_{ledger,collisions,boundary}.csv:必要逐步量与分解。
blow/suction_propagation.csv、*_summary.json、*_signals.npz:信号与对齐基线。
result.json:固定判据结果;regions.json:坐标/方向;integrity.json:范围完整性。
incremental.diff:唯一生产增量;baseline_*.json:保留旧文件的哈希基线。
代码/数值只读agent交叉复核见review.txt。所有最终文本每份<=40000字符。
限制:以上仅短时离散联合一致性和启动扰动跨接口证据。原始FP32漂移仍存在,
未在本轮修正;不证明物理精度、空间收敛、稳态、长时稳定、性能或通用AMR。
此步已完成并停止,没有延伸B墙穿接口候选、checkpoint或其他特性。
@@ -0,0 +1,412 @@
{
"passed": true,
"runs": {
"zero": {
"speed": 0.0,
"initial_leaf": [
560.7500041779131,
0.0,
0.0
],
"final_leaf": [
560.7502328557894,
4.124827682971954e-06,
3.1795352697372437e-06
],
"raw_residual": [
0.00022911839187145233,
5.905516445636749e-06,
3.916211426258087e-06
],
"exact_average_residual": [
0.00022854655981063843,
5.717389285564423e-06,
3.6330893635749817e-06
],
"cumulative": {
"boundary": [
1.3131648302078247e-07,
-1.5925616025924683e-06,
-4.5355409383773804e-07
],
"fine_transfer": [
-9.47713851928711e-05,
3.1068921089172363e-06,
-2.084299921989441e-06
],
"coarse_transfer": [
9.419955313205719e-05,
-3.295019268989563e-06,
1.8011778593063354e-06
],
"rounding": [
0.00022911839187145233,
5.905516445636749e-06,
3.916211426258087e-06
],
"average": [
-5.718320608139038e-07,
-1.8812716007232666e-07,
-2.8312206268310547e-07
]
},
"checks": {
"validity": true,
"geometry_unchanged": true,
"boundary_count": 48,
"collision_count": 72,
"local_collision": true,
"local_regime": true,
"bfl": true,
"transfer_rounding": true,
"interval_closure": true,
"cumulative_closure": true
},
"max_collision_ratio": 0.46394191845799526,
"max_collision_error": 1.2914339875269576e-07,
"max_bfl_error": 1.0332863675799331e-08,
"max_interval_closure": 0.0,
"drive_mass": 3.733417470608985e-07
},
"blow": {
"speed": 0.002,
"initial_leaf": [
560.7500041779131,
0.0,
0.0
],
"final_leaf": [
560.8438616539352,
0.014835720416158438,
0.012527641374617815
],
"raw_residual": [
0.0002896524965763092,
8.014030754566193e-06,
4.828907549381256e-06
],
"exact_average_residual": [
0.00028958916664123535,
7.874332368373871e-06,
4.7245994210243225e-06
],
"cumulative": {
"boundary": [
0.09356788685545325,
0.014827846083790064,
0.01252291677519679
],
"fine_transfer": [
-0.0672332551330328,
-0.01191190630197525,
-0.010114157572388649
],
"coarse_transfer": [
0.06723319180309772,
0.011911766603589058,
0.010114053264260292
],
"rounding": [
0.0002896524965763092,
8.014030754566193e-06,
4.828907549381256e-06
],
"average": [
-6.332993507385254e-08,
-1.3969838619232178e-07,
-1.043081283569336e-07
]
},
"checks": {
"validity": true,
"geometry_unchanged": true,
"boundary_count": 48,
"collision_count": 72,
"local_collision": true,
"local_regime": true,
"bfl": true,
"transfer_rounding": true,
"interval_closure": true,
"cumulative_closure": true,
"propagation": true,
"drive_sign": true
},
"max_collision_ratio": 0.5696050037738337,
"max_collision_error": 1.5865499780609582e-07,
"max_bfl_error": 1.2725840020655355e-08,
"max_interval_closure": 0.0,
"drive_mass": 0.07436401406617413,
"propagation": {
"coarse_interface_u": {
"threshold": 1e-06,
"baseline_factor": 10,
"first_arrival": {
"time": 7,
"signal": 4.0664670353703905e-06,
"baseline": 2.0116559817931723e-07,
"absolute": 4.267265792606936e-06,
"x": 20.5,
"y": 13.5
},
"peak": {
"metric": "coarse_interface_u",
"time": 14,
"signal": 0.00028850325159438407,
"baseline": 3.003423681142711e-08,
"absolute": 0.00028847339892346693,
"any_crossed": true,
"peak_crossed": true,
"x": 20.5,
"y": 15.5
}
},
"coarse_bulk_u": {
"threshold": 1e-06,
"baseline_factor": 10,
"first_arrival": {
"time": 8,
"signal": 1.1069172403255332e-06,
"baseline": 1.005827957173589e-07,
"absolute": 1.2074577299858699e-06,
"x": 13.5,
"y": 21.5
},
"peak": {
"metric": "coarse_bulk_u",
"time": 16,
"signal": 0.00025699080829703886,
"baseline": 0.0,
"absolute": 0.00025699080829703886,
"any_crossed": true,
"peak_crossed": true,
"x": 21.5,
"y": 15.5
}
},
"fine_band_neq": {
"threshold": 1e-07,
"baseline_factor": 10,
"first_arrival": {
"time": 6,
"signal": 3.8661114470928126e-07,
"baseline": 9.934099098884985e-09,
"absolute": 3.766770456103963e-07,
"x": 19.75,
"y": 13.25
},
"peak": {
"metric": "fine_band_neq",
"time": 10,
"signal": 7.498180437826019e-06,
"baseline": 9.106256526614231e-09,
"absolute": 7.489074181299404e-06,
"any_crossed": true,
"peak_crossed": true,
"x": 19.75,
"y": 15.25
}
},
"transfer_neq": {
"threshold": 1e-07,
"baseline_factor": 10,
"first_arrival": {
"time": 7,
"signal": 9.917490157301811e-07,
"baseline": 1.4901174696935193e-08,
"absolute": 9.76847841033246e-07,
"q": 1,
"x": 20.5,
"y": 13.5
},
"peak": {
"metric": "transfer_neq",
"time": 11,
"signal": 2.6366830318105827e-05,
"baseline": 8.692339972804497e-09,
"absolute": 2.6375522658078632e-05,
"any_crossed": true,
"peak_crossed": true,
"q": 1,
"x": 20.5,
"y": 14.5
}
}
},
"raw_minus_zero": [
6.053410470485687e-05,
2.1085143089294434e-06,
9.126961231231689e-07
]
},
"suction": {
"speed": -0.002,
"initial_leaf": [
560.7500041779131,
0.0,
0.0
],
"final_leaf": [
560.6568783186376,
-0.014766339212656021,
-0.012467360123991966
],
"raw_residual": [
0.00033393828198313713,
2.193264663219452e-07,
2.6496127247810364e-07
],
"exact_average_residual": [
0.00033389730378985405,
1.0663643479347229e-07,
7.683411240577698e-08
],
"cumulative": {
"boundary": [
-0.0934597565792501,
-0.014766445849090815,
-0.012467436958104372
],
"fine_transfer": [
0.06703074648976326,
0.011895491741597652,
0.010098854079842567
],
"coarse_transfer": [
-0.06703078746795654,
-0.011895604431629181,
-0.01009904220700264
],
"rounding": [
0.00033393828198313713,
2.193264663219452e-07,
2.6496127247810364e-07
],
"average": [
-4.0978193283081055e-08,
-1.126900315284729e-07,
-1.8812716007232666e-07
]
},
"checks": {
"validity": true,
"geometry_unchanged": true,
"boundary_count": 48,
"collision_count": 72,
"local_collision": true,
"local_regime": true,
"bfl": true,
"transfer_rounding": true,
"interval_closure": true,
"cumulative_closure": true,
"propagation": true,
"drive_sign": true
},
"max_collision_ratio": 0.5285112236646456,
"max_collision_error": 1.6477090769573266e-07,
"max_bfl_error": 1.2498588997100768e-08,
"max_interval_closure": 0.0,
"drive_mass": -0.07426865905109248,
"propagation": {
"coarse_interface_u": {
"threshold": 1e-06,
"baseline_factor": 10,
"first_arrival": {
"time": 7,
"signal": 4.091979903802207e-06,
"baseline": 2.0116559817931723e-07,
"absolute": 3.8910894220610345e-06,
"x": 20.5,
"y": 13.5
},
"peak": {
"metric": "coarse_interface_u",
"time": 14,
"signal": 0.0002878189146376881,
"baseline": 3.003423681142711e-08,
"absolute": 0.0002878487673732557,
"any_crossed": true,
"peak_crossed": true,
"x": 20.5,
"y": 15.5
}
},
"coarse_bulk_u": {
"threshold": 1e-06,
"baseline_factor": 10,
"first_arrival": {
"time": 8,
"signal": 1.0179867624062477e-06,
"baseline": 1.005827957173589e-07,
"absolute": 9.175116276483961e-07,
"x": 13.5,
"y": 21.5
},
"peak": {
"metric": "coarse_bulk_u",
"time": 16,
"signal": 0.00025644070267233306,
"baseline": 0.0,
"absolute": 0.00025644070267233306,
"any_crossed": true,
"peak_crossed": true,
"x": 21.5,
"y": 15.5
}
},
"fine_band_neq": {
"threshold": 1e-07,
"baseline_factor": 10,
"first_arrival": {
"time": 6,
"signal": 3.733491271140643e-07,
"baseline": 9.934099098884985e-09,
"absolute": 3.832832262129493e-07,
"x": 19.75,
"y": 13.25
},
"peak": {
"metric": "fine_band_neq",
"time": 10,
"signal": 7.386030289713297e-06,
"baseline": 9.106256526614231e-09,
"absolute": 7.395136546239911e-06,
"any_crossed": true,
"peak_crossed": true,
"x": 19.75,
"y": 15.25
}
},
"transfer_neq": {
"threshold": 1e-07,
"baseline_factor": 10,
"first_arrival": {
"time": 7,
"signal": 1.0066612778220074e-06,
"baseline": 1.4901174696935193e-08,
"absolute": 1.0215624525189426e-06,
"q": 1,
"x": 20.5,
"y": 13.5
},
"peak": {
"metric": "transfer_neq",
"time": 11,
"signal": 2.6241128339946074e-05,
"baseline": 8.692339972804497e-09,
"absolute": 2.623243599997327e-05,
"any_crossed": true,
"peak_crossed": true,
"q": 1,
"x": 20.5,
"y": 14.5
}
}
},
"raw_minus_zero": [
0.0001048198901116848,
-5.686189979314804e-06,
-3.6512501537799835e-06
]
}
}
}
@@ -0,0 +1,36 @@
Read-only agent review, 2026-10-14
/root/architecture — pre-run:
No blocking issue in hooked kernel arguments/order, masks or area weighting.
Caught CSV signal-location ambiguity and exchange-unit ambiguity before freeze:
fixed any_crossed versus peak_crossed; renamed latest_body_impulse_x/y and
latest_body_angular_impulse. No production behavior changes.
/root/numerical — pre-run:
Avoid rho/u at partly valid halo children; transfer neq is defined at full
coarse incoming vector, actual replaced q. No double-counting average rounding.
Require independent local SRT oracle before describing measured local drift as
rounding. Freeze pointwise baseline comparisons; startup propagation may be
acoustic, not established jet advection. Suggestions incorporated before GPU.
/root/architecture — post-run:
All frozen hashes match current sources; frozen.json digest matches gpu_run.
Freeze05:55:03 precedes launch05:55:16UTC, real exit0. Each trajectory has correct
ordered24ledger/72collision/48boundary rows; result/summary/final ledger agree.
Independently reconstructed all4metrics' per-time any_crossed/peak_crossed,
first-arrival and peaks/locations from saved signals.npz; all agree.
All text artifacts inspected within40000characters. No material gap.
/root/numerical — post-run:
Independently summed all3ledger/collision CSVs: all components of locally
measured collision drift exactly reproduce raw global residual. Each interval
fine_transfer+coarse_transfer-average_rounding is0. Largest FP64ideal moment
defect about2.94e-14. Maximum independent local oracle normalized error.569605
is below fixed1. Thus ledger closure is not the sole acceptance gate.
No blocking issue. Raw mass residuals2.29118e-4/2.89652e-4/3.33938e-4 remain;
identifying their FP32 source does not physically repair them or establish
strict conservation. First6/7/8 are integer sampling threshold witnesses,
not accurate propagation-speed or mature-jet/accuracy claims.
Agents performed read-only inspection/offline data parsing, no file edits,
no GPU launch and no old regression runs. Root is the sole editor/launcher.
@@ -0,0 +1,130 @@
"""One launch, fresh resource guards, only owned scratch/process-group cleanup."""
import hashlib
import json
import os
from pathlib import Path
import shutil
import signal
import subprocess
import tempfile
import time
from datetime import datetime, timezone
ROOT = Path('/home/frank14f/CelerisLab')
OUT = Path(__file__).resolve().parent
PYTHON = '/home/frank14f/anaconda3/envs/pycuda_3_10/bin/python'
UUID = 'GPU-e8853ae7-a302-6a17-bcfa-aa767e9ed20c'
def command(args):
return subprocess.check_output(args, text=True, timeout=10)
def gpu():
return command(['nvidia-smi', '--query-gpu=index,uuid,name,memory.used,memory.free,utilization.gpu', '--format=csv,noheader,nounits'])
def apps():
return command(['nvidia-smi', '--query-compute-apps=gpu_uuid,pid,process_name,used_memory', '--format=csv,noheader,nounits'])
def ram():
for line in Path('/proc/meminfo').read_text().splitlines():
if line.startswith('MemAvailable:'):
return int(line.split()[1])*1024
raise RuntimeError('MemAvailable unavailable')
def disk(paths):
return sum(p.stat().st_size for root in paths for p in root.rglob('*') if p.is_file())
def group_rss(pgid):
total = 0
for proc in Path('/proc').iterdir():
if not proc.name.isdigit():
continue
try:
fields = (proc/'stat').read_text().rsplit(') ', 1)[1].split()
if int(fields[2]) == pgid:
for line in (proc/'status').read_text().splitlines():
if line.startswith('VmRSS:'):
total += int(line.split()[1])*1024
except (OSError, ValueError, IndexError):
pass
return total
def main():
assert not (OUT/'gpu_run.json').exists(), 'Do not repeat an existing launch'
data = dict(start_utc=datetime.now(timezone.utc).isoformat(), command=[PYTHON, str(OUT/'validate.py')],
cwd=str(ROOT), physical_gpu_uuid=UUID, note='Sampled guards, not an OS hard isolation; no fixed RSS/AS cap.')
scratch = None
process = None
started = time.monotonic()
code = 1
try:
frozen = json.loads((OUT/'frozen.json').read_text())
for path, digest in frozen['hashes'].items():
assert hashlib.sha256((ROOT/path).read_bytes()).hexdigest() == digest, path
data['preflight_gpu'], data['preflight_apps'], data['preflight_ram_bytes'] = gpu(), apps(), ram()
fields = next(line.split(', ') for line in data['preflight_gpu'].splitlines() if UUID in line)
used, free, util = map(int, fields[-3:])
assert fields[0] == '0' and used <= 16 and free >= 2048 and util == 0
assert UUID not in data['preflight_apps'] and data['preflight_ram_bytes'] >= 4*1024**3
limits = dict(wall_seconds=180, temp_bytes=2_000_000_000,
ram_reserve_bytes=max(4*1024**3, data['preflight_ram_bytes']//10),
vram_reserve_MiB=max(512, free//10))
data['limits'] = limits
scratch = Path(tempfile.mkdtemp(prefix='celeris-joint24-'))
env = dict(PYTHONPATH=str(ROOT/'src'), PYTHONNOUSERSITE='1', PYTHONDONTWRITEBYTECODE='1',
OPENBLAS_NUM_THREADS='1', CUDA_VISIBLE_DEVICES=UUID,
CUDA_CACHE_DISABLE='1', TMPDIR=str(scratch))
data['env'] = env
data['frozen_sha256'] = hashlib.sha256((OUT/'frozen.json').read_bytes()).hexdigest()
data['peak_group_rss_bytes'] = 0
data['peak_temp_bytes'] = disk([OUT,scratch])
data['min_ram_bytes'] = data['preflight_ram_bytes']
data['min_vram_free_MiB'] = free
data['termination_reason'] = None
with (OUT/'stdout.txt').open('w') as output:
process = subprocess.Popen(data['command'], cwd=ROOT, env={**os.environ, **env},
stdout=output, stderr=subprocess.STDOUT, start_new_session=True)
while process.poll() is None:
available, occupied = ram(), disk([OUT,scratch])
free = int(next(line.split(', ')[-2] for line in gpu().splitlines() if UUID in line))
data['peak_group_rss_bytes'] = max(data['peak_group_rss_bytes'], group_rss(process.pid))
data['peak_temp_bytes'] = max(data['peak_temp_bytes'], occupied)
data['min_ram_bytes'] = min(data['min_ram_bytes'], available)
data['min_vram_free_MiB'] = min(data['min_vram_free_MiB'], free)
if (time.monotonic()-started > limits['wall_seconds'] or occupied > limits['temp_bytes']
or available < limits['ram_reserve_bytes'] or free < limits['vram_reserve_MiB']):
data['termination_reason'] = 'Time/disk/RAM/VRAM guard triggered'
os.killpg(process.pid, signal.SIGTERM)
try:
process.wait(timeout=5)
except subprocess.TimeoutExpired:
os.killpg(process.pid, signal.SIGKILL)
break
time.sleep(.5)
code = process.wait(timeout=10)
data['postflight_gpu'], data['postflight_apps'] = gpu(), apps()
except BaseException as error:
data['runner_error'] = repr(error)
if process is not None and process.poll() is None:
os.killpg(process.pid, signal.SIGKILL)
process.wait(timeout=10)
raise
finally:
data['exit_code'] = code
data['elapsed_seconds'] = time.monotonic()-started
if scratch is not None:
shutil.rmtree(scratch)
data['scratch_removed'] = scratch is None or not scratch.exists()
(OUT/'gpu_run.json').write_text(json.dumps(data, indent=2)+'\n')
print(json.dumps(data, indent=2), flush=True)
raise SystemExit(code)
if __name__ == '__main__':
main()
File diff suppressed because one or more lines are too long
@@ -0,0 +1,49 @@
step,substep,time,bfl_error,drive_mass,latest_body_impulse_x,latest_body_impulse_y,latest_body_angular_impulse,boundary_m,boundary_px,boundary_py,fine_transfer_m,fine_transfer_px,fine_transfer_py
1,1,0.5,3.7331066016221826e-09,-0.0015482641756534576,0.0010669892653822899,0.0009111212566494942,1.329833948571224e-05,-0.0015482641756534576,-0.0010669846087694168,-0.0009111212566494942,0.0,0.0,0.0
1,2,1.0,7.450580596923828e-09,-0.001546488821844781,0.0005881106480956078,0.0005055302754044533,7.090981909652072e-06,-0.0018966365605592728,-0.000588112510740757,-0.0005055312067270279,-3.557652235031128e-07,0.0,0.0
2,1,1.5,7.450580596923828e-09,-0.0015455698188904868,0.0007474450394511223,0.000630686990916729,6.323601846380811e-06,-0.0017942930571734905,-0.0007474464364349842,-0.0006306902505457401,-8.530914783477783e-07,-7.450580596923828e-09,-1.6763806343078613e-07
2,2,2.0,7.450580596923828e-09,-0.0015454305605910922,0.0006957640871405602,0.0005812598392367363,-9.326976928458741e-06,-0.0019257990643382072,-0.0006957687437534332,-0.0005812682211399078,-1.3401731848716736e-06,2.7939677238464355e-09,-9.313225746154785e-10
3,1,2.5,7.450580596923828e-09,-0.0015454182331193405,0.0007162690162658691,0.0006032083183526993,2.0262676536653146e-06,-0.0019086366519331932,-0.0007162792608141899,-0.0006032129749655724,-1.6577541828155518e-06,1.5832483768463135e-07,1.5832483768463135e-07
3,2,3.0,8.221284986120736e-09,-0.0015455955498631406,0.000675516203045845,0.0005694478750228882,-2.283530538660372e-06,-0.0019611637108027935,-0.0006755241192877293,-0.0005694576539099216,-1.982320100069046e-06,3.1152740120887756e-07,3.096647560596466e-07
4,1,3.5,7.450580596923828e-09,-0.0015457821940822736,0.0006534429267048836,0.000552385114133358,3.1464089307320364e-06,-0.001949384342879057,-0.0006534415297210217,-0.000552391167730093,-3.2121315598487854e-06,3.5297125577926636e-07,3.762543201446533e-07
4,2,4.0,7.450580596923828e-09,-0.0015460265831878312,0.0006101150065660477,0.0005156379193067551,2.1656969761973954e-07,-0.001972564961761236,-0.000610120128840208,-0.0005156439729034901,-3.698747605085373e-06,-3.585591912269592e-08,1.909211277961731e-08
5,1,4.5,7.450580596923828e-09,-0.0015462236236817618,0.0005800491198897362,0.0004902100190520287,2.4401852956046355e-06,-0.0019627874717116356,-0.0005800472572445869,-0.0004902174696326256,-3.6563724279403687e-06,5.550682544708252e-07,2.4121254682540894e-07
5,2,5.0,8.17224322935406e-09,-0.001546429669342637,0.0005416562780737877,0.00045779068022966385,6.411905253411732e-07,-0.0019741454161703587,-0.0005416539497673512,-0.000457793939858675,-3.6312267184257507e-06,5.122274160385132e-07,2.2258609533309937e-07
6,1,5.5,7.450580596923828e-09,-0.0015465991853560995,0.0005121780559420586,0.00043242890387773514,1.926527342988038e-06,-0.001966074574738741,-0.0005121775902807713,-0.000432425644248724,-2.8940849006175995e-06,5.164183676242828e-07,3.213062882423401e-08
6,2,6.0,1.0613033563089402e-08,-0.001546759810737387,0.00047842320054769516,0.00040392857044935226,7.323118594859679e-07,-0.001972377300262451,-0.0004784250631928444,-0.00040392763912677765,-2.0721927285194397e-06,6.435438990592957e-07,9.12696123123169e-08
7,1,6.5,7.450580596923828e-09,-0.0015468885373133533,0.00045062508434057236,0.0003800736740231514,1.5839877249845813e-06,-0.0019662114791572094,-0.0004506339319050312,-0.00038006948307156563,2.334360033273697e-06,3.114808350801468e-06,1.4849938452243805e-06
7,2,7.0,8.999190503899968e-09,-0.0015470132347384351,0.00042080413550138474,0.0003548497334122658,8.012649583832854e-07,-0.0019701728597283363,-0.0004208004102110863,-0.00035485532134771347,1.5432480722665787e-05,1.1287163943052292e-05,5.935784429311752e-06
8,1,7.5,1.0738867337045654e-08,-0.0015471137993936443,0.0003952737897634506,0.00033300556242465973,1.388882160391347e-06,-0.0019654585048556328,-0.0003952831029891968,-0.0003329990431666374,5.064625293016434e-05,2.6551075279712677e-05,1.5786848962306976e-05
8,2,8.0,7.94032639639397e-09,-0.0015472117748432483,0.00036898814141750336,0.00031079165637493134,8.204820101109789e-07,-0.0019681239500641823,-0.0003689778968691826,-0.0003107842057943344,0.00010942388325929642,6.19497150182724e-05,3.8951635360717773e-05
9,1,8.5,8.976009713279609e-09,-0.0015472804270270975,0.00034602265805006027,0.0002911807969212532,1.3696224959725e-06,-0.001964463386684656,-0.0003460417501628399,-0.00029119057580828667,0.0002314508892595768,9.650783613324165e-05,6.443960592150688e-05
9,2,9.0,1.0052167986884797e-08,-0.001547337366734857,0.00032305438071489334,0.0002718055620789528,8.737507810607781e-07,-0.00196637911722064,-0.00032305577769875526,-0.0002718069590628147,0.0003751874901354313,0.00017973734065890312,0.00012484891340136528
10,1,9.5,7.4023787099974925e-09,-0.001547404346943595,0.00030282605439424515,0.0002545500174164772,1.3337265093449346e-06,-0.0019635148346424103,-0.00030282698571681976,-0.00025455933064222336,0.0006195390596985817,0.00022383593022823334,0.000162455253303051
10,2,10.0,6.968939966767174e-09,-0.001547448671976346,0.0002828845754265785,0.00023786630481481552,9.501839344228102e-07,-0.001965020317584276,-0.00028289156034588814,-0.00023785652592778206,0.0008522137068212032,0.00035300618037581444,0.0002658138982951641
11,1,10.5,1.0530962046839676e-08,-0.0015474870615136364,0.00026516150683164597,0.00022298935800790787,1.3016631345008634e-06,-0.0019626920111477375,-0.00026516104117035866,-0.00022298330441117287,0.0011819470673799515,0.0003880225121974945,0.00030118972063064575
11,2,11.0,7.354702624695619e-09,-0.0015475354224584415,0.0002481304109096527,0.00020870380103588104,8.941672690054858e-07,-0.0019638948142528534,-0.00024813972413539886,-0.00020870286971330643,0.00145752914249897,0.0005337242037057877,0.00042963773012161255
12,1,11.5,8.767222503536232e-09,-0.001547562607513273,0.00023286882787942886,0.00019576307386159897,1.1601679523742803e-06,-0.001962078735232353,-0.0002328716218471527,-0.00019576400518417358,0.0017802291549742222,0.0005506309680640697,0.00045162299647927284
12,2,12.0,9.096382980189333e-09,-0.0015476002059964218,0.00021828524768352509,0.00018361210823059082,8.859918445569548e-07,-0.0019631017930805683,-0.00021829502657055855,-0.00018362188711762428,0.002031440380960703,0.0006739604286849499,0.000572004821151495
13,1,12.5,6.5197561377461355e-09,-0.0015476129016728998,0.00020523089915513992,0.00017269793897867203,1.2139267550059785e-06,-0.0019616251811385155,-0.00020523276180028915,-0.00017269421368837357,0.0022674263454973698,0.00067532854154706,0.0005780183710157871
13,2,13.0,5.146194359539891e-09,-0.0015476392796307777,0.00019292067736387253,0.00016248133033514023,9.107929975771256e-07,-0.0019624661654233932,-0.0001929309219121933,-0.0001624850556254387,0.002446614671498537,0.0007499088533222675,0.0006604096852242947
14,1,13.5,8.330306375259333e-09,-0.0015476535128897996,0.0001819990575313568,0.00015316344797611237,1.1346972110803932e-06,-0.0019612740725278854,-0.0001819925382733345,-0.00015317555516958237,0.0025721797719597816,0.0007412796840071678,0.0006537484005093575
14,2,14.0,8.454041688921166e-09,-0.0015476762461938956,0.00017176009714603424,0.00014458410441875458,9.925571977653647e-07,-0.0019619660452008247,-0.00017175264656543732,-0.0001445794478058815,0.0026705721393227577,0.000760519877076149,0.0006827609613537788
15,1,14.5,8.024249306681774e-09,-0.0015476863880568553,0.0001627029851078987,0.00013693515211343765,1.1326488877916319e-06,-0.0019609066657721996,-0.00016270345076918602,-0.00013692351058125496,0.0027098902501165867,0.0007453667931258678,0.0006675352342426777
15,2,15.0,8.5509712643983e-09,-0.0015477023138736976,0.00015427079051733017,0.0001298980787396431,1.0080659256228586e-06,-0.0019614454358816147,-0.00015425775200128555,-0.00012989435344934464,0.0027480190619826317,0.0007168371230363846,0.0006446875631809235
16,1,15.5,1.2498588997100768e-08,-0.0015477122014419843,0.0001468295231461525,0.000123598612844944,1.1824087963185903e-06,-0.001960494089871645,-0.00014683278277516365,-0.000123604666441679,0.002740874420851469,0.0006989189423620701,0.000626422930508852
16,2,16.0,9.256705402194143e-09,-0.0015477301148594871,0.00014006812125444412,0.00011796411126852036,9.308136234009723e-07,-0.0019609369337558746,-0.00014007184654474258,-0.00011796131730079651,0.002747458405792713,0.0006359582766890526,0.0005640769377350807
17,1,16.5,9.86708736938624e-09,-0.0015477351078586202,0.00013425014913082123,0.00011301040649414062,1.1052945718681428e-06,-0.001960096415132284,-0.0001342552714049816,-0.0001130090095102787,0.002724500373005867,0.0006184643134474754,0.0005468325689435005
17,2,17.0,8.028477438415393e-09,-0.0015477600973967448,0.00012889597564935684,0.00010859500616788864,9.277017700703993e-07,-0.001960489433258772,-0.0001288936473429203,-0.00010859174653887749,0.0027201655320823193,0.0005353703163564205,0.00046224379912018776
18,1,17.5,7.699842763386755e-09,-0.0015477556081742207,0.00012428779155015945,0.00010465551167726517,1.036442421664674e-06,-0.00195977371186018,-0.0001242849975824356,-0.00010466109961271286,0.0026930058375000954,0.0005191462114453316,0.0004479791969060898
18,2,18.0,7.779478172764698e-09,-0.0015477652772308585,0.00011980719864368439,0.00010108202695846558,9.591615347526172e-07,-0.001960138790309429,-0.00011981278657913208,-0.0001010717824101448,0.0026853615418076515,0.00042929593473672867,0.0003578970208764076
19,1,18.5,1.0115823734224705e-08,-0.0015477747316547663,0.00011577177792787552,9.778235107660294e-05,1.1382919499203226e-06,-0.001959627028554678,-0.00011577224358916283,-9.777536615729332e-05,0.002648819237947464,0.0004100445657968521,0.0003434009850025177
19,2,19.0,9.594118610678493e-09,-0.0015477738185972504,0.00011185649782419205,9.45916399359703e-05,8.908682038732962e-07,-0.0019600135274231434,-0.0001118597574532032,-9.458651766180992e-05,0.0026350892148911953,0.0003254576586186886,0.00026165833696722984
20,1,19.5,8.744199350707582e-09,-0.0015477812550560438,0.00010816752910614014,9.154155850410461e-05,1.0807081907149296e-06,-0.001959587913006544,-0.0001081652007997036,-9.154481813311577e-05,0.0025749970227479935,0.0002942616119980812,0.00023942533880472183
20,2,20.0,7.241793387180451e-09,-0.0015478027222764852,0.00010451860725879669,8.863583207130432e-05,9.283607647070369e-07,-0.0019599981606006622,-0.00010452233254909515,-8.862745016813278e-05,0.002547156997025013,0.00022500474005937576,0.0001754332333803177
21,1,20.5,9.080666218963529e-09,-0.0015478099147822168,0.00010123103857040405,8.586794137954712e-05,1.0566826715852073e-06,-0.0019596004858613014,-0.00010123662650585175,-8.586607873439789e-05,0.0024467245675623417,0.0001708432100713253,0.0001354874111711979
21,2,21.0,8.309436028142159e-09,-0.001547811782321707,9.799562394618988e-05,8.317828178405762e-05,9.359370445327642e-07,-0.0019598989747464657,-9.798770770430565e-05,-8.317967876791954e-05,0.0023957067169249058,0.0001242239959537983,9.476905688643456e-05
22,1,21.5,8.807171658631319e-09,-0.0015478071837582907,9.528174996376038e-05,8.07885080575943e-05,1.0299947542646848e-06,-0.001959493849426508,-9.528035297989845e-05,-8.077593520283699e-05,0.0022453111596405506,3.82973812520504e-05,2.8362032026052475e-05
22,2,22.0,7.708700941466695e-09,-0.0015478350620986127,9.280815720558167e-05,7.856637239456177e-05,9.84289633354507e-07,-0.0019597294740378857,-9.280489757657051e-05,-7.857801392674446e-05,0.0021656760945916176,1.8442049622535706e-05,1.2994743883609772e-05
23,1,22.5,5.829010607527607e-09,-0.0015478298144738873,9.077228605747223e-05,7.675401866436005e-05,1.0561968476485717e-06,-0.0019593103788793087,-9.077740833163261e-05,-7.675448432564735e-05,0.001967994961887598,-0.00010093534365296364,-8.322251960635185e-05
23,2,23.0,1.00678847481106e-08,-0.0015478396129139588,8.917506784200668e-05,7.518846541643143e-05,9.189075473869934e-07,-0.001959436573088169,-8.916761726140976e-05,-7.51987099647522e-05,0.0018595317378640175,-9.398628026247025e-05,-7.435213774442673e-05
24,1,23.5,9.096645881001564e-09,-0.0015478476094394076,8.79606232047081e-05,7.397029548883438e-05,9.397743796490943e-07,-0.0019590607844293118,-8.79545696079731e-05,-7.396889850497246e-05,0.0016328254714608192,-0.00023874826729297638,-0.00019633769989013672
24,2,24.0,8.815424390462567e-09,-0.001547844811637395,8.694268763065338e-05,7.304549217224121e-05,9.335749210359623e-07,-0.001959147397428751,-8.693570271134377e-05,-7.305433973670006e-05,0.0015028249472379684,-0.0002091461792588234,-0.00016683153808116913
1 step substep time bfl_error drive_mass latest_body_impulse_x latest_body_impulse_y latest_body_angular_impulse boundary_m boundary_px boundary_py fine_transfer_m fine_transfer_px fine_transfer_py
2 1 1 0.5 3.7331066016221826e-09 -0.0015482641756534576 0.0010669892653822899 0.0009111212566494942 1.329833948571224e-05 -0.0015482641756534576 -0.0010669846087694168 -0.0009111212566494942 0.0 0.0 0.0
3 1 2 1.0 7.450580596923828e-09 -0.001546488821844781 0.0005881106480956078 0.0005055302754044533 7.090981909652072e-06 -0.0018966365605592728 -0.000588112510740757 -0.0005055312067270279 -3.557652235031128e-07 0.0 0.0
4 2 1 1.5 7.450580596923828e-09 -0.0015455698188904868 0.0007474450394511223 0.000630686990916729 6.323601846380811e-06 -0.0017942930571734905 -0.0007474464364349842 -0.0006306902505457401 -8.530914783477783e-07 -7.450580596923828e-09 -1.6763806343078613e-07
5 2 2 2.0 7.450580596923828e-09 -0.0015454305605910922 0.0006957640871405602 0.0005812598392367363 -9.326976928458741e-06 -0.0019257990643382072 -0.0006957687437534332 -0.0005812682211399078 -1.3401731848716736e-06 2.7939677238464355e-09 -9.313225746154785e-10
6 3 1 2.5 7.450580596923828e-09 -0.0015454182331193405 0.0007162690162658691 0.0006032083183526993 2.0262676536653146e-06 -0.0019086366519331932 -0.0007162792608141899 -0.0006032129749655724 -1.6577541828155518e-06 1.5832483768463135e-07 1.5832483768463135e-07
7 3 2 3.0 8.221284986120736e-09 -0.0015455955498631406 0.000675516203045845 0.0005694478750228882 -2.283530538660372e-06 -0.0019611637108027935 -0.0006755241192877293 -0.0005694576539099216 -1.982320100069046e-06 3.1152740120887756e-07 3.096647560596466e-07
8 4 1 3.5 7.450580596923828e-09 -0.0015457821940822736 0.0006534429267048836 0.000552385114133358 3.1464089307320364e-06 -0.001949384342879057 -0.0006534415297210217 -0.000552391167730093 -3.2121315598487854e-06 3.5297125577926636e-07 3.762543201446533e-07
9 4 2 4.0 7.450580596923828e-09 -0.0015460265831878312 0.0006101150065660477 0.0005156379193067551 2.1656969761973954e-07 -0.001972564961761236 -0.000610120128840208 -0.0005156439729034901 -3.698747605085373e-06 -3.585591912269592e-08 1.909211277961731e-08
10 5 1 4.5 7.450580596923828e-09 -0.0015462236236817618 0.0005800491198897362 0.0004902100190520287 2.4401852956046355e-06 -0.0019627874717116356 -0.0005800472572445869 -0.0004902174696326256 -3.6563724279403687e-06 5.550682544708252e-07 2.4121254682540894e-07
11 5 2 5.0 8.17224322935406e-09 -0.001546429669342637 0.0005416562780737877 0.00045779068022966385 6.411905253411732e-07 -0.0019741454161703587 -0.0005416539497673512 -0.000457793939858675 -3.6312267184257507e-06 5.122274160385132e-07 2.2258609533309937e-07
12 6 1 5.5 7.450580596923828e-09 -0.0015465991853560995 0.0005121780559420586 0.00043242890387773514 1.926527342988038e-06 -0.001966074574738741 -0.0005121775902807713 -0.000432425644248724 -2.8940849006175995e-06 5.164183676242828e-07 3.213062882423401e-08
13 6 2 6.0 1.0613033563089402e-08 -0.001546759810737387 0.00047842320054769516 0.00040392857044935226 7.323118594859679e-07 -0.001972377300262451 -0.0004784250631928444 -0.00040392763912677765 -2.0721927285194397e-06 6.435438990592957e-07 9.12696123123169e-08
14 7 1 6.5 7.450580596923828e-09 -0.0015468885373133533 0.00045062508434057236 0.0003800736740231514 1.5839877249845813e-06 -0.0019662114791572094 -0.0004506339319050312 -0.00038006948307156563 2.334360033273697e-06 3.114808350801468e-06 1.4849938452243805e-06
15 7 2 7.0 8.999190503899968e-09 -0.0015470132347384351 0.00042080413550138474 0.0003548497334122658 8.012649583832854e-07 -0.0019701728597283363 -0.0004208004102110863 -0.00035485532134771347 1.5432480722665787e-05 1.1287163943052292e-05 5.935784429311752e-06
16 8 1 7.5 1.0738867337045654e-08 -0.0015471137993936443 0.0003952737897634506 0.00033300556242465973 1.388882160391347e-06 -0.0019654585048556328 -0.0003952831029891968 -0.0003329990431666374 5.064625293016434e-05 2.6551075279712677e-05 1.5786848962306976e-05
17 8 2 8.0 7.94032639639397e-09 -0.0015472117748432483 0.00036898814141750336 0.00031079165637493134 8.204820101109789e-07 -0.0019681239500641823 -0.0003689778968691826 -0.0003107842057943344 0.00010942388325929642 6.19497150182724e-05 3.8951635360717773e-05
18 9 1 8.5 8.976009713279609e-09 -0.0015472804270270975 0.00034602265805006027 0.0002911807969212532 1.3696224959725e-06 -0.001964463386684656 -0.0003460417501628399 -0.00029119057580828667 0.0002314508892595768 9.650783613324165e-05 6.443960592150688e-05
19 9 2 9.0 1.0052167986884797e-08 -0.001547337366734857 0.00032305438071489334 0.0002718055620789528 8.737507810607781e-07 -0.00196637911722064 -0.00032305577769875526 -0.0002718069590628147 0.0003751874901354313 0.00017973734065890312 0.00012484891340136528
20 10 1 9.5 7.4023787099974925e-09 -0.001547404346943595 0.00030282605439424515 0.0002545500174164772 1.3337265093449346e-06 -0.0019635148346424103 -0.00030282698571681976 -0.00025455933064222336 0.0006195390596985817 0.00022383593022823334 0.000162455253303051
21 10 2 10.0 6.968939966767174e-09 -0.001547448671976346 0.0002828845754265785 0.00023786630481481552 9.501839344228102e-07 -0.001965020317584276 -0.00028289156034588814 -0.00023785652592778206 0.0008522137068212032 0.00035300618037581444 0.0002658138982951641
22 11 1 10.5 1.0530962046839676e-08 -0.0015474870615136364 0.00026516150683164597 0.00022298935800790787 1.3016631345008634e-06 -0.0019626920111477375 -0.00026516104117035866 -0.00022298330441117287 0.0011819470673799515 0.0003880225121974945 0.00030118972063064575
23 11 2 11.0 7.354702624695619e-09 -0.0015475354224584415 0.0002481304109096527 0.00020870380103588104 8.941672690054858e-07 -0.0019638948142528534 -0.00024813972413539886 -0.00020870286971330643 0.00145752914249897 0.0005337242037057877 0.00042963773012161255
24 12 1 11.5 8.767222503536232e-09 -0.001547562607513273 0.00023286882787942886 0.00019576307386159897 1.1601679523742803e-06 -0.001962078735232353 -0.0002328716218471527 -0.00019576400518417358 0.0017802291549742222 0.0005506309680640697 0.00045162299647927284
25 12 2 12.0 9.096382980189333e-09 -0.0015476002059964218 0.00021828524768352509 0.00018361210823059082 8.859918445569548e-07 -0.0019631017930805683 -0.00021829502657055855 -0.00018362188711762428 0.002031440380960703 0.0006739604286849499 0.000572004821151495
26 13 1 12.5 6.5197561377461355e-09 -0.0015476129016728998 0.00020523089915513992 0.00017269793897867203 1.2139267550059785e-06 -0.0019616251811385155 -0.00020523276180028915 -0.00017269421368837357 0.0022674263454973698 0.00067532854154706 0.0005780183710157871
27 13 2 13.0 5.146194359539891e-09 -0.0015476392796307777 0.00019292067736387253 0.00016248133033514023 9.107929975771256e-07 -0.0019624661654233932 -0.0001929309219121933 -0.0001624850556254387 0.002446614671498537 0.0007499088533222675 0.0006604096852242947
28 14 1 13.5 8.330306375259333e-09 -0.0015476535128897996 0.0001819990575313568 0.00015316344797611237 1.1346972110803932e-06 -0.0019612740725278854 -0.0001819925382733345 -0.00015317555516958237 0.0025721797719597816 0.0007412796840071678 0.0006537484005093575
29 14 2 14.0 8.454041688921166e-09 -0.0015476762461938956 0.00017176009714603424 0.00014458410441875458 9.925571977653647e-07 -0.0019619660452008247 -0.00017175264656543732 -0.0001445794478058815 0.0026705721393227577 0.000760519877076149 0.0006827609613537788
30 15 1 14.5 8.024249306681774e-09 -0.0015476863880568553 0.0001627029851078987 0.00013693515211343765 1.1326488877916319e-06 -0.0019609066657721996 -0.00016270345076918602 -0.00013692351058125496 0.0027098902501165867 0.0007453667931258678 0.0006675352342426777
31 15 2 15.0 8.5509712643983e-09 -0.0015477023138736976 0.00015427079051733017 0.0001298980787396431 1.0080659256228586e-06 -0.0019614454358816147 -0.00015425775200128555 -0.00012989435344934464 0.0027480190619826317 0.0007168371230363846 0.0006446875631809235
32 16 1 15.5 1.2498588997100768e-08 -0.0015477122014419843 0.0001468295231461525 0.000123598612844944 1.1824087963185903e-06 -0.001960494089871645 -0.00014683278277516365 -0.000123604666441679 0.002740874420851469 0.0006989189423620701 0.000626422930508852
33 16 2 16.0 9.256705402194143e-09 -0.0015477301148594871 0.00014006812125444412 0.00011796411126852036 9.308136234009723e-07 -0.0019609369337558746 -0.00014007184654474258 -0.00011796131730079651 0.002747458405792713 0.0006359582766890526 0.0005640769377350807
34 17 1 16.5 9.86708736938624e-09 -0.0015477351078586202 0.00013425014913082123 0.00011301040649414062 1.1052945718681428e-06 -0.001960096415132284 -0.0001342552714049816 -0.0001130090095102787 0.002724500373005867 0.0006184643134474754 0.0005468325689435005
35 17 2 17.0 8.028477438415393e-09 -0.0015477600973967448 0.00012889597564935684 0.00010859500616788864 9.277017700703993e-07 -0.001960489433258772 -0.0001288936473429203 -0.00010859174653887749 0.0027201655320823193 0.0005353703163564205 0.00046224379912018776
36 18 1 17.5 7.699842763386755e-09 -0.0015477556081742207 0.00012428779155015945 0.00010465551167726517 1.036442421664674e-06 -0.00195977371186018 -0.0001242849975824356 -0.00010466109961271286 0.0026930058375000954 0.0005191462114453316 0.0004479791969060898
37 18 2 18.0 7.779478172764698e-09 -0.0015477652772308585 0.00011980719864368439 0.00010108202695846558 9.591615347526172e-07 -0.001960138790309429 -0.00011981278657913208 -0.0001010717824101448 0.0026853615418076515 0.00042929593473672867 0.0003578970208764076
38 19 1 18.5 1.0115823734224705e-08 -0.0015477747316547663 0.00011577177792787552 9.778235107660294e-05 1.1382919499203226e-06 -0.001959627028554678 -0.00011577224358916283 -9.777536615729332e-05 0.002648819237947464 0.0004100445657968521 0.0003434009850025177
39 19 2 19.0 9.594118610678493e-09 -0.0015477738185972504 0.00011185649782419205 9.45916399359703e-05 8.908682038732962e-07 -0.0019600135274231434 -0.0001118597574532032 -9.458651766180992e-05 0.0026350892148911953 0.0003254576586186886 0.00026165833696722984
40 20 1 19.5 8.744199350707582e-09 -0.0015477812550560438 0.00010816752910614014 9.154155850410461e-05 1.0807081907149296e-06 -0.001959587913006544 -0.0001081652007997036 -9.154481813311577e-05 0.0025749970227479935 0.0002942616119980812 0.00023942533880472183
41 20 2 20.0 7.241793387180451e-09 -0.0015478027222764852 0.00010451860725879669 8.863583207130432e-05 9.283607647070369e-07 -0.0019599981606006622 -0.00010452233254909515 -8.862745016813278e-05 0.002547156997025013 0.00022500474005937576 0.0001754332333803177
42 21 1 20.5 9.080666218963529e-09 -0.0015478099147822168 0.00010123103857040405 8.586794137954712e-05 1.0566826715852073e-06 -0.0019596004858613014 -0.00010123662650585175 -8.586607873439789e-05 0.0024467245675623417 0.0001708432100713253 0.0001354874111711979
43 21 2 21.0 8.309436028142159e-09 -0.001547811782321707 9.799562394618988e-05 8.317828178405762e-05 9.359370445327642e-07 -0.0019598989747464657 -9.798770770430565e-05 -8.317967876791954e-05 0.0023957067169249058 0.0001242239959537983 9.476905688643456e-05
44 22 1 21.5 8.807171658631319e-09 -0.0015478071837582907 9.528174996376038e-05 8.07885080575943e-05 1.0299947542646848e-06 -0.001959493849426508 -9.528035297989845e-05 -8.077593520283699e-05 0.0022453111596405506 3.82973812520504e-05 2.8362032026052475e-05
45 22 2 22.0 7.708700941466695e-09 -0.0015478350620986127 9.280815720558167e-05 7.856637239456177e-05 9.84289633354507e-07 -0.0019597294740378857 -9.280489757657051e-05 -7.857801392674446e-05 0.0021656760945916176 1.8442049622535706e-05 1.2994743883609772e-05
46 23 1 22.5 5.829010607527607e-09 -0.0015478298144738873 9.077228605747223e-05 7.675401866436005e-05 1.0561968476485717e-06 -0.0019593103788793087 -9.077740833163261e-05 -7.675448432564735e-05 0.001967994961887598 -0.00010093534365296364 -8.322251960635185e-05
47 23 2 23.0 1.00678847481106e-08 -0.0015478396129139588 8.917506784200668e-05 7.518846541643143e-05 9.189075473869934e-07 -0.001959436573088169 -8.916761726140976e-05 -7.51987099647522e-05 0.0018595317378640175 -9.398628026247025e-05 -7.435213774442673e-05
48 24 1 23.5 9.096645881001564e-09 -0.0015478476094394076 8.79606232047081e-05 7.397029548883438e-05 9.397743796490943e-07 -0.0019590607844293118 -8.79545696079731e-05 -7.396889850497246e-05 0.0016328254714608192 -0.00023874826729297638 -0.00019633769989013672
49 24 2 24.0 8.815424390462567e-09 -0.001547844811637395 8.694268763065338e-05 7.304549217224121e-05 9.335749210359623e-07 -0.001959147397428751 -8.693570271134377e-05 -7.305433973670006e-05 0.0015028249472379684 -0.0002091461792588234 -0.00016683153808116913
@@ -0,0 +1,73 @@
step,level,substep,max_error,max_ratio,regime,drift_m,drift_px,drift_py,ideal_defect_m,ideal_defect_px,ideal_defect_py,measured_rounding_m,measured_rounding_px,measured_rounding_py
1,fine,1,8.229037262719174e-08,0.3569820693406681,True,1.626182347536087e-05,-3.3527612686157227e-08,-1.7695128917694092e-08,-3.0010716134398763e-16,-1.214306433183765e-17,-1.734723475976807e-18,1.6261823475660978e-05,-3.352761267401416e-08,-1.7695128915959368e-08
1,fine,2,5.173531247848473e-08,0.2677766155245442,True,-3.394670784473419e-07,1.3969838619232178e-09,1.7229467630386353e-08,-5.745404152435185e-15,-1.0408340855860843e-17,5.898059818321144e-17,-3.3946707270193777e-07,1.3969838723315586e-09,1.7229467571405754e-08
1,coarse,1,1.1080350609260492e-08,0.10456730670501622,True,-1.5292316675186157e-06,-1.30385160446167e-08,-1.5832483768463135e-07,-4.288236432614667e-15,-5.551115123125783e-17,1.3877787807814457e-17,-1.5292316632303793e-06,-1.3038515989105548e-08,-1.5832483769850914e-07
2,fine,1,9.892327201832529e-08,0.29769478490638285,True,9.881332516670227e-07,-3.3527612686157227e-08,-1.993030309677124e-07,-5.195496810550537e-15,-2.949029909160572e-17,2.1337098754514727e-16,9.881332568625195e-07,-3.352761265666693e-08,-1.993030311810834e-07
2,fine,2,8.832159215099722e-08,0.3121116042355555,True,2.668239176273346e-06,-4.284083843231201e-08,1.2852251529693604e-07,-1.1539380562197721e-14,-1.457167719820518e-16,2.2898349882893854e-16,2.6682391878127265e-06,-4.284083828659524e-08,1.2852251506795254e-07
2,coarse,1,1.6365805183271576e-08,0.1544470929589978,True,-1.426786184310913e-06,-3.0919909477233887e-07,-3.0919909477233887e-07,-6.286637876939949e-15,-8.326672684688674e-17,-8.326672684688674e-17,-1.4267861780242752e-06,-3.0919909468907214e-07,-3.0919909468907214e-07
3,fine,1,8.23703105723439e-08,0.31152334896616624,True,4.902016371488571e-06,1.5227124094963074e-07,1.280568540096283e-07,-1.1922754450388595e-14,9.540979117872439e-17,3.452099717193846e-16,4.902016383411326e-06,1.5227124085422095e-07,1.2805685366441832e-07
3,fine,2,1.0607572520360264e-07,0.3828123813437159,True,8.435919880867004e-06,7.35744833946228e-08,-3.259629011154175e-08,-1.7525911277793682e-14,9.540979117872439e-17,3.5561831257524545e-16,8.435919898392916e-06,7.357448329921301e-08,-3.259629046716006e-08
3,coarse,1,1.0010523732173482e-07,0.2854567053212911,True,9.115785360336304e-06,3.3155083656311035e-07,3.203749656677246e-07,-3.837208328860697e-15,1.5334955527634975e-15,1.2420620087993939e-15,9.115785364173512e-06,3.315508350296148e-07,3.203749644256626e-07
4,fine,1,9.437402781475868e-08,0.3632811360585352,True,1.0774470865726471e-05,2.8405338525772095e-07,3.0174851417541504e-07,-2.0582494042464816e-14,2.411265631607762e-16,2.7929047963226594e-16,1.0774470886308965e-05,2.840533850165944e-07,3.0174851389612456e-07
4,fine,2,1.411709008580786e-07,0.4323516759917293,True,1.1160969734191895e-05,2.169981598854065e-07,5.774199962615967e-08,-1.6453852169640015e-14,-5.533767888366015e-16,-4.2847669856627135e-16,1.1160969750645747e-05,2.1699816043878328e-07,5.7742000054636367e-08
4,coarse,1,1.2150177930436712e-07,0.37139422446265463,True,1.3064593076705933e-05,5.997717380523682e-07,5.62518835067749e-07,-1.2559397966072083e-14,-5.967448757360216e-16,-2.498001805406602e-16,1.306459308926533e-05,5.99771738649113e-07,5.625188353175492e-07
5,fine,1,1.2376571800754022e-07,0.4335945297787668,True,1.0852236300706863e-05,-3.022141754627228e-07,-3.1618401408195496e-07,-1.5610776560315287e-14,5.377642775528102e-17,-3.625572064791527e-16,1.085223631631764e-05,-3.022141755164992e-07,-3.1618401371939775e-07
5,fine,2,1.2417755734794866e-07,0.3644862055932074,True,8.977483958005905e-06,-2.621673047542572e-07,-7.031485438346863e-08,-1.519617764955683e-14,-1.8041124150158794e-16,8.430756093247282e-16,8.977483973202083e-06,-2.6216730457384596e-07,-7.031485522654424e-08
5,coarse,1,1.2532259030528792e-07,0.38942307019337585,True,1.49458646774292e-05,9.723007678985596e-07,1.2628734111785889e-06,-1.6535384173010925e-14,1.5959455978986625e-16,6.175615574477433e-16,1.4945864693964583e-05,9.72300767738965e-07,1.2628734105610273e-06
6,fine,1,9.483337493065847e-08,0.32226540864225656,True,6.834045052528381e-06,4.284083843231201e-08,-1.0244548320770264e-07,-1.4689638394571602e-14,1.1102230246251565e-16,2.914335439641036e-16,6.83404506721802e-06,4.284083832128971e-08,-1.0244548349913618e-07
6,fine,2,1.1486422213380365e-07,0.36328113343919116,True,6.2193721532821655e-06,-4.190951585769653e-08,-1.30385160446167e-08,-1.437044927499187e-14,1.7694179454963432e-16,-1.0408340855860843e-17,6.219372167652615e-06,-4.190951603463833e-08,-1.3038516034208358e-08
6,coarse,1,1.0239773140519048e-07,0.43028837580529966,True,1.383945345878601e-05,4.954636096954346e-07,4.284083843231201e-07,-2.0011770018868447e-14,3.191891195797325e-16,1.0269562977782698e-15,1.383945347879778e-05,4.954636093762455e-07,4.284083832961638e-07
7,fine,1,1.1381071352012384e-07,0.39830750519457453,True,5.2102841436862946e-06,-2.0023435354232788e-08,-1.0477378964424133e-07,-1.6167622796103842e-14,9.020562075079397e-17,0.0,5.210284159853917e-06,-2.002343544443841e-08,-1.0477378964424133e-07
7,fine,2,1.1557639800763297e-07,0.4252975630997776,True,4.476867616176605e-06,-1.2479722499847412e-07,4.0046870708465576e-08,-1.4878723253453074e-14,8.673617379884035e-18,4.388850394221322e-16,4.4768676310553285e-06,-1.2479722500714774e-07,4.004687026958054e-08
7,coarse,1,1.0902046165828239e-07,0.38161058826685446,True,1.321360468864441e-05,9.126961231231689e-07,-2.086162567138672e-07,-2.4445723223465166e-14,-5.898059818321144e-16,-3.122502256758253e-16,1.3213604713090132e-05,9.126961237129749e-07,-2.0861625640161696e-07
8,fine,1,1.2369974378145798e-07,0.3659033398608433,True,4.209578037261963e-06,-1.2479722499847412e-07,-2.421438694000244e-08,-1.5269036035547856e-14,-1.4224732503009818e-16,-7.28583859910259e-17,4.209578052530999e-06,-1.247972248562268e-07,-2.4214386867144055e-08
8,fine,2,1.3039186863572638e-07,0.3566417233064843,True,4.0014274418354034e-06,5.075708031654358e-08,-1.6298145055770874e-08,-1.6002824065886045e-14,-2.949029909160572e-17,-2.5153490401663703e-16,4.0014274578382275e-06,5.075708034603388e-08,-1.629814480423597e-08
8,coarse,1,1.265961931951054e-07,0.38341345468786764,True,9.08784568309784e-06,6.09084963798523e-07,-5.979090929031372e-07,-2.2336299476677368e-14,-1.4224732503009818e-15,2.0816681711721685e-17,9.087845705434139e-06,6.090849652209962e-07,-5.979090929239539e-07
9,fine,1,1.1700286717264419e-07,0.42325024900493485,True,2.2551976144313812e-06,-1.150183379650116e-07,-3.026798367500305e-08,-1.5406079190150024e-14,6.418476861114186e-17,2.6194324487249787e-16,2.2551976298374604e-06,-1.1501833802919637e-07,-3.0267983936946297e-08
9,fine,2,1.05960657470483e-07,0.3591277749177671,True,3.159046173095703e-06,-5.8673322200775146e-08,-1.471489667892456e-07,-1.5987211554602254e-14,-6.245004513516506e-17,-2.0816681711721685e-17,3.1590461890829147e-06,-5.86733221383251e-08,-1.4714896676842892e-07
9,coarse,1,1.1063907701114317e-07,0.4156431955412631,True,5.3513795137405396e-06,-3.1478703022003174e-07,-5.345791578292847e-07,-2.5042468099201187e-14,1.0408340855860843e-16,-2.2898349882893854e-16,5.351379538783008e-06,-3.1478703032411515e-07,-5.345791576003012e-07
10,fine,1,1.6477090769573266e-07,0.3991506368171169,True,2.605374902486801e-06,1.2619420886039734e-07,6.007030606269836e-08,-1.5024440025435126e-14,-3.2786273695961654e-16,-2.8622937353617317e-16,2.605374917511241e-06,1.2619420918826008e-07,6.007030634892774e-08
10,fine,2,1.233670676725751e-07,0.3467327260376902,True,2.4153850972652435e-06,-1.5133991837501526e-07,-1.19674950838089e-07,-1.5607307113363333e-14,-1.9949319973733282e-16,4.631711680858075e-16,2.4153851128725506e-06,-1.5133991817552206e-07,-1.1967495130126016e-07
10,coarse,1,1.3984166169489498e-07,0.4038458162128909,True,6.22868537902832e-06,-2.942979335784912e-07,3.725290298461914e-09,-2.3592239273284576e-14,-4.163336342344337e-16,1.1657341758564144e-15,6.22868540262056e-06,-2.942979331621576e-07,3.725289132727738e-09
11,fine,1,1.1264907540109448e-07,0.37435057774799535,True,1.6032718122005463e-06,4.190951585769653e-09,2.9336661100387573e-08,-1.5607307113363333e-14,2.723515857283587e-16,-1.0234868508263162e-16,1.6032718278078534e-06,4.190951313418068e-09,2.9336661202736258e-08
11,fine,2,1.3385929209519531e-07,0.4296446436631812,True,1.1781230568885803e-06,2.3469328880310059e-07,1.126900315284729e-07,-1.665854953980528e-14,2.0296264668928643e-16,3.2959746043559335e-17,1.1781230735471299e-06,2.3469328860013794e-07,1.1269003149551315e-07
11,coarse,1,1.2484760447684096e-07,0.3737977990108256,True,1.9688159227371216e-06,-6.146728992462158e-08,-2.421438694000244e-08,-2.295386103412511e-14,-1.5265566588595902e-16,-9.575673587391975e-16,1.9688159456909826e-06,-6.146728977196592e-08,-2.4214385982435083e-08
12,fine,1,1.1342225503252479e-07,0.3929712248585018,True,2.9103830456733704e-06,1.1827796697616577e-07,1.6670674085617065e-07,-1.6981208106336965e-14,2.5153490401663703e-16,1.0234868508263162e-16,2.9103830626545785e-06,1.1827796672463087e-07,1.6670674075382197e-07
12,fine,2,1.2337913590787508e-07,0.3632480304781915,True,2.22865492105484e-06,7.450580596923828e-09,1.3690441846847534e-07,-1.7019372022808454e-14,-1.9081958235744878e-17,1.6479873021779667e-16,2.228654938074212e-06,7.450580616005786e-09,1.369044183036766e-07
12,coarse,1,1.0392955884785948e-07,0.34435036745116887,True,4.416331648826599e-06,8.009374141693115e-08,-7.264316082000732e-08,-2.665923037881157e-14,1.942890293094024e-16,3.3306690738754696e-16,4.4163316754858295e-06,8.009374122264212e-08,-7.264316115307423e-08
13,fine,1,1.120637568297056e-07,0.3794727716066827,True,1.1702068150043488e-06,-1.4016404747962952e-07,-1.0477378964424133e-07,-1.6571813366006438e-14,8.153200337090993e-17,-1.0928757898653885e-16,1.1702068315761621e-06,-1.4016404756116152e-07,-1.0477378953495375e-07
13,fine,2,1.1608141914365433e-07,0.3684207409368108,True,1.93621963262558e-06,-2.1979212760925293e-07,-7.543712854385376e-08,-1.696733031852915e-14,1.5612511283791264e-17,4.0072112295064244e-16,1.93621964959291e-06,-2.1979212762486544e-07,-7.543712894457488e-08
13,coarse,1,1.1553440504297185e-07,0.413461159221051,True,2.12155282497406e-06,9.872019290924072e-08,3.1851232051849365e-07,-2.4966140266258208e-14,1.0685896612017132e-15,3.885780586188048e-16,2.1215528499402003e-06,9.872019184065106e-08,3.185123201299156e-07
14,fine,1,1.3012184874039434e-07,0.4470057319678252,True,2.093147486448288e-06,-2.7474015951156616e-08,1.816079020500183e-08,-1.6941309466389498e-14,2.0469737016526324e-16,-2.393918396847994e-16,2.0931475033895974e-06,-2.7474016155853986e-08,1.816079044439367e-08
14,fine,2,1.161938236737825e-07,0.43455223301865037,True,2.180226147174835e-06,1.6577541828155518e-07,3.166496753692627e-08,-1.662038562333379e-14,-3.139849491518021e-16,-5.724587470723463e-17,2.180226163795221e-06,1.6577541859554012e-07,3.1664967594172144e-08
14,coarse,1,1.171716388359556e-07,0.34014613609932465,True,3.285706043243408e-06,5.21540641784668e-08,-8.940696716308594e-08,-2.5222879340702775e-14,2.0122792321330962e-16,-3.95516952522712e-16,3.2857060684662875e-06,5.2154063977238874e-08,-8.940696676756898e-08
15,fine,1,1.188765739179587e-07,0.3778719310571328,True,2.386048436164856e-06,1.0989606380462646e-07,4.190951585769653e-08,-1.6297727056802103e-14,3.0010716134398763e-16,5.0306980803327406e-17,2.386048452462583e-06,1.098960635045193e-07,4.190951580738955e-08
15,fine,2,1.2815464434101642e-07,0.3887039950605819,True,2.2151507437229156e-06,5.3551048040390015e-08,1.5599653124809265e-07,-1.6632528687665626e-14,-3.469446951953614e-17,-2.220446049250313e-16,2.2151507603554443e-06,5.3551048075084484e-08,1.5599653147013726e-07
15,coarse,1,1.132467172260121e-07,0.3798076391349909,True,4.431232810020447e-06,-6.891787052154541e-08,-4.6566128730773926e-08,-2.4917568008930857e-14,5.898059818321144e-16,7.008282842946301e-16,4.431232834938015e-06,-6.891787111135139e-08,-4.656612943160221e-08
16,fine,1,1.1449205894464853e-07,0.4232816528057199,True,1.267995685338974e-06,7.962808012962341e-08,8.89413058757782e-08,-1.7224069392973718e-14,1.9255430583342559e-16,2.3071822230491534e-16,1.2679957025630434e-06,7.962807993706911e-08,8.894130564505998e-08
16,fine,2,1.1465035798519096e-07,0.38660659294745114,True,1.61072239279747e-06,2.0070001482963562e-07,8.242204785346985e-08,-1.688579831515824e-14,2.0816681711721685e-16,-3.95516952522712e-16,1.6107224096832684e-06,2.007000146214688e-07,8.24220482489868e-08
16,coarse,1,1.026492656430733e-07,0.39551928594354874,True,4.755333065986633e-06,2.8870999813079834e-07,-1.30385160446167e-08,-2.5340840537069198e-14,8.465450562766819e-16,-1.4988010832439613e-15,4.755333091327474e-06,2.887099972842533e-07,-1.3038514545815616e-08
17,fine,1,1.4306400941688224e-07,0.3804206132029011,True,2.477318048477173e-06,2.952292561531067e-07,2.1420419216156006e-07,-1.6018436577169837e-14,1.1102230246251565e-16,-2.498001805406602e-16,2.4773180644956094e-06,2.952292560420844e-07,2.1420419241136024e-07
17,fine,2,1.206053866775747e-07,0.40931703720753354,True,2.6957131922245026e-06,3.655441105365753e-07,1.7834827303886414e-07,-1.704365815147213e-14,3.382710778154774e-16,-1.43982048506075e-16,2.6957132092681607e-06,3.6554411019830424e-07,1.7834827318284618e-07
17,coarse,1,1.3320810943184824e-07,0.4098554436464823,True,4.893168807029724e-06,2.3655593395233154e-07,3.632158041000366e-07,-2.93723378952393e-14,-4.649058915617843e-16,4.2327252813834093e-16,4.893168836402062e-06,2.3655593441723743e-07,3.632158036767641e-07
18,fine,1,1.1518374609664761e-07,0.37525164303996766,True,3.0049122869968414e-06,2.92900949716568e-07,2.4633482098579407e-07,-1.704365815147213e-14,-1.474514954580286e-16,5.724587470723463e-17,3.0049123040404996e-06,2.929009498640195e-07,2.463348209285482e-07
18,fine,2,1.5383020013359783e-07,0.4339170567027524,True,2.28220596909523e-06,3.2549723982810974e-07,2.48197466135025e-07,-1.700029006457271e-14,-1.214306433183765e-16,-3.122502256758253e-16,2.28220598609552e-06,3.254972399495404e-07,2.4819746644727525e-07
18,coarse,1,1.4574858631100085e-07,0.42004802685791165,True,4.898756742477417e-06,-1.564621925354004e-07,-2.123415470123291e-07,-2.679106936298581e-14,1.457167719820518e-16,-4.85722573273506e-17,4.898756769268486e-06,-1.5646219268111716e-07,-2.1234154696375684e-07
19,fine,1,1.1289196333308382e-07,0.4426868958150174,True,2.4051405489444733e-06,3.8230791687965393e-07,4.23286110162735e-07,-1.7246620798161416e-14,-5.447031714567174e-16,-2.42861286636753e-16,2.405140566191094e-06,3.823079174243571e-07,4.2328611040559627e-07
19,fine,2,1.3318459290978524e-07,0.4458767766498759,True,2.4051405489444733e-06,-1.3504177331924438e-08,-1.6298145055770874e-08,-1.6679366221517e-14,-1.8561541192951836e-16,4.683753385137379e-17,2.4051405656238395e-06,-1.3504177146309027e-08,-1.6298145102608408e-08
19,coarse,1,1.3627775263813646e-07,0.37598585924709055,True,6.38328492641449e-06,-2.514570951461792e-07,2.1792948246002197e-07,-2.724209746673978e-14,-7.91033905045424e-16,-1.3877787807814457e-17,6.383284953656587e-06,-2.514570943551453e-07,2.1792948247389976e-07
20,fine,1,1.2067538701643343e-07,0.397654453667931,True,3.3676624298095703e-06,-7.636845111846924e-08,8.195638656616211e-08,-1.6471199404399783e-14,1.0581813203458523e-16,7.806255641895632e-17,3.3676624462807697e-06,-7.636845122428737e-08,8.195638648809955e-08
20,fine,2,1.1349498318935503e-07,0.4276325956343959,True,3.5767443478107452e-06,-7.869675755500793e-08,6.565824151039124e-08,-1.5959455978986625e-14,9.020562075079397e-17,5.898059818321144e-17,3.5767443637702012e-06,-7.869675764521356e-08,6.565824145141064e-08
20,coarse,1,1.5850306378517587e-07,0.5285112236646456,True,3.5408884286880493e-06,-1.993030309677124e-07,-3.7066638469696045e-07,-2.525757381022231e-14,7.91033905045424e-16,-2.3592239273284576e-16,3.540888453945623e-06,-1.993030317587463e-07,-3.7066638446103806e-07
21,fine,1,1.2747028055315468e-07,0.3807671146447972,True,3.180466592311859e-06,-9.872019290924072e-08,-4.377216100692749e-08,-1.619537837171947e-14,5.204170427930421e-17,-1.4224732503009818e-16,3.1804666085072375e-06,-9.872019296128243e-08,-4.3772160864680165e-08
21,fine,2,1.1436689684174439e-07,0.41457208617159613,True,2.8158538043498993e-06,-4.516914486885071e-08,3.119930624961853e-08,-1.622833811776303e-14,-2.0296264668928643e-16,-1.7867651802561113e-16,2.8158538205782374e-06,-4.516914466588806e-08,3.119930642829505e-08
21,coarse,1,1.3219836714206679e-07,0.4111722561110483,True,5.48921525478363e-06,-9.816139936447144e-07,-5.345791578292847e-07,-2.7602919949742954e-14,4.0245584642661925e-16,2.7755575615628914e-16,5.48921528238655e-06,-9.816139940471702e-07,-5.345791581068404e-07
22,fine,1,1.247986221031283e-07,0.4025936491208882,True,2.5955960154533386e-06,-1.1734664440155029e-07,7.636845111846924e-08,-1.670712179713263e-14,2.0643209364124004e-16,-1.196959198423997e-16,2.5955960321604604e-06,-1.1734664460798239e-07,7.636845123816516e-08
22,fine,2,1.2467687349193568e-07,0.4026463456064581,True,2.169981598854065e-06,-2.0023435354232788e-07,-2.5331974029541016e-07,-1.5954251808558695e-14,4.336808689942018e-17,8.847089727481716e-17,2.1699816148083167e-06,-2.0023435358569597e-07,-2.5331974038388105e-07
22,coarse,1,1.303169513411362e-07,0.4534581358023719,True,4.8317015171051025e-06,-1.4826655387878418e-06,-8.456408977508545e-07,-2.6728619317850644e-14,-9.71445146547012e-17,-4.163336342344337e-16,4.831701543833722e-06,-1.4826655386906973e-06,-8.456408973345209e-07
23,fine,1,1.1580148451262318e-07,0.3892248238329876,True,2.83215194940567e-06,-4.284083843231201e-08,-1.3317912817001343e-07,-1.7317744460676465e-14,2.2551405187698492e-17,-3.9898639947466563e-17,2.8321519667234146e-06,-4.284083845486342e-08,-1.331791281301148e-07
23,fine,2,1.4772394407724931e-07,0.44883956143532583,True,2.432148903608322e-06,-1.0570511221885681e-07,-3.306195139884949e-08,-1.628211454551831e-14,4.85722573273506e-17,1.1796119636642288e-16,2.4321489198904367e-06,-1.0570511226742907e-07,-3.3061951516810684e-08
23,coarse,1,1.4415727089822639e-07,0.46236304392819116,True,8.864328265190125e-06,-8.624047040939331e-07,-5.19677996635437e-07,-2.839395385478838e-14,-3.7470027081099033e-16,-1.0269562977782698e-15,8.864328293584078e-06,-8.624047037192328e-07,-5.196779956084807e-07
24,fine,1,1.1816075007331506e-07,0.40334771123509106,True,2.196524292230606e-06,-5.2619725465774536e-08,-1.327134668827057e-07,-1.619537837171947e-14,3.400058012914542e-16,7.979727989493313e-17,2.1965243084259845e-06,-5.261972580578034e-08,-1.3271346696250297e-07
24,fine,2,1.2605529897680157e-07,0.4651221485857391,True,2.941582351922989e-06,-2.2584572434425354e-07,6.05359673500061e-09,-1.802204219192305e-14,-2.5153490401663703e-16,2.3418766925686896e-16,2.941582369945031e-06,-2.2584572409271864e-07,6.053596500812941e-09
24,coarse,1,1.573361411155716e-07,0.43294013951653565,True,9.939074516296387e-06,-2.905726432800293e-07,1.4156103134155273e-07,-2.768618667658984e-14,-1.6653345369377348e-16,1.1102230246251565e-15,9.939074543982573e-06,-2.9057264311349584e-07,1.415610302313297e-07
1 step level substep max_error max_ratio regime drift_m drift_px drift_py ideal_defect_m ideal_defect_px ideal_defect_py measured_rounding_m measured_rounding_px measured_rounding_py
2 1 fine 1 8.229037262719174e-08 0.3569820693406681 True 1.626182347536087e-05 -3.3527612686157227e-08 -1.7695128917694092e-08 -3.0010716134398763e-16 -1.214306433183765e-17 -1.734723475976807e-18 1.6261823475660978e-05 -3.352761267401416e-08 -1.7695128915959368e-08
3 1 fine 2 5.173531247848473e-08 0.2677766155245442 True -3.394670784473419e-07 1.3969838619232178e-09 1.7229467630386353e-08 -5.745404152435185e-15 -1.0408340855860843e-17 5.898059818321144e-17 -3.3946707270193777e-07 1.3969838723315586e-09 1.7229467571405754e-08
4 1 coarse 1 1.1080350609260492e-08 0.10456730670501622 True -1.5292316675186157e-06 -1.30385160446167e-08 -1.5832483768463135e-07 -4.288236432614667e-15 -5.551115123125783e-17 1.3877787807814457e-17 -1.5292316632303793e-06 -1.3038515989105548e-08 -1.5832483769850914e-07
5 2 fine 1 9.892327201832529e-08 0.29769478490638285 True 9.881332516670227e-07 -3.3527612686157227e-08 -1.993030309677124e-07 -5.195496810550537e-15 -2.949029909160572e-17 2.1337098754514727e-16 9.881332568625195e-07 -3.352761265666693e-08 -1.993030311810834e-07
6 2 fine 2 8.832159215099722e-08 0.3121116042355555 True 2.668239176273346e-06 -4.284083843231201e-08 1.2852251529693604e-07 -1.1539380562197721e-14 -1.457167719820518e-16 2.2898349882893854e-16 2.6682391878127265e-06 -4.284083828659524e-08 1.2852251506795254e-07
7 2 coarse 1 1.6365805183271576e-08 0.1544470929589978 True -1.426786184310913e-06 -3.0919909477233887e-07 -3.0919909477233887e-07 -6.286637876939949e-15 -8.326672684688674e-17 -8.326672684688674e-17 -1.4267861780242752e-06 -3.0919909468907214e-07 -3.0919909468907214e-07
8 3 fine 1 8.23703105723439e-08 0.31152334896616624 True 4.902016371488571e-06 1.5227124094963074e-07 1.280568540096283e-07 -1.1922754450388595e-14 9.540979117872439e-17 3.452099717193846e-16 4.902016383411326e-06 1.5227124085422095e-07 1.2805685366441832e-07
9 3 fine 2 1.0607572520360264e-07 0.3828123813437159 True 8.435919880867004e-06 7.35744833946228e-08 -3.259629011154175e-08 -1.7525911277793682e-14 9.540979117872439e-17 3.5561831257524545e-16 8.435919898392916e-06 7.357448329921301e-08 -3.259629046716006e-08
10 3 coarse 1 1.0010523732173482e-07 0.2854567053212911 True 9.115785360336304e-06 3.3155083656311035e-07 3.203749656677246e-07 -3.837208328860697e-15 1.5334955527634975e-15 1.2420620087993939e-15 9.115785364173512e-06 3.315508350296148e-07 3.203749644256626e-07
11 4 fine 1 9.437402781475868e-08 0.3632811360585352 True 1.0774470865726471e-05 2.8405338525772095e-07 3.0174851417541504e-07 -2.0582494042464816e-14 2.411265631607762e-16 2.7929047963226594e-16 1.0774470886308965e-05 2.840533850165944e-07 3.0174851389612456e-07
12 4 fine 2 1.411709008580786e-07 0.4323516759917293 True 1.1160969734191895e-05 2.169981598854065e-07 5.774199962615967e-08 -1.6453852169640015e-14 -5.533767888366015e-16 -4.2847669856627135e-16 1.1160969750645747e-05 2.1699816043878328e-07 5.7742000054636367e-08
13 4 coarse 1 1.2150177930436712e-07 0.37139422446265463 True 1.3064593076705933e-05 5.997717380523682e-07 5.62518835067749e-07 -1.2559397966072083e-14 -5.967448757360216e-16 -2.498001805406602e-16 1.306459308926533e-05 5.99771738649113e-07 5.625188353175492e-07
14 5 fine 1 1.2376571800754022e-07 0.4335945297787668 True 1.0852236300706863e-05 -3.022141754627228e-07 -3.1618401408195496e-07 -1.5610776560315287e-14 5.377642775528102e-17 -3.625572064791527e-16 1.085223631631764e-05 -3.022141755164992e-07 -3.1618401371939775e-07
15 5 fine 2 1.2417755734794866e-07 0.3644862055932074 True 8.977483958005905e-06 -2.621673047542572e-07 -7.031485438346863e-08 -1.519617764955683e-14 -1.8041124150158794e-16 8.430756093247282e-16 8.977483973202083e-06 -2.6216730457384596e-07 -7.031485522654424e-08
16 5 coarse 1 1.2532259030528792e-07 0.38942307019337585 True 1.49458646774292e-05 9.723007678985596e-07 1.2628734111785889e-06 -1.6535384173010925e-14 1.5959455978986625e-16 6.175615574477433e-16 1.4945864693964583e-05 9.72300767738965e-07 1.2628734105610273e-06
17 6 fine 1 9.483337493065847e-08 0.32226540864225656 True 6.834045052528381e-06 4.284083843231201e-08 -1.0244548320770264e-07 -1.4689638394571602e-14 1.1102230246251565e-16 2.914335439641036e-16 6.83404506721802e-06 4.284083832128971e-08 -1.0244548349913618e-07
18 6 fine 2 1.1486422213380365e-07 0.36328113343919116 True 6.2193721532821655e-06 -4.190951585769653e-08 -1.30385160446167e-08 -1.437044927499187e-14 1.7694179454963432e-16 -1.0408340855860843e-17 6.219372167652615e-06 -4.190951603463833e-08 -1.3038516034208358e-08
19 6 coarse 1 1.0239773140519048e-07 0.43028837580529966 True 1.383945345878601e-05 4.954636096954346e-07 4.284083843231201e-07 -2.0011770018868447e-14 3.191891195797325e-16 1.0269562977782698e-15 1.383945347879778e-05 4.954636093762455e-07 4.284083832961638e-07
20 7 fine 1 1.1381071352012384e-07 0.39830750519457453 True 5.2102841436862946e-06 -2.0023435354232788e-08 -1.0477378964424133e-07 -1.6167622796103842e-14 9.020562075079397e-17 0.0 5.210284159853917e-06 -2.002343544443841e-08 -1.0477378964424133e-07
21 7 fine 2 1.1557639800763297e-07 0.4252975630997776 True 4.476867616176605e-06 -1.2479722499847412e-07 4.0046870708465576e-08 -1.4878723253453074e-14 8.673617379884035e-18 4.388850394221322e-16 4.4768676310553285e-06 -1.2479722500714774e-07 4.004687026958054e-08
22 7 coarse 1 1.0902046165828239e-07 0.38161058826685446 True 1.321360468864441e-05 9.126961231231689e-07 -2.086162567138672e-07 -2.4445723223465166e-14 -5.898059818321144e-16 -3.122502256758253e-16 1.3213604713090132e-05 9.126961237129749e-07 -2.0861625640161696e-07
23 8 fine 1 1.2369974378145798e-07 0.3659033398608433 True 4.209578037261963e-06 -1.2479722499847412e-07 -2.421438694000244e-08 -1.5269036035547856e-14 -1.4224732503009818e-16 -7.28583859910259e-17 4.209578052530999e-06 -1.247972248562268e-07 -2.4214386867144055e-08
24 8 fine 2 1.3039186863572638e-07 0.3566417233064843 True 4.0014274418354034e-06 5.075708031654358e-08 -1.6298145055770874e-08 -1.6002824065886045e-14 -2.949029909160572e-17 -2.5153490401663703e-16 4.0014274578382275e-06 5.075708034603388e-08 -1.629814480423597e-08
25 8 coarse 1 1.265961931951054e-07 0.38341345468786764 True 9.08784568309784e-06 6.09084963798523e-07 -5.979090929031372e-07 -2.2336299476677368e-14 -1.4224732503009818e-15 2.0816681711721685e-17 9.087845705434139e-06 6.090849652209962e-07 -5.979090929239539e-07
26 9 fine 1 1.1700286717264419e-07 0.42325024900493485 True 2.2551976144313812e-06 -1.150183379650116e-07 -3.026798367500305e-08 -1.5406079190150024e-14 6.418476861114186e-17 2.6194324487249787e-16 2.2551976298374604e-06 -1.1501833802919637e-07 -3.0267983936946297e-08
27 9 fine 2 1.05960657470483e-07 0.3591277749177671 True 3.159046173095703e-06 -5.8673322200775146e-08 -1.471489667892456e-07 -1.5987211554602254e-14 -6.245004513516506e-17 -2.0816681711721685e-17 3.1590461890829147e-06 -5.86733221383251e-08 -1.4714896676842892e-07
28 9 coarse 1 1.1063907701114317e-07 0.4156431955412631 True 5.3513795137405396e-06 -3.1478703022003174e-07 -5.345791578292847e-07 -2.5042468099201187e-14 1.0408340855860843e-16 -2.2898349882893854e-16 5.351379538783008e-06 -3.1478703032411515e-07 -5.345791576003012e-07
29 10 fine 1 1.6477090769573266e-07 0.3991506368171169 True 2.605374902486801e-06 1.2619420886039734e-07 6.007030606269836e-08 -1.5024440025435126e-14 -3.2786273695961654e-16 -2.8622937353617317e-16 2.605374917511241e-06 1.2619420918826008e-07 6.007030634892774e-08
30 10 fine 2 1.233670676725751e-07 0.3467327260376902 True 2.4153850972652435e-06 -1.5133991837501526e-07 -1.19674950838089e-07 -1.5607307113363333e-14 -1.9949319973733282e-16 4.631711680858075e-16 2.4153851128725506e-06 -1.5133991817552206e-07 -1.1967495130126016e-07
31 10 coarse 1 1.3984166169489498e-07 0.4038458162128909 True 6.22868537902832e-06 -2.942979335784912e-07 3.725290298461914e-09 -2.3592239273284576e-14 -4.163336342344337e-16 1.1657341758564144e-15 6.22868540262056e-06 -2.942979331621576e-07 3.725289132727738e-09
32 11 fine 1 1.1264907540109448e-07 0.37435057774799535 True 1.6032718122005463e-06 4.190951585769653e-09 2.9336661100387573e-08 -1.5607307113363333e-14 2.723515857283587e-16 -1.0234868508263162e-16 1.6032718278078534e-06 4.190951313418068e-09 2.9336661202736258e-08
33 11 fine 2 1.3385929209519531e-07 0.4296446436631812 True 1.1781230568885803e-06 2.3469328880310059e-07 1.126900315284729e-07 -1.665854953980528e-14 2.0296264668928643e-16 3.2959746043559335e-17 1.1781230735471299e-06 2.3469328860013794e-07 1.1269003149551315e-07
34 11 coarse 1 1.2484760447684096e-07 0.3737977990108256 True 1.9688159227371216e-06 -6.146728992462158e-08 -2.421438694000244e-08 -2.295386103412511e-14 -1.5265566588595902e-16 -9.575673587391975e-16 1.9688159456909826e-06 -6.146728977196592e-08 -2.4214385982435083e-08
35 12 fine 1 1.1342225503252479e-07 0.3929712248585018 True 2.9103830456733704e-06 1.1827796697616577e-07 1.6670674085617065e-07 -1.6981208106336965e-14 2.5153490401663703e-16 1.0234868508263162e-16 2.9103830626545785e-06 1.1827796672463087e-07 1.6670674075382197e-07
36 12 fine 2 1.2337913590787508e-07 0.3632480304781915 True 2.22865492105484e-06 7.450580596923828e-09 1.3690441846847534e-07 -1.7019372022808454e-14 -1.9081958235744878e-17 1.6479873021779667e-16 2.228654938074212e-06 7.450580616005786e-09 1.369044183036766e-07
37 12 coarse 1 1.0392955884785948e-07 0.34435036745116887 True 4.416331648826599e-06 8.009374141693115e-08 -7.264316082000732e-08 -2.665923037881157e-14 1.942890293094024e-16 3.3306690738754696e-16 4.4163316754858295e-06 8.009374122264212e-08 -7.264316115307423e-08
38 13 fine 1 1.120637568297056e-07 0.3794727716066827 True 1.1702068150043488e-06 -1.4016404747962952e-07 -1.0477378964424133e-07 -1.6571813366006438e-14 8.153200337090993e-17 -1.0928757898653885e-16 1.1702068315761621e-06 -1.4016404756116152e-07 -1.0477378953495375e-07
39 13 fine 2 1.1608141914365433e-07 0.3684207409368108 True 1.93621963262558e-06 -2.1979212760925293e-07 -7.543712854385376e-08 -1.696733031852915e-14 1.5612511283791264e-17 4.0072112295064244e-16 1.93621964959291e-06 -2.1979212762486544e-07 -7.543712894457488e-08
40 13 coarse 1 1.1553440504297185e-07 0.413461159221051 True 2.12155282497406e-06 9.872019290924072e-08 3.1851232051849365e-07 -2.4966140266258208e-14 1.0685896612017132e-15 3.885780586188048e-16 2.1215528499402003e-06 9.872019184065106e-08 3.185123201299156e-07
41 14 fine 1 1.3012184874039434e-07 0.4470057319678252 True 2.093147486448288e-06 -2.7474015951156616e-08 1.816079020500183e-08 -1.6941309466389498e-14 2.0469737016526324e-16 -2.393918396847994e-16 2.0931475033895974e-06 -2.7474016155853986e-08 1.816079044439367e-08
42 14 fine 2 1.161938236737825e-07 0.43455223301865037 True 2.180226147174835e-06 1.6577541828155518e-07 3.166496753692627e-08 -1.662038562333379e-14 -3.139849491518021e-16 -5.724587470723463e-17 2.180226163795221e-06 1.6577541859554012e-07 3.1664967594172144e-08
43 14 coarse 1 1.171716388359556e-07 0.34014613609932465 True 3.285706043243408e-06 5.21540641784668e-08 -8.940696716308594e-08 -2.5222879340702775e-14 2.0122792321330962e-16 -3.95516952522712e-16 3.2857060684662875e-06 5.2154063977238874e-08 -8.940696676756898e-08
44 15 fine 1 1.188765739179587e-07 0.3778719310571328 True 2.386048436164856e-06 1.0989606380462646e-07 4.190951585769653e-08 -1.6297727056802103e-14 3.0010716134398763e-16 5.0306980803327406e-17 2.386048452462583e-06 1.098960635045193e-07 4.190951580738955e-08
45 15 fine 2 1.2815464434101642e-07 0.3887039950605819 True 2.2151507437229156e-06 5.3551048040390015e-08 1.5599653124809265e-07 -1.6632528687665626e-14 -3.469446951953614e-17 -2.220446049250313e-16 2.2151507603554443e-06 5.3551048075084484e-08 1.5599653147013726e-07
46 15 coarse 1 1.132467172260121e-07 0.3798076391349909 True 4.431232810020447e-06 -6.891787052154541e-08 -4.6566128730773926e-08 -2.4917568008930857e-14 5.898059818321144e-16 7.008282842946301e-16 4.431232834938015e-06 -6.891787111135139e-08 -4.656612943160221e-08
47 16 fine 1 1.1449205894464853e-07 0.4232816528057199 True 1.267995685338974e-06 7.962808012962341e-08 8.89413058757782e-08 -1.7224069392973718e-14 1.9255430583342559e-16 2.3071822230491534e-16 1.2679957025630434e-06 7.962807993706911e-08 8.894130564505998e-08
48 16 fine 2 1.1465035798519096e-07 0.38660659294745114 True 1.61072239279747e-06 2.0070001482963562e-07 8.242204785346985e-08 -1.688579831515824e-14 2.0816681711721685e-16 -3.95516952522712e-16 1.6107224096832684e-06 2.007000146214688e-07 8.24220482489868e-08
49 16 coarse 1 1.026492656430733e-07 0.39551928594354874 True 4.755333065986633e-06 2.8870999813079834e-07 -1.30385160446167e-08 -2.5340840537069198e-14 8.465450562766819e-16 -1.4988010832439613e-15 4.755333091327474e-06 2.887099972842533e-07 -1.3038514545815616e-08
50 17 fine 1 1.4306400941688224e-07 0.3804206132029011 True 2.477318048477173e-06 2.952292561531067e-07 2.1420419216156006e-07 -1.6018436577169837e-14 1.1102230246251565e-16 -2.498001805406602e-16 2.4773180644956094e-06 2.952292560420844e-07 2.1420419241136024e-07
51 17 fine 2 1.206053866775747e-07 0.40931703720753354 True 2.6957131922245026e-06 3.655441105365753e-07 1.7834827303886414e-07 -1.704365815147213e-14 3.382710778154774e-16 -1.43982048506075e-16 2.6957132092681607e-06 3.6554411019830424e-07 1.7834827318284618e-07
52 17 coarse 1 1.3320810943184824e-07 0.4098554436464823 True 4.893168807029724e-06 2.3655593395233154e-07 3.632158041000366e-07 -2.93723378952393e-14 -4.649058915617843e-16 4.2327252813834093e-16 4.893168836402062e-06 2.3655593441723743e-07 3.632158036767641e-07
53 18 fine 1 1.1518374609664761e-07 0.37525164303996766 True 3.0049122869968414e-06 2.92900949716568e-07 2.4633482098579407e-07 -1.704365815147213e-14 -1.474514954580286e-16 5.724587470723463e-17 3.0049123040404996e-06 2.929009498640195e-07 2.463348209285482e-07
54 18 fine 2 1.5383020013359783e-07 0.4339170567027524 True 2.28220596909523e-06 3.2549723982810974e-07 2.48197466135025e-07 -1.700029006457271e-14 -1.214306433183765e-16 -3.122502256758253e-16 2.28220598609552e-06 3.254972399495404e-07 2.4819746644727525e-07
55 18 coarse 1 1.4574858631100085e-07 0.42004802685791165 True 4.898756742477417e-06 -1.564621925354004e-07 -2.123415470123291e-07 -2.679106936298581e-14 1.457167719820518e-16 -4.85722573273506e-17 4.898756769268486e-06 -1.5646219268111716e-07 -2.1234154696375684e-07
56 19 fine 1 1.1289196333308382e-07 0.4426868958150174 True 2.4051405489444733e-06 3.8230791687965393e-07 4.23286110162735e-07 -1.7246620798161416e-14 -5.447031714567174e-16 -2.42861286636753e-16 2.405140566191094e-06 3.823079174243571e-07 4.2328611040559627e-07
57 19 fine 2 1.3318459290978524e-07 0.4458767766498759 True 2.4051405489444733e-06 -1.3504177331924438e-08 -1.6298145055770874e-08 -1.6679366221517e-14 -1.8561541192951836e-16 4.683753385137379e-17 2.4051405656238395e-06 -1.3504177146309027e-08 -1.6298145102608408e-08
58 19 coarse 1 1.3627775263813646e-07 0.37598585924709055 True 6.38328492641449e-06 -2.514570951461792e-07 2.1792948246002197e-07 -2.724209746673978e-14 -7.91033905045424e-16 -1.3877787807814457e-17 6.383284953656587e-06 -2.514570943551453e-07 2.1792948247389976e-07
59 20 fine 1 1.2067538701643343e-07 0.397654453667931 True 3.3676624298095703e-06 -7.636845111846924e-08 8.195638656616211e-08 -1.6471199404399783e-14 1.0581813203458523e-16 7.806255641895632e-17 3.3676624462807697e-06 -7.636845122428737e-08 8.195638648809955e-08
60 20 fine 2 1.1349498318935503e-07 0.4276325956343959 True 3.5767443478107452e-06 -7.869675755500793e-08 6.565824151039124e-08 -1.5959455978986625e-14 9.020562075079397e-17 5.898059818321144e-17 3.5767443637702012e-06 -7.869675764521356e-08 6.565824145141064e-08
61 20 coarse 1 1.5850306378517587e-07 0.5285112236646456 True 3.5408884286880493e-06 -1.993030309677124e-07 -3.7066638469696045e-07 -2.525757381022231e-14 7.91033905045424e-16 -2.3592239273284576e-16 3.540888453945623e-06 -1.993030317587463e-07 -3.7066638446103806e-07
62 21 fine 1 1.2747028055315468e-07 0.3807671146447972 True 3.180466592311859e-06 -9.872019290924072e-08 -4.377216100692749e-08 -1.619537837171947e-14 5.204170427930421e-17 -1.4224732503009818e-16 3.1804666085072375e-06 -9.872019296128243e-08 -4.3772160864680165e-08
63 21 fine 2 1.1436689684174439e-07 0.41457208617159613 True 2.8158538043498993e-06 -4.516914486885071e-08 3.119930624961853e-08 -1.622833811776303e-14 -2.0296264668928643e-16 -1.7867651802561113e-16 2.8158538205782374e-06 -4.516914466588806e-08 3.119930642829505e-08
64 21 coarse 1 1.3219836714206679e-07 0.4111722561110483 True 5.48921525478363e-06 -9.816139936447144e-07 -5.345791578292847e-07 -2.7602919949742954e-14 4.0245584642661925e-16 2.7755575615628914e-16 5.48921528238655e-06 -9.816139940471702e-07 -5.345791581068404e-07
65 22 fine 1 1.247986221031283e-07 0.4025936491208882 True 2.5955960154533386e-06 -1.1734664440155029e-07 7.636845111846924e-08 -1.670712179713263e-14 2.0643209364124004e-16 -1.196959198423997e-16 2.5955960321604604e-06 -1.1734664460798239e-07 7.636845123816516e-08
66 22 fine 2 1.2467687349193568e-07 0.4026463456064581 True 2.169981598854065e-06 -2.0023435354232788e-07 -2.5331974029541016e-07 -1.5954251808558695e-14 4.336808689942018e-17 8.847089727481716e-17 2.1699816148083167e-06 -2.0023435358569597e-07 -2.5331974038388105e-07
67 22 coarse 1 1.303169513411362e-07 0.4534581358023719 True 4.8317015171051025e-06 -1.4826655387878418e-06 -8.456408977508545e-07 -2.6728619317850644e-14 -9.71445146547012e-17 -4.163336342344337e-16 4.831701543833722e-06 -1.4826655386906973e-06 -8.456408973345209e-07
68 23 fine 1 1.1580148451262318e-07 0.3892248238329876 True 2.83215194940567e-06 -4.284083843231201e-08 -1.3317912817001343e-07 -1.7317744460676465e-14 2.2551405187698492e-17 -3.9898639947466563e-17 2.8321519667234146e-06 -4.284083845486342e-08 -1.331791281301148e-07
69 23 fine 2 1.4772394407724931e-07 0.44883956143532583 True 2.432148903608322e-06 -1.0570511221885681e-07 -3.306195139884949e-08 -1.628211454551831e-14 4.85722573273506e-17 1.1796119636642288e-16 2.4321489198904367e-06 -1.0570511226742907e-07 -3.3061951516810684e-08
70 23 coarse 1 1.4415727089822639e-07 0.46236304392819116 True 8.864328265190125e-06 -8.624047040939331e-07 -5.19677996635437e-07 -2.839395385478838e-14 -3.7470027081099033e-16 -1.0269562977782698e-15 8.864328293584078e-06 -8.624047037192328e-07 -5.196779956084807e-07
71 24 fine 1 1.1816075007331506e-07 0.40334771123509106 True 2.196524292230606e-06 -5.2619725465774536e-08 -1.327134668827057e-07 -1.619537837171947e-14 3.400058012914542e-16 7.979727989493313e-17 2.1965243084259845e-06 -5.261972580578034e-08 -1.3271346696250297e-07
72 24 fine 2 1.2605529897680157e-07 0.4651221485857391 True 2.941582351922989e-06 -2.2584572434425354e-07 6.05359673500061e-09 -1.802204219192305e-14 -2.5153490401663703e-16 2.3418766925686896e-16 2.941582369945031e-06 -2.2584572409271864e-07 6.053596500812941e-09
73 24 coarse 1 1.573361411155716e-07 0.43294013951653565 True 9.939074516296387e-06 -2.905726432800293e-07 1.4156103134155273e-07 -2.768618667658984e-14 -1.6653345369377348e-16 1.1102230246251565e-15 9.939074543982573e-06 -2.9057264311349584e-07 1.415610302313297e-07

Some files were not shown because too many files have changed in this diff Show More