Skip to content

fix: fix ramping-/rolling horizon logic#1428

Merged
lkstrp merged 6 commits intomasterfrom
fix-ramping
Oct 31, 2025
Merged

fix: fix ramping-/rolling horizon logic#1428
lkstrp merged 6 commits intomasterfrom
fix-ramping

Conversation

@Irieo
Copy link
Copy Markdown
Contributor

@Irieo Irieo commented Oct 31, 2025

Closes #1424

Changes proposed in this Pull Request

This PR fixes several issues we have in ramping constraints. Citing @lkstrp, it is another case of our very annoying p == p0 but != p0

the original point was whether p0 here is redundant:

attr = {"p", "p0"}.intersection(c.dynamic.keys()).pop()

A: No. Although during optimization it indeed -p (dynamic attribute p0 does not exist at point of optimization and is created after solve in assign_solution). However, there is a case when define_ramp_limit_constraints is applied in rolling horizon mode. In this case we have to refer to previous period's dispatch (stored in p0 for a Link specifically).

  • One problem here that our lovely test suite never had Link & ramp_limits together.
  • If I add such test, the constraint breaks because of a buggy logic: c.dynamic.keys() assumes that at least one of {"p", "p0"} there, but on the first optimization run, nothing exists yet in the dynamic data for Links.
  • Furthermore, the constraint breaks also in a standard n.optimize() call (w/o RH) because function tries to access p0 before checking whether we are at all in the rolling horizon mode.
  • And finally, docstring is wrong. Ramping limits are applied to attributes that have ramping attributes, which are only Generator and Links.

Checklist

  • Code changes are sufficiently documented; i.e. new functions contain docstrings and further explanations may be given in docs.
  • Unit tests for new features were added (if applicable).
  • A note for the release notes docs/release-notes.md of the upcoming release is included.
  • I consent to the release of this PR's code under the MIT license.

@Irieo Irieo marked this pull request as ready for review October 31, 2025 10:34
@Irieo
Copy link
Copy Markdown
Contributor Author

Irieo commented Oct 31, 2025

🟢

Copy link
Copy Markdown
Member

@fneum fneum left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@lkstrp lkstrp merged commit 05d2148 into master Oct 31, 2025
22 checks passed
@lkstrp lkstrp deleted the fix-ramping branch October 31, 2025 17:22
@FabianHofmann
Copy link
Copy Markdown
Contributor

Just stumbled over this bug, and there comes the fix 😇 Thanks @Irieo

a-buntjer pushed a commit to a-buntjer/PyPSA that referenced this pull request Nov 27, 2025
Merged changes from PyPSA v1.0.3 and v1.0.4 including:
- Fix busmap clustering for multilinks (PyPSA#1441)
- Fix handling of inactive storage components (PyPSA#1442)
- Fix masking of nan constraints in kvl (PyPSA#1438)
- Fix snapshot selection for operational in multi period (PyPSA#1437)
- Fix ramping-/rolling horizon logic (PyPSA#1428)
- CI improvements and dependency updates

Resolved conflicts in pypsa/optimization/constraints.py:
- Used upstream's c.active_assets approach (cleaner, already handles MultiIndex)
- Preserved our stochastic Store constraint fix (transpose for dimension alignment)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Ramp limit links in 1.0 fails

4 participants