Skip to content

ramp limit consolidation and fix#1553

Merged
FabianHofmann merged 17 commits intomasterfrom
start-up-constraints
Feb 12, 2026
Merged

ramp limit consolidation and fix#1553
FabianHofmann merged 17 commits intomasterfrom
start-up-constraints

Conversation

@FabianHofmann
Copy link
Copy Markdown
Contributor

@FabianHofmann FabianHofmann commented Feb 6, 2026

Changes

requires PyPSA/linopy#568
closes #592
closes #1540
supersedes #1540

This refactor consolidates ramp limit constraint definitions into a unified formulation that handles all operational types (fixed, extendable, committable) with a single constraint. It also introduces p_init to enable ramp constraints at the first snapshot.

New Attribute: p_init added to generators and links (pypsa/data/component_attrs/):

  • Specifies the initial active power for ramp limit constraints at the first snapshot
  • When set, ramp constraints are applied at sns[0] using p_init as the previous dispatch
  • For committable**: Initial status is derived from up_time_before > 0

Default Value Changes (Breaking)

ramp_limit_start_up and ramp_limit_shut_down:

Consolidated Constraint Formulation

The constraint code (pypsa/optimization/constraints.py) was simplified from ~230 lines with separate handling for fix/ext/com to ~75 lines with a unified formulation:

Ramp Up:

p[t] - p[t-1] <= ru * p_nom * u[t-1] + rusu * p_nom * (u[t] - u[t-1])

Ramp Down:

p[t] - p[t-1] >= -rd * p_nom * u[t] - rdsd * p_nom * (u[t-1] - u[t])

Key insight: For non-committable components, status = 1 for all t, so start-up/shut-down terms vanish naturally. For extendable components, p_nom is replaced by the capacity variable.

Constraint Naming (Breaking)

  • Before: {c}-fix-p-ramp_limit_*, {c}-ext-p-ramp_limit_*, {c}-com-p-ramp_limit_*
  • After: {c}-p-ramp_limit_up, {c}-p-ramp_limit_down

First Snapshot Handling

Scenario Previous Dispatch Previous Status
Rolling horizon (sns[0] != n.snapshots[0]) c.dynamic[hist_attr][start_i] c.dynamic.status[start_i]
First snapshot with p_init set p_init * initially_up up_time_before > 0
First snapshot without p_init No constraint at sns[0] -

Merge Order

This should go in before #1007 because there the ramp limits not yet fully sorted out.

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.

- Change default ramp_limit_start_up/shut_down from 1 to NaN
- Refactor committable ramp constraints to handle first snapshot
- Add tests for start-up-only, shut-down-only, and multi-invest cases
- Use notnull() instead of ~isnull() for cleaner code
@Irieo
Copy link
Copy Markdown
Contributor

Irieo commented Feb 6, 2026

The plan is to close #1540 or to merge it before this PR?
The release notes here repeat information about new defaults for ramp_limit_start_up and ramp_limit_shut_down but do not mention the main reason #1540 was there is to fix the bug that these attributes were ignored in binary UC.

@FabianHofmann
Copy link
Copy Markdown
Contributor Author

The plan is to close #1540 or to merge it before this PR? The release notes here repeat information about new defaults for ramp_limit_start_up and ramp_limit_shut_down but do not mention the main reason #1540 was there is to fix the bug that these attributes were ignored in binary UC.

if you don't mind, we could give this one prio and close #1540 ; I have to release a new linopy version first, though

@Irieo
Copy link
Copy Markdown
Contributor

Irieo commented Feb 6, 2026

The plan is to close #1540 or to merge it before this PR? The release notes here repeat information about new defaults for ramp_limit_start_up and ramp_limit_shut_down but do not mention the main reason #1540 was there is to fix the bug that these attributes were ignored in binary UC.

if you don't mind, we could give this one prio and close #1540 ; I have to release a new linopy version first, though

No worries. I thought we wanted merge 1553 after 1540 due to different logic (direct fix vs code refac + new att), but if you think it is better so you can just close #1540. Maybe just pull my unit tests.

@FabianHofmann FabianHofmann enabled auto-merge (squash) February 12, 2026 11:19
@FabianHofmann FabianHofmann merged commit 03a2795 into master Feb 12, 2026
27 checks passed
@FabianHofmann FabianHofmann deleted the start-up-constraints branch February 12, 2026 12:01
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.

Links ramp_start_up_limit not behaving as expected

3 participants