ramp limit consolidation and fix#1553
Conversation
- 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
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. |
Add ramp_limit_down alongside ramp_limit_shut_down in the first-snapshot test, matching correct UC semantics. Fix MultiIndex handling in define_ramp_limit_constraints.
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_initto enable ramp constraints at the first snapshot.New Attribute:
p_initadded to generators and links (pypsa/data/component_attrs/):sns[0]usingp_initas the previous dispatchup_time_before > 0Default Value Changes (Breaking)
ramp_limit_start_upandramp_limit_shut_down:1(full ramp allowed)NaN(no limit / ignored)(like in Fix: ramp_limit_start_up attribute is ignored in binary UC #1540)
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:
Ramp Down:
Key insight: For non-committable components,
status = 1for allt, so start-up/shut-down terms vanish naturally. For extendable components,p_nomis replaced by the capacity variable.Constraint Naming (Breaking)
{c}-fix-p-ramp_limit_*,{c}-ext-p-ramp_limit_*,{c}-com-p-ramp_limit_*{c}-p-ramp_limit_up,{c}-p-ramp_limit_downFirst Snapshot Handling
sns[0] != n.snapshots[0])c.dynamic[hist_attr][start_i]c.dynamic.status[start_i]p_initsetp_init * initially_upup_time_before > 0p_initsns[0]Merge Order
This should go in before #1007 because there the ramp limits not yet fully sorted out.
Checklist
docs.docs/release-notes.mdof the upcoming release is included.