4.3 KiB
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.