[GP-02] Sequential mode: configurable carry-over-length, correct stitching for block-overlap != 1 - #274
Open
aoustry wants to merge 8 commits into
Open
[GP-02] Sequential mode: configurable carry-over-length, correct stitching for block-overlap != 1#274aoustry wants to merge 8 commits into
aoustry wants to merge 8 commits into
Conversation
Add 'carry-over-length' to ResolutionConfig (issue #271): optional, defaults to block-overlap via effective_carry_over_length, validated as 0 <= carry-over-length <= block-overlap with no special case at block-overlap == 0. Also add the previously missing range check 0 <= block-overlap < block-length. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_018BsEZdPwCrguejkXxz33FS
…ial mode The sequential carry-over always extracted block N's last timestep and pinned it to block N+1's first timestep, which only refers to the same absolute timestep when block-overlap == 1; for overlap >= 2 it silently stitched the wrong pair of timesteps (issue #271). _extract_carry_over now extracts effective_carry_over_length values starting at local index block_length - block_overlap (the earliest shared timestep), re-indexed to time 0..k-1, and Phase 5 pins the next block's first k timesteps against them. Scalar initial_values (no time dim) keep the legacy single-timestep pin for direct build_problem callers. Behavioural consequence: with block-overlap: 0 nothing is carried between blocks any more (the previous implicit single-timestep seeding is gone) — state continuity now requires block-overlap >= 1. The new e2e test fails against the previous runtime behaviour for all four of its cases and passes with this fix; existing block-overlap: 1 e2e tests pass unmodified. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_018BsEZdPwCrguejkXxz33FS
Document the new 'carry-over-length' resolution setting: parameter table entry, expanded sequential-subproblems section with an annotated timeline diagram (block-length / block-overlap / carry-over-length), default and explicit-zero semantics, validation rules, and a breaking-change warning for block-overlap: 0 configs. Add the corresponding CHANGELOG entries. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_018BsEZdPwCrguejkXxz33FS
aoustry
commented
Aug 14, 2026
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_018BsEZdPwCrguejkXxz33FS
With block-overlap: 0 no carry-over constraint is created: each block's initial state is free (block 1 serves its t=7 peak by pre-charging from a free SoC, which the old implicit single-timestep seeding made impossible), and the sequential result is identical to parallel-subproblems mode, which solves the same windows independently by construction. The test fails against the pre-#271 runtime behaviour. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_018BsEZdPwCrguejkXxz33FS
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Process ID
Process: GP-02
Description
Closes #271.
In
sequential-subproblemsmode, the carry-over that stitches block N to block N+1 was hardcoded: it extracted block N's last timestep and pinned it to block N+1's first timestep. That pairing only refers to the same absolute timestep whenblock-overlap == 1; forblock-overlap >= 2it silently pinned the wrong pair of timesteps.This PR makes the carry-over an explicit
resolutionsetting and fixes the absolute-timestep alignment:carry-over-lengthadded toResolutionConfig(optional; omitted → defaults toblock-overlap, i.e. full pin of the overlap zone). Explicit0is legal and distinct from unset: blocks overlap for lag-constraint history but are not stitched at all.0 <= carry-over-length <= block-overlap(no special case atblock-overlap == 0), plus the previously missing range check0 <= block-overlap < block-length._extract_carry_overnow extractseffective_carry_over_lengthvalues starting at the earliest shared timestep (local indexblock_length - block_overlap) instead of always the last one; Phase 5 pins the next block's first k timesteps against them (clamped for truncated final blocks). Scalarinitial_valueskeep the legacy single-timestep pin for directbuild_problemcallers.docs/user-guide/optim-config.mddocuments the three parameters with an annotated timeline diagram (from the issue discussion), defaults, validation, and a breaking-change warning;docs/CHANGELOG.mdgains a BREAKING entry with the migration note.Breaking change: with
block-overlap: 0(the default) nothing is carried between blocks any more — the previous implicit single-timestep seeding is gone. Configs relying on state continuity (e.g. storage state-of-charge) must setblock-overlap: 1(and optionallycarry-over-length: 1).Impact Analysis
Affected modules:
optim_config/—ResolutionConfigschema: new field + validators (src/gems_craft/optim_config/parsing.py).gems_runner/session/—_run_sequential/_extract_carry_overgeneralized to a multi-timestep window.gems_runner/simulation/—optimization.pyPhase 5 carry-over constraints generalized;build_problemdocstring updated.docs/— user guide + changelog.Solver output values expected to change: yes, for sequential mode only:
block-overlap >= 2: outputs change because the previous stitching was incorrect (wrong absolute timestep pinned); the new behaviour pins each shared timestep to its matching absolute timestep.block-overlap: 0: outputs change because blocks no longer inherit the previous block's final state (breaking change above).block-overlap: 1: no change — the new default is identical to the old hardcoded single-timestep pin; the existing e2e tests (test_rolling_horizon_suboptimality.py,test_optim_modes.py) pass unmodified.frontal/parallel-subproblems/benders-decomposition: unaffected.Test coverage: 13 new unit tests for the validators and default resolution; new e2e module
test_sequential_carry_over_length.py(block-length 6, block-overlap 3, carry-over 3/1/0 over an aperiodic 12-step demand) asserting every pinned shared timestep is identical in both blocks — all four cases fail against the previous runtime behaviour and pass with the fix.Checklist
pytest) — 604 passed, 6 skipped, 2 xfailedmypy)black,isort)pyproject.tomlversion bumped if applicable — not applicable (version bumps are handled via thefeat(release):workflow)AGENTS.mdreviewed for impact and updated if needed — no update needed (resolution-mode internals are not described there)