Hacktoberfest 2026: le issue che i maintainer hanno segnato per ottobre, aperte e adatte ai principianti. Sfoglia le issue Hacktoberfest

Ramp limits of a fixed modular committable unit scale with p_nom times the number of running modules

Aperta Adatta ai principianti
#1,985 0 commenti 0 reazioni 0 assegnatari Vedi su GitHub

I maintainer di solito rispondono entro 1 giorno

Nessuno ha ancora preso questa issue.

Valutazione

Difficoltà
2/5
Tempo stimato
1-3 ore
Idoneità per principianti
75/100
Tipo di issue
Bug
Chiarezza
Specificata chiaramente
Stato di attività
Attiva
Stack tecnologico
python, sqlalchemy
Ambito
backend

Direzione di ricerca

Inizia in pypsa/optimization/constraints.py, in corrispondenza di define_ramp_limit_constraints, intorno alle righe 1036–1038, e confronta le relative righe di rampa con i limiti operativi modulari intorno alle righe 479–501. Esegui il riproduttore fornito con uv run --script mre.py; il lavoro è completato quando le unità modulari fisse ed espandibili rispettano lo stesso limite di rampa e il caso fisso usa la generazione di punta per i 40 MW rimanenti.

Scritto dal modello di indicizzazione a partire dal testo della issue.

Descrizione

operational realism optimization

[!NOTE]
This issue was drafted by AI.

Version Checks (indicate both or one)
  • I have confirmed this bug exists on the latest release of PyPSA (1.3.0).
  • I have confirmed this bug exists on the current master branch of PyPSA (51986084).
Issue Description

For a committable unit with p_nom_mod > 0, status is an integer that counts the running modules. The dispatch rows use p_nom_mod * status. The ramp rows of a fixed (not extendable) modular unit use p_nom * status. With N modules running, the ramp allowance is N times ramp_limit_up * p_nom, so it is N times too loose. The same applies to ramp_limit_start_up, ramp_limit_down and ramp_limit_shut_down.

An extendable modular committable unit uses p_nom_mod * status, which is correct. So the same plant ramps differently when it is written as fixed or as extendable with p_nom_min = p_nom_max.

In the example, the unit has 10 modules of 10 MW and ramp_limit_up = ramp_limit_start_up = 0.1. The ramp from snapshot 0 to 1 must be at most 10 MW. The fixed unit ramps by 50 MW.

Reproducible Example

Run with uv run --script mre.py.

# /// script
# dependencies = ["pypsa @ git+https://github.com/PyPSA/PyPSA@51986084bfb68d38e5b64021649cb339448112cb", "highspy"]
# ///
import pypsa


def solve(extendable: bool) -> None:
    n = pypsa.Network()
    n.set_snapshots(range(2))
    n.add("Bus", "b")
    n.add("Load", "l", bus="b", p_set=[50, 100])
    n.add("Generator", "peak", bus="b", p_nom=1000, marginal_cost=100)
    n.add(
        "Generator",
        "uc",
        bus="b",
        committable=True,
        p_nom=0 if extendable else 100,
        p_nom_extendable=extendable,
        p_nom_min=100,
        p_nom_max=100,
        p_nom_mod=10,
        ramp_limit_up=0.1,
        ramp_limit_start_up=0.1,
        marginal_cost=1,
    )
    n.optimize(log_to_console=False)
    label = "extendable p_nom_min=p_nom_max=100" if extendable else "fixed p_nom=100"
    print(f"{label}:")
    print("  uc status:", n.generators_t.status["uc"].tolist())
    print("  uc p:     ", n.generators_t.p["uc"].tolist())
    print("  peak p:   ", n.generators_t.p["peak"].tolist())


solve(extendable=False)
solve(extendable=True)

Output (stdout, solver log and warnings removed):

fixed p_nom=100:
  uc status: [10.0, 10.0]
  uc p:      [50.0, 100.0]
  peak p:    [0.0, 0.0]
extendable p_nom_min=p_nom_max=100:
  uc status: [10.0, 10.0]
  uc p:      [50.0, 60.0]
  peak p:    [0.0, 40.0]
Expected Behavior

Both units give the same result: uc ramps by at most 0.1 * 10 * 10 = 10 MW, and peak covers 40 MW in snapshot 1. This matches the attribute description, "per unit of the nominal power", which also gives 10 MW.

Actual: the fixed unit ramps by 50 MW. Its row allows 0.1 * 100 * 10 = 100 MW.

Cause

On 51986084, in define_ramp_limit_constraints:

  • pypsa/optimization/constraints.py:1010: is_com_fix = is_com & ~is_com_ext, and is_com_ext excludes modular units. So is_com_fix holds both fixed modular and extendable modular committables, and both get status as the module count (:1045-1050).
  • :1036-1038: p_nom takes the module size p_nom_mod only for is_com_ext_mod. A fixed modular unit keeps p_nom.
  • :1082, :1084, :1112, :1114 multiply p_nom by status, status_prev or their difference.

The operational rows of all modular committables use p_nom_mod * status (:479-501). define_committability_variables_constraints_with_fixed_upper_limit bounds status by p_nom / p_nom_mod (:1948-1949).

Proposed direction

At :1037, use is_com & is_modular instead of is_com_ext_mod, so every modular committable ramps against p_nom_mod.

Related
  • #1899 (closed by #1901) fixed the operational bounds of the same fixed modular committable units. The ramp rows were not changed.
  • #1007 made committable, extendable and modular units compatible, and added the p_nom_mod case for extendable units in the ramp rows.

Found while recording PyPSA reference models for energy-models/mathspec#783.

Installed Versions
  • pypsa 1.3.0.post1.dev41+g51986084b
  • linopy 0.9.1
  • highspy 1.15.1
  • pandas 3.0.6
  • xarray 2026.9.0
  • Python 3.13.11
Lingua principale
Python
Stelle
2.2k
Fork
709
Merge medio
1g 20h
PR unite (30g)
30

Preparare l'ambiente

Come iniziare

  1. Leggi tutta la issue e poi la guida ai contributi del progetto.
  2. Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
  3. Fai un fork del repository e lavora su un branch.
  4. Apri una pull request che faccia riferimento al numero della issue.

Altre issue di PyPSA/PyPSA

Tutte le issue di PyPSA/PyPSA

Issue simili

Altre issue su Python

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.