From c11b138a096c578acd10b9d23e1b3ee7a765b23f Mon Sep 17 00:00:00 2001 From: Claude Date: Sat, 17 Oct 2026 01:37:24 +0000 Subject: [PATCH] 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 --- src/CelerisLab/lbm/refinement_stepper.py | 23 ++++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/src/CelerisLab/lbm/refinement_stepper.py b/src/CelerisLab/lbm/refinement_stepper.py index 50f602f..aeb40da 100644 --- a/src/CelerisLab/lbm/refinement_stepper.py +++ b/src/CelerisLab/lbm/refinement_stepper.py @@ -90,6 +90,19 @@ def _legacy_levels(bounds, *, fine_block, base_block, child, child_block, child_ return refinements, blocks, objects, level_jets +def _initial_levels(level_g, coarse_g, fine_g, child_g): + """One tuple of per-level arrays from initialize()'s positional or legacy named form.""" + if coarse_g is None and fine_g is None: + if child_g is not None and len(level_g) != 2: + raise TypeError("child_g needs exactly the coarse and fine arrays before it") + return tuple(level_g) + (() if child_g is None else (child_g,)) + if level_g: + raise TypeError("pass level arrays positionally or as coarse_g/fine_g/child_g, not both") + if coarse_g is None or fine_g is None: + raise TypeError("coarse_g and fine_g are both required in the named form") + return (coarse_g, fine_g) + (() if child_g is None else (child_g,)) + + def _check_levels(refinements, blocks, objects, jets): """Candidate limits shared by the list and the legacy entry points.""" depth = len(refinements) + 1 @@ -430,11 +443,15 @@ class FixedPatchStepper: for array, leaf in zip(arrays, self._leaf): array[:, ~leaf] = np.nan - def initialize(self, *level_g, child_g=None): - """Upload an explicit G_0, one Q-major array per level; non-leaves are discarded.""" + def initialize(self, *level_g, coarse_g=None, fine_g=None, child_g=None): + """Upload an explicit G_0, one Q-major array per level; non-leaves are discarded. + + Pass the level arrays positionally (L0 first), or use the original + two/three-level names coarse_g, fine_g[, child_g]; mixing is rejected. + """ + given = _initial_levels(level_g, coarse_g, fine_g, child_g) with self._lock, self.ctx.activate(): self._require("new", "ready") - given = level_g + (() if child_g is None else (child_g,)) if len(given) != len(self._levels): raise ValueError("Expected one Q-major array per level") arrays = [np.array(a, dtype=np.float32, order="C", copy=True) for a in given]