Skip to content

Ramp constraints incorrectly applied to fixed components #1493

@sasa821

Description

@sasa821

Version Checks (indicate both or one)

  • I have confirmed this bug exists on the lastest release of PyPSA.

  • I have confirmed this bug exists on the current master branch of PyPSA.

Issue Description

In PyPSA versions ≥ 1.0.0, generators and links with NaN ramp_limit_up/down will receive ramp constraints once ramping is enabled for any other asset of the same component.

In this situation, NaN ramp limits appear to be effectively interpreted as zero, leading to constraints such as:

p(t) - p(t-1) ≤ 0

As a result, assets that are intended to be fully flexible (e.g. load-shedding or slack generators) are prevented from changing output between snapshots, which can cause infeasibilities.

Reproducible Example

"""Simple example network with one generator having ramp limits and another without"""

import pandas as pd
import pypsa

n = pypsa.Network()
n.set_snapshots(pd.date_range("2025-01-01", periods=2, freq="h"))
n.add(class_name="Bus", name="bus")
n.add(
    class_name="Load",
    name="load",
    bus="bus",
    p_set=pd.Series([0.0, 50.0], index=n.snapshots),  # sudden load increase
)

# Small generator with ramp limits
n.add(
    class_name="Generator",
    name="generator",
    bus="bus",
    p_nom=10,
    ramp_limit_up=0.5,
    ramp_limit_down=0.5,
    marginal_cost=0,
)

# Load shedding generator without ramp limits
n.add(
    class_name="Generator",
    name="load_shedding",
    bus="bus",
    p_nom=1000,
    marginal_cost=10,
)

n.optimize(solver_name="highs")

print(n.model.constraints["Generator-fix-p-ramp_limit_up"])

Expected Behavior

Here is what the optimization results currently look like:

WARNING:pypsa.consistency:The following buses have carriers which are not defined:
Index(['bus'], dtype='object', name='name')
INFO:linopy.model: Solve problem using Highs solver
INFO:linopy.io: Writing time: 0.02s
Running HiGHS 1.12.0 (git hash: 755a8e0): Copyright (c) 2025 HiGHS under MIT licence terms
LP linopy-problem-b0a5luci has 14 rows; 4 cols; 20 nonzeros
Coefficient ranges:
  Matrix  [1e+00, 1e+00]
  Cost    [1e+01, 1e+01]
  Bound   [0e+00, 0e+00]
  RHS     [5e+00, 1e+03]
Presolving model
4 rows, 1 cols, 4 nonzeros  0s
Problem status detected on presolve: Infeasible
Model name          : linopy-problem-b0a5luci
Model status        : Infeasible
Objective value     :  0.0000000000e+00
HiGHS run time      :          0.00
WARNING:linopy.constants:Optimization potentially failed: 
Status: warning
Termination condition: infeasible
Solution: 0 primals, 0 duals
Objective: nan
Solver model: available
Solver message: Infeasible

Constraint `Generator-fix-p-ramp_limit_up` [snapshot: 1, name: 2]:
------------------------------------------------------------------
[2025-01-01 01:00:00, generator]: +1 Generator-p[2025-01-01 01:00:00, generator] - 1 Generator-p[2025-01-01 00:00:00, generator]             ≤ 5.0
[2025-01-01 01:00:00, load_shedding]: +1 Generator-p[2025-01-01 01:00:00, load_shedding] - 1 Generator-p[2025-01-01 00:00:00, load_shedding] ≤ -0.0

This clearly shows the infeasibility and indicates that a zero ramp limit is being imposed on the load-shedding generator, preventing it from increasing output to cover the load.

The expected behavior is that ramp constraints are ignored for the load-shedding generator (since no ramp limits are specified for it), which would result in a feasible solution.

Installed Versions

Details This bug happens in pypsa>=1.0.0

Metadata

Metadata

Assignees

Labels

needs triageIssue needs initial review by the maintainers

Type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions