What we found
Style Charter §7 says variable data in new code goes through array with the
three-index shapes, and gives the flat .data property exactly one sanctioned
use: a raw variable-to-variable copy inside the non-dimensionalisation
boundary. docs/developer/subsystems/data-access.md, the governing document,
sanctions vec for solver internals — not .data.
The transport and particle work added ~20 flat-.data sites. Roughly half are
the sanctioned raw copy. The rest read, compute and write values, so they are
neither the user-facing array path nor the solver-internal vec path:
Merged (#703, #707):
src/underworld3/systems/ddt.py:1936, 4207-4211, 4438, 4464, 4478
src/underworld3/swarm.py:1247, 1275
Open PRs:
Sanctioned and correct, listed so the line is visibly drawn rather than
guessed at: ddt.py:1945, 1953, 4435, 4472, 4488 and #720 ddt.py:4567 are
raw variable-to-variable copies.
Why it matters beyond style
The flat .data bypasses units evaluation and re-packing. Where the value
being written has been through _to_nondim_ndarray or arithmetic, whether that
bypass is correct depends on the caller, and nothing in the code says which it
is. .array makes it not a question.
Note on §2
Charter §2 is explicit that surrounding code is not authority. ddt.py uses
flat .data throughout, which is why the new lines match it; that is the drift
the clause exists to stop.
Underworld development team with AI support from Claude Code
What we found
Style Charter §7 says variable data in new code goes through
arraywith thethree-index shapes, and gives the flat
.dataproperty exactly one sanctioneduse: a raw variable-to-variable copy inside the non-dimensionalisation
boundary.
docs/developer/subsystems/data-access.md, the governing document,sanctions
vecfor solver internals — not.data.The transport and particle work added ~20 flat-
.datasites. Roughly half arethe sanctioned raw copy. The rest read, compute and write values, so they are
neither the user-facing
arraypath nor the solver-internalvecpath:Merged (#703, #707):
src/underworld3/systems/ddt.py:1936, 4207-4211, 4438, 4464, 4478src/underworld3/swarm.py:1247, 1275Open PRs:
src/underworld3/materials.py:609, 611, 644;src/underworld3/swarm.py:2978, 2987, 2996;src/underworld3/swarm_materials.py:214;src/underworld3/function/_function.pyx:851src/underworld3/systems/ddt.py:4526Sanctioned and correct, listed so the line is visibly drawn rather than
guessed at:
ddt.py:1945, 1953, 4435, 4472, 4488and #720ddt.py:4567areraw variable-to-variable copies.
Why it matters beyond style
The flat
.databypasses units evaluation and re-packing. Where the valuebeing written has been through
_to_nondim_ndarrayor arithmetic, whether thatbypass is correct depends on the caller, and nothing in the code says which it
is.
.arraymakes it not a question.Note on §2
Charter §2 is explicit that surrounding code is not authority.
ddt.pyusesflat
.datathroughout, which is why the new lines match it; that is the driftthe clause exists to stop.
Underworld development team with AI support from Claude Code