Found by the public adversarial review of the #330/#397/#384 batch (2026-07-23).
MeshVariable._tensor_stats (discretisation_mesh_variables.py) reads components as self.array[:, 0, i] for i in range(self.num_components) — but for a rank-2 tensor variable num_components = d*d (4 in 2D) while self.array has structured shape (N, d, d), so the loop indexes 4 against an axis of size 2:
IndexError: index 2 is out of bounds for axis 2 with size 2
Demonstrated live on a (2,2) tensor variable. The Frobenius accumulation should read the flat layout (self.data[:, i]) or iterate the structured axes. Until then, stats() on any true TENSOR/SYM_TENSOR variable raises — the method is effectively dead code for its own case (vector variables are unaffected; they take _vector_stats).
Pre-existing on development — the #330-batch diff only renamed the temporary variable inside it.
Underworld development team with AI support from Claude Code
Found by the public adversarial review of the #330/#397/#384 batch (2026-07-23).
MeshVariable._tensor_stats(discretisation_mesh_variables.py) reads components asself.array[:, 0, i]fori in range(self.num_components)— but for a rank-2 tensor variablenum_components = d*d(4 in 2D) whileself.arrayhas structured shape(N, d, d), so the loop indexes 4 against an axis of size 2:Demonstrated live on a (2,2) tensor variable. The Frobenius accumulation should read the flat layout (
self.data[:, i]) or iterate the structured axes. Until then,stats()on any true TENSOR/SYM_TENSOR variable raises — the method is effectively dead code for its own case (vector variables are unaffected; they take_vector_stats).Pre-existing on development — the #330-batch diff only renamed the temporary variable inside it.
Underworld development team with AI support from Claude Code