From c9a38674672d24e7413eb41a1ab1b87a22d9723c Mon Sep 17 00:00:00 2001 From: Claude Date: Thu, 1 Oct 2026 14:59:44 +0000 Subject: [PATCH 1/2] docs(pypsa): the pypsa spec names its repeated row conditions as masks, and its topic files read them under given: masks: Sixteen masks name the conditions examples/pypsa.yaml wrote out at every row: per committable class C, C_committed (26 sites), C_com_ext (8), C_maint_ext (5) and C_ramps_from_previous (6); StorageUnit_fix and _ext (6 each); Line_lossy and Transformer_lossy (4 each). 165 where strings change. Each where, with every mask expanded, equals the one it replaces: 352 declarations and every cased expression were compared conjunct by conjunct. tools/pypsa_split.py places a mask in the topic its name names and writes given: masks: for every other topic that reads it. All 24 fragments load alone and merge to the one file's canonical form. The symbol table spells the masks as on^{qualifier} and prev, and the gallery's table cut includes masks. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01PBmqeqBrqpQC6MVoSrguHK --- CHANGELOG.md | 1 + docs/examples/pypsa.md | 607 +++++++++---------- docs/examples/pypsa/generator.md | 21 + docs/examples/pypsa/generator_commitment.md | 123 ++-- docs/examples/pypsa/generator_maintenance.md | 82 ++- docs/examples/pypsa/generator_ramping.md | 63 +- docs/examples/pypsa/line.md | 37 +- docs/examples/pypsa/link.md | 21 + docs/examples/pypsa/link_commitment.md | 123 ++-- docs/examples/pypsa/link_maintenance.md | 81 ++- docs/examples/pypsa/link_ramping.md | 67 +- docs/examples/pypsa/process.md | 21 + docs/examples/pypsa/process_commitment.md | 123 ++-- docs/examples/pypsa/process_maintenance.md | 82 ++- docs/examples/pypsa/process_ramping.md | 65 +- docs/examples/pypsa/storage_unit.md | 81 ++- docs/examples/pypsa/transformer.md | 37 +- examples/pypsa.yaml | 469 ++++++++------ examples/pypsa/generator.yaml | 7 + examples/pypsa/generator_commitment.yaml | 62 +- examples/pypsa/generator_maintenance.yaml | 43 +- examples/pypsa/generator_ramping.yaml | 36 +- examples/pypsa/line.yaml | 15 +- examples/pypsa/link.yaml | 7 + examples/pypsa/link_commitment.yaml | 62 +- examples/pypsa/link_maintenance.yaml | 42 +- examples/pypsa/link_ramping.yaml | 40 +- examples/pypsa/process.yaml | 7 + examples/pypsa/process_commitment.yaml | 62 +- examples/pypsa/process_maintenance.yaml | 43 +- examples/pypsa/process_ramping.yaml | 38 +- examples/pypsa/storage_unit.yaml | 36 +- examples/pypsa/transformer.yaml | 15 +- examples/symbols/pypsa.yaml | 16 + tools/gallery.py | 2 + tools/pypsa_split.py | 18 +- 36 files changed, 1610 insertions(+), 1045 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3b6eb6ee1..3329192a7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,7 @@ it releases that version ([RELEASING.md](https://github.com/energy-models/mathsp ## Upcoming version +- docs(pypsa): the pypsa spec names its repeated row conditions as masks, and its topic files read them under `given: masks:` ([#PR](https://github.com/energy-models/mathspec/pull/PR)) - feat(language): a where predicate is named once under `masks:`, and another file reads it under `given: masks:` ([#821](https://github.com/energy-models/mathspec/pull/821)) ## 0.2.1 (2026-10-01) diff --git a/docs/examples/pypsa.md b/docs/examples/pypsa.md index be933fe2e..883f72b3e 100644 --- a/docs/examples/pypsa.md +++ b/docs/examples/pypsa.md @@ -5323,6 +5323,27 @@ A plain `n.optimize()`, and its multi-period and stochastic classes, in one file | $`\mathit{Transformer\_angle\_sum}`$ | `Transformer_angle_sum` over $`\Xi \times \mathcal{T} \times \mathcal{C}`$ | | $`\mathit{Cycle\_angle\_sum}`$ | `Cycle_angle_sum` over $`\Xi \times \mathcal{T} \times \mathcal{C}`$ — the voltage angle differences around a cycle: every branch flow times its cycle weight, and every transformer phase shift | +#### Masks + +| Symbol | Meaning | +|---|---| +| $`\mathrm{on}^{\mathrm{com,ext}}`$ | `Generator_com_ext` over $`\mathcal{T} \times \mathcal{G}`$ — a committable generator with an extendable, non-modular build that stands in the snapshot's period — PyPSA's `com-ext` rows, whose status is relaxed against the chosen build | +| $`\mathrm{on}^{\mathrm{mnt,ext}}`$ | `Generator_maint_ext` over $`\mathcal{T} \times \mathcal{G}`$ — a maintainable generator with an extendable build, unless it is committable and modular, that stands in the snapshot's period — the maintenance rows against the chosen build | +| $`\mathrm{on}^{\mathrm{com}}`$ | `Generator_committed` over $`\mathcal{T} \times \mathcal{G}`$ — a committable generator that stands in the snapshot's period — every unit-commitment row's set | +| $`\mathrm{prev}`$ | `Generator_ramps_from_previous` over $`\Xi \times \mathcal{T} \times \mathcal{G}`$ — a snapshot whose ramp reads a previous output — any snapshot but its period's first, and the horizon's first where the generator comes in off or carries an initial output | +| $`\mathrm{on}^{f,\mathrm{com,ext}}`$ | `Link_com_ext` over $`\mathcal{T} \times \mathcal{L}`$ — a committable link with an extendable, non-modular build that stands in the snapshot's period — PyPSA's `com-ext` rows, whose status is relaxed against the chosen build | +| $`\mathrm{on}^{f,\mathrm{mnt,ext}}`$ | `Link_maint_ext` over $`\mathcal{T} \times \mathcal{L}`$ — a maintainable link with an extendable build, unless it is committable and modular, that stands in the snapshot's period — the maintenance rows against the chosen build | +| $`\mathrm{on}^{f,\mathrm{com}}`$ | `Link_committed` over $`\mathcal{T} \times \mathcal{L}`$ — a committable link that stands in the snapshot's period — every unit-commitment row's set | +| $`\mathrm{prev}^{f}`$ | `Link_ramps_from_previous` over $`\Xi \times \mathcal{T} \times \mathcal{L}`$ — a snapshot whose ramp reads a previous output — any snapshot but its period's first, and the horizon's first where the link comes in off or carries an initial output | +| $`\mathrm{on}^{z,\mathrm{com,ext}}`$ | `Process_com_ext` over $`\mathcal{T} \times \mathcal{J}`$ — a committable process with an extendable, non-modular build that stands in the snapshot's period — PyPSA's `com-ext` rows, whose status is relaxed against the chosen build | +| $`\mathrm{on}^{z,\mathrm{mnt,ext}}`$ | `Process_maint_ext` over $`\mathcal{T} \times \mathcal{J}`$ — a maintainable process with an extendable build, unless it is committable and modular, that stands in the snapshot's period — the maintenance rows against the chosen build | +| $`\mathrm{on}^{z,\mathrm{com}}`$ | `Process_committed` over $`\mathcal{T} \times \mathcal{J}`$ — a committable process that stands in the snapshot's period — every unit-commitment row's set | +| $`\mathrm{prev}^{z}`$ | `Process_ramps_from_previous` over $`\Xi \times \mathcal{T} \times \mathcal{J}`$ — a snapshot whose ramp reads a previous output — any snapshot but its period's first, and the horizon's first where the process comes in off or carries an initial output | +| $`\mathrm{on}^{h,\mathrm{fix}}`$ | `StorageUnit_fix` over $`\mathcal{T} \times \mathcal{S}`$ — a storage unit with a fixed build that stands in the snapshot's period — PyPSA's `fix` rows | +| $`\mathrm{on}^{h,\mathrm{ext}}`$ | `StorageUnit_ext` over $`\mathcal{T} \times \mathcal{S}`$ — a storage unit with an extendable build that stands in the snapshot's period — PyPSA's `ext` rows | +| $`\mathrm{on}^{s,\mathrm{lossy}}`$ | `Line_lossy` over $`\mathcal{T} \times \mathcal{K}`$ — a line that stands in the snapshot's period, where the run models transmission losses | +| $`\mathrm{on}^{\sigma,\mathrm{lossy}}`$ | `Transformer_lossy` over $`\mathcal{T} \times \mathcal{M}`$ — a transformer that stands in the snapshot's period, where the run models transmission losses | + Upright is what the data supplies — a parameter such as $`\mathrm{Transformer\_phase\_shift\_varying}`$, a coordinate map, a label — and italic is what the solver chooses, such as $`\mathit{Transformer\_phase\_shift}`$. An index is italic too, being what a quantifier chooses, and a set is script. $`t \ominus k`$ denotes cyclic translation: index $`t-k`$ taken modulo the size of the dimension (`roll`). Plain $`t-k`$ (`shift`) has no wraparound — terms translated past the edge are simply absent. @@ -5725,12 +5746,12 @@ Z_{j} = \mathrm{z}^{\mathrm{nom,set}}_{\xi,j} \qquad \forall\, \xi \in \Xi,\ j \ StorageUnit_fix_p_dispatch_lower: description: "`StorageUnit-fix-p_dispatch-lower` — dispatch is non-negative" dims: [scenario, snapshot, storage_unit] - where: not StorageUnit_p_nom_extendable AND StorageUnit_active + where: StorageUnit_fix expression: StorageUnit_p_dispatch >= 0 ``` ```math -h^{+}_{\xi,t,s} \ge 0 \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ s \in \mathcal{S} \,:\, \neg \mathrm{ext}^{h}_{s} \wedge \mathrm{on}^{h}_{t,s} +h^{+}_{\xi,t,s} \ge 0 \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ s \in \mathcal{S} \,:\, \mathrm{on}^{h,\mathrm{fix}}_{t,s} ``` ### `StorageUnit-fix-p_dispatch-upper` @@ -5741,12 +5762,12 @@ h^{+}_{\xi,t,s} \ge 0 \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ s \in \ StorageUnit_fix_p_dispatch_upper: description: "`StorageUnit-fix-p_dispatch-upper` — a fixed unit dispatches at most its nominal power" dims: [scenario, snapshot, storage_unit] - where: not StorageUnit_p_nom_extendable AND StorageUnit_active + where: StorageUnit_fix expression: StorageUnit_p_dispatch <= StorageUnit_p_max_pu * StorageUnit_p_nom ``` ```math -h^{+}_{\xi,t,s} \le \overline{\mathrm{h}}_{\xi,t,s} \cdot \mathrm{h}^{\mathrm{nom}}_{\xi,s} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ s \in \mathcal{S} \,:\, \neg \mathrm{ext}^{h}_{s} \wedge \mathrm{on}^{h}_{t,s} +h^{+}_{\xi,t,s} \le \overline{\mathrm{h}}_{\xi,t,s} \cdot \mathrm{h}^{\mathrm{nom}}_{\xi,s} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ s \in \mathcal{S} \,:\, \mathrm{on}^{h,\mathrm{fix}}_{t,s} ``` ### `StorageUnit-fix-p_store-lower` @@ -5757,12 +5778,12 @@ h^{+}_{\xi,t,s} \le \overline{\mathrm{h}}_{\xi,t,s} \cdot \mathrm{h}^{\mathrm{no StorageUnit_fix_p_store_lower: description: "`StorageUnit-fix-p_store-lower` — storing is non-negative" dims: [scenario, snapshot, storage_unit] - where: not StorageUnit_p_nom_extendable AND StorageUnit_active + where: StorageUnit_fix expression: StorageUnit_p_store >= 0 ``` ```math -h^{-}_{\xi,t,s} \ge 0 \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ s \in \mathcal{S} \,:\, \neg \mathrm{ext}^{h}_{s} \wedge \mathrm{on}^{h}_{t,s} +h^{-}_{\xi,t,s} \ge 0 \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ s \in \mathcal{S} \,:\, \mathrm{on}^{h,\mathrm{fix}}_{t,s} ``` ### `StorageUnit-fix-p_store-upper` @@ -5775,12 +5796,12 @@ StorageUnit_fix_p_store_upper: `StorageUnit-fix-p_store-upper` — a fixed unit stores at most its nominal power, the minimum-per-unit column carrying that cap negated dims: [scenario, snapshot, storage_unit] - where: not StorageUnit_p_nom_extendable AND StorageUnit_active + where: StorageUnit_fix expression: StorageUnit_p_store <= -StorageUnit_p_min_pu * StorageUnit_p_nom ``` ```math -h^{-}_{\xi,t,s} \le -\underline{\mathrm{h}}_{\xi,t,s} \cdot \mathrm{h}^{\mathrm{nom}}_{\xi,s} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ s \in \mathcal{S} \,:\, \neg \mathrm{ext}^{h}_{s} \wedge \mathrm{on}^{h}_{t,s} +h^{-}_{\xi,t,s} \le -\underline{\mathrm{h}}_{\xi,t,s} \cdot \mathrm{h}^{\mathrm{nom}}_{\xi,s} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ s \in \mathcal{S} \,:\, \mathrm{on}^{h,\mathrm{fix}}_{t,s} ``` ### `StorageUnit-fix-state_of_charge-lower` @@ -5791,12 +5812,12 @@ h^{-}_{\xi,t,s} \le -\underline{\mathrm{h}}_{\xi,t,s} \cdot \mathrm{h}^{\mathrm{ StorageUnit_fix_state_of_charge_lower: description: "`StorageUnit-fix-state_of_charge-lower` — charge is non-negative" dims: [scenario, snapshot, storage_unit] - where: not StorageUnit_p_nom_extendable AND StorageUnit_active + where: StorageUnit_fix expression: StorageUnit_state_of_charge >= 0 ``` ```math -\mathit{soc}_{\xi,t,s} \ge 0 \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ s \in \mathcal{S} \,:\, \neg \mathrm{ext}^{h}_{s} \wedge \mathrm{on}^{h}_{t,s} +\mathit{soc}_{\xi,t,s} \ge 0 \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ s \in \mathcal{S} \,:\, \mathrm{on}^{h,\mathrm{fix}}_{t,s} ``` ### `StorageUnit-fix-state_of_charge-upper` @@ -5807,12 +5828,12 @@ StorageUnit_fix_state_of_charge_lower: StorageUnit_fix_state_of_charge_upper: description: "`StorageUnit-fix-state_of_charge-upper` — a fixed unit holds at most its hours at nominal power" dims: [scenario, snapshot, storage_unit] - where: not StorageUnit_p_nom_extendable AND StorageUnit_active + where: StorageUnit_fix expression: StorageUnit_state_of_charge <= StorageUnit_max_hours * StorageUnit_p_nom ``` ```math -\mathit{soc}_{\xi,t,s} \le \mathrm{T}^{h}_{\xi,s} \cdot \mathrm{h}^{\mathrm{nom}}_{\xi,s} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ s \in \mathcal{S} \,:\, \neg \mathrm{ext}^{h}_{s} \wedge \mathrm{on}^{h}_{t,s} +\mathit{soc}_{\xi,t,s} \le \mathrm{T}^{h}_{\xi,s} \cdot \mathrm{h}^{\mathrm{nom}}_{\xi,s} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ s \in \mathcal{S} \,:\, \mathrm{on}^{h,\mathrm{fix}}_{t,s} ``` ### `Generator-com-p-lower` @@ -5823,12 +5844,12 @@ StorageUnit_fix_state_of_charge_upper: Generator_com_p_lower: description: "`Generator-com-p-lower` — a committed unit outputs at least its minimum; off, at least nothing" dims: [scenario, snapshot, generator] - where: Generator_committable AND not Generator_p_nom_extendable AND Generator_active + where: Generator_committed AND NOT Generator_p_nom_extendable expression: Generator_p >= Generator_p_min_pu * Generator_p_nom * (Generator_status - Generator_maintenance_pu * Generator_maintenance_status) ``` ```math -p_{\xi,t,g} \ge \underline{\mathrm{p}}_{\xi,t,g} \cdot \mathrm{p}^{\mathrm{nom}}_{\xi,g} \cdot \left( u_{\xi,t,g} - \gamma_{\xi,g} \cdot \mu^{u}_{\xi,t,g} \right) \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ g \in \mathcal{G} \,:\, \mathrm{com}_{g} \wedge \neg \mathrm{ext}_{g} \wedge \mathrm{on}_{t,g} +p_{\xi,t,g} \ge \underline{\mathrm{p}}_{\xi,t,g} \cdot \mathrm{p}^{\mathrm{nom}}_{\xi,g} \cdot \left( u_{\xi,t,g} - \gamma_{\xi,g} \cdot \mu^{u}_{\xi,t,g} \right) \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ g \in \mathcal{G} \,:\, \mathrm{on}^{\mathrm{com}}_{t,g} \wedge \neg \mathrm{ext}_{g} ``` ### `Generator-com-p-upper` @@ -5839,12 +5860,12 @@ p_{\xi,t,g} \ge \underline{\mathrm{p}}_{\xi,t,g} \cdot \mathrm{p}^{\mathrm{nom}} Generator_com_p_upper: description: "`Generator-com-p-upper` — a committed unit outputs at most what is available; off, at most nothing" dims: [scenario, snapshot, generator] - where: Generator_committable AND not Generator_p_nom_extendable AND Generator_active + where: Generator_committed AND NOT Generator_p_nom_extendable expression: Generator_p <= Generator_p_max_pu * Generator_p_nom * (Generator_status - Generator_maintenance_pu * Generator_maintenance_status) ``` ```math -p_{\xi,t,g} \le \overline{\mathrm{p}}_{\xi,t,g} \cdot \mathrm{p}^{\mathrm{nom}}_{\xi,g} \cdot \left( u_{\xi,t,g} - \gamma_{\xi,g} \cdot \mu^{u}_{\xi,t,g} \right) \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ g \in \mathcal{G} \,:\, \mathrm{com}_{g} \wedge \neg \mathrm{ext}_{g} \wedge \mathrm{on}_{t,g} +p_{\xi,t,g} \le \overline{\mathrm{p}}_{\xi,t,g} \cdot \mathrm{p}^{\mathrm{nom}}_{\xi,g} \cdot \left( u_{\xi,t,g} - \gamma_{\xi,g} \cdot \mu^{u}_{\xi,t,g} \right) \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ g \in \mathcal{G} \,:\, \mathrm{on}^{\mathrm{com}}_{t,g} \wedge \neg \mathrm{ext}_{g} ``` ### `Generator-com-transition-start-up` @@ -5855,12 +5876,12 @@ p_{\xi,t,g} \le \overline{\mathrm{p}}_{\xi,t,g} \cdot \mathrm{p}^{\mathrm{nom}}_ Generator_com_transition_start_up: description: "`Generator-com-transition-start-up` — turning on is a start, counted against the state the unit carried into the snapshot" dims: [scenario, snapshot, generator] - where: Generator_committable AND Generator_active + where: Generator_committed expression: Generator_start_up >= Generator_status - Generator_previous_status ``` ```math -\mathit{up}_{\xi,t,g} \ge u_{\xi,t,g} - \overleftarrow{u}_{\xi,t,g} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ g \in \mathcal{G} \,:\, \mathrm{com}_{g} \wedge \mathrm{on}_{t,g} +\mathit{up}_{\xi,t,g} \ge u_{\xi,t,g} - \overleftarrow{u}_{\xi,t,g} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ g \in \mathcal{G} \,:\, \mathrm{on}^{\mathrm{com}}_{t,g} ``` ### `Generator-com-transition-shut-down` @@ -5871,12 +5892,12 @@ Generator_com_transition_start_up: Generator_com_transition_shut_down: description: "`Generator-com-transition-shut-down` — turning off is a stop, counted against the state the unit carried into the snapshot" dims: [scenario, snapshot, generator] - where: Generator_committable AND Generator_active + where: Generator_committed expression: Generator_shut_down >= Generator_previous_status - Generator_status ``` ```math -\mathit{dn}_{\xi,t,g} \ge \overleftarrow{u}_{\xi,t,g} - u_{\xi,t,g} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ g \in \mathcal{G} \,:\, \mathrm{com}_{g} \wedge \mathrm{on}_{t,g} +\mathit{dn}_{\xi,t,g} \ge \overleftarrow{u}_{\xi,t,g} - u_{\xi,t,g} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ g \in \mathcal{G} \,:\, \mathrm{on}^{\mathrm{com}}_{t,g} ``` ### `Generator-com-up-time` @@ -5890,12 +5911,12 @@ Generator_com_up_time: is still on. The first snapshot's share of the window is the brought-in up time's, which the must-stay-up mask carries dims: [scenario, snapshot, generator] - where: Generator_committable AND Generator_min_up_time > 0 AND position(snapshot) > 0 AND Generator_active + where: Generator_committed AND Generator_min_up_time > 0 AND position(snapshot) > 0 expression: sum_back(Generator_start_up, along=snapshot, window=Generator_min_up_time) <= Generator_status ``` ```math -\sum_{t' \in \mathcal{T} \,:\, 0 \le t - t' < \mathrm{UT}} \mathit{up}_{\xi,t',g} \le u_{\xi,t,g} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ g \in \mathcal{G} \,:\, \mathrm{com}_{g} \wedge \mathrm{UT}_{\xi,g} > 0 \wedge \mathrm{pos}(t) > 0 \wedge \mathrm{on}_{t,g} +\sum_{t' \in \mathcal{T} \,:\, 0 \le t - t' < \mathrm{UT}} \mathit{up}_{\xi,t',g} \le u_{\xi,t,g} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ g \in \mathcal{G} \,:\, \mathrm{on}^{\mathrm{com}}_{t,g} \wedge \mathrm{UT}_{\xi,g} > 0 \wedge \mathrm{pos}(t) > 0 ``` ### `Generator-com-down-time` @@ -5909,12 +5930,12 @@ Generator_com_down_time: time is still off. The first snapshot's share of the window is the brought-in down time's, which the must-stay-down mask carries dims: [scenario, snapshot, generator] - where: Generator_committable AND Generator_min_down_time > 0 AND position(snapshot) > 0 AND Generator_active + where: Generator_committed AND Generator_min_down_time > 0 AND position(snapshot) > 0 expression: sum_back(Generator_shut_down, along=snapshot, window=Generator_min_down_time) <= 1 - Generator_status ``` ```math -\sum_{t' \in \mathcal{T} \,:\, 0 \le t - t' < \mathrm{DT}} \mathit{dn}_{\xi,t',g} \le 1 - u_{\xi,t,g} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ g \in \mathcal{G} \,:\, \mathrm{com}_{g} \wedge \mathrm{DT}_{\xi,g} > 0 \wedge \mathrm{pos}(t) > 0 \wedge \mathrm{on}_{t,g} +\sum_{t' \in \mathcal{T} \,:\, 0 \le t - t' < \mathrm{DT}} \mathit{dn}_{\xi,t',g} \le 1 - u_{\xi,t,g} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ g \in \mathcal{G} \,:\, \mathrm{on}^{\mathrm{com}}_{t,g} \wedge \mathrm{DT}_{\xi,g} > 0 \wedge \mathrm{pos}(t) > 0 ``` ### `Generator-com-status-min_up_time_must_stay_up` @@ -5925,12 +5946,12 @@ Generator_com_down_time: Generator_com_status_must_stay_up: description: "`Generator-com-status-min_up_time_must_stay_up` — a unit still serving the up time it brought in stays on" dims: [scenario, snapshot, generator] - where: Generator_committable AND Generator_must_stay_up AND Generator_active + where: Generator_committed AND Generator_must_stay_up expression: Generator_status == 1 ``` ```math -u_{\xi,t,g} = 1 \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ g \in \mathcal{G} \,:\, \mathrm{com}_{g} \wedge \mathrm{hold}_{\xi,t,g} \wedge \mathrm{on}_{t,g} +u_{\xi,t,g} = 1 \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ g \in \mathcal{G} \,:\, \mathrm{on}^{\mathrm{com}}_{t,g} \wedge \mathrm{hold}_{\xi,t,g} ``` ### `Generator-com-status-min_down_time_must_stay_up` @@ -5943,12 +5964,12 @@ Generator_com_status_must_stay_down: `Generator-com-status-min_down_time_must_stay_up` — a unit still serving the down time it brought in stays off; PyPSA names the row `_must_stay_up` dims: [scenario, snapshot, generator] - where: Generator_committable AND Generator_must_stay_down AND Generator_active + where: Generator_committed AND Generator_must_stay_down expression: Generator_status == 0 ``` ```math -u_{\xi,t,g} = 0 \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ g \in \mathcal{G} \,:\, \mathrm{com}_{g} \wedge \mathrm{rest}_{\xi,t,g} \wedge \mathrm{on}_{t,g} +u_{\xi,t,g} = 0 \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ g \in \mathcal{G} \,:\, \mathrm{on}^{\mathrm{com}}_{t,g} \wedge \mathrm{rest}_{\xi,t,g} ``` ### `Generator-p-ramp_limit_up-run-bigM` @@ -5963,10 +5984,9 @@ Generator_p_ramp_limit_up_run_big_m: releases the row in the snapshot it turns on dims: [scenario, snapshot, generator] where: >- - Generator_committable AND Generator_p_nom_extendable AND NOT (Generator_p_nom_mod > 0) + Generator_com_ext AND (Generator_ramp_limit_up OR Generator_ramp_limit_start_up) - AND (position(snapshot, by=snapshot_period, within=period) > 0 OR (position(snapshot) == 0 AND (Generator_status_initial == 0 OR Generator_p_init))) - AND Generator_active + AND Generator_ramps_from_previous expression: >- Generator_p - Generator_previous_p <= Generator_ramp_up_rate * Generator_p_nom_ext @@ -5974,7 +5994,7 @@ Generator_p_ramp_limit_up_run_big_m: ``` ```math -p_{\xi,t,g} - \overleftarrow{p}_{\xi,t,g} \le \widetilde{\mathrm{ru}}_{\xi,t,g} \cdot P_{g} + \mathrm{M}_{\xi,g} - \mathrm{M}_{\xi,g} \cdot \overleftarrow{u}_{\xi,t,g} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ g \in \mathcal{G} \,:\, \mathrm{com}_{g} \wedge \mathrm{ext}_{g} \wedge \neg \left( \mathrm{p}^{\mathrm{mod}}_{g} > 0 \right) \wedge \left( \mathrm{ru}_{\xi,t,g} \text{ is defined} \vee \mathrm{ru}^{\mathrm{up}}_{\xi,g} \text{ is defined} \right) \wedge \left( \mathrm{pos}_{\mathrm{snapshot\_period}(t)}(t) > 0 \vee \mathrm{pos}(t) = 0 \wedge \left( \mathrm{u}^{0}_{\xi,g} = 0 \vee \mathrm{p}^{0}_{\xi,g} \text{ is defined} \right) \right) \wedge \mathrm{on}_{t,g} +p_{\xi,t,g} - \overleftarrow{p}_{\xi,t,g} \le \widetilde{\mathrm{ru}}_{\xi,t,g} \cdot P_{g} + \mathrm{M}_{\xi,g} - \mathrm{M}_{\xi,g} \cdot \overleftarrow{u}_{\xi,t,g} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ g \in \mathcal{G} \,:\, \mathrm{on}^{\mathrm{com,ext}}_{t,g} \wedge \left( \mathrm{ru}_{\xi,t,g} \text{ is defined} \vee \mathrm{ru}^{\mathrm{up}}_{\xi,g} \text{ is defined} \right) \wedge \mathrm{prev}_{\xi,t,g} ``` ### `Generator-p-ramp_limit_up-start-bigM` @@ -5989,10 +6009,9 @@ Generator_p_ramp_limit_up_start_big_m: the chosen build; the big M releases the row everywhere else dims: [scenario, snapshot, generator] where: >- - Generator_committable AND Generator_p_nom_extendable AND NOT (Generator_p_nom_mod > 0) + Generator_com_ext AND (Generator_ramp_limit_up OR Generator_ramp_limit_start_up) - AND (position(snapshot, by=snapshot_period, within=period) > 0 OR (position(snapshot) == 0 AND (Generator_status_initial == 0 OR Generator_p_init))) - AND Generator_active + AND Generator_ramps_from_previous expression: >- Generator_p - Generator_previous_p <= Generator_start_up_rate * Generator_p_nom_ext @@ -6000,7 +6019,7 @@ Generator_p_ramp_limit_up_start_big_m: ``` ```math -p_{\xi,t,g} - \overleftarrow{p}_{\xi,t,g} \le \widetilde{\mathrm{ru}}^{\mathrm{up}}_{\xi,g} \cdot P_{g} + \mathrm{M}_{\xi,g} - \mathrm{M}_{\xi,g} \cdot \mathit{up}_{\xi,t,g} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ g \in \mathcal{G} \,:\, \mathrm{com}_{g} \wedge \mathrm{ext}_{g} \wedge \neg \left( \mathrm{p}^{\mathrm{mod}}_{g} > 0 \right) \wedge \left( \mathrm{ru}_{\xi,t,g} \text{ is defined} \vee \mathrm{ru}^{\mathrm{up}}_{\xi,g} \text{ is defined} \right) \wedge \left( \mathrm{pos}_{\mathrm{snapshot\_period}(t)}(t) > 0 \vee \mathrm{pos}(t) = 0 \wedge \left( \mathrm{u}^{0}_{\xi,g} = 0 \vee \mathrm{p}^{0}_{\xi,g} \text{ is defined} \right) \right) \wedge \mathrm{on}_{t,g} +p_{\xi,t,g} - \overleftarrow{p}_{\xi,t,g} \le \widetilde{\mathrm{ru}}^{\mathrm{up}}_{\xi,g} \cdot P_{g} + \mathrm{M}_{\xi,g} - \mathrm{M}_{\xi,g} \cdot \mathit{up}_{\xi,t,g} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ g \in \mathcal{G} \,:\, \mathrm{on}^{\mathrm{com,ext}}_{t,g} \wedge \left( \mathrm{ru}_{\xi,t,g} \text{ is defined} \vee \mathrm{ru}^{\mathrm{up}}_{\xi,g} \text{ is defined} \right) \wedge \mathrm{prev}_{\xi,t,g} ``` ### `Generator-p-ramp_limit_down-run-bigM` @@ -6015,10 +6034,9 @@ Generator_p_ramp_limit_down_run_big_m: releases the row in the snapshot it turns off dims: [scenario, snapshot, generator] where: >- - Generator_committable AND Generator_p_nom_extendable AND NOT (Generator_p_nom_mod > 0) + Generator_com_ext AND (Generator_ramp_limit_down OR Generator_ramp_limit_shut_down) - AND (position(snapshot, by=snapshot_period, within=period) > 0 OR (position(snapshot) == 0 AND (Generator_status_initial == 0 OR Generator_p_init))) - AND Generator_active + AND Generator_ramps_from_previous expression: >- Generator_previous_p - Generator_p <= Generator_ramp_down_rate * Generator_p_nom_ext @@ -6026,7 +6044,7 @@ Generator_p_ramp_limit_down_run_big_m: ``` ```math -\overleftarrow{p}_{\xi,t,g} - p_{\xi,t,g} \le \widetilde{\mathrm{rd}}_{\xi,t,g} \cdot P_{g} + \mathrm{M}_{\xi,g} - \mathrm{M}_{\xi,g} \cdot u_{\xi,t,g} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ g \in \mathcal{G} \,:\, \mathrm{com}_{g} \wedge \mathrm{ext}_{g} \wedge \neg \left( \mathrm{p}^{\mathrm{mod}}_{g} > 0 \right) \wedge \left( \mathrm{rd}_{\xi,t,g} \text{ is defined} \vee \mathrm{rd}^{\mathrm{dn}}_{\xi,g} \text{ is defined} \right) \wedge \left( \mathrm{pos}_{\mathrm{snapshot\_period}(t)}(t) > 0 \vee \mathrm{pos}(t) = 0 \wedge \left( \mathrm{u}^{0}_{\xi,g} = 0 \vee \mathrm{p}^{0}_{\xi,g} \text{ is defined} \right) \right) \wedge \mathrm{on}_{t,g} +\overleftarrow{p}_{\xi,t,g} - p_{\xi,t,g} \le \widetilde{\mathrm{rd}}_{\xi,t,g} \cdot P_{g} + \mathrm{M}_{\xi,g} - \mathrm{M}_{\xi,g} \cdot u_{\xi,t,g} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ g \in \mathcal{G} \,:\, \mathrm{on}^{\mathrm{com,ext}}_{t,g} \wedge \left( \mathrm{rd}_{\xi,t,g} \text{ is defined} \vee \mathrm{rd}^{\mathrm{dn}}_{\xi,g} \text{ is defined} \right) \wedge \mathrm{prev}_{\xi,t,g} ``` ### `Generator-p-ramp_limit_down-shut-bigM` @@ -6041,10 +6059,9 @@ Generator_p_ramp_limit_down_shut_big_m: the chosen build; the big M releases the row everywhere else dims: [scenario, snapshot, generator] where: >- - Generator_committable AND Generator_p_nom_extendable AND NOT (Generator_p_nom_mod > 0) + Generator_com_ext AND (Generator_ramp_limit_down OR Generator_ramp_limit_shut_down) - AND (position(snapshot, by=snapshot_period, within=period) > 0 OR (position(snapshot) == 0 AND (Generator_status_initial == 0 OR Generator_p_init))) - AND Generator_active + AND Generator_ramps_from_previous expression: >- Generator_previous_p - Generator_p <= Generator_shut_down_rate * Generator_p_nom_ext @@ -6052,7 +6069,7 @@ Generator_p_ramp_limit_down_shut_big_m: ``` ```math -\overleftarrow{p}_{\xi,t,g} - p_{\xi,t,g} \le \widetilde{\mathrm{rd}}^{\mathrm{dn}}_{\xi,g} \cdot P_{g} + \mathrm{M}_{\xi,g} - \mathrm{M}_{\xi,g} \cdot \mathit{dn}_{\xi,t,g} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ g \in \mathcal{G} \,:\, \mathrm{com}_{g} \wedge \mathrm{ext}_{g} \wedge \neg \left( \mathrm{p}^{\mathrm{mod}}_{g} > 0 \right) \wedge \left( \mathrm{rd}_{\xi,t,g} \text{ is defined} \vee \mathrm{rd}^{\mathrm{dn}}_{\xi,g} \text{ is defined} \right) \wedge \left( \mathrm{pos}_{\mathrm{snapshot\_period}(t)}(t) > 0 \vee \mathrm{pos}(t) = 0 \wedge \left( \mathrm{u}^{0}_{\xi,g} = 0 \vee \mathrm{p}^{0}_{\xi,g} \text{ is defined} \right) \right) \wedge \mathrm{on}_{t,g} +\overleftarrow{p}_{\xi,t,g} - p_{\xi,t,g} \le \widetilde{\mathrm{rd}}^{\mathrm{dn}}_{\xi,g} \cdot P_{g} + \mathrm{M}_{\xi,g} - \mathrm{M}_{\xi,g} \cdot \mathit{dn}_{\xi,t,g} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ g \in \mathcal{G} \,:\, \mathrm{on}^{\mathrm{com,ext}}_{t,g} \wedge \left( \mathrm{rd}_{\xi,t,g} \text{ is defined} \vee \mathrm{rd}^{\mathrm{dn}}_{\xi,g} \text{ is defined} \right) \wedge \mathrm{prev}_{\xi,t,g} ``` ### `Generator-p_nom_modularity` @@ -6081,12 +6098,12 @@ Generator_com_ext_p_upper_cap: `Generator-com-ext-p-upper-cap` — a committed extendable unit outputs at most what is available of the chosen build, whatever its status dims: [scenario, snapshot, generator] - where: Generator_committable AND Generator_p_nom_extendable AND NOT (Generator_p_nom_mod > 0) AND Generator_active + where: Generator_com_ext expression: Generator_p <= Generator_p_max_pu * (Generator_p_nom_ext - Generator_maintenance_pu * Generator_maintenance_capacity) ``` ```math -p_{\xi,t,g} \le \overline{\mathrm{p}}_{\xi,t,g} \cdot \left( P_{g} - \gamma_{\xi,g} \cdot \mu^{\mathrm{nom}}_{\xi,t,g} \right) \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ g \in \mathcal{G} \,:\, \mathrm{com}_{g} \wedge \mathrm{ext}_{g} \wedge \neg \left( \mathrm{p}^{\mathrm{mod}}_{g} > 0 \right) \wedge \mathrm{on}_{t,g} +p_{\xi,t,g} \le \overline{\mathrm{p}}_{\xi,t,g} \cdot \left( P_{g} - \gamma_{\xi,g} \cdot \mu^{\mathrm{nom}}_{\xi,t,g} \right) \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ g \in \mathcal{G} \,:\, \mathrm{on}^{\mathrm{com,ext}}_{t,g} ``` ### `Generator-com-ext-p-upper-bigM` @@ -6097,12 +6114,12 @@ p_{\xi,t,g} \le \overline{\mathrm{p}}_{\xi,t,g} \cdot \left( P_{g} - \gamma_{\xi Generator_com_ext_p_upper_big_m: description: "`Generator-com-ext-p-upper-bigM` — off, a unit outputs nothing; on, the big M is no bound" dims: [scenario, snapshot, generator] - where: Generator_committable AND Generator_p_nom_extendable AND NOT (Generator_p_nom_mod > 0) AND Generator_active + where: Generator_com_ext expression: Generator_p <= Generator_big_m * Generator_status ``` ```math -p_{\xi,t,g} \le \mathrm{M}_{\xi,g} \cdot u_{\xi,t,g} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ g \in \mathcal{G} \,:\, \mathrm{com}_{g} \wedge \mathrm{ext}_{g} \wedge \neg \left( \mathrm{p}^{\mathrm{mod}}_{g} > 0 \right) \wedge \mathrm{on}_{t,g} +p_{\xi,t,g} \le \mathrm{M}_{\xi,g} \cdot u_{\xi,t,g} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ g \in \mathcal{G} \,:\, \mathrm{on}^{\mathrm{com,ext}}_{t,g} ``` ### `Generator-com-ext-p-lower` @@ -6115,7 +6132,7 @@ Generator_com_ext_p_lower: `Generator-com-ext-p-lower` — a committed extendable unit outputs at least its minimum of the chosen build; off, the big M releases the row dims: [scenario, snapshot, generator] - where: Generator_committable AND Generator_p_nom_extendable AND NOT (Generator_p_nom_mod > 0) AND Generator_active + where: Generator_com_ext expression: >- Generator_p >= Generator_p_min_pu * (Generator_p_nom_ext - Generator_maintenance_pu * Generator_maintenance_capacity) @@ -6123,7 +6140,7 @@ Generator_com_ext_p_lower: ``` ```math -p_{\xi,t,g} \ge \underline{\mathrm{p}}_{\xi,t,g} \cdot \left( P_{g} - \gamma_{\xi,g} \cdot \mu^{\mathrm{nom}}_{\xi,t,g} \right) + \mathrm{M}_{\xi,g} \cdot u_{\xi,t,g} - \mathrm{M}_{\xi,g} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ g \in \mathcal{G} \,:\, \mathrm{com}_{g} \wedge \mathrm{ext}_{g} \wedge \neg \left( \mathrm{p}^{\mathrm{mod}}_{g} > 0 \right) \wedge \mathrm{on}_{t,g} +p_{\xi,t,g} \ge \underline{\mathrm{p}}_{\xi,t,g} \cdot \left( P_{g} - \gamma_{\xi,g} \cdot \mu^{\mathrm{nom}}_{\xi,t,g} \right) + \mathrm{M}_{\xi,g} \cdot u_{\xi,t,g} - \mathrm{M}_{\xi,g} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ g \in \mathcal{G} \,:\, \mathrm{on}^{\mathrm{com,ext}}_{t,g} ``` ### `Generator-com-ext-p-lower-nonneg` @@ -6137,14 +6154,12 @@ Generator_com_ext_p_lower_nonneg: negative, output is also plainly non-negative, a row the big-M lower cannot assert while the unit is off dims: [scenario, snapshot, generator] - where: >- - Generator_committable AND Generator_p_nom_extendable - AND Generator_p_min_pu_nonneg AND NOT (Generator_p_nom_mod > 0) AND Generator_active + where: Generator_com_ext AND Generator_p_min_pu_nonneg expression: Generator_p >= 0 ``` ```math -p_{\xi,t,g} \ge 0 \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ g \in \mathcal{G} \,:\, \mathrm{com}_{g} \wedge \mathrm{ext}_{g} \wedge \mathrm{nonneg}_{g} \wedge \neg \left( \mathrm{p}^{\mathrm{mod}}_{g} > 0 \right) \wedge \mathrm{on}_{t,g} +p_{\xi,t,g} \ge 0 \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ g \in \mathcal{G} \,:\, \mathrm{on}^{\mathrm{com,ext}}_{t,g} \wedge \mathrm{nonneg}_{g} ``` ### `Generator-com-mod-p-lower` @@ -6157,12 +6172,12 @@ Generator_com_mod_p_lower: `Generator-com-mod-p-lower` — a committed modular unit outputs at least its minimum of one module, whether the build is fixed or a decision dims: [scenario, snapshot, generator] - where: Generator_committable AND Generator_p_nom_mod > 0 AND Generator_active + where: Generator_committed AND Generator_p_nom_mod > 0 expression: Generator_p >= Generator_p_min_pu * Generator_p_nom_mod * (Generator_status - Generator_maintenance_pu * Generator_maintenance_status) ``` ```math -p_{\xi,t,g} \ge \underline{\mathrm{p}}_{\xi,t,g} \cdot \mathrm{p}^{\mathrm{mod}}_{g} \cdot \left( u_{\xi,t,g} - \gamma_{\xi,g} \cdot \mu^{u}_{\xi,t,g} \right) \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ g \in \mathcal{G} \,:\, \mathrm{com}_{g} \wedge \mathrm{p}^{\mathrm{mod}}_{g} > 0 \wedge \mathrm{on}_{t,g} +p_{\xi,t,g} \ge \underline{\mathrm{p}}_{\xi,t,g} \cdot \mathrm{p}^{\mathrm{mod}}_{g} \cdot \left( u_{\xi,t,g} - \gamma_{\xi,g} \cdot \mu^{u}_{\xi,t,g} \right) \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ g \in \mathcal{G} \,:\, \mathrm{on}^{\mathrm{com}}_{t,g} \wedge \mathrm{p}^{\mathrm{mod}}_{g} > 0 ``` ### `Generator-com-mod-p-upper` @@ -6175,12 +6190,12 @@ Generator_com_mod_p_upper: `Generator-com-mod-p-upper` — a committed modular unit outputs at most one module's share, whether the build is fixed or a decision dims: [scenario, snapshot, generator] - where: Generator_committable AND Generator_p_nom_mod > 0 AND Generator_active + where: Generator_committed AND Generator_p_nom_mod > 0 expression: Generator_p <= Generator_p_max_pu * Generator_p_nom_mod * (Generator_status - Generator_maintenance_pu * Generator_maintenance_status) ``` ```math -p_{\xi,t,g} \le \overline{\mathrm{p}}_{\xi,t,g} \cdot \mathrm{p}^{\mathrm{mod}}_{g} \cdot \left( u_{\xi,t,g} - \gamma_{\xi,g} \cdot \mu^{u}_{\xi,t,g} \right) \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ g \in \mathcal{G} \,:\, \mathrm{com}_{g} \wedge \mathrm{p}^{\mathrm{mod}}_{g} > 0 \wedge \mathrm{on}_{t,g} +p_{\xi,t,g} \le \overline{\mathrm{p}}_{\xi,t,g} \cdot \mathrm{p}^{\mathrm{mod}}_{g} \cdot \left( u_{\xi,t,g} - \gamma_{\xi,g} \cdot \mu^{u}_{\xi,t,g} \right) \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ g \in \mathcal{G} \,:\, \mathrm{on}^{\mathrm{com}}_{t,g} \wedge \mathrm{p}^{\mathrm{mod}}_{g} > 0 ``` ### `Generator-status-p-fixed-upper` @@ -6194,12 +6209,12 @@ Generator_status_p_fixed_upper: place, an explicit row as PyPSA writes it: one where the build is not modular, and the fixed build's whole count of modules where it is dims: [scenario, snapshot, generator] - where: Generator_committable AND NOT (Generator_p_nom_extendable AND Generator_p_nom_mod > 0) AND Generator_active + where: Generator_committed AND NOT (Generator_p_nom_extendable AND Generator_p_nom_mod > 0) expression: Generator_status <= Generator_modules_installed ``` ```math -u_{\xi,t,g} \le \mathrm{N}^{\mathrm{fix}}_{\xi,g} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ g \in \mathcal{G} \,:\, \mathrm{com}_{g} \wedge \neg \left( \mathrm{ext}_{g} \wedge \mathrm{p}^{\mathrm{mod}}_{g} > 0 \right) \wedge \mathrm{on}_{t,g} +u_{\xi,t,g} \le \mathrm{N}^{\mathrm{fix}}_{\xi,g} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ g \in \mathcal{G} \,:\, \mathrm{on}^{\mathrm{com}}_{t,g} \wedge \neg \left( \mathrm{ext}_{g} \wedge \mathrm{p}^{\mathrm{mod}}_{g} > 0 \right) ``` ### `Generator-start_up-p-fixed-upper` @@ -6213,12 +6228,12 @@ Generator_start_up_p_fixed_upper: place, an explicit row as PyPSA writes it: one where the build is not modular, and the fixed build's whole count of modules where it is dims: [scenario, snapshot, generator] - where: Generator_committable AND NOT (Generator_p_nom_extendable AND Generator_p_nom_mod > 0) AND Generator_active + where: Generator_committed AND NOT (Generator_p_nom_extendable AND Generator_p_nom_mod > 0) expression: Generator_start_up <= Generator_modules_installed ``` ```math -\mathit{up}_{\xi,t,g} \le \mathrm{N}^{\mathrm{fix}}_{\xi,g} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ g \in \mathcal{G} \,:\, \mathrm{com}_{g} \wedge \neg \left( \mathrm{ext}_{g} \wedge \mathrm{p}^{\mathrm{mod}}_{g} > 0 \right) \wedge \mathrm{on}_{t,g} +\mathit{up}_{\xi,t,g} \le \mathrm{N}^{\mathrm{fix}}_{\xi,g} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ g \in \mathcal{G} \,:\, \mathrm{on}^{\mathrm{com}}_{t,g} \wedge \neg \left( \mathrm{ext}_{g} \wedge \mathrm{p}^{\mathrm{mod}}_{g} > 0 \right) ``` ### `Generator-shut_down-p-fixed-upper` @@ -6232,12 +6247,12 @@ Generator_shut_down_p_fixed_upper: place, an explicit row as PyPSA writes it: one where the build is not modular, and the fixed build's whole count of modules where it is dims: [scenario, snapshot, generator] - where: Generator_committable AND NOT (Generator_p_nom_extendable AND Generator_p_nom_mod > 0) AND Generator_active + where: Generator_committed AND NOT (Generator_p_nom_extendable AND Generator_p_nom_mod > 0) expression: Generator_shut_down <= Generator_modules_installed ``` ```math -\mathit{dn}_{\xi,t,g} \le \mathrm{N}^{\mathrm{fix}}_{\xi,g} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ g \in \mathcal{G} \,:\, \mathrm{com}_{g} \wedge \neg \left( \mathrm{ext}_{g} \wedge \mathrm{p}^{\mathrm{mod}}_{g} > 0 \right) \wedge \mathrm{on}_{t,g} +\mathit{dn}_{\xi,t,g} \le \mathrm{N}^{\mathrm{fix}}_{\xi,g} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ g \in \mathcal{G} \,:\, \mathrm{on}^{\mathrm{com}}_{t,g} \wedge \neg \left( \mathrm{ext}_{g} \wedge \mathrm{p}^{\mathrm{mod}}_{g} > 0 \right) ``` ### `Generator-status-p_nom-variable-upper` @@ -6248,12 +6263,12 @@ Generator_shut_down_p_fixed_upper: Generator_status_p_nom_variable_upper: description: "`Generator-status-p_nom-variable-upper` — a modular unit is on only where a module is built" dims: [scenario, snapshot, generator] - where: Generator_committable AND Generator_p_nom_extendable AND Generator_p_nom_mod > 0 AND Generator_active + where: Generator_committed AND Generator_p_nom_extendable AND Generator_p_nom_mod > 0 expression: Generator_status <= Generator_n_mod ``` ```math -u_{\xi,t,g} \le N_{g} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ g \in \mathcal{G} \,:\, \mathrm{com}_{g} \wedge \mathrm{ext}_{g} \wedge \mathrm{p}^{\mathrm{mod}}_{g} > 0 \wedge \mathrm{on}_{t,g} +u_{\xi,t,g} \le N_{g} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ g \in \mathcal{G} \,:\, \mathrm{on}^{\mathrm{com}}_{t,g} \wedge \mathrm{ext}_{g} \wedge \mathrm{p}^{\mathrm{mod}}_{g} > 0 ``` ### `Generator-start_up-p_nom-variable-upper` @@ -6264,12 +6279,12 @@ u_{\xi,t,g} \le N_{g} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ g \in \ Generator_start_up_p_nom_variable_upper: description: "`Generator-start_up-p_nom-variable-upper` — a modular unit starts only where a module is built" dims: [scenario, snapshot, generator] - where: Generator_committable AND Generator_p_nom_extendable AND Generator_p_nom_mod > 0 AND Generator_active + where: Generator_committed AND Generator_p_nom_extendable AND Generator_p_nom_mod > 0 expression: Generator_start_up <= Generator_n_mod ``` ```math -\mathit{up}_{\xi,t,g} \le N_{g} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ g \in \mathcal{G} \,:\, \mathrm{com}_{g} \wedge \mathrm{ext}_{g} \wedge \mathrm{p}^{\mathrm{mod}}_{g} > 0 \wedge \mathrm{on}_{t,g} +\mathit{up}_{\xi,t,g} \le N_{g} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ g \in \mathcal{G} \,:\, \mathrm{on}^{\mathrm{com}}_{t,g} \wedge \mathrm{ext}_{g} \wedge \mathrm{p}^{\mathrm{mod}}_{g} > 0 ``` ### `Generator-shut_down-p_nom-variable-upper` @@ -6280,12 +6295,12 @@ Generator_start_up_p_nom_variable_upper: Generator_shut_down_p_nom_variable_upper: description: "`Generator-shut_down-p_nom-variable-upper` — a modular unit stops only where a module is built" dims: [scenario, snapshot, generator] - where: Generator_committable AND Generator_p_nom_extendable AND Generator_p_nom_mod > 0 AND Generator_active + where: Generator_committed AND Generator_p_nom_extendable AND Generator_p_nom_mod > 0 expression: Generator_shut_down <= Generator_n_mod ``` ```math -\mathit{dn}_{\xi,t,g} \le N_{g} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ g \in \mathcal{G} \,:\, \mathrm{com}_{g} \wedge \mathrm{ext}_{g} \wedge \mathrm{p}^{\mathrm{mod}}_{g} > 0 \wedge \mathrm{on}_{t,g} +\mathit{dn}_{\xi,t,g} \le N_{g} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ g \in \mathcal{G} \,:\, \mathrm{on}^{\mathrm{com}}_{t,g} \wedge \mathrm{ext}_{g} \wedge \mathrm{p}^{\mathrm{mod}}_{g} > 0 ``` ### `Generator-maint-event-count` @@ -6349,12 +6364,12 @@ Generator_maintcap_upper: `Generator-maintcap_upper` — the build taken off is at most the chosen build in maintenance, and at most the build less its floor out of it dims: [scenario, snapshot, generator] - where: Generator_maintainable AND Generator_p_nom_extendable AND NOT (Generator_committable AND Generator_p_nom_mod > 0) AND Generator_active + where: Generator_maint_ext expression: Generator_maintenance_capacity <= Generator_p_nom_ext - Generator_p_nom_min * (1 - Generator_maintenance) ``` ```math -\mu^{\mathrm{nom}}_{\xi,t,g} \le P_{g} - \underline{\mathrm{p}}^{\mathrm{nom}}_{\xi,g} \cdot \left( 1 - \mu_{\xi,t,g} \right) \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ g \in \mathcal{G} \,:\, \mathrm{mnt}_{g} \wedge \mathrm{ext}_{g} \wedge \neg \left( \mathrm{com}_{g} \wedge \mathrm{p}^{\mathrm{mod}}_{g} > 0 \right) \wedge \mathrm{on}_{t,g} +\mu^{\mathrm{nom}}_{\xi,t,g} \le P_{g} - \underline{\mathrm{p}}^{\mathrm{nom}}_{\xi,g} \cdot \left( 1 - \mu_{\xi,t,g} \right) \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ g \in \mathcal{G} \,:\, \mathrm{on}^{\mathrm{mnt,ext}}_{t,g} ``` ### `Generator-maintcap_upper_nommax` @@ -6365,12 +6380,12 @@ Generator_maintcap_upper: Generator_maintcap_upper_nommax: description: "`Generator-maintcap_upper_nommax` — out of maintenance, no build is taken off" dims: [scenario, snapshot, generator] - where: Generator_maintainable AND Generator_p_nom_extendable AND NOT (Generator_committable AND Generator_p_nom_mod > 0) AND Generator_active + where: Generator_maint_ext expression: Generator_maintenance_capacity <= Generator_p_nom_max * Generator_maintenance ``` ```math -\mu^{\mathrm{nom}}_{\xi,t,g} \le \overline{\mathrm{p}}^{\mathrm{nom}}_{\xi,g} \cdot \mu_{\xi,t,g} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ g \in \mathcal{G} \,:\, \mathrm{mnt}_{g} \wedge \mathrm{ext}_{g} \wedge \neg \left( \mathrm{com}_{g} \wedge \mathrm{p}^{\mathrm{mod}}_{g} > 0 \right) \wedge \mathrm{on}_{t,g} +\mu^{\mathrm{nom}}_{\xi,t,g} \le \overline{\mathrm{p}}^{\mathrm{nom}}_{\xi,g} \cdot \mu_{\xi,t,g} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ g \in \mathcal{G} \,:\, \mathrm{on}^{\mathrm{mnt,ext}}_{t,g} ``` ### `Generator-maintcap_lower_nommax` @@ -6381,12 +6396,12 @@ Generator_maintcap_upper_nommax: Generator_maintcap_lower_nommax: description: "`Generator-maintcap_lower_nommax` — in maintenance, the whole chosen build is taken off" dims: [scenario, snapshot, generator] - where: Generator_maintainable AND Generator_p_nom_extendable AND NOT (Generator_committable AND Generator_p_nom_mod > 0) AND Generator_active + where: Generator_maint_ext expression: Generator_maintenance_capacity >= Generator_p_nom_ext - Generator_p_nom_max * (1 - Generator_maintenance) ``` ```math -\mu^{\mathrm{nom}}_{\xi,t,g} \ge P_{g} - \overline{\mathrm{p}}^{\mathrm{nom}}_{\xi,g} \cdot \left( 1 - \mu_{\xi,t,g} \right) \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ g \in \mathcal{G} \,:\, \mathrm{mnt}_{g} \wedge \mathrm{ext}_{g} \wedge \neg \left( \mathrm{com}_{g} \wedge \mathrm{p}^{\mathrm{mod}}_{g} > 0 \right) \wedge \mathrm{on}_{t,g} +\mu^{\mathrm{nom}}_{\xi,t,g} \ge P_{g} - \overline{\mathrm{p}}^{\mathrm{nom}}_{\xi,g} \cdot \left( 1 - \mu_{\xi,t,g} \right) \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ g \in \mathcal{G} \,:\, \mathrm{on}^{\mathrm{mnt,ext}}_{t,g} ``` ### `Generator-maintcap_lower_nommin` @@ -6397,12 +6412,12 @@ Generator_maintcap_lower_nommax: Generator_maintcap_lower_nommin: description: "`Generator-maintcap_lower_nommin` — in maintenance, at least the floor of the build is taken off" dims: [scenario, snapshot, generator] - where: Generator_maintainable AND Generator_p_nom_extendable AND NOT (Generator_committable AND Generator_p_nom_mod > 0) AND Generator_active AND Generator_p_nom_min > 0 + where: Generator_maint_ext AND Generator_p_nom_min > 0 expression: Generator_maintenance_capacity >= Generator_p_nom_min * Generator_maintenance ``` ```math -\mu^{\mathrm{nom}}_{\xi,t,g} \ge \underline{\mathrm{p}}^{\mathrm{nom}}_{\xi,g} \cdot \mu_{\xi,t,g} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ g \in \mathcal{G} \,:\, \mathrm{mnt}_{g} \wedge \mathrm{ext}_{g} \wedge \neg \left( \mathrm{com}_{g} \wedge \mathrm{p}^{\mathrm{mod}}_{g} > 0 \right) \wedge \mathrm{on}_{t,g} \wedge \underline{\mathrm{p}}^{\mathrm{nom}}_{\xi,g} > 0 +\mu^{\mathrm{nom}}_{\xi,t,g} \ge \underline{\mathrm{p}}^{\mathrm{nom}}_{\xi,g} \cdot \mu_{\xi,t,g} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ g \in \mathcal{G} \,:\, \mathrm{on}^{\mathrm{mnt,ext}}_{t,g} \wedge \underline{\mathrm{p}}^{\mathrm{nom}}_{\xi,g} > 0 ``` ### `Generator-maint-status-le-status` @@ -6413,12 +6428,12 @@ Generator_maintcap_lower_nommin: Generator_maint_status_le_status: description: "`Generator-maint-status-le-status` — the status in maintenance is at most the status" dims: [scenario, snapshot, generator] - where: Generator_maintainable AND Generator_committable AND NOT Generator_p_nom_extendable AND Generator_active + where: Generator_maintainable AND Generator_committed AND NOT Generator_p_nom_extendable expression: Generator_maintenance_status <= Generator_status ``` ```math -\mu^{u}_{\xi,t,g} \le u_{\xi,t,g} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ g \in \mathcal{G} \,:\, \mathrm{mnt}_{g} \wedge \mathrm{com}_{g} \wedge \neg \mathrm{ext}_{g} \wedge \mathrm{on}_{t,g} +\mu^{u}_{\xi,t,g} \le u_{\xi,t,g} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ g \in \mathcal{G} \,:\, \mathrm{mnt}_{g} \wedge \mathrm{on}^{\mathrm{com}}_{t,g} \wedge \neg \mathrm{ext}_{g} ``` ### `Generator-maint-status-le-maint` @@ -6429,12 +6444,12 @@ Generator_maint_status_le_status: Generator_maint_status_le_maint: description: "`Generator-maint-status-le-maint` — out of maintenance, the status in maintenance is zero" dims: [scenario, snapshot, generator] - where: Generator_maintainable AND Generator_committable AND NOT Generator_p_nom_extendable AND Generator_active + where: Generator_maintainable AND Generator_committed AND NOT Generator_p_nom_extendable expression: Generator_maintenance_status <= Generator_maintenance ``` ```math -\mu^{u}_{\xi,t,g} \le \mu_{\xi,t,g} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ g \in \mathcal{G} \,:\, \mathrm{mnt}_{g} \wedge \mathrm{com}_{g} \wedge \neg \mathrm{ext}_{g} \wedge \mathrm{on}_{t,g} +\mu^{u}_{\xi,t,g} \le \mu_{\xi,t,g} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ g \in \mathcal{G} \,:\, \mathrm{mnt}_{g} \wedge \mathrm{on}^{\mathrm{com}}_{t,g} \wedge \neg \mathrm{ext}_{g} ``` ### `Generator-maint-status-lb` @@ -6445,12 +6460,12 @@ Generator_maint_status_le_maint: Generator_maint_status_lb: description: "`Generator-maint-status-lb` — on and in maintenance, the status in maintenance is one" dims: [scenario, snapshot, generator] - where: Generator_maintainable AND Generator_committable AND NOT Generator_p_nom_extendable AND Generator_active + where: Generator_maintainable AND Generator_committed AND NOT Generator_p_nom_extendable expression: Generator_maintenance_status >= Generator_status + Generator_maintenance - 1 ``` ```math -\mu^{u}_{\xi,t,g} \ge u_{\xi,t,g} + \mu_{\xi,t,g} - 1 \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ g \in \mathcal{G} \,:\, \mathrm{mnt}_{g} \wedge \mathrm{com}_{g} \wedge \neg \mathrm{ext}_{g} \wedge \mathrm{on}_{t,g} +\mu^{u}_{\xi,t,g} \ge u_{\xi,t,g} + \mu_{\xi,t,g} - 1 \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ g \in \mathcal{G} \,:\, \mathrm{mnt}_{g} \wedge \mathrm{on}^{\mathrm{com}}_{t,g} \wedge \neg \mathrm{ext}_{g} ``` ### `Generator-maint-modstatus-le-status` @@ -6461,12 +6476,12 @@ Generator_maint_status_lb: Generator_maint_modstatus_le_status: description: "`Generator-maint-modstatus-le-status` — the modules on in maintenance are at most the modules on" dims: [scenario, snapshot, generator] - where: Generator_maintainable AND Generator_committable AND Generator_p_nom_mod > 0 AND Generator_active + where: Generator_maintainable AND Generator_committed AND Generator_p_nom_mod > 0 expression: Generator_maintenance_status <= Generator_status ``` ```math -\mu^{u}_{\xi,t,g} \le u_{\xi,t,g} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ g \in \mathcal{G} \,:\, \mathrm{mnt}_{g} \wedge \mathrm{com}_{g} \wedge \mathrm{p}^{\mathrm{mod}}_{g} > 0 \wedge \mathrm{on}_{t,g} +\mu^{u}_{\xi,t,g} \le u_{\xi,t,g} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ g \in \mathcal{G} \,:\, \mathrm{mnt}_{g} \wedge \mathrm{on}^{\mathrm{com}}_{t,g} \wedge \mathrm{p}^{\mathrm{mod}}_{g} > 0 ``` ### `Generator-maint-modstatus-le-maint` @@ -6479,12 +6494,12 @@ Generator_maint_modstatus_le_maint: `Generator-maint-modstatus-le-maint` — out of maintenance, no module is on in maintenance; in it, at most the modules the build cap holds dims: [scenario, snapshot, generator] - where: Generator_maintainable AND Generator_committable AND Generator_p_nom_mod > 0 AND Generator_active + where: Generator_maintainable AND Generator_committed AND Generator_p_nom_mod > 0 expression: Generator_maintenance_status <= Generator_p_nom_max / Generator_p_nom_mod * Generator_maintenance ``` ```math -\mu^{u}_{\xi,t,g} \le \frac{\overline{\mathrm{p}}^{\mathrm{nom}}_{\xi,g}}{\mathrm{p}^{\mathrm{mod}}_{g}} \cdot \mu_{\xi,t,g} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ g \in \mathcal{G} \,:\, \mathrm{mnt}_{g} \wedge \mathrm{com}_{g} \wedge \mathrm{p}^{\mathrm{mod}}_{g} > 0 \wedge \mathrm{on}_{t,g} +\mu^{u}_{\xi,t,g} \le \frac{\overline{\mathrm{p}}^{\mathrm{nom}}_{\xi,g}}{\mathrm{p}^{\mathrm{mod}}_{g}} \cdot \mu_{\xi,t,g} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ g \in \mathcal{G} \,:\, \mathrm{mnt}_{g} \wedge \mathrm{on}^{\mathrm{com}}_{t,g} \wedge \mathrm{p}^{\mathrm{mod}}_{g} > 0 ``` ### `Generator-maint-modstatus-lb` @@ -6495,12 +6510,12 @@ Generator_maint_modstatus_le_maint: Generator_maint_modstatus_lb: description: "`Generator-maint-modstatus-lb` — in maintenance, every module on is on in maintenance" dims: [scenario, snapshot, generator] - where: Generator_maintainable AND Generator_committable AND Generator_p_nom_mod > 0 AND Generator_active + where: Generator_maintainable AND Generator_committed AND Generator_p_nom_mod > 0 expression: Generator_maintenance_status >= Generator_status - Generator_p_nom_max / Generator_p_nom_mod * (1 - Generator_maintenance) ``` ```math -\mu^{u}_{\xi,t,g} \ge u_{\xi,t,g} - \frac{\overline{\mathrm{p}}^{\mathrm{nom}}_{\xi,g}}{\mathrm{p}^{\mathrm{mod}}_{g}} \cdot \left( 1 - \mu_{\xi,t,g} \right) \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ g \in \mathcal{G} \,:\, \mathrm{mnt}_{g} \wedge \mathrm{com}_{g} \wedge \mathrm{p}^{\mathrm{mod}}_{g} > 0 \wedge \mathrm{on}_{t,g} +\mu^{u}_{\xi,t,g} \ge u_{\xi,t,g} - \frac{\overline{\mathrm{p}}^{\mathrm{nom}}_{\xi,g}}{\mathrm{p}^{\mathrm{mod}}_{g}} \cdot \left( 1 - \mu_{\xi,t,g} \right) \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ g \in \mathcal{G} \,:\, \mathrm{mnt}_{g} \wedge \mathrm{on}^{\mathrm{com}}_{t,g} \wedge \mathrm{p}^{\mathrm{mod}}_{g} > 0 ``` ### `Link-com-p-lower` @@ -6511,12 +6526,12 @@ Generator_maint_modstatus_lb: Link_com_p_lower: description: "`Link-com-p-lower` — a committed link flows at least its minimum; off, at least nothing" dims: [scenario, snapshot, link] - where: Link_committable AND not Link_p_nom_extendable AND Link_active + where: Link_committed AND NOT Link_p_nom_extendable expression: Link_p >= Link_p_min_pu * Link_p_nom * (Link_status - Link_maintenance_pu * Link_maintenance_status) ``` ```math -f_{\xi,t,l} \ge \underline{\mathrm{f}}_{\xi,t,l} \cdot \mathrm{f}^{\mathrm{nom}}_{\xi,l} \cdot \left( u^{f}_{\xi,t,l} - \gamma^{f}_{\xi,l} \cdot \mu^{f,u}_{\xi,t,l} \right) \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ l \in \mathcal{L} \,:\, \mathrm{com}^{f}_{l} \wedge \neg \mathrm{ext}^{f}_{l} \wedge \mathrm{on}^{f}_{t,l} +f_{\xi,t,l} \ge \underline{\mathrm{f}}_{\xi,t,l} \cdot \mathrm{f}^{\mathrm{nom}}_{\xi,l} \cdot \left( u^{f}_{\xi,t,l} - \gamma^{f}_{\xi,l} \cdot \mu^{f,u}_{\xi,t,l} \right) \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ l \in \mathcal{L} \,:\, \mathrm{on}^{f,\mathrm{com}}_{t,l} \wedge \neg \mathrm{ext}^{f}_{l} ``` ### `Link-com-p-upper` @@ -6527,12 +6542,12 @@ f_{\xi,t,l} \ge \underline{\mathrm{f}}_{\xi,t,l} \cdot \mathrm{f}^{\mathrm{nom}} Link_com_p_upper: description: "`Link-com-p-upper` — a committed link flows at most what is available; off, at most nothing" dims: [scenario, snapshot, link] - where: Link_committable AND not Link_p_nom_extendable AND Link_active + where: Link_committed AND NOT Link_p_nom_extendable expression: Link_p <= Link_p_max_pu * Link_p_nom * (Link_status - Link_maintenance_pu * Link_maintenance_status) ``` ```math -f_{\xi,t,l} \le \overline{\mathrm{f}}_{\xi,t,l} \cdot \mathrm{f}^{\mathrm{nom}}_{\xi,l} \cdot \left( u^{f}_{\xi,t,l} - \gamma^{f}_{\xi,l} \cdot \mu^{f,u}_{\xi,t,l} \right) \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ l \in \mathcal{L} \,:\, \mathrm{com}^{f}_{l} \wedge \neg \mathrm{ext}^{f}_{l} \wedge \mathrm{on}^{f}_{t,l} +f_{\xi,t,l} \le \overline{\mathrm{f}}_{\xi,t,l} \cdot \mathrm{f}^{\mathrm{nom}}_{\xi,l} \cdot \left( u^{f}_{\xi,t,l} - \gamma^{f}_{\xi,l} \cdot \mu^{f,u}_{\xi,t,l} \right) \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ l \in \mathcal{L} \,:\, \mathrm{on}^{f,\mathrm{com}}_{t,l} \wedge \neg \mathrm{ext}^{f}_{l} ``` ### `Link-com-transition-start-up` @@ -6543,12 +6558,12 @@ f_{\xi,t,l} \le \overline{\mathrm{f}}_{\xi,t,l} \cdot \mathrm{f}^{\mathrm{nom}}_ Link_com_transition_start_up: description: "`Link-com-transition-start-up` — turning on is a start, counted against the state the link carried into the snapshot" dims: [scenario, snapshot, link] - where: Link_committable AND Link_active + where: Link_committed expression: Link_start_up >= Link_status - Link_previous_status ``` ```math -\mathit{up}^{f}_{\xi,t,l} \ge u^{f}_{\xi,t,l} - \overleftarrow{u}^{f}_{\xi,t,l} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ l \in \mathcal{L} \,:\, \mathrm{com}^{f}_{l} \wedge \mathrm{on}^{f}_{t,l} +\mathit{up}^{f}_{\xi,t,l} \ge u^{f}_{\xi,t,l} - \overleftarrow{u}^{f}_{\xi,t,l} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ l \in \mathcal{L} \,:\, \mathrm{on}^{f,\mathrm{com}}_{t,l} ``` ### `Link-com-transition-shut-down` @@ -6559,12 +6574,12 @@ Link_com_transition_start_up: Link_com_transition_shut_down: description: "`Link-com-transition-shut-down` — turning off is a stop, counted against the state the link carried into the snapshot" dims: [scenario, snapshot, link] - where: Link_committable AND Link_active + where: Link_committed expression: Link_shut_down >= Link_previous_status - Link_status ``` ```math -\mathit{dn}^{f}_{\xi,t,l} \ge \overleftarrow{u}^{f}_{\xi,t,l} - u^{f}_{\xi,t,l} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ l \in \mathcal{L} \,:\, \mathrm{com}^{f}_{l} \wedge \mathrm{on}^{f}_{t,l} +\mathit{dn}^{f}_{\xi,t,l} \ge \overleftarrow{u}^{f}_{\xi,t,l} - u^{f}_{\xi,t,l} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ l \in \mathcal{L} \,:\, \mathrm{on}^{f,\mathrm{com}}_{t,l} ``` ### `Link-com-up-time` @@ -6578,12 +6593,12 @@ Link_com_up_time: is still on. The first snapshot's share of the window is the brought-in up time's, which the must-stay-up mask carries dims: [scenario, snapshot, link] - where: Link_committable AND Link_min_up_time > 0 AND position(snapshot) > 0 AND Link_active + where: Link_committed AND Link_min_up_time > 0 AND position(snapshot) > 0 expression: sum_back(Link_start_up, along=snapshot, window=Link_min_up_time) <= Link_status ``` ```math -\sum_{t' \in \mathcal{T} \,:\, 0 \le t - t' < \mathrm{UT}^{f}} \mathit{up}^{f}_{\xi,t',l} \le u^{f}_{\xi,t,l} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ l \in \mathcal{L} \,:\, \mathrm{com}^{f}_{l} \wedge \mathrm{UT}^{f}_{\xi,l} > 0 \wedge \mathrm{pos}(t) > 0 \wedge \mathrm{on}^{f}_{t,l} +\sum_{t' \in \mathcal{T} \,:\, 0 \le t - t' < \mathrm{UT}^{f}} \mathit{up}^{f}_{\xi,t',l} \le u^{f}_{\xi,t,l} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ l \in \mathcal{L} \,:\, \mathrm{on}^{f,\mathrm{com}}_{t,l} \wedge \mathrm{UT}^{f}_{\xi,l} > 0 \wedge \mathrm{pos}(t) > 0 ``` ### `Link-com-down-time` @@ -6597,12 +6612,12 @@ Link_com_down_time: time is still off. The first snapshot's share of the window is the brought-in down time's, which the must-stay-down mask carries dims: [scenario, snapshot, link] - where: Link_committable AND Link_min_down_time > 0 AND position(snapshot) > 0 AND Link_active + where: Link_committed AND Link_min_down_time > 0 AND position(snapshot) > 0 expression: sum_back(Link_shut_down, along=snapshot, window=Link_min_down_time) <= 1 - Link_status ``` ```math -\sum_{t' \in \mathcal{T} \,:\, 0 \le t - t' < \mathrm{DT}^{f}} \mathit{dn}^{f}_{\xi,t',l} \le 1 - u^{f}_{\xi,t,l} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ l \in \mathcal{L} \,:\, \mathrm{com}^{f}_{l} \wedge \mathrm{DT}^{f}_{\xi,l} > 0 \wedge \mathrm{pos}(t) > 0 \wedge \mathrm{on}^{f}_{t,l} +\sum_{t' \in \mathcal{T} \,:\, 0 \le t - t' < \mathrm{DT}^{f}} \mathit{dn}^{f}_{\xi,t',l} \le 1 - u^{f}_{\xi,t,l} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ l \in \mathcal{L} \,:\, \mathrm{on}^{f,\mathrm{com}}_{t,l} \wedge \mathrm{DT}^{f}_{\xi,l} > 0 \wedge \mathrm{pos}(t) > 0 ``` ### `Link-com-status-min_up_time_must_stay_up` @@ -6613,12 +6628,12 @@ Link_com_down_time: Link_com_status_must_stay_up: description: "`Link-com-status-min_up_time_must_stay_up` — a link still serving the up time it brought in stays on" dims: [scenario, snapshot, link] - where: Link_committable AND Link_must_stay_up AND Link_active + where: Link_committed AND Link_must_stay_up expression: Link_status == 1 ``` ```math -u^{f}_{\xi,t,l} = 1 \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ l \in \mathcal{L} \,:\, \mathrm{com}^{f}_{l} \wedge \mathrm{hold}^{f}_{\xi,t,l} \wedge \mathrm{on}^{f}_{t,l} +u^{f}_{\xi,t,l} = 1 \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ l \in \mathcal{L} \,:\, \mathrm{on}^{f,\mathrm{com}}_{t,l} \wedge \mathrm{hold}^{f}_{\xi,t,l} ``` ### `Link-com-status-min_down_time_must_stay_up` @@ -6631,12 +6646,12 @@ Link_com_status_must_stay_down: `Link-com-status-min_down_time_must_stay_up` — a link still serving the down time it brought in stays off; PyPSA names the row `_must_stay_up` dims: [scenario, snapshot, link] - where: Link_committable AND Link_must_stay_down AND Link_active + where: Link_committed AND Link_must_stay_down expression: Link_status == 0 ``` ```math -u^{f}_{\xi,t,l} = 0 \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ l \in \mathcal{L} \,:\, \mathrm{com}^{f}_{l} \wedge \mathrm{rest}^{f}_{\xi,t,l} \wedge \mathrm{on}^{f}_{t,l} +u^{f}_{\xi,t,l} = 0 \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ l \in \mathcal{L} \,:\, \mathrm{on}^{f,\mathrm{com}}_{t,l} \wedge \mathrm{rest}^{f}_{\xi,t,l} ``` ### `Link-p-ramp_limit_up-run-bigM` @@ -6650,11 +6665,7 @@ Link_p_ramp_limit_up_run_big_m: raises flow no faster than its limit of the chosen build; the big M releases the row in the snapshot it turns on dims: [scenario, snapshot, link] - where: >- - Link_committable AND Link_p_nom_extendable AND NOT (Link_p_nom_mod > 0) - AND (Link_ramp_limit_up OR Link_ramp_limit_start_up) - AND (position(snapshot, by=snapshot_period, within=period) > 0 OR (position(snapshot) == 0 AND (Link_status_initial == 0 OR Link_p_init))) - AND Link_active + where: Link_com_ext AND (Link_ramp_limit_up OR Link_ramp_limit_start_up) AND Link_ramps_from_previous expression: >- Link_p - Link_previous_p <= Link_ramp_up_rate * Link_p_nom_ext @@ -6662,7 +6673,7 @@ Link_p_ramp_limit_up_run_big_m: ``` ```math -f_{\xi,t,l} - \overleftarrow{f}_{\xi,t,l} \le \widetilde{\mathrm{ru}}^{f}_{\xi,t,l} \cdot F_{l} + \mathrm{M}^{f}_{\xi,l} - \mathrm{M}^{f}_{\xi,l} \cdot \overleftarrow{u}^{f}_{\xi,t,l} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ l \in \mathcal{L} \,:\, \mathrm{com}^{f}_{l} \wedge \mathrm{ext}^{f}_{l} \wedge \neg \left( \mathrm{f}^{\mathrm{mod}}_{l} > 0 \right) \wedge \left( \mathrm{ru}^{f}_{\xi,t,l} \text{ is defined} \vee \mathrm{ru}^{f,\mathrm{up}}_{\xi,l} \text{ is defined} \right) \wedge \left( \mathrm{pos}_{\mathrm{snapshot\_period}(t)}(t) > 0 \vee \mathrm{pos}(t) = 0 \wedge \left( \mathrm{u}^{f,0}_{\xi,l} = 0 \vee \mathrm{f}^{0}_{\xi,l} \text{ is defined} \right) \right) \wedge \mathrm{on}^{f}_{t,l} +f_{\xi,t,l} - \overleftarrow{f}_{\xi,t,l} \le \widetilde{\mathrm{ru}}^{f}_{\xi,t,l} \cdot F_{l} + \mathrm{M}^{f}_{\xi,l} - \mathrm{M}^{f}_{\xi,l} \cdot \overleftarrow{u}^{f}_{\xi,t,l} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ l \in \mathcal{L} \,:\, \mathrm{on}^{f,\mathrm{com,ext}}_{t,l} \wedge \left( \mathrm{ru}^{f}_{\xi,t,l} \text{ is defined} \vee \mathrm{ru}^{f,\mathrm{up}}_{\xi,l} \text{ is defined} \right) \wedge \mathrm{prev}^{f}_{\xi,t,l} ``` ### `Link-p-ramp_limit_up-start-bigM` @@ -6676,11 +6687,7 @@ Link_p_ramp_limit_up_start_big_m: committed extendable link ramps no further than its start-up ramp of the chosen build; the big M releases the row everywhere else dims: [scenario, snapshot, link] - where: >- - Link_committable AND Link_p_nom_extendable AND NOT (Link_p_nom_mod > 0) - AND (Link_ramp_limit_up OR Link_ramp_limit_start_up) - AND (position(snapshot, by=snapshot_period, within=period) > 0 OR (position(snapshot) == 0 AND (Link_status_initial == 0 OR Link_p_init))) - AND Link_active + where: Link_com_ext AND (Link_ramp_limit_up OR Link_ramp_limit_start_up) AND Link_ramps_from_previous expression: >- Link_p - Link_previous_p <= Link_start_up_rate * Link_p_nom_ext @@ -6688,7 +6695,7 @@ Link_p_ramp_limit_up_start_big_m: ``` ```math -f_{\xi,t,l} - \overleftarrow{f}_{\xi,t,l} \le \widetilde{\mathrm{ru}}^{f,\mathrm{up}}_{\xi,l} \cdot F_{l} + \mathrm{M}^{f}_{\xi,l} - \mathrm{M}^{f}_{\xi,l} \cdot \mathit{up}^{f}_{\xi,t,l} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ l \in \mathcal{L} \,:\, \mathrm{com}^{f}_{l} \wedge \mathrm{ext}^{f}_{l} \wedge \neg \left( \mathrm{f}^{\mathrm{mod}}_{l} > 0 \right) \wedge \left( \mathrm{ru}^{f}_{\xi,t,l} \text{ is defined} \vee \mathrm{ru}^{f,\mathrm{up}}_{\xi,l} \text{ is defined} \right) \wedge \left( \mathrm{pos}_{\mathrm{snapshot\_period}(t)}(t) > 0 \vee \mathrm{pos}(t) = 0 \wedge \left( \mathrm{u}^{f,0}_{\xi,l} = 0 \vee \mathrm{f}^{0}_{\xi,l} \text{ is defined} \right) \right) \wedge \mathrm{on}^{f}_{t,l} +f_{\xi,t,l} - \overleftarrow{f}_{\xi,t,l} \le \widetilde{\mathrm{ru}}^{f,\mathrm{up}}_{\xi,l} \cdot F_{l} + \mathrm{M}^{f}_{\xi,l} - \mathrm{M}^{f}_{\xi,l} \cdot \mathit{up}^{f}_{\xi,t,l} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ l \in \mathcal{L} \,:\, \mathrm{on}^{f,\mathrm{com,ext}}_{t,l} \wedge \left( \mathrm{ru}^{f}_{\xi,t,l} \text{ is defined} \vee \mathrm{ru}^{f,\mathrm{up}}_{\xi,l} \text{ is defined} \right) \wedge \mathrm{prev}^{f}_{\xi,t,l} ``` ### `Link-p-ramp_limit_down-run-bigM` @@ -6702,11 +6709,7 @@ Link_p_ramp_limit_down_run_big_m: lowers flow no faster than its limit of the chosen build; the big M releases the row in the snapshot it turns off dims: [scenario, snapshot, link] - where: >- - Link_committable AND Link_p_nom_extendable AND NOT (Link_p_nom_mod > 0) - AND (Link_ramp_limit_down OR Link_ramp_limit_shut_down) - AND (position(snapshot, by=snapshot_period, within=period) > 0 OR (position(snapshot) == 0 AND (Link_status_initial == 0 OR Link_p_init))) - AND Link_active + where: Link_com_ext AND (Link_ramp_limit_down OR Link_ramp_limit_shut_down) AND Link_ramps_from_previous expression: >- Link_previous_p - Link_p <= Link_ramp_down_rate * Link_p_nom_ext @@ -6714,7 +6717,7 @@ Link_p_ramp_limit_down_run_big_m: ``` ```math -\overleftarrow{f}_{\xi,t,l} - f_{\xi,t,l} \le \widetilde{\mathrm{rd}}^{f}_{\xi,t,l} \cdot F_{l} + \mathrm{M}^{f}_{\xi,l} - \mathrm{M}^{f}_{\xi,l} \cdot u^{f}_{\xi,t,l} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ l \in \mathcal{L} \,:\, \mathrm{com}^{f}_{l} \wedge \mathrm{ext}^{f}_{l} \wedge \neg \left( \mathrm{f}^{\mathrm{mod}}_{l} > 0 \right) \wedge \left( \mathrm{rd}^{f}_{\xi,t,l} \text{ is defined} \vee \mathrm{rd}^{f,\mathrm{dn}}_{\xi,l} \text{ is defined} \right) \wedge \left( \mathrm{pos}_{\mathrm{snapshot\_period}(t)}(t) > 0 \vee \mathrm{pos}(t) = 0 \wedge \left( \mathrm{u}^{f,0}_{\xi,l} = 0 \vee \mathrm{f}^{0}_{\xi,l} \text{ is defined} \right) \right) \wedge \mathrm{on}^{f}_{t,l} +\overleftarrow{f}_{\xi,t,l} - f_{\xi,t,l} \le \widetilde{\mathrm{rd}}^{f}_{\xi,t,l} \cdot F_{l} + \mathrm{M}^{f}_{\xi,l} - \mathrm{M}^{f}_{\xi,l} \cdot u^{f}_{\xi,t,l} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ l \in \mathcal{L} \,:\, \mathrm{on}^{f,\mathrm{com,ext}}_{t,l} \wedge \left( \mathrm{rd}^{f}_{\xi,t,l} \text{ is defined} \vee \mathrm{rd}^{f,\mathrm{dn}}_{\xi,l} \text{ is defined} \right) \wedge \mathrm{prev}^{f}_{\xi,t,l} ``` ### `Link-p-ramp_limit_down-shut-bigM` @@ -6728,11 +6731,7 @@ Link_p_ramp_limit_down_shut_big_m: a committed extendable link ramps no further than its shut-down ramp of the chosen build; the big M releases the row everywhere else dims: [scenario, snapshot, link] - where: >- - Link_committable AND Link_p_nom_extendable AND NOT (Link_p_nom_mod > 0) - AND (Link_ramp_limit_down OR Link_ramp_limit_shut_down) - AND (position(snapshot, by=snapshot_period, within=period) > 0 OR (position(snapshot) == 0 AND (Link_status_initial == 0 OR Link_p_init))) - AND Link_active + where: Link_com_ext AND (Link_ramp_limit_down OR Link_ramp_limit_shut_down) AND Link_ramps_from_previous expression: >- Link_previous_p - Link_p <= Link_shut_down_rate * Link_p_nom_ext @@ -6740,7 +6739,7 @@ Link_p_ramp_limit_down_shut_big_m: ``` ```math -\overleftarrow{f}_{\xi,t,l} - f_{\xi,t,l} \le \widetilde{\mathrm{rd}}^{f,\mathrm{dn}}_{\xi,l} \cdot F_{l} + \mathrm{M}^{f}_{\xi,l} - \mathrm{M}^{f}_{\xi,l} \cdot \mathit{dn}^{f}_{\xi,t,l} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ l \in \mathcal{L} \,:\, \mathrm{com}^{f}_{l} \wedge \mathrm{ext}^{f}_{l} \wedge \neg \left( \mathrm{f}^{\mathrm{mod}}_{l} > 0 \right) \wedge \left( \mathrm{rd}^{f}_{\xi,t,l} \text{ is defined} \vee \mathrm{rd}^{f,\mathrm{dn}}_{\xi,l} \text{ is defined} \right) \wedge \left( \mathrm{pos}_{\mathrm{snapshot\_period}(t)}(t) > 0 \vee \mathrm{pos}(t) = 0 \wedge \left( \mathrm{u}^{f,0}_{\xi,l} = 0 \vee \mathrm{f}^{0}_{\xi,l} \text{ is defined} \right) \right) \wedge \mathrm{on}^{f}_{t,l} +\overleftarrow{f}_{\xi,t,l} - f_{\xi,t,l} \le \widetilde{\mathrm{rd}}^{f,\mathrm{dn}}_{\xi,l} \cdot F_{l} + \mathrm{M}^{f}_{\xi,l} - \mathrm{M}^{f}_{\xi,l} \cdot \mathit{dn}^{f}_{\xi,t,l} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ l \in \mathcal{L} \,:\, \mathrm{on}^{f,\mathrm{com,ext}}_{t,l} \wedge \left( \mathrm{rd}^{f}_{\xi,t,l} \text{ is defined} \vee \mathrm{rd}^{f,\mathrm{dn}}_{\xi,l} \text{ is defined} \right) \wedge \mathrm{prev}^{f}_{\xi,t,l} ``` ### `Link-p_nom_modularity` @@ -6769,12 +6768,12 @@ Link_com_ext_p_upper_cap: `Link-com-ext-p-upper-cap` — a committed extendable link flows at most what is available of the chosen build, whatever its status dims: [scenario, snapshot, link] - where: Link_committable AND Link_p_nom_extendable AND NOT (Link_p_nom_mod > 0) AND Link_active + where: Link_com_ext expression: Link_p <= Link_p_max_pu * (Link_p_nom_ext - Link_maintenance_pu * Link_maintenance_capacity) ``` ```math -f_{\xi,t,l} \le \overline{\mathrm{f}}_{\xi,t,l} \cdot \left( F_{l} - \gamma^{f}_{\xi,l} \cdot \mu^{f,\mathrm{nom}}_{\xi,t,l} \right) \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ l \in \mathcal{L} \,:\, \mathrm{com}^{f}_{l} \wedge \mathrm{ext}^{f}_{l} \wedge \neg \left( \mathrm{f}^{\mathrm{mod}}_{l} > 0 \right) \wedge \mathrm{on}^{f}_{t,l} +f_{\xi,t,l} \le \overline{\mathrm{f}}_{\xi,t,l} \cdot \left( F_{l} - \gamma^{f}_{\xi,l} \cdot \mu^{f,\mathrm{nom}}_{\xi,t,l} \right) \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ l \in \mathcal{L} \,:\, \mathrm{on}^{f,\mathrm{com,ext}}_{t,l} ``` ### `Link-com-ext-p-upper-bigM` @@ -6785,12 +6784,12 @@ f_{\xi,t,l} \le \overline{\mathrm{f}}_{\xi,t,l} \cdot \left( F_{l} - \gamma^{f}_ Link_com_ext_p_upper_big_m: description: "`Link-com-ext-p-upper-bigM` — off, a link flows nothing; on, the big M is no bound" dims: [scenario, snapshot, link] - where: Link_committable AND Link_p_nom_extendable AND NOT (Link_p_nom_mod > 0) AND Link_active + where: Link_com_ext expression: Link_p <= Link_big_m * Link_status ``` ```math -f_{\xi,t,l} \le \mathrm{M}^{f}_{\xi,l} \cdot u^{f}_{\xi,t,l} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ l \in \mathcal{L} \,:\, \mathrm{com}^{f}_{l} \wedge \mathrm{ext}^{f}_{l} \wedge \neg \left( \mathrm{f}^{\mathrm{mod}}_{l} > 0 \right) \wedge \mathrm{on}^{f}_{t,l} +f_{\xi,t,l} \le \mathrm{M}^{f}_{\xi,l} \cdot u^{f}_{\xi,t,l} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ l \in \mathcal{L} \,:\, \mathrm{on}^{f,\mathrm{com,ext}}_{t,l} ``` ### `Link-com-ext-p-lower` @@ -6803,7 +6802,7 @@ Link_com_ext_p_lower: `Link-com-ext-p-lower` — a committed extendable link flows at least its minimum of the chosen build; off, the big M releases the row dims: [scenario, snapshot, link] - where: Link_committable AND Link_p_nom_extendable AND NOT (Link_p_nom_mod > 0) AND Link_active + where: Link_com_ext expression: >- Link_p >= Link_p_min_pu * (Link_p_nom_ext - Link_maintenance_pu * Link_maintenance_capacity) @@ -6811,7 +6810,7 @@ Link_com_ext_p_lower: ``` ```math -f_{\xi,t,l} \ge \underline{\mathrm{f}}_{\xi,t,l} \cdot \left( F_{l} - \gamma^{f}_{\xi,l} \cdot \mu^{f,\mathrm{nom}}_{\xi,t,l} \right) + \mathrm{M}^{f}_{\xi,l} \cdot u^{f}_{\xi,t,l} - \mathrm{M}^{f}_{\xi,l} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ l \in \mathcal{L} \,:\, \mathrm{com}^{f}_{l} \wedge \mathrm{ext}^{f}_{l} \wedge \neg \left( \mathrm{f}^{\mathrm{mod}}_{l} > 0 \right) \wedge \mathrm{on}^{f}_{t,l} +f_{\xi,t,l} \ge \underline{\mathrm{f}}_{\xi,t,l} \cdot \left( F_{l} - \gamma^{f}_{\xi,l} \cdot \mu^{f,\mathrm{nom}}_{\xi,t,l} \right) + \mathrm{M}^{f}_{\xi,l} \cdot u^{f}_{\xi,t,l} - \mathrm{M}^{f}_{\xi,l} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ l \in \mathcal{L} \,:\, \mathrm{on}^{f,\mathrm{com,ext}}_{t,l} ``` ### `Link-com-ext-p-lower-nonneg` @@ -6825,14 +6824,12 @@ Link_com_ext_p_lower_nonneg: negative, flow is also plainly non-negative, a row the big-M lower cannot assert while the link is off dims: [scenario, snapshot, link] - where: >- - Link_committable AND Link_p_nom_extendable - AND Link_p_min_pu_nonneg AND NOT (Link_p_nom_mod > 0) AND Link_active + where: Link_com_ext AND Link_p_min_pu_nonneg expression: Link_p >= 0 ``` ```math -f_{\xi,t,l} \ge 0 \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ l \in \mathcal{L} \,:\, \mathrm{com}^{f}_{l} \wedge \mathrm{ext}^{f}_{l} \wedge \mathrm{nonneg}^{f}_{l} \wedge \neg \left( \mathrm{f}^{\mathrm{mod}}_{l} > 0 \right) \wedge \mathrm{on}^{f}_{t,l} +f_{\xi,t,l} \ge 0 \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ l \in \mathcal{L} \,:\, \mathrm{on}^{f,\mathrm{com,ext}}_{t,l} \wedge \mathrm{nonneg}^{f}_{l} ``` ### `Link-com-mod-p-lower` @@ -6845,12 +6842,12 @@ Link_com_mod_p_lower: `Link-com-mod-p-lower` — a committed modular link flows at least its minimum of one module, whether the build is fixed or a decision dims: [scenario, snapshot, link] - where: Link_committable AND Link_p_nom_mod > 0 AND Link_active + where: Link_committed AND Link_p_nom_mod > 0 expression: Link_p >= Link_p_min_pu * Link_p_nom_mod * (Link_status - Link_maintenance_pu * Link_maintenance_status) ``` ```math -f_{\xi,t,l} \ge \underline{\mathrm{f}}_{\xi,t,l} \cdot \mathrm{f}^{\mathrm{mod}}_{l} \cdot \left( u^{f}_{\xi,t,l} - \gamma^{f}_{\xi,l} \cdot \mu^{f,u}_{\xi,t,l} \right) \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ l \in \mathcal{L} \,:\, \mathrm{com}^{f}_{l} \wedge \mathrm{f}^{\mathrm{mod}}_{l} > 0 \wedge \mathrm{on}^{f}_{t,l} +f_{\xi,t,l} \ge \underline{\mathrm{f}}_{\xi,t,l} \cdot \mathrm{f}^{\mathrm{mod}}_{l} \cdot \left( u^{f}_{\xi,t,l} - \gamma^{f}_{\xi,l} \cdot \mu^{f,u}_{\xi,t,l} \right) \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ l \in \mathcal{L} \,:\, \mathrm{on}^{f,\mathrm{com}}_{t,l} \wedge \mathrm{f}^{\mathrm{mod}}_{l} > 0 ``` ### `Link-com-mod-p-upper` @@ -6863,12 +6860,12 @@ Link_com_mod_p_upper: `Link-com-mod-p-upper` — a committed modular link flows at most one module's share, whether the build is fixed or a decision dims: [scenario, snapshot, link] - where: Link_committable AND Link_p_nom_mod > 0 AND Link_active + where: Link_committed AND Link_p_nom_mod > 0 expression: Link_p <= Link_p_max_pu * Link_p_nom_mod * (Link_status - Link_maintenance_pu * Link_maintenance_status) ``` ```math -f_{\xi,t,l} \le \overline{\mathrm{f}}_{\xi,t,l} \cdot \mathrm{f}^{\mathrm{mod}}_{l} \cdot \left( u^{f}_{\xi,t,l} - \gamma^{f}_{\xi,l} \cdot \mu^{f,u}_{\xi,t,l} \right) \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ l \in \mathcal{L} \,:\, \mathrm{com}^{f}_{l} \wedge \mathrm{f}^{\mathrm{mod}}_{l} > 0 \wedge \mathrm{on}^{f}_{t,l} +f_{\xi,t,l} \le \overline{\mathrm{f}}_{\xi,t,l} \cdot \mathrm{f}^{\mathrm{mod}}_{l} \cdot \left( u^{f}_{\xi,t,l} - \gamma^{f}_{\xi,l} \cdot \mu^{f,u}_{\xi,t,l} \right) \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ l \in \mathcal{L} \,:\, \mathrm{on}^{f,\mathrm{com}}_{t,l} \wedge \mathrm{f}^{\mathrm{mod}}_{l} > 0 ``` ### `Link-status-p-fixed-upper` @@ -6882,12 +6879,12 @@ Link_status_p_fixed_upper: place, an explicit row as PyPSA writes it: one where the build is not modular, and the fixed build's whole count of modules where it is dims: [scenario, snapshot, link] - where: Link_committable AND NOT (Link_p_nom_extendable AND Link_p_nom_mod > 0) AND Link_active + where: Link_committed AND NOT (Link_p_nom_extendable AND Link_p_nom_mod > 0) expression: Link_status <= Link_modules_installed ``` ```math -u^{f}_{\xi,t,l} \le \mathrm{N}^{f,\mathrm{fix}}_{\xi,l} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ l \in \mathcal{L} \,:\, \mathrm{com}^{f}_{l} \wedge \neg \left( \mathrm{ext}^{f}_{l} \wedge \mathrm{f}^{\mathrm{mod}}_{l} > 0 \right) \wedge \mathrm{on}^{f}_{t,l} +u^{f}_{\xi,t,l} \le \mathrm{N}^{f,\mathrm{fix}}_{\xi,l} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ l \in \mathcal{L} \,:\, \mathrm{on}^{f,\mathrm{com}}_{t,l} \wedge \neg \left( \mathrm{ext}^{f}_{l} \wedge \mathrm{f}^{\mathrm{mod}}_{l} > 0 \right) ``` ### `Link-start_up-p-fixed-upper` @@ -6901,12 +6898,12 @@ Link_start_up_p_fixed_upper: place, an explicit row as PyPSA writes it: one where the build is not modular, and the fixed build's whole count of modules where it is dims: [scenario, snapshot, link] - where: Link_committable AND NOT (Link_p_nom_extendable AND Link_p_nom_mod > 0) AND Link_active + where: Link_committed AND NOT (Link_p_nom_extendable AND Link_p_nom_mod > 0) expression: Link_start_up <= Link_modules_installed ``` ```math -\mathit{up}^{f}_{\xi,t,l} \le \mathrm{N}^{f,\mathrm{fix}}_{\xi,l} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ l \in \mathcal{L} \,:\, \mathrm{com}^{f}_{l} \wedge \neg \left( \mathrm{ext}^{f}_{l} \wedge \mathrm{f}^{\mathrm{mod}}_{l} > 0 \right) \wedge \mathrm{on}^{f}_{t,l} +\mathit{up}^{f}_{\xi,t,l} \le \mathrm{N}^{f,\mathrm{fix}}_{\xi,l} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ l \in \mathcal{L} \,:\, \mathrm{on}^{f,\mathrm{com}}_{t,l} \wedge \neg \left( \mathrm{ext}^{f}_{l} \wedge \mathrm{f}^{\mathrm{mod}}_{l} > 0 \right) ``` ### `Link-shut_down-p-fixed-upper` @@ -6920,12 +6917,12 @@ Link_shut_down_p_fixed_upper: place, an explicit row as PyPSA writes it: one where the build is not modular, and the fixed build's whole count of modules where it is dims: [scenario, snapshot, link] - where: Link_committable AND NOT (Link_p_nom_extendable AND Link_p_nom_mod > 0) AND Link_active + where: Link_committed AND NOT (Link_p_nom_extendable AND Link_p_nom_mod > 0) expression: Link_shut_down <= Link_modules_installed ``` ```math -\mathit{dn}^{f}_{\xi,t,l} \le \mathrm{N}^{f,\mathrm{fix}}_{\xi,l} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ l \in \mathcal{L} \,:\, \mathrm{com}^{f}_{l} \wedge \neg \left( \mathrm{ext}^{f}_{l} \wedge \mathrm{f}^{\mathrm{mod}}_{l} > 0 \right) \wedge \mathrm{on}^{f}_{t,l} +\mathit{dn}^{f}_{\xi,t,l} \le \mathrm{N}^{f,\mathrm{fix}}_{\xi,l} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ l \in \mathcal{L} \,:\, \mathrm{on}^{f,\mathrm{com}}_{t,l} \wedge \neg \left( \mathrm{ext}^{f}_{l} \wedge \mathrm{f}^{\mathrm{mod}}_{l} > 0 \right) ``` ### `Link-status-p_nom-variable-upper` @@ -6936,12 +6933,12 @@ Link_shut_down_p_fixed_upper: Link_status_p_nom_variable_upper: description: "`Link-status-p_nom-variable-upper` — a modular link is on only where a module is built" dims: [scenario, snapshot, link] - where: Link_committable AND Link_p_nom_extendable AND Link_p_nom_mod > 0 AND Link_active + where: Link_committed AND Link_p_nom_extendable AND Link_p_nom_mod > 0 expression: Link_status <= Link_n_mod ``` ```math -u^{f}_{\xi,t,l} \le N^{f}_{l} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ l \in \mathcal{L} \,:\, \mathrm{com}^{f}_{l} \wedge \mathrm{ext}^{f}_{l} \wedge \mathrm{f}^{\mathrm{mod}}_{l} > 0 \wedge \mathrm{on}^{f}_{t,l} +u^{f}_{\xi,t,l} \le N^{f}_{l} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ l \in \mathcal{L} \,:\, \mathrm{on}^{f,\mathrm{com}}_{t,l} \wedge \mathrm{ext}^{f}_{l} \wedge \mathrm{f}^{\mathrm{mod}}_{l} > 0 ``` ### `Link-start_up-p_nom-variable-upper` @@ -6952,12 +6949,12 @@ u^{f}_{\xi,t,l} \le N^{f}_{l} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ Link_start_up_p_nom_variable_upper: description: "`Link-start_up-p_nom-variable-upper` — a modular link starts only where a module is built" dims: [scenario, snapshot, link] - where: Link_committable AND Link_p_nom_extendable AND Link_p_nom_mod > 0 AND Link_active + where: Link_committed AND Link_p_nom_extendable AND Link_p_nom_mod > 0 expression: Link_start_up <= Link_n_mod ``` ```math -\mathit{up}^{f}_{\xi,t,l} \le N^{f}_{l} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ l \in \mathcal{L} \,:\, \mathrm{com}^{f}_{l} \wedge \mathrm{ext}^{f}_{l} \wedge \mathrm{f}^{\mathrm{mod}}_{l} > 0 \wedge \mathrm{on}^{f}_{t,l} +\mathit{up}^{f}_{\xi,t,l} \le N^{f}_{l} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ l \in \mathcal{L} \,:\, \mathrm{on}^{f,\mathrm{com}}_{t,l} \wedge \mathrm{ext}^{f}_{l} \wedge \mathrm{f}^{\mathrm{mod}}_{l} > 0 ``` ### `Link-shut_down-p_nom-variable-upper` @@ -6968,12 +6965,12 @@ Link_start_up_p_nom_variable_upper: Link_shut_down_p_nom_variable_upper: description: "`Link-shut_down-p_nom-variable-upper` — a modular link stops only where a module is built" dims: [scenario, snapshot, link] - where: Link_committable AND Link_p_nom_extendable AND Link_p_nom_mod > 0 AND Link_active + where: Link_committed AND Link_p_nom_extendable AND Link_p_nom_mod > 0 expression: Link_shut_down <= Link_n_mod ``` ```math -\mathit{dn}^{f}_{\xi,t,l} \le N^{f}_{l} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ l \in \mathcal{L} \,:\, \mathrm{com}^{f}_{l} \wedge \mathrm{ext}^{f}_{l} \wedge \mathrm{f}^{\mathrm{mod}}_{l} > 0 \wedge \mathrm{on}^{f}_{t,l} +\mathit{dn}^{f}_{\xi,t,l} \le N^{f}_{l} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ l \in \mathcal{L} \,:\, \mathrm{on}^{f,\mathrm{com}}_{t,l} \wedge \mathrm{ext}^{f}_{l} \wedge \mathrm{f}^{\mathrm{mod}}_{l} > 0 ``` ### `Link-maint-event-count` @@ -7037,12 +7034,12 @@ Link_maintcap_upper: `Link-maintcap_upper` — the build taken off is at most the chosen build in maintenance, and at most the build less its floor out of it dims: [scenario, snapshot, link] - where: Link_maintainable AND Link_p_nom_extendable AND NOT (Link_committable AND Link_p_nom_mod > 0) AND Link_active + where: Link_maint_ext expression: Link_maintenance_capacity <= Link_p_nom_ext - Link_p_nom_min * (1 - Link_maintenance) ``` ```math -\mu^{f,\mathrm{nom}}_{\xi,t,l} \le F_{l} - \underline{\mathrm{f}}^{\mathrm{nom}}_{\xi,l} \cdot \left( 1 - \mu^{f}_{\xi,t,l} \right) \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ l \in \mathcal{L} \,:\, \mathrm{mnt}^{f}_{l} \wedge \mathrm{ext}^{f}_{l} \wedge \neg \left( \mathrm{com}^{f}_{l} \wedge \mathrm{f}^{\mathrm{mod}}_{l} > 0 \right) \wedge \mathrm{on}^{f}_{t,l} +\mu^{f,\mathrm{nom}}_{\xi,t,l} \le F_{l} - \underline{\mathrm{f}}^{\mathrm{nom}}_{\xi,l} \cdot \left( 1 - \mu^{f}_{\xi,t,l} \right) \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ l \in \mathcal{L} \,:\, \mathrm{on}^{f,\mathrm{mnt,ext}}_{t,l} ``` ### `Link-maintcap_upper_nommax` @@ -7053,12 +7050,12 @@ Link_maintcap_upper: Link_maintcap_upper_nommax: description: "`Link-maintcap_upper_nommax` — out of maintenance, no build is taken off" dims: [scenario, snapshot, link] - where: Link_maintainable AND Link_p_nom_extendable AND NOT (Link_committable AND Link_p_nom_mod > 0) AND Link_active + where: Link_maint_ext expression: Link_maintenance_capacity <= Link_p_nom_max * Link_maintenance ``` ```math -\mu^{f,\mathrm{nom}}_{\xi,t,l} \le \overline{\mathrm{f}}^{\mathrm{nom}}_{\xi,l} \cdot \mu^{f}_{\xi,t,l} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ l \in \mathcal{L} \,:\, \mathrm{mnt}^{f}_{l} \wedge \mathrm{ext}^{f}_{l} \wedge \neg \left( \mathrm{com}^{f}_{l} \wedge \mathrm{f}^{\mathrm{mod}}_{l} > 0 \right) \wedge \mathrm{on}^{f}_{t,l} +\mu^{f,\mathrm{nom}}_{\xi,t,l} \le \overline{\mathrm{f}}^{\mathrm{nom}}_{\xi,l} \cdot \mu^{f}_{\xi,t,l} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ l \in \mathcal{L} \,:\, \mathrm{on}^{f,\mathrm{mnt,ext}}_{t,l} ``` ### `Link-maintcap_lower_nommax` @@ -7069,12 +7066,12 @@ Link_maintcap_upper_nommax: Link_maintcap_lower_nommax: description: "`Link-maintcap_lower_nommax` — in maintenance, the whole chosen build is taken off" dims: [scenario, snapshot, link] - where: Link_maintainable AND Link_p_nom_extendable AND NOT (Link_committable AND Link_p_nom_mod > 0) AND Link_active + where: Link_maint_ext expression: Link_maintenance_capacity >= Link_p_nom_ext - Link_p_nom_max * (1 - Link_maintenance) ``` ```math -\mu^{f,\mathrm{nom}}_{\xi,t,l} \ge F_{l} - \overline{\mathrm{f}}^{\mathrm{nom}}_{\xi,l} \cdot \left( 1 - \mu^{f}_{\xi,t,l} \right) \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ l \in \mathcal{L} \,:\, \mathrm{mnt}^{f}_{l} \wedge \mathrm{ext}^{f}_{l} \wedge \neg \left( \mathrm{com}^{f}_{l} \wedge \mathrm{f}^{\mathrm{mod}}_{l} > 0 \right) \wedge \mathrm{on}^{f}_{t,l} +\mu^{f,\mathrm{nom}}_{\xi,t,l} \ge F_{l} - \overline{\mathrm{f}}^{\mathrm{nom}}_{\xi,l} \cdot \left( 1 - \mu^{f}_{\xi,t,l} \right) \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ l \in \mathcal{L} \,:\, \mathrm{on}^{f,\mathrm{mnt,ext}}_{t,l} ``` ### `Link-maintcap_lower_nommin` @@ -7085,12 +7082,12 @@ Link_maintcap_lower_nommax: Link_maintcap_lower_nommin: description: "`Link-maintcap_lower_nommin` — in maintenance, at least the floor of the build is taken off" dims: [scenario, snapshot, link] - where: Link_maintainable AND Link_p_nom_extendable AND NOT (Link_committable AND Link_p_nom_mod > 0) AND Link_active AND Link_p_nom_min > 0 + where: Link_maint_ext AND Link_p_nom_min > 0 expression: Link_maintenance_capacity >= Link_p_nom_min * Link_maintenance ``` ```math -\mu^{f,\mathrm{nom}}_{\xi,t,l} \ge \underline{\mathrm{f}}^{\mathrm{nom}}_{\xi,l} \cdot \mu^{f}_{\xi,t,l} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ l \in \mathcal{L} \,:\, \mathrm{mnt}^{f}_{l} \wedge \mathrm{ext}^{f}_{l} \wedge \neg \left( \mathrm{com}^{f}_{l} \wedge \mathrm{f}^{\mathrm{mod}}_{l} > 0 \right) \wedge \mathrm{on}^{f}_{t,l} \wedge \underline{\mathrm{f}}^{\mathrm{nom}}_{\xi,l} > 0 +\mu^{f,\mathrm{nom}}_{\xi,t,l} \ge \underline{\mathrm{f}}^{\mathrm{nom}}_{\xi,l} \cdot \mu^{f}_{\xi,t,l} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ l \in \mathcal{L} \,:\, \mathrm{on}^{f,\mathrm{mnt,ext}}_{t,l} \wedge \underline{\mathrm{f}}^{\mathrm{nom}}_{\xi,l} > 0 ``` ### `Link-maint-status-le-status` @@ -7101,12 +7098,12 @@ Link_maintcap_lower_nommin: Link_maint_status_le_status: description: "`Link-maint-status-le-status` — the status in maintenance is at most the status" dims: [scenario, snapshot, link] - where: Link_maintainable AND Link_committable AND NOT Link_p_nom_extendable AND Link_active + where: Link_maintainable AND Link_committed AND NOT Link_p_nom_extendable expression: Link_maintenance_status <= Link_status ``` ```math -\mu^{f,u}_{\xi,t,l} \le u^{f}_{\xi,t,l} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ l \in \mathcal{L} \,:\, \mathrm{mnt}^{f}_{l} \wedge \mathrm{com}^{f}_{l} \wedge \neg \mathrm{ext}^{f}_{l} \wedge \mathrm{on}^{f}_{t,l} +\mu^{f,u}_{\xi,t,l} \le u^{f}_{\xi,t,l} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ l \in \mathcal{L} \,:\, \mathrm{mnt}^{f}_{l} \wedge \mathrm{on}^{f,\mathrm{com}}_{t,l} \wedge \neg \mathrm{ext}^{f}_{l} ``` ### `Link-maint-status-le-maint` @@ -7117,12 +7114,12 @@ Link_maint_status_le_status: Link_maint_status_le_maint: description: "`Link-maint-status-le-maint` — out of maintenance, the status in maintenance is zero" dims: [scenario, snapshot, link] - where: Link_maintainable AND Link_committable AND NOT Link_p_nom_extendable AND Link_active + where: Link_maintainable AND Link_committed AND NOT Link_p_nom_extendable expression: Link_maintenance_status <= Link_maintenance ``` ```math -\mu^{f,u}_{\xi,t,l} \le \mu^{f}_{\xi,t,l} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ l \in \mathcal{L} \,:\, \mathrm{mnt}^{f}_{l} \wedge \mathrm{com}^{f}_{l} \wedge \neg \mathrm{ext}^{f}_{l} \wedge \mathrm{on}^{f}_{t,l} +\mu^{f,u}_{\xi,t,l} \le \mu^{f}_{\xi,t,l} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ l \in \mathcal{L} \,:\, \mathrm{mnt}^{f}_{l} \wedge \mathrm{on}^{f,\mathrm{com}}_{t,l} \wedge \neg \mathrm{ext}^{f}_{l} ``` ### `Link-maint-status-lb` @@ -7133,12 +7130,12 @@ Link_maint_status_le_maint: Link_maint_status_lb: description: "`Link-maint-status-lb` — on and in maintenance, the status in maintenance is one" dims: [scenario, snapshot, link] - where: Link_maintainable AND Link_committable AND NOT Link_p_nom_extendable AND Link_active + where: Link_maintainable AND Link_committed AND NOT Link_p_nom_extendable expression: Link_maintenance_status >= Link_status + Link_maintenance - 1 ``` ```math -\mu^{f,u}_{\xi,t,l} \ge u^{f}_{\xi,t,l} + \mu^{f}_{\xi,t,l} - 1 \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ l \in \mathcal{L} \,:\, \mathrm{mnt}^{f}_{l} \wedge \mathrm{com}^{f}_{l} \wedge \neg \mathrm{ext}^{f}_{l} \wedge \mathrm{on}^{f}_{t,l} +\mu^{f,u}_{\xi,t,l} \ge u^{f}_{\xi,t,l} + \mu^{f}_{\xi,t,l} - 1 \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ l \in \mathcal{L} \,:\, \mathrm{mnt}^{f}_{l} \wedge \mathrm{on}^{f,\mathrm{com}}_{t,l} \wedge \neg \mathrm{ext}^{f}_{l} ``` ### `Link-maint-modstatus-le-status` @@ -7149,12 +7146,12 @@ Link_maint_status_lb: Link_maint_modstatus_le_status: description: "`Link-maint-modstatus-le-status` — the modules on in maintenance are at most the modules on" dims: [scenario, snapshot, link] - where: Link_maintainable AND Link_committable AND Link_p_nom_mod > 0 AND Link_active + where: Link_maintainable AND Link_committed AND Link_p_nom_mod > 0 expression: Link_maintenance_status <= Link_status ``` ```math -\mu^{f,u}_{\xi,t,l} \le u^{f}_{\xi,t,l} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ l \in \mathcal{L} \,:\, \mathrm{mnt}^{f}_{l} \wedge \mathrm{com}^{f}_{l} \wedge \mathrm{f}^{\mathrm{mod}}_{l} > 0 \wedge \mathrm{on}^{f}_{t,l} +\mu^{f,u}_{\xi,t,l} \le u^{f}_{\xi,t,l} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ l \in \mathcal{L} \,:\, \mathrm{mnt}^{f}_{l} \wedge \mathrm{on}^{f,\mathrm{com}}_{t,l} \wedge \mathrm{f}^{\mathrm{mod}}_{l} > 0 ``` ### `Link-maint-modstatus-le-maint` @@ -7167,12 +7164,12 @@ Link_maint_modstatus_le_maint: `Link-maint-modstatus-le-maint` — out of maintenance, no module is on in maintenance; in it, at most the modules the build cap holds dims: [scenario, snapshot, link] - where: Link_maintainable AND Link_committable AND Link_p_nom_mod > 0 AND Link_active + where: Link_maintainable AND Link_committed AND Link_p_nom_mod > 0 expression: Link_maintenance_status <= Link_p_nom_max / Link_p_nom_mod * Link_maintenance ``` ```math -\mu^{f,u}_{\xi,t,l} \le \frac{\overline{\mathrm{f}}^{\mathrm{nom}}_{\xi,l}}{\mathrm{f}^{\mathrm{mod}}_{l}} \cdot \mu^{f}_{\xi,t,l} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ l \in \mathcal{L} \,:\, \mathrm{mnt}^{f}_{l} \wedge \mathrm{com}^{f}_{l} \wedge \mathrm{f}^{\mathrm{mod}}_{l} > 0 \wedge \mathrm{on}^{f}_{t,l} +\mu^{f,u}_{\xi,t,l} \le \frac{\overline{\mathrm{f}}^{\mathrm{nom}}_{\xi,l}}{\mathrm{f}^{\mathrm{mod}}_{l}} \cdot \mu^{f}_{\xi,t,l} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ l \in \mathcal{L} \,:\, \mathrm{mnt}^{f}_{l} \wedge \mathrm{on}^{f,\mathrm{com}}_{t,l} \wedge \mathrm{f}^{\mathrm{mod}}_{l} > 0 ``` ### `Link-maint-modstatus-lb` @@ -7183,12 +7180,12 @@ Link_maint_modstatus_le_maint: Link_maint_modstatus_lb: description: "`Link-maint-modstatus-lb` — in maintenance, every module on is on in maintenance" dims: [scenario, snapshot, link] - where: Link_maintainable AND Link_committable AND Link_p_nom_mod > 0 AND Link_active + where: Link_maintainable AND Link_committed AND Link_p_nom_mod > 0 expression: Link_maintenance_status >= Link_status - Link_p_nom_max / Link_p_nom_mod * (1 - Link_maintenance) ``` ```math -\mu^{f,u}_{\xi,t,l} \ge u^{f}_{\xi,t,l} - \frac{\overline{\mathrm{f}}^{\mathrm{nom}}_{\xi,l}}{\mathrm{f}^{\mathrm{mod}}_{l}} \cdot \left( 1 - \mu^{f}_{\xi,t,l} \right) \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ l \in \mathcal{L} \,:\, \mathrm{mnt}^{f}_{l} \wedge \mathrm{com}^{f}_{l} \wedge \mathrm{f}^{\mathrm{mod}}_{l} > 0 \wedge \mathrm{on}^{f}_{t,l} +\mu^{f,u}_{\xi,t,l} \ge u^{f}_{\xi,t,l} - \frac{\overline{\mathrm{f}}^{\mathrm{nom}}_{\xi,l}}{\mathrm{f}^{\mathrm{mod}}_{l}} \cdot \left( 1 - \mu^{f}_{\xi,t,l} \right) \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ l \in \mathcal{L} \,:\, \mathrm{mnt}^{f}_{l} \wedge \mathrm{on}^{f,\mathrm{com}}_{t,l} \wedge \mathrm{f}^{\mathrm{mod}}_{l} > 0 ``` ### `Process-com-p-lower` @@ -7199,12 +7196,12 @@ Link_maint_modstatus_lb: Process_com_p_lower: description: "`Process-com-p-lower` — a committed process runs at least its minimum; off, at least nothing" dims: [scenario, snapshot, process] - where: Process_committable AND not Process_p_nom_extendable AND Process_active + where: Process_committed AND NOT Process_p_nom_extendable expression: Process_p >= Process_p_min_pu * Process_p_nom * (Process_status - Process_maintenance_pu * Process_maintenance_status) ``` ```math -z_{\xi,t,j} \ge \underline{\mathrm{z}}_{\xi,t,j} \cdot \mathrm{z}^{\mathrm{nom}}_{\xi,j} \cdot \left( u^{z}_{\xi,t,j} - \gamma^{z}_{\xi,j} \cdot \mu^{z,u}_{\xi,t,j} \right) \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ j \in \mathcal{J} \,:\, \mathrm{com}^{z}_{j} \wedge \neg \mathrm{ext}^{z}_{j} \wedge \mathrm{on}^{z}_{t,j} +z_{\xi,t,j} \ge \underline{\mathrm{z}}_{\xi,t,j} \cdot \mathrm{z}^{\mathrm{nom}}_{\xi,j} \cdot \left( u^{z}_{\xi,t,j} - \gamma^{z}_{\xi,j} \cdot \mu^{z,u}_{\xi,t,j} \right) \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ j \in \mathcal{J} \,:\, \mathrm{on}^{z,\mathrm{com}}_{t,j} \wedge \neg \mathrm{ext}^{z}_{j} ``` ### `Process-com-p-upper` @@ -7215,12 +7212,12 @@ z_{\xi,t,j} \ge \underline{\mathrm{z}}_{\xi,t,j} \cdot \mathrm{z}^{\mathrm{nom}} Process_com_p_upper: description: "`Process-com-p-upper` — a committed process runs at most what is available; off, at most nothing" dims: [scenario, snapshot, process] - where: Process_committable AND not Process_p_nom_extendable AND Process_active + where: Process_committed AND NOT Process_p_nom_extendable expression: Process_p <= Process_p_max_pu * Process_p_nom * (Process_status - Process_maintenance_pu * Process_maintenance_status) ``` ```math -z_{\xi,t,j} \le \overline{\mathrm{z}}_{\xi,t,j} \cdot \mathrm{z}^{\mathrm{nom}}_{\xi,j} \cdot \left( u^{z}_{\xi,t,j} - \gamma^{z}_{\xi,j} \cdot \mu^{z,u}_{\xi,t,j} \right) \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ j \in \mathcal{J} \,:\, \mathrm{com}^{z}_{j} \wedge \neg \mathrm{ext}^{z}_{j} \wedge \mathrm{on}^{z}_{t,j} +z_{\xi,t,j} \le \overline{\mathrm{z}}_{\xi,t,j} \cdot \mathrm{z}^{\mathrm{nom}}_{\xi,j} \cdot \left( u^{z}_{\xi,t,j} - \gamma^{z}_{\xi,j} \cdot \mu^{z,u}_{\xi,t,j} \right) \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ j \in \mathcal{J} \,:\, \mathrm{on}^{z,\mathrm{com}}_{t,j} \wedge \neg \mathrm{ext}^{z}_{j} ``` ### `Process-com-transition-start-up` @@ -7231,12 +7228,12 @@ z_{\xi,t,j} \le \overline{\mathrm{z}}_{\xi,t,j} \cdot \mathrm{z}^{\mathrm{nom}}_ Process_com_transition_start_up: description: "`Process-com-transition-start-up` — turning on is a start, counted against the state the process carried into the snapshot" dims: [scenario, snapshot, process] - where: Process_committable AND Process_active + where: Process_committed expression: Process_start_up >= Process_status - Process_previous_status ``` ```math -\mathit{up}^{z}_{\xi,t,j} \ge u^{z}_{\xi,t,j} - \overleftarrow{u}^{z}_{\xi,t,j} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ j \in \mathcal{J} \,:\, \mathrm{com}^{z}_{j} \wedge \mathrm{on}^{z}_{t,j} +\mathit{up}^{z}_{\xi,t,j} \ge u^{z}_{\xi,t,j} - \overleftarrow{u}^{z}_{\xi,t,j} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ j \in \mathcal{J} \,:\, \mathrm{on}^{z,\mathrm{com}}_{t,j} ``` ### `Process-com-transition-shut-down` @@ -7247,12 +7244,12 @@ Process_com_transition_start_up: Process_com_transition_shut_down: description: "`Process-com-transition-shut-down` — turning off is a stop, counted against the state the process carried into the snapshot" dims: [scenario, snapshot, process] - where: Process_committable AND Process_active + where: Process_committed expression: Process_shut_down >= Process_previous_status - Process_status ``` ```math -\mathit{dn}^{z}_{\xi,t,j} \ge \overleftarrow{u}^{z}_{\xi,t,j} - u^{z}_{\xi,t,j} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ j \in \mathcal{J} \,:\, \mathrm{com}^{z}_{j} \wedge \mathrm{on}^{z}_{t,j} +\mathit{dn}^{z}_{\xi,t,j} \ge \overleftarrow{u}^{z}_{\xi,t,j} - u^{z}_{\xi,t,j} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ j \in \mathcal{J} \,:\, \mathrm{on}^{z,\mathrm{com}}_{t,j} ``` ### `Process-com-up-time` @@ -7266,12 +7263,12 @@ Process_com_up_time: is still on. The first snapshot's share of the window is the brought-in up time's, which the must-stay-up mask carries dims: [scenario, snapshot, process] - where: Process_committable AND Process_min_up_time > 0 AND position(snapshot) > 0 AND Process_active + where: Process_committed AND Process_min_up_time > 0 AND position(snapshot) > 0 expression: sum_back(Process_start_up, along=snapshot, window=Process_min_up_time) <= Process_status ``` ```math -\sum_{t' \in \mathcal{T} \,:\, 0 \le t - t' < \mathrm{UT}^{z}} \mathit{up}^{z}_{\xi,t',j} \le u^{z}_{\xi,t,j} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ j \in \mathcal{J} \,:\, \mathrm{com}^{z}_{j} \wedge \mathrm{UT}^{z}_{\xi,j} > 0 \wedge \mathrm{pos}(t) > 0 \wedge \mathrm{on}^{z}_{t,j} +\sum_{t' \in \mathcal{T} \,:\, 0 \le t - t' < \mathrm{UT}^{z}} \mathit{up}^{z}_{\xi,t',j} \le u^{z}_{\xi,t,j} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ j \in \mathcal{J} \,:\, \mathrm{on}^{z,\mathrm{com}}_{t,j} \wedge \mathrm{UT}^{z}_{\xi,j} > 0 \wedge \mathrm{pos}(t) > 0 ``` ### `Process-com-down-time` @@ -7285,12 +7282,12 @@ Process_com_down_time: time is still off. The first snapshot's share of the window is the brought-in down time's, which the must-stay-down mask carries dims: [scenario, snapshot, process] - where: Process_committable AND Process_min_down_time > 0 AND position(snapshot) > 0 AND Process_active + where: Process_committed AND Process_min_down_time > 0 AND position(snapshot) > 0 expression: sum_back(Process_shut_down, along=snapshot, window=Process_min_down_time) <= 1 - Process_status ``` ```math -\sum_{t' \in \mathcal{T} \,:\, 0 \le t - t' < \mathrm{DT}^{z}} \mathit{dn}^{z}_{\xi,t',j} \le 1 - u^{z}_{\xi,t,j} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ j \in \mathcal{J} \,:\, \mathrm{com}^{z}_{j} \wedge \mathrm{DT}^{z}_{\xi,j} > 0 \wedge \mathrm{pos}(t) > 0 \wedge \mathrm{on}^{z}_{t,j} +\sum_{t' \in \mathcal{T} \,:\, 0 \le t - t' < \mathrm{DT}^{z}} \mathit{dn}^{z}_{\xi,t',j} \le 1 - u^{z}_{\xi,t,j} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ j \in \mathcal{J} \,:\, \mathrm{on}^{z,\mathrm{com}}_{t,j} \wedge \mathrm{DT}^{z}_{\xi,j} > 0 \wedge \mathrm{pos}(t) > 0 ``` ### `Process-com-status-min_up_time_must_stay_up` @@ -7301,12 +7298,12 @@ Process_com_down_time: Process_com_status_must_stay_up: description: "`Process-com-status-min_up_time_must_stay_up` — a process still serving the up time it brought in stays on" dims: [scenario, snapshot, process] - where: Process_committable AND Process_must_stay_up AND Process_active + where: Process_committed AND Process_must_stay_up expression: Process_status == 1 ``` ```math -u^{z}_{\xi,t,j} = 1 \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ j \in \mathcal{J} \,:\, \mathrm{com}^{z}_{j} \wedge \mathrm{hold}^{z}_{\xi,t,j} \wedge \mathrm{on}^{z}_{t,j} +u^{z}_{\xi,t,j} = 1 \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ j \in \mathcal{J} \,:\, \mathrm{on}^{z,\mathrm{com}}_{t,j} \wedge \mathrm{hold}^{z}_{\xi,t,j} ``` ### `Process-com-status-min_down_time_must_stay_up` @@ -7319,12 +7316,12 @@ Process_com_status_must_stay_down: `Process-com-status-min_down_time_must_stay_up` — a process still serving the down time it brought in stays off; PyPSA names the row `_must_stay_up` dims: [scenario, snapshot, process] - where: Process_committable AND Process_must_stay_down AND Process_active + where: Process_committed AND Process_must_stay_down expression: Process_status == 0 ``` ```math -u^{z}_{\xi,t,j} = 0 \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ j \in \mathcal{J} \,:\, \mathrm{com}^{z}_{j} \wedge \mathrm{rest}^{z}_{\xi,t,j} \wedge \mathrm{on}^{z}_{t,j} +u^{z}_{\xi,t,j} = 0 \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ j \in \mathcal{J} \,:\, \mathrm{on}^{z,\mathrm{com}}_{t,j} \wedge \mathrm{rest}^{z}_{\xi,t,j} ``` ### `Process-p-ramp_limit_up-run-bigM` @@ -7338,11 +7335,7 @@ Process_p_ramp_limit_up_run_big_m: raises internal power no faster than its limit of the chosen build; the big M releases the row in the snapshot it turns on dims: [scenario, snapshot, process] - where: >- - Process_committable AND Process_p_nom_extendable AND NOT (Process_p_nom_mod > 0) - AND (Process_ramp_limit_up OR Process_ramp_limit_start_up) - AND (position(snapshot, by=snapshot_period, within=period) > 0 OR (position(snapshot) == 0 AND (Process_status_initial == 0 OR Process_p_init))) - AND Process_active + where: Process_com_ext AND (Process_ramp_limit_up OR Process_ramp_limit_start_up) AND Process_ramps_from_previous expression: >- Process_p - Process_previous_p <= Process_ramp_up_rate * Process_p_nom_ext @@ -7350,7 +7343,7 @@ Process_p_ramp_limit_up_run_big_m: ``` ```math -z_{\xi,t,j} - \overleftarrow{z}_{\xi,t,j} \le \widetilde{\mathrm{ru}}^{z}_{\xi,t,j} \cdot Z_{j} + \mathrm{M}^{z}_{\xi,j} - \mathrm{M}^{z}_{\xi,j} \cdot \overleftarrow{u}^{z}_{\xi,t,j} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ j \in \mathcal{J} \,:\, \mathrm{com}^{z}_{j} \wedge \mathrm{ext}^{z}_{j} \wedge \neg \left( \mathrm{z}^{\mathrm{mod}}_{j} > 0 \right) \wedge \left( \mathrm{ru}^{z}_{\xi,t,j} \text{ is defined} \vee \mathrm{ru}^{z,\mathrm{up}}_{\xi,j} \text{ is defined} \right) \wedge \left( \mathrm{pos}_{\mathrm{snapshot\_period}(t)}(t) > 0 \vee \mathrm{pos}(t) = 0 \wedge \left( \mathrm{u}^{z,0}_{\xi,j} = 0 \vee \mathrm{z}^{0}_{\xi,j} \text{ is defined} \right) \right) \wedge \mathrm{on}^{z}_{t,j} +z_{\xi,t,j} - \overleftarrow{z}_{\xi,t,j} \le \widetilde{\mathrm{ru}}^{z}_{\xi,t,j} \cdot Z_{j} + \mathrm{M}^{z}_{\xi,j} - \mathrm{M}^{z}_{\xi,j} \cdot \overleftarrow{u}^{z}_{\xi,t,j} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ j \in \mathcal{J} \,:\, \mathrm{on}^{z,\mathrm{com,ext}}_{t,j} \wedge \left( \mathrm{ru}^{z}_{\xi,t,j} \text{ is defined} \vee \mathrm{ru}^{z,\mathrm{up}}_{\xi,j} \text{ is defined} \right) \wedge \mathrm{prev}^{z}_{\xi,t,j} ``` ### `Process-p-ramp_limit_up-start-bigM` @@ -7364,11 +7357,7 @@ Process_p_ramp_limit_up_start_big_m: committed extendable process ramps no further than its start-up ramp of the chosen build; the big M releases the row everywhere else dims: [scenario, snapshot, process] - where: >- - Process_committable AND Process_p_nom_extendable AND NOT (Process_p_nom_mod > 0) - AND (Process_ramp_limit_up OR Process_ramp_limit_start_up) - AND (position(snapshot, by=snapshot_period, within=period) > 0 OR (position(snapshot) == 0 AND (Process_status_initial == 0 OR Process_p_init))) - AND Process_active + where: Process_com_ext AND (Process_ramp_limit_up OR Process_ramp_limit_start_up) AND Process_ramps_from_previous expression: >- Process_p - Process_previous_p <= Process_start_up_rate * Process_p_nom_ext @@ -7376,7 +7365,7 @@ Process_p_ramp_limit_up_start_big_m: ``` ```math -z_{\xi,t,j} - \overleftarrow{z}_{\xi,t,j} \le \widetilde{\mathrm{ru}}^{z,\mathrm{up}}_{\xi,j} \cdot Z_{j} + \mathrm{M}^{z}_{\xi,j} - \mathrm{M}^{z}_{\xi,j} \cdot \mathit{up}^{z}_{\xi,t,j} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ j \in \mathcal{J} \,:\, \mathrm{com}^{z}_{j} \wedge \mathrm{ext}^{z}_{j} \wedge \neg \left( \mathrm{z}^{\mathrm{mod}}_{j} > 0 \right) \wedge \left( \mathrm{ru}^{z}_{\xi,t,j} \text{ is defined} \vee \mathrm{ru}^{z,\mathrm{up}}_{\xi,j} \text{ is defined} \right) \wedge \left( \mathrm{pos}_{\mathrm{snapshot\_period}(t)}(t) > 0 \vee \mathrm{pos}(t) = 0 \wedge \left( \mathrm{u}^{z,0}_{\xi,j} = 0 \vee \mathrm{z}^{0}_{\xi,j} \text{ is defined} \right) \right) \wedge \mathrm{on}^{z}_{t,j} +z_{\xi,t,j} - \overleftarrow{z}_{\xi,t,j} \le \widetilde{\mathrm{ru}}^{z,\mathrm{up}}_{\xi,j} \cdot Z_{j} + \mathrm{M}^{z}_{\xi,j} - \mathrm{M}^{z}_{\xi,j} \cdot \mathit{up}^{z}_{\xi,t,j} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ j \in \mathcal{J} \,:\, \mathrm{on}^{z,\mathrm{com,ext}}_{t,j} \wedge \left( \mathrm{ru}^{z}_{\xi,t,j} \text{ is defined} \vee \mathrm{ru}^{z,\mathrm{up}}_{\xi,j} \text{ is defined} \right) \wedge \mathrm{prev}^{z}_{\xi,t,j} ``` ### `Process-p-ramp_limit_down-run-bigM` @@ -7391,10 +7380,9 @@ Process_p_ramp_limit_down_run_big_m: releases the row in the snapshot it turns off dims: [scenario, snapshot, process] where: >- - Process_committable AND Process_p_nom_extendable AND NOT (Process_p_nom_mod > 0) + Process_com_ext AND (Process_ramp_limit_down OR Process_ramp_limit_shut_down) - AND (position(snapshot, by=snapshot_period, within=period) > 0 OR (position(snapshot) == 0 AND (Process_status_initial == 0 OR Process_p_init))) - AND Process_active + AND Process_ramps_from_previous expression: >- Process_previous_p - Process_p <= Process_ramp_down_rate * Process_p_nom_ext @@ -7402,7 +7390,7 @@ Process_p_ramp_limit_down_run_big_m: ``` ```math -\overleftarrow{z}_{\xi,t,j} - z_{\xi,t,j} \le \widetilde{\mathrm{rd}}^{z}_{\xi,t,j} \cdot Z_{j} + \mathrm{M}^{z}_{\xi,j} - \mathrm{M}^{z}_{\xi,j} \cdot u^{z}_{\xi,t,j} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ j \in \mathcal{J} \,:\, \mathrm{com}^{z}_{j} \wedge \mathrm{ext}^{z}_{j} \wedge \neg \left( \mathrm{z}^{\mathrm{mod}}_{j} > 0 \right) \wedge \left( \mathrm{rd}^{z}_{\xi,t,j} \text{ is defined} \vee \mathrm{rd}^{z,\mathrm{dn}}_{\xi,j} \text{ is defined} \right) \wedge \left( \mathrm{pos}_{\mathrm{snapshot\_period}(t)}(t) > 0 \vee \mathrm{pos}(t) = 0 \wedge \left( \mathrm{u}^{z,0}_{\xi,j} = 0 \vee \mathrm{z}^{0}_{\xi,j} \text{ is defined} \right) \right) \wedge \mathrm{on}^{z}_{t,j} +\overleftarrow{z}_{\xi,t,j} - z_{\xi,t,j} \le \widetilde{\mathrm{rd}}^{z}_{\xi,t,j} \cdot Z_{j} + \mathrm{M}^{z}_{\xi,j} - \mathrm{M}^{z}_{\xi,j} \cdot u^{z}_{\xi,t,j} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ j \in \mathcal{J} \,:\, \mathrm{on}^{z,\mathrm{com,ext}}_{t,j} \wedge \left( \mathrm{rd}^{z}_{\xi,t,j} \text{ is defined} \vee \mathrm{rd}^{z,\mathrm{dn}}_{\xi,j} \text{ is defined} \right) \wedge \mathrm{prev}^{z}_{\xi,t,j} ``` ### `Process-p-ramp_limit_down-shut-bigM` @@ -7417,10 +7405,9 @@ Process_p_ramp_limit_down_shut_big_m: the chosen build; the big M releases the row everywhere else dims: [scenario, snapshot, process] where: >- - Process_committable AND Process_p_nom_extendable AND NOT (Process_p_nom_mod > 0) + Process_com_ext AND (Process_ramp_limit_down OR Process_ramp_limit_shut_down) - AND (position(snapshot, by=snapshot_period, within=period) > 0 OR (position(snapshot) == 0 AND (Process_status_initial == 0 OR Process_p_init))) - AND Process_active + AND Process_ramps_from_previous expression: >- Process_previous_p - Process_p <= Process_shut_down_rate * Process_p_nom_ext @@ -7428,7 +7415,7 @@ Process_p_ramp_limit_down_shut_big_m: ``` ```math -\overleftarrow{z}_{\xi,t,j} - z_{\xi,t,j} \le \widetilde{\mathrm{rd}}^{z,\mathrm{dn}}_{\xi,j} \cdot Z_{j} + \mathrm{M}^{z}_{\xi,j} - \mathrm{M}^{z}_{\xi,j} \cdot \mathit{dn}^{z}_{\xi,t,j} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ j \in \mathcal{J} \,:\, \mathrm{com}^{z}_{j} \wedge \mathrm{ext}^{z}_{j} \wedge \neg \left( \mathrm{z}^{\mathrm{mod}}_{j} > 0 \right) \wedge \left( \mathrm{rd}^{z}_{\xi,t,j} \text{ is defined} \vee \mathrm{rd}^{z,\mathrm{dn}}_{\xi,j} \text{ is defined} \right) \wedge \left( \mathrm{pos}_{\mathrm{snapshot\_period}(t)}(t) > 0 \vee \mathrm{pos}(t) = 0 \wedge \left( \mathrm{u}^{z,0}_{\xi,j} = 0 \vee \mathrm{z}^{0}_{\xi,j} \text{ is defined} \right) \right) \wedge \mathrm{on}^{z}_{t,j} +\overleftarrow{z}_{\xi,t,j} - z_{\xi,t,j} \le \widetilde{\mathrm{rd}}^{z,\mathrm{dn}}_{\xi,j} \cdot Z_{j} + \mathrm{M}^{z}_{\xi,j} - \mathrm{M}^{z}_{\xi,j} \cdot \mathit{dn}^{z}_{\xi,t,j} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ j \in \mathcal{J} \,:\, \mathrm{on}^{z,\mathrm{com,ext}}_{t,j} \wedge \left( \mathrm{rd}^{z}_{\xi,t,j} \text{ is defined} \vee \mathrm{rd}^{z,\mathrm{dn}}_{\xi,j} \text{ is defined} \right) \wedge \mathrm{prev}^{z}_{\xi,t,j} ``` ### `Process-p_nom_modularity` @@ -7457,12 +7444,12 @@ Process_com_ext_p_upper_cap: `Process-com-ext-p-upper-cap` — a committed extendable process runs at most what is available of the chosen build, whatever its status dims: [scenario, snapshot, process] - where: Process_committable AND Process_p_nom_extendable AND NOT (Process_p_nom_mod > 0) AND Process_active + where: Process_com_ext expression: Process_p <= Process_p_max_pu * (Process_p_nom_ext - Process_maintenance_pu * Process_maintenance_capacity) ``` ```math -z_{\xi,t,j} \le \overline{\mathrm{z}}_{\xi,t,j} \cdot \left( Z_{j} - \gamma^{z}_{\xi,j} \cdot \mu^{z,\mathrm{nom}}_{\xi,t,j} \right) \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ j \in \mathcal{J} \,:\, \mathrm{com}^{z}_{j} \wedge \mathrm{ext}^{z}_{j} \wedge \neg \left( \mathrm{z}^{\mathrm{mod}}_{j} > 0 \right) \wedge \mathrm{on}^{z}_{t,j} +z_{\xi,t,j} \le \overline{\mathrm{z}}_{\xi,t,j} \cdot \left( Z_{j} - \gamma^{z}_{\xi,j} \cdot \mu^{z,\mathrm{nom}}_{\xi,t,j} \right) \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ j \in \mathcal{J} \,:\, \mathrm{on}^{z,\mathrm{com,ext}}_{t,j} ``` ### `Process-com-ext-p-upper-bigM` @@ -7473,12 +7460,12 @@ z_{\xi,t,j} \le \overline{\mathrm{z}}_{\xi,t,j} \cdot \left( Z_{j} - \gamma^{z}_ Process_com_ext_p_upper_big_m: description: "`Process-com-ext-p-upper-bigM` — off, a process does not run; on, the big M is no bound" dims: [scenario, snapshot, process] - where: Process_committable AND Process_p_nom_extendable AND NOT (Process_p_nom_mod > 0) AND Process_active + where: Process_com_ext expression: Process_p <= Process_big_m * Process_status ``` ```math -z_{\xi,t,j} \le \mathrm{M}^{z}_{\xi,j} \cdot u^{z}_{\xi,t,j} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ j \in \mathcal{J} \,:\, \mathrm{com}^{z}_{j} \wedge \mathrm{ext}^{z}_{j} \wedge \neg \left( \mathrm{z}^{\mathrm{mod}}_{j} > 0 \right) \wedge \mathrm{on}^{z}_{t,j} +z_{\xi,t,j} \le \mathrm{M}^{z}_{\xi,j} \cdot u^{z}_{\xi,t,j} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ j \in \mathcal{J} \,:\, \mathrm{on}^{z,\mathrm{com,ext}}_{t,j} ``` ### `Process-com-ext-p-lower` @@ -7491,7 +7478,7 @@ Process_com_ext_p_lower: `Process-com-ext-p-lower` — a committed extendable process runs at least its minimum of the chosen build; off, the big M releases the row dims: [scenario, snapshot, process] - where: Process_committable AND Process_p_nom_extendable AND NOT (Process_p_nom_mod > 0) AND Process_active + where: Process_com_ext expression: >- Process_p >= Process_p_min_pu * (Process_p_nom_ext - Process_maintenance_pu * Process_maintenance_capacity) @@ -7499,7 +7486,7 @@ Process_com_ext_p_lower: ``` ```math -z_{\xi,t,j} \ge \underline{\mathrm{z}}_{\xi,t,j} \cdot \left( Z_{j} - \gamma^{z}_{\xi,j} \cdot \mu^{z,\mathrm{nom}}_{\xi,t,j} \right) + \mathrm{M}^{z}_{\xi,j} \cdot u^{z}_{\xi,t,j} - \mathrm{M}^{z}_{\xi,j} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ j \in \mathcal{J} \,:\, \mathrm{com}^{z}_{j} \wedge \mathrm{ext}^{z}_{j} \wedge \neg \left( \mathrm{z}^{\mathrm{mod}}_{j} > 0 \right) \wedge \mathrm{on}^{z}_{t,j} +z_{\xi,t,j} \ge \underline{\mathrm{z}}_{\xi,t,j} \cdot \left( Z_{j} - \gamma^{z}_{\xi,j} \cdot \mu^{z,\mathrm{nom}}_{\xi,t,j} \right) + \mathrm{M}^{z}_{\xi,j} \cdot u^{z}_{\xi,t,j} - \mathrm{M}^{z}_{\xi,j} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ j \in \mathcal{J} \,:\, \mathrm{on}^{z,\mathrm{com,ext}}_{t,j} ``` ### `Process-com-ext-p-lower-nonneg` @@ -7513,14 +7500,12 @@ Process_com_ext_p_lower_nonneg: negative, internal power is also plainly non-negative, a row the big-M lower cannot assert while the process is off dims: [scenario, snapshot, process] - where: >- - Process_committable AND Process_p_nom_extendable - AND Process_p_min_pu_nonneg AND NOT (Process_p_nom_mod > 0) AND Process_active + where: Process_com_ext AND Process_p_min_pu_nonneg expression: Process_p >= 0 ``` ```math -z_{\xi,t,j} \ge 0 \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ j \in \mathcal{J} \,:\, \mathrm{com}^{z}_{j} \wedge \mathrm{ext}^{z}_{j} \wedge \mathrm{nonneg}^{z}_{j} \wedge \neg \left( \mathrm{z}^{\mathrm{mod}}_{j} > 0 \right) \wedge \mathrm{on}^{z}_{t,j} +z_{\xi,t,j} \ge 0 \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ j \in \mathcal{J} \,:\, \mathrm{on}^{z,\mathrm{com,ext}}_{t,j} \wedge \mathrm{nonneg}^{z}_{j} ``` ### `Process-com-mod-p-lower` @@ -7533,12 +7518,12 @@ Process_com_mod_p_lower: `Process-com-mod-p-lower` — a committed modular process runs at least its minimum of one module, whether the build is fixed or a decision dims: [scenario, snapshot, process] - where: Process_committable AND Process_p_nom_mod > 0 AND Process_active + where: Process_committed AND Process_p_nom_mod > 0 expression: Process_p >= Process_p_min_pu * Process_p_nom_mod * (Process_status - Process_maintenance_pu * Process_maintenance_status) ``` ```math -z_{\xi,t,j} \ge \underline{\mathrm{z}}_{\xi,t,j} \cdot \mathrm{z}^{\mathrm{mod}}_{j} \cdot \left( u^{z}_{\xi,t,j} - \gamma^{z}_{\xi,j} \cdot \mu^{z,u}_{\xi,t,j} \right) \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ j \in \mathcal{J} \,:\, \mathrm{com}^{z}_{j} \wedge \mathrm{z}^{\mathrm{mod}}_{j} > 0 \wedge \mathrm{on}^{z}_{t,j} +z_{\xi,t,j} \ge \underline{\mathrm{z}}_{\xi,t,j} \cdot \mathrm{z}^{\mathrm{mod}}_{j} \cdot \left( u^{z}_{\xi,t,j} - \gamma^{z}_{\xi,j} \cdot \mu^{z,u}_{\xi,t,j} \right) \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ j \in \mathcal{J} \,:\, \mathrm{on}^{z,\mathrm{com}}_{t,j} \wedge \mathrm{z}^{\mathrm{mod}}_{j} > 0 ``` ### `Process-com-mod-p-upper` @@ -7551,12 +7536,12 @@ Process_com_mod_p_upper: `Process-com-mod-p-upper` — a committed modular process runs at most one module's share, whether the build is fixed or a decision dims: [scenario, snapshot, process] - where: Process_committable AND Process_p_nom_mod > 0 AND Process_active + where: Process_committed AND Process_p_nom_mod > 0 expression: Process_p <= Process_p_max_pu * Process_p_nom_mod * (Process_status - Process_maintenance_pu * Process_maintenance_status) ``` ```math -z_{\xi,t,j} \le \overline{\mathrm{z}}_{\xi,t,j} \cdot \mathrm{z}^{\mathrm{mod}}_{j} \cdot \left( u^{z}_{\xi,t,j} - \gamma^{z}_{\xi,j} \cdot \mu^{z,u}_{\xi,t,j} \right) \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ j \in \mathcal{J} \,:\, \mathrm{com}^{z}_{j} \wedge \mathrm{z}^{\mathrm{mod}}_{j} > 0 \wedge \mathrm{on}^{z}_{t,j} +z_{\xi,t,j} \le \overline{\mathrm{z}}_{\xi,t,j} \cdot \mathrm{z}^{\mathrm{mod}}_{j} \cdot \left( u^{z}_{\xi,t,j} - \gamma^{z}_{\xi,j} \cdot \mu^{z,u}_{\xi,t,j} \right) \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ j \in \mathcal{J} \,:\, \mathrm{on}^{z,\mathrm{com}}_{t,j} \wedge \mathrm{z}^{\mathrm{mod}}_{j} > 0 ``` ### `Process-status-p-fixed-upper` @@ -7570,12 +7555,12 @@ Process_status_p_fixed_upper: place, an explicit row as PyPSA writes it: one where the build is not modular, and the fixed build's whole count of modules where it is dims: [scenario, snapshot, process] - where: Process_committable AND NOT (Process_p_nom_extendable AND Process_p_nom_mod > 0) AND Process_active + where: Process_committed AND NOT (Process_p_nom_extendable AND Process_p_nom_mod > 0) expression: Process_status <= Process_modules_installed ``` ```math -u^{z}_{\xi,t,j} \le \mathrm{N}^{z,\mathrm{fix}}_{\xi,j} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ j \in \mathcal{J} \,:\, \mathrm{com}^{z}_{j} \wedge \neg \left( \mathrm{ext}^{z}_{j} \wedge \mathrm{z}^{\mathrm{mod}}_{j} > 0 \right) \wedge \mathrm{on}^{z}_{t,j} +u^{z}_{\xi,t,j} \le \mathrm{N}^{z,\mathrm{fix}}_{\xi,j} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ j \in \mathcal{J} \,:\, \mathrm{on}^{z,\mathrm{com}}_{t,j} \wedge \neg \left( \mathrm{ext}^{z}_{j} \wedge \mathrm{z}^{\mathrm{mod}}_{j} > 0 \right) ``` ### `Process-start_up-p-fixed-upper` @@ -7589,12 +7574,12 @@ Process_start_up_p_fixed_upper: place, an explicit row as PyPSA writes it: one where the build is not modular, and the fixed build's whole count of modules where it is dims: [scenario, snapshot, process] - where: Process_committable AND NOT (Process_p_nom_extendable AND Process_p_nom_mod > 0) AND Process_active + where: Process_committed AND NOT (Process_p_nom_extendable AND Process_p_nom_mod > 0) expression: Process_start_up <= Process_modules_installed ``` ```math -\mathit{up}^{z}_{\xi,t,j} \le \mathrm{N}^{z,\mathrm{fix}}_{\xi,j} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ j \in \mathcal{J} \,:\, \mathrm{com}^{z}_{j} \wedge \neg \left( \mathrm{ext}^{z}_{j} \wedge \mathrm{z}^{\mathrm{mod}}_{j} > 0 \right) \wedge \mathrm{on}^{z}_{t,j} +\mathit{up}^{z}_{\xi,t,j} \le \mathrm{N}^{z,\mathrm{fix}}_{\xi,j} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ j \in \mathcal{J} \,:\, \mathrm{on}^{z,\mathrm{com}}_{t,j} \wedge \neg \left( \mathrm{ext}^{z}_{j} \wedge \mathrm{z}^{\mathrm{mod}}_{j} > 0 \right) ``` ### `Process-shut_down-p-fixed-upper` @@ -7608,12 +7593,12 @@ Process_shut_down_p_fixed_upper: place, an explicit row as PyPSA writes it: one where the build is not modular, and the fixed build's whole count of modules where it is dims: [scenario, snapshot, process] - where: Process_committable AND NOT (Process_p_nom_extendable AND Process_p_nom_mod > 0) AND Process_active + where: Process_committed AND NOT (Process_p_nom_extendable AND Process_p_nom_mod > 0) expression: Process_shut_down <= Process_modules_installed ``` ```math -\mathit{dn}^{z}_{\xi,t,j} \le \mathrm{N}^{z,\mathrm{fix}}_{\xi,j} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ j \in \mathcal{J} \,:\, \mathrm{com}^{z}_{j} \wedge \neg \left( \mathrm{ext}^{z}_{j} \wedge \mathrm{z}^{\mathrm{mod}}_{j} > 0 \right) \wedge \mathrm{on}^{z}_{t,j} +\mathit{dn}^{z}_{\xi,t,j} \le \mathrm{N}^{z,\mathrm{fix}}_{\xi,j} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ j \in \mathcal{J} \,:\, \mathrm{on}^{z,\mathrm{com}}_{t,j} \wedge \neg \left( \mathrm{ext}^{z}_{j} \wedge \mathrm{z}^{\mathrm{mod}}_{j} > 0 \right) ``` ### `Process-status-p_nom-variable-upper` @@ -7624,12 +7609,12 @@ Process_shut_down_p_fixed_upper: Process_status_p_nom_variable_upper: description: "`Process-status-p_nom-variable-upper` — a modular process is on only where a module is built" dims: [scenario, snapshot, process] - where: Process_committable AND Process_p_nom_extendable AND Process_p_nom_mod > 0 AND Process_active + where: Process_committed AND Process_p_nom_extendable AND Process_p_nom_mod > 0 expression: Process_status <= Process_n_mod ``` ```math -u^{z}_{\xi,t,j} \le N^{z}_{j} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ j \in \mathcal{J} \,:\, \mathrm{com}^{z}_{j} \wedge \mathrm{ext}^{z}_{j} \wedge \mathrm{z}^{\mathrm{mod}}_{j} > 0 \wedge \mathrm{on}^{z}_{t,j} +u^{z}_{\xi,t,j} \le N^{z}_{j} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ j \in \mathcal{J} \,:\, \mathrm{on}^{z,\mathrm{com}}_{t,j} \wedge \mathrm{ext}^{z}_{j} \wedge \mathrm{z}^{\mathrm{mod}}_{j} > 0 ``` ### `Process-start_up-p_nom-variable-upper` @@ -7640,12 +7625,12 @@ u^{z}_{\xi,t,j} \le N^{z}_{j} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ Process_start_up_p_nom_variable_upper: description: "`Process-start_up-p_nom-variable-upper` — a modular process starts only where a module is built" dims: [scenario, snapshot, process] - where: Process_committable AND Process_p_nom_extendable AND Process_p_nom_mod > 0 AND Process_active + where: Process_committed AND Process_p_nom_extendable AND Process_p_nom_mod > 0 expression: Process_start_up <= Process_n_mod ``` ```math -\mathit{up}^{z}_{\xi,t,j} \le N^{z}_{j} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ j \in \mathcal{J} \,:\, \mathrm{com}^{z}_{j} \wedge \mathrm{ext}^{z}_{j} \wedge \mathrm{z}^{\mathrm{mod}}_{j} > 0 \wedge \mathrm{on}^{z}_{t,j} +\mathit{up}^{z}_{\xi,t,j} \le N^{z}_{j} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ j \in \mathcal{J} \,:\, \mathrm{on}^{z,\mathrm{com}}_{t,j} \wedge \mathrm{ext}^{z}_{j} \wedge \mathrm{z}^{\mathrm{mod}}_{j} > 0 ``` ### `Process-shut_down-p_nom-variable-upper` @@ -7656,12 +7641,12 @@ Process_start_up_p_nom_variable_upper: Process_shut_down_p_nom_variable_upper: description: "`Process-shut_down-p_nom-variable-upper` — a modular process stops only where a module is built" dims: [scenario, snapshot, process] - where: Process_committable AND Process_p_nom_extendable AND Process_p_nom_mod > 0 AND Process_active + where: Process_committed AND Process_p_nom_extendable AND Process_p_nom_mod > 0 expression: Process_shut_down <= Process_n_mod ``` ```math -\mathit{dn}^{z}_{\xi,t,j} \le N^{z}_{j} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ j \in \mathcal{J} \,:\, \mathrm{com}^{z}_{j} \wedge \mathrm{ext}^{z}_{j} \wedge \mathrm{z}^{\mathrm{mod}}_{j} > 0 \wedge \mathrm{on}^{z}_{t,j} +\mathit{dn}^{z}_{\xi,t,j} \le N^{z}_{j} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ j \in \mathcal{J} \,:\, \mathrm{on}^{z,\mathrm{com}}_{t,j} \wedge \mathrm{ext}^{z}_{j} \wedge \mathrm{z}^{\mathrm{mod}}_{j} > 0 ``` ### `Process-maint-event-count` @@ -7725,12 +7710,12 @@ Process_maintcap_upper: `Process-maintcap_upper` — the build taken off is at most the chosen build in maintenance, and at most the build less its floor out of it dims: [scenario, snapshot, process] - where: Process_maintainable AND Process_p_nom_extendable AND NOT (Process_committable AND Process_p_nom_mod > 0) AND Process_active + where: Process_maint_ext expression: Process_maintenance_capacity <= Process_p_nom_ext - Process_p_nom_min * (1 - Process_maintenance) ``` ```math -\mu^{z,\mathrm{nom}}_{\xi,t,j} \le Z_{j} - \underline{\mathrm{z}}^{\mathrm{nom}}_{\xi,j} \cdot \left( 1 - \mu^{z}_{\xi,t,j} \right) \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ j \in \mathcal{J} \,:\, \mathrm{mnt}^{z}_{j} \wedge \mathrm{ext}^{z}_{j} \wedge \neg \left( \mathrm{com}^{z}_{j} \wedge \mathrm{z}^{\mathrm{mod}}_{j} > 0 \right) \wedge \mathrm{on}^{z}_{t,j} +\mu^{z,\mathrm{nom}}_{\xi,t,j} \le Z_{j} - \underline{\mathrm{z}}^{\mathrm{nom}}_{\xi,j} \cdot \left( 1 - \mu^{z}_{\xi,t,j} \right) \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ j \in \mathcal{J} \,:\, \mathrm{on}^{z,\mathrm{mnt,ext}}_{t,j} ``` ### `Process-maintcap_upper_nommax` @@ -7741,12 +7726,12 @@ Process_maintcap_upper: Process_maintcap_upper_nommax: description: "`Process-maintcap_upper_nommax` — out of maintenance, no build is taken off" dims: [scenario, snapshot, process] - where: Process_maintainable AND Process_p_nom_extendable AND NOT (Process_committable AND Process_p_nom_mod > 0) AND Process_active + where: Process_maint_ext expression: Process_maintenance_capacity <= Process_p_nom_max * Process_maintenance ``` ```math -\mu^{z,\mathrm{nom}}_{\xi,t,j} \le \overline{\mathrm{z}}^{\mathrm{nom}}_{\xi,j} \cdot \mu^{z}_{\xi,t,j} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ j \in \mathcal{J} \,:\, \mathrm{mnt}^{z}_{j} \wedge \mathrm{ext}^{z}_{j} \wedge \neg \left( \mathrm{com}^{z}_{j} \wedge \mathrm{z}^{\mathrm{mod}}_{j} > 0 \right) \wedge \mathrm{on}^{z}_{t,j} +\mu^{z,\mathrm{nom}}_{\xi,t,j} \le \overline{\mathrm{z}}^{\mathrm{nom}}_{\xi,j} \cdot \mu^{z}_{\xi,t,j} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ j \in \mathcal{J} \,:\, \mathrm{on}^{z,\mathrm{mnt,ext}}_{t,j} ``` ### `Process-maintcap_lower_nommax` @@ -7757,12 +7742,12 @@ Process_maintcap_upper_nommax: Process_maintcap_lower_nommax: description: "`Process-maintcap_lower_nommax` — in maintenance, the whole chosen build is taken off" dims: [scenario, snapshot, process] - where: Process_maintainable AND Process_p_nom_extendable AND NOT (Process_committable AND Process_p_nom_mod > 0) AND Process_active + where: Process_maint_ext expression: Process_maintenance_capacity >= Process_p_nom_ext - Process_p_nom_max * (1 - Process_maintenance) ``` ```math -\mu^{z,\mathrm{nom}}_{\xi,t,j} \ge Z_{j} - \overline{\mathrm{z}}^{\mathrm{nom}}_{\xi,j} \cdot \left( 1 - \mu^{z}_{\xi,t,j} \right) \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ j \in \mathcal{J} \,:\, \mathrm{mnt}^{z}_{j} \wedge \mathrm{ext}^{z}_{j} \wedge \neg \left( \mathrm{com}^{z}_{j} \wedge \mathrm{z}^{\mathrm{mod}}_{j} > 0 \right) \wedge \mathrm{on}^{z}_{t,j} +\mu^{z,\mathrm{nom}}_{\xi,t,j} \ge Z_{j} - \overline{\mathrm{z}}^{\mathrm{nom}}_{\xi,j} \cdot \left( 1 - \mu^{z}_{\xi,t,j} \right) \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ j \in \mathcal{J} \,:\, \mathrm{on}^{z,\mathrm{mnt,ext}}_{t,j} ``` ### `Process-maintcap_lower_nommin` @@ -7773,12 +7758,12 @@ Process_maintcap_lower_nommax: Process_maintcap_lower_nommin: description: "`Process-maintcap_lower_nommin` — in maintenance, at least the floor of the build is taken off" dims: [scenario, snapshot, process] - where: Process_maintainable AND Process_p_nom_extendable AND NOT (Process_committable AND Process_p_nom_mod > 0) AND Process_active AND Process_p_nom_min > 0 + where: Process_maint_ext AND Process_p_nom_min > 0 expression: Process_maintenance_capacity >= Process_p_nom_min * Process_maintenance ``` ```math -\mu^{z,\mathrm{nom}}_{\xi,t,j} \ge \underline{\mathrm{z}}^{\mathrm{nom}}_{\xi,j} \cdot \mu^{z}_{\xi,t,j} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ j \in \mathcal{J} \,:\, \mathrm{mnt}^{z}_{j} \wedge \mathrm{ext}^{z}_{j} \wedge \neg \left( \mathrm{com}^{z}_{j} \wedge \mathrm{z}^{\mathrm{mod}}_{j} > 0 \right) \wedge \mathrm{on}^{z}_{t,j} \wedge \underline{\mathrm{z}}^{\mathrm{nom}}_{\xi,j} > 0 +\mu^{z,\mathrm{nom}}_{\xi,t,j} \ge \underline{\mathrm{z}}^{\mathrm{nom}}_{\xi,j} \cdot \mu^{z}_{\xi,t,j} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ j \in \mathcal{J} \,:\, \mathrm{on}^{z,\mathrm{mnt,ext}}_{t,j} \wedge \underline{\mathrm{z}}^{\mathrm{nom}}_{\xi,j} > 0 ``` ### `Process-maint-status-le-status` @@ -7789,12 +7774,12 @@ Process_maintcap_lower_nommin: Process_maint_status_le_status: description: "`Process-maint-status-le-status` — the status in maintenance is at most the status" dims: [scenario, snapshot, process] - where: Process_maintainable AND Process_committable AND NOT Process_p_nom_extendable AND Process_active + where: Process_maintainable AND Process_committed AND NOT Process_p_nom_extendable expression: Process_maintenance_status <= Process_status ``` ```math -\mu^{z,u}_{\xi,t,j} \le u^{z}_{\xi,t,j} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ j \in \mathcal{J} \,:\, \mathrm{mnt}^{z}_{j} \wedge \mathrm{com}^{z}_{j} \wedge \neg \mathrm{ext}^{z}_{j} \wedge \mathrm{on}^{z}_{t,j} +\mu^{z,u}_{\xi,t,j} \le u^{z}_{\xi,t,j} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ j \in \mathcal{J} \,:\, \mathrm{mnt}^{z}_{j} \wedge \mathrm{on}^{z,\mathrm{com}}_{t,j} \wedge \neg \mathrm{ext}^{z}_{j} ``` ### `Process-maint-status-le-maint` @@ -7805,12 +7790,12 @@ Process_maint_status_le_status: Process_maint_status_le_maint: description: "`Process-maint-status-le-maint` — out of maintenance, the status in maintenance is zero" dims: [scenario, snapshot, process] - where: Process_maintainable AND Process_committable AND NOT Process_p_nom_extendable AND Process_active + where: Process_maintainable AND Process_committed AND NOT Process_p_nom_extendable expression: Process_maintenance_status <= Process_maintenance ``` ```math -\mu^{z,u}_{\xi,t,j} \le \mu^{z}_{\xi,t,j} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ j \in \mathcal{J} \,:\, \mathrm{mnt}^{z}_{j} \wedge \mathrm{com}^{z}_{j} \wedge \neg \mathrm{ext}^{z}_{j} \wedge \mathrm{on}^{z}_{t,j} +\mu^{z,u}_{\xi,t,j} \le \mu^{z}_{\xi,t,j} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ j \in \mathcal{J} \,:\, \mathrm{mnt}^{z}_{j} \wedge \mathrm{on}^{z,\mathrm{com}}_{t,j} \wedge \neg \mathrm{ext}^{z}_{j} ``` ### `Process-maint-status-lb` @@ -7821,12 +7806,12 @@ Process_maint_status_le_maint: Process_maint_status_lb: description: "`Process-maint-status-lb` — on and in maintenance, the status in maintenance is one" dims: [scenario, snapshot, process] - where: Process_maintainable AND Process_committable AND NOT Process_p_nom_extendable AND Process_active + where: Process_maintainable AND Process_committed AND NOT Process_p_nom_extendable expression: Process_maintenance_status >= Process_status + Process_maintenance - 1 ``` ```math -\mu^{z,u}_{\xi,t,j} \ge u^{z}_{\xi,t,j} + \mu^{z}_{\xi,t,j} - 1 \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ j \in \mathcal{J} \,:\, \mathrm{mnt}^{z}_{j} \wedge \mathrm{com}^{z}_{j} \wedge \neg \mathrm{ext}^{z}_{j} \wedge \mathrm{on}^{z}_{t,j} +\mu^{z,u}_{\xi,t,j} \ge u^{z}_{\xi,t,j} + \mu^{z}_{\xi,t,j} - 1 \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ j \in \mathcal{J} \,:\, \mathrm{mnt}^{z}_{j} \wedge \mathrm{on}^{z,\mathrm{com}}_{t,j} \wedge \neg \mathrm{ext}^{z}_{j} ``` ### `Process-maint-modstatus-le-status` @@ -7837,12 +7822,12 @@ Process_maint_status_lb: Process_maint_modstatus_le_status: description: "`Process-maint-modstatus-le-status` — the modules on in maintenance are at most the modules on" dims: [scenario, snapshot, process] - where: Process_maintainable AND Process_committable AND Process_p_nom_mod > 0 AND Process_active + where: Process_maintainable AND Process_committed AND Process_p_nom_mod > 0 expression: Process_maintenance_status <= Process_status ``` ```math -\mu^{z,u}_{\xi,t,j} \le u^{z}_{\xi,t,j} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ j \in \mathcal{J} \,:\, \mathrm{mnt}^{z}_{j} \wedge \mathrm{com}^{z}_{j} \wedge \mathrm{z}^{\mathrm{mod}}_{j} > 0 \wedge \mathrm{on}^{z}_{t,j} +\mu^{z,u}_{\xi,t,j} \le u^{z}_{\xi,t,j} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ j \in \mathcal{J} \,:\, \mathrm{mnt}^{z}_{j} \wedge \mathrm{on}^{z,\mathrm{com}}_{t,j} \wedge \mathrm{z}^{\mathrm{mod}}_{j} > 0 ``` ### `Process-maint-modstatus-le-maint` @@ -7855,12 +7840,12 @@ Process_maint_modstatus_le_maint: `Process-maint-modstatus-le-maint` — out of maintenance, no module is on in maintenance; in it, at most the modules the build cap holds dims: [scenario, snapshot, process] - where: Process_maintainable AND Process_committable AND Process_p_nom_mod > 0 AND Process_active + where: Process_maintainable AND Process_committed AND Process_p_nom_mod > 0 expression: Process_maintenance_status <= Process_p_nom_max / Process_p_nom_mod * Process_maintenance ``` ```math -\mu^{z,u}_{\xi,t,j} \le \frac{\overline{\mathrm{z}}^{\mathrm{nom}}_{\xi,j}}{\mathrm{z}^{\mathrm{mod}}_{j}} \cdot \mu^{z}_{\xi,t,j} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ j \in \mathcal{J} \,:\, \mathrm{mnt}^{z}_{j} \wedge \mathrm{com}^{z}_{j} \wedge \mathrm{z}^{\mathrm{mod}}_{j} > 0 \wedge \mathrm{on}^{z}_{t,j} +\mu^{z,u}_{\xi,t,j} \le \frac{\overline{\mathrm{z}}^{\mathrm{nom}}_{\xi,j}}{\mathrm{z}^{\mathrm{mod}}_{j}} \cdot \mu^{z}_{\xi,t,j} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ j \in \mathcal{J} \,:\, \mathrm{mnt}^{z}_{j} \wedge \mathrm{on}^{z,\mathrm{com}}_{t,j} \wedge \mathrm{z}^{\mathrm{mod}}_{j} > 0 ``` ### `Process-maint-modstatus-lb` @@ -7871,12 +7856,12 @@ Process_maint_modstatus_le_maint: Process_maint_modstatus_lb: description: "`Process-maint-modstatus-lb` — in maintenance, every module on is on in maintenance" dims: [scenario, snapshot, process] - where: Process_maintainable AND Process_committable AND Process_p_nom_mod > 0 AND Process_active + where: Process_maintainable AND Process_committed AND Process_p_nom_mod > 0 expression: Process_maintenance_status >= Process_status - Process_p_nom_max / Process_p_nom_mod * (1 - Process_maintenance) ``` ```math -\mu^{z,u}_{\xi,t,j} \ge u^{z}_{\xi,t,j} - \frac{\overline{\mathrm{z}}^{\mathrm{nom}}_{\xi,j}}{\mathrm{z}^{\mathrm{mod}}_{j}} \cdot \left( 1 - \mu^{z}_{\xi,t,j} \right) \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ j \in \mathcal{J} \,:\, \mathrm{mnt}^{z}_{j} \wedge \mathrm{com}^{z}_{j} \wedge \mathrm{z}^{\mathrm{mod}}_{j} > 0 \wedge \mathrm{on}^{z}_{t,j} +\mu^{z,u}_{\xi,t,j} \ge u^{z}_{\xi,t,j} - \frac{\overline{\mathrm{z}}^{\mathrm{nom}}_{\xi,j}}{\mathrm{z}^{\mathrm{mod}}_{j}} \cdot \left( 1 - \mu^{z}_{\xi,t,j} \right) \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ j \in \mathcal{J} \,:\, \mathrm{mnt}^{z}_{j} \wedge \mathrm{on}^{z,\mathrm{com}}_{t,j} \wedge \mathrm{z}^{\mathrm{mod}}_{j} > 0 ``` ### `Line-fix-s-lower` @@ -8015,12 +8000,12 @@ s_{\xi,t,k} = \mathrm{s}^{\mathrm{set}}_{\xi,t,k} \qquad \forall\, \xi \in \Xi,\ Line_loss_upper: description: "`Line-loss_upper` — a line dissipates at most the loss at its rating" dims: [scenario, snapshot, line] - where: transmission_losses AND Line_active + where: Line_lossy expression: Line_loss <= Line_loss_max ``` ```math -\ell_{\xi,t,k} \le \overline{\ell}_{\xi,t,k} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ k \in \mathcal{K} \,:\, \mathrm{lossy} \wedge \mathrm{on}^{s}_{t,k} +\ell_{\xi,t,k} \le \overline{\ell}_{\xi,t,k} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ k \in \mathcal{K} \,:\, \mathrm{on}^{s,\mathrm{lossy}}_{t,k} ``` ### `Line-loss_tangents-{k}-1` @@ -8035,12 +8020,12 @@ Line_loss_tangents_forward: `k`, or one row stacked over its `secant` axis, and this block states them all over the segment dimension dims: [scenario, snapshot, line, segment] - where: transmission_losses AND Line_active + where: Line_lossy expression: Line_loss + Line_loss_slope * Line_s >= Line_loss_offset ``` ```math -\ell_{\xi,t,k} + \mathrm{a}_{\xi,t,k,b} \cdot s_{\xi,t,k} \ge \mathrm{b}_{\xi,t,k,b} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ k \in \mathcal{K},\ b \in \mathcal{B} \,:\, \mathrm{lossy} \wedge \mathrm{on}^{s}_{t,k} +\ell_{\xi,t,k} + \mathrm{a}_{\xi,t,k,b} \cdot s_{\xi,t,k} \ge \mathrm{b}_{\xi,t,k,b} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ k \in \mathcal{K},\ b \in \mathcal{B} \,:\, \mathrm{on}^{s,\mathrm{lossy}}_{t,k} ``` ### `Line-loss_tangents-{k}--1` @@ -8053,12 +8038,12 @@ Line_loss_tangents_reverse: `Line-loss_tangents-{k}--1`, `Line-loss_secants-neg` — the same fan mirrored, the loss depending on the flow's magnitude dims: [scenario, snapshot, line, segment] - where: transmission_losses AND Line_active + where: Line_lossy expression: Line_loss - Line_loss_slope * Line_s >= Line_loss_offset ``` ```math -\ell_{\xi,t,k} - \mathrm{a}_{\xi,t,k,b} \cdot s_{\xi,t,k} \ge \mathrm{b}_{\xi,t,k,b} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ k \in \mathcal{K},\ b \in \mathcal{B} \,:\, \mathrm{lossy} \wedge \mathrm{on}^{s}_{t,k} +\ell_{\xi,t,k} - \mathrm{a}_{\xi,t,k,b} \cdot s_{\xi,t,k} \ge \mathrm{b}_{\xi,t,k,b} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ k \in \mathcal{K},\ b \in \mathcal{B} \,:\, \mathrm{on}^{s,\mathrm{lossy}}_{t,k} ``` ### `Transformer-fix-s-lower` @@ -8197,12 +8182,12 @@ Transformer_s_set: Transformer_loss_upper: description: "`Transformer-loss_upper` — a transformer dissipates at most the loss at its rating" dims: [scenario, snapshot, transformer] - where: transmission_losses AND Transformer_active + where: Transformer_lossy expression: Transformer_loss <= Transformer_loss_max ``` ```math -\ell^{\sigma}_{\xi,t,m} \le \overline{\ell}^{\sigma}_{\xi,t,m} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ m \in \mathcal{M} \,:\, \mathrm{lossy} \wedge \mathrm{on}^{\sigma}_{t,m} +\ell^{\sigma}_{\xi,t,m} \le \overline{\ell}^{\sigma}_{\xi,t,m} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ m \in \mathcal{M} \,:\, \mathrm{on}^{\sigma,\mathrm{lossy}}_{t,m} ``` ### `Transformer-loss_tangents-{k}-1` @@ -8216,12 +8201,12 @@ Transformer_loss_tangents_forward: loss sits above every cut to its curve for flow one way, as a line's does, over the segment dimension dims: [scenario, snapshot, transformer, segment] - where: transmission_losses AND Transformer_active + where: Transformer_lossy expression: Transformer_loss + Transformer_loss_slope * Transformer_s >= Transformer_loss_offset ``` ```math -\ell^{\sigma}_{\xi,t,m} + \mathrm{a}^{\sigma}_{\xi,t,m,b} \cdot \sigma_{\xi,t,m} \ge \mathrm{b}^{\sigma}_{\xi,t,m,b} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ m \in \mathcal{M},\ b \in \mathcal{B} \,:\, \mathrm{lossy} \wedge \mathrm{on}^{\sigma}_{t,m} +\ell^{\sigma}_{\xi,t,m} + \mathrm{a}^{\sigma}_{\xi,t,m,b} \cdot \sigma_{\xi,t,m} \ge \mathrm{b}^{\sigma}_{\xi,t,m,b} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ m \in \mathcal{M},\ b \in \mathcal{B} \,:\, \mathrm{on}^{\sigma,\mathrm{lossy}}_{t,m} ``` ### `Transformer-loss_tangents-{k}--1` @@ -8234,12 +8219,12 @@ Transformer_loss_tangents_reverse: `Transformer-loss_tangents-{k}--1`, `Transformer-loss_secants-neg` — the same fan mirrored, the loss depending on the flow's magnitude dims: [scenario, snapshot, transformer, segment] - where: transmission_losses AND Transformer_active + where: Transformer_lossy expression: Transformer_loss - Transformer_loss_slope * Transformer_s >= Transformer_loss_offset ``` ```math -\ell^{\sigma}_{\xi,t,m} - \mathrm{a}^{\sigma}_{\xi,t,m,b} \cdot \sigma_{\xi,t,m} \ge \mathrm{b}^{\sigma}_{\xi,t,m,b} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ m \in \mathcal{M},\ b \in \mathcal{B} \,:\, \mathrm{lossy} \wedge \mathrm{on}^{\sigma}_{t,m} +\ell^{\sigma}_{\xi,t,m} - \mathrm{a}^{\sigma}_{\xi,t,m,b} \cdot \sigma_{\xi,t,m} \ge \mathrm{b}^{\sigma}_{\xi,t,m,b} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ m \in \mathcal{M},\ b \in \mathcal{B} \,:\, \mathrm{on}^{\sigma,\mathrm{lossy}}_{t,m} ``` ### `Line-fix-s-lower-security-for-{c}-outage-in-sub-network-{n}` @@ -8454,13 +8439,13 @@ Generator_p_ramp_limit_up: where: >- (Generator_ramp_limit_up OR Generator_ramp_limit_start_up) AND NOT (Generator_committable AND Generator_p_nom_extendable AND NOT (Generator_p_nom_mod > 0)) - AND (position(snapshot, by=snapshot_period, within=period) > 0 OR (position(snapshot) == 0 AND (Generator_status_initial == 0 OR Generator_p_init))) + AND Generator_ramps_from_previous AND Generator_active expression: Generator_p - Generator_previous_p <= Generator_ramp_up_allowance ``` ```math -p_{\xi,t,g} - \overleftarrow{p}_{\xi,t,g} \le \Delta^{+}_{\xi,t,g} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ g \in \mathcal{G} \,:\, \left( \mathrm{ru}_{\xi,t,g} \text{ is defined} \vee \mathrm{ru}^{\mathrm{up}}_{\xi,g} \text{ is defined} \right) \wedge \neg \left( \mathrm{com}_{g} \wedge \mathrm{ext}_{g} \wedge \neg \left( \mathrm{p}^{\mathrm{mod}}_{g} > 0 \right) \right) \wedge \left( \mathrm{pos}_{\mathrm{snapshot\_period}(t)}(t) > 0 \vee \mathrm{pos}(t) = 0 \wedge \left( \mathrm{u}^{0}_{\xi,g} = 0 \vee \mathrm{p}^{0}_{\xi,g} \text{ is defined} \right) \right) \wedge \mathrm{on}_{t,g} +p_{\xi,t,g} - \overleftarrow{p}_{\xi,t,g} \le \Delta^{+}_{\xi,t,g} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ g \in \mathcal{G} \,:\, \left( \mathrm{ru}_{\xi,t,g} \text{ is defined} \vee \mathrm{ru}^{\mathrm{up}}_{\xi,g} \text{ is defined} \right) \wedge \neg \left( \mathrm{com}_{g} \wedge \mathrm{ext}_{g} \wedge \neg \left( \mathrm{p}^{\mathrm{mod}}_{g} > 0 \right) \right) \wedge \mathrm{prev}_{\xi,t,g} \wedge \mathrm{on}_{t,g} ``` ### `Generator-p-ramp_limit_down` @@ -8480,13 +8465,13 @@ Generator_p_ramp_limit_down: where: >- (Generator_ramp_limit_down OR Generator_ramp_limit_shut_down) AND NOT (Generator_committable AND Generator_p_nom_extendable AND NOT (Generator_p_nom_mod > 0)) - AND (position(snapshot, by=snapshot_period, within=period) > 0 OR (position(snapshot) == 0 AND (Generator_status_initial == 0 OR Generator_p_init))) + AND Generator_ramps_from_previous AND Generator_active expression: Generator_previous_p - Generator_p <= Generator_ramp_down_allowance ``` ```math -\overleftarrow{p}_{\xi,t,g} - p_{\xi,t,g} \le \Delta^{-}_{\xi,t,g} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ g \in \mathcal{G} \,:\, \left( \mathrm{rd}_{\xi,t,g} \text{ is defined} \vee \mathrm{rd}^{\mathrm{dn}}_{\xi,g} \text{ is defined} \right) \wedge \neg \left( \mathrm{com}_{g} \wedge \mathrm{ext}_{g} \wedge \neg \left( \mathrm{p}^{\mathrm{mod}}_{g} > 0 \right) \right) \wedge \left( \mathrm{pos}_{\mathrm{snapshot\_period}(t)}(t) > 0 \vee \mathrm{pos}(t) = 0 \wedge \left( \mathrm{u}^{0}_{\xi,g} = 0 \vee \mathrm{p}^{0}_{\xi,g} \text{ is defined} \right) \right) \wedge \mathrm{on}_{t,g} +\overleftarrow{p}_{\xi,t,g} - p_{\xi,t,g} \le \Delta^{-}_{\xi,t,g} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ g \in \mathcal{G} \,:\, \left( \mathrm{rd}_{\xi,t,g} \text{ is defined} \vee \mathrm{rd}^{\mathrm{dn}}_{\xi,g} \text{ is defined} \right) \wedge \neg \left( \mathrm{com}_{g} \wedge \mathrm{ext}_{g} \wedge \neg \left( \mathrm{p}^{\mathrm{mod}}_{g} > 0 \right) \right) \wedge \mathrm{prev}_{\xi,t,g} \wedge \mathrm{on}_{t,g} ``` ### `Link-p-ramp_limit_up` @@ -8506,13 +8491,13 @@ Link_p_ramp_limit_up: where: >- (Link_ramp_limit_up OR Link_ramp_limit_start_up) AND NOT (Link_committable AND Link_p_nom_extendable AND NOT (Link_p_nom_mod > 0)) - AND (position(snapshot, by=snapshot_period, within=period) > 0 OR (position(snapshot) == 0 AND (Link_status_initial == 0 OR Link_p_init))) + AND Link_ramps_from_previous AND Link_active expression: Link_p - Link_previous_p <= Link_ramp_up_allowance ``` ```math -f_{\xi,t,l} - \overleftarrow{f}_{\xi,t,l} \le \Delta^{f,+}_{\xi,t,l} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ l \in \mathcal{L} \,:\, \left( \mathrm{ru}^{f}_{\xi,t,l} \text{ is defined} \vee \mathrm{ru}^{f,\mathrm{up}}_{\xi,l} \text{ is defined} \right) \wedge \neg \left( \mathrm{com}^{f}_{l} \wedge \mathrm{ext}^{f}_{l} \wedge \neg \left( \mathrm{f}^{\mathrm{mod}}_{l} > 0 \right) \right) \wedge \left( \mathrm{pos}_{\mathrm{snapshot\_period}(t)}(t) > 0 \vee \mathrm{pos}(t) = 0 \wedge \left( \mathrm{u}^{f,0}_{\xi,l} = 0 \vee \mathrm{f}^{0}_{\xi,l} \text{ is defined} \right) \right) \wedge \mathrm{on}^{f}_{t,l} +f_{\xi,t,l} - \overleftarrow{f}_{\xi,t,l} \le \Delta^{f,+}_{\xi,t,l} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ l \in \mathcal{L} \,:\, \left( \mathrm{ru}^{f}_{\xi,t,l} \text{ is defined} \vee \mathrm{ru}^{f,\mathrm{up}}_{\xi,l} \text{ is defined} \right) \wedge \neg \left( \mathrm{com}^{f}_{l} \wedge \mathrm{ext}^{f}_{l} \wedge \neg \left( \mathrm{f}^{\mathrm{mod}}_{l} > 0 \right) \right) \wedge \mathrm{prev}^{f}_{\xi,t,l} \wedge \mathrm{on}^{f}_{t,l} ``` ### `Link-p-ramp_limit_down` @@ -8532,13 +8517,13 @@ Link_p_ramp_limit_down: where: >- (Link_ramp_limit_down OR Link_ramp_limit_shut_down) AND NOT (Link_committable AND Link_p_nom_extendable AND NOT (Link_p_nom_mod > 0)) - AND (position(snapshot, by=snapshot_period, within=period) > 0 OR (position(snapshot) == 0 AND (Link_status_initial == 0 OR Link_p_init))) + AND Link_ramps_from_previous AND Link_active expression: Link_previous_p - Link_p <= Link_ramp_down_allowance ``` ```math -\overleftarrow{f}_{\xi,t,l} - f_{\xi,t,l} \le \Delta^{f,-}_{\xi,t,l} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ l \in \mathcal{L} \,:\, \left( \mathrm{rd}^{f}_{\xi,t,l} \text{ is defined} \vee \mathrm{rd}^{f,\mathrm{dn}}_{\xi,l} \text{ is defined} \right) \wedge \neg \left( \mathrm{com}^{f}_{l} \wedge \mathrm{ext}^{f}_{l} \wedge \neg \left( \mathrm{f}^{\mathrm{mod}}_{l} > 0 \right) \right) \wedge \left( \mathrm{pos}_{\mathrm{snapshot\_period}(t)}(t) > 0 \vee \mathrm{pos}(t) = 0 \wedge \left( \mathrm{u}^{f,0}_{\xi,l} = 0 \vee \mathrm{f}^{0}_{\xi,l} \text{ is defined} \right) \right) \wedge \mathrm{on}^{f}_{t,l} +\overleftarrow{f}_{\xi,t,l} - f_{\xi,t,l} \le \Delta^{f,-}_{\xi,t,l} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ l \in \mathcal{L} \,:\, \left( \mathrm{rd}^{f}_{\xi,t,l} \text{ is defined} \vee \mathrm{rd}^{f,\mathrm{dn}}_{\xi,l} \text{ is defined} \right) \wedge \neg \left( \mathrm{com}^{f}_{l} \wedge \mathrm{ext}^{f}_{l} \wedge \neg \left( \mathrm{f}^{\mathrm{mod}}_{l} > 0 \right) \right) \wedge \mathrm{prev}^{f}_{\xi,t,l} \wedge \mathrm{on}^{f}_{t,l} ``` ### `Process-p-ramp_limit_up` @@ -8558,13 +8543,13 @@ Process_p_ramp_limit_up: where: >- (Process_ramp_limit_up OR Process_ramp_limit_start_up) AND NOT (Process_committable AND Process_p_nom_extendable AND NOT (Process_p_nom_mod > 0)) - AND (position(snapshot, by=snapshot_period, within=period) > 0 OR (position(snapshot) == 0 AND (Process_status_initial == 0 OR Process_p_init))) + AND Process_ramps_from_previous AND Process_active expression: Process_p - Process_previous_p <= Process_ramp_up_allowance ``` ```math -z_{\xi,t,j} - \overleftarrow{z}_{\xi,t,j} \le \Delta^{z,+}_{\xi,t,j} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ j \in \mathcal{J} \,:\, \left( \mathrm{ru}^{z}_{\xi,t,j} \text{ is defined} \vee \mathrm{ru}^{z,\mathrm{up}}_{\xi,j} \text{ is defined} \right) \wedge \neg \left( \mathrm{com}^{z}_{j} \wedge \mathrm{ext}^{z}_{j} \wedge \neg \left( \mathrm{z}^{\mathrm{mod}}_{j} > 0 \right) \right) \wedge \left( \mathrm{pos}_{\mathrm{snapshot\_period}(t)}(t) > 0 \vee \mathrm{pos}(t) = 0 \wedge \left( \mathrm{u}^{z,0}_{\xi,j} = 0 \vee \mathrm{z}^{0}_{\xi,j} \text{ is defined} \right) \right) \wedge \mathrm{on}^{z}_{t,j} +z_{\xi,t,j} - \overleftarrow{z}_{\xi,t,j} \le \Delta^{z,+}_{\xi,t,j} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ j \in \mathcal{J} \,:\, \left( \mathrm{ru}^{z}_{\xi,t,j} \text{ is defined} \vee \mathrm{ru}^{z,\mathrm{up}}_{\xi,j} \text{ is defined} \right) \wedge \neg \left( \mathrm{com}^{z}_{j} \wedge \mathrm{ext}^{z}_{j} \wedge \neg \left( \mathrm{z}^{\mathrm{mod}}_{j} > 0 \right) \right) \wedge \mathrm{prev}^{z}_{\xi,t,j} \wedge \mathrm{on}^{z}_{t,j} ``` ### `Process-p-ramp_limit_down` @@ -8584,13 +8569,13 @@ Process_p_ramp_limit_down: where: >- (Process_ramp_limit_down OR Process_ramp_limit_shut_down) AND NOT (Process_committable AND Process_p_nom_extendable AND NOT (Process_p_nom_mod > 0)) - AND (position(snapshot, by=snapshot_period, within=period) > 0 OR (position(snapshot) == 0 AND (Process_status_initial == 0 OR Process_p_init))) + AND Process_ramps_from_previous AND Process_active expression: Process_previous_p - Process_p <= Process_ramp_down_allowance ``` ```math -\overleftarrow{z}_{\xi,t,j} - z_{\xi,t,j} \le \Delta^{z,-}_{\xi,t,j} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ j \in \mathcal{J} \,:\, \left( \mathrm{rd}^{z}_{\xi,t,j} \text{ is defined} \vee \mathrm{rd}^{z,\mathrm{dn}}_{\xi,j} \text{ is defined} \right) \wedge \neg \left( \mathrm{com}^{z}_{j} \wedge \mathrm{ext}^{z}_{j} \wedge \neg \left( \mathrm{z}^{\mathrm{mod}}_{j} > 0 \right) \right) \wedge \left( \mathrm{pos}_{\mathrm{snapshot\_period}(t)}(t) > 0 \vee \mathrm{pos}(t) = 0 \wedge \left( \mathrm{u}^{z,0}_{\xi,j} = 0 \vee \mathrm{z}^{0}_{\xi,j} \text{ is defined} \right) \right) \wedge \mathrm{on}^{z}_{t,j} +\overleftarrow{z}_{\xi,t,j} - z_{\xi,t,j} \le \Delta^{z,-}_{\xi,t,j} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ j \in \mathcal{J} \,:\, \left( \mathrm{rd}^{z}_{\xi,t,j} \text{ is defined} \vee \mathrm{rd}^{z,\mathrm{dn}}_{\xi,j} \text{ is defined} \right) \wedge \neg \left( \mathrm{com}^{z}_{j} \wedge \mathrm{ext}^{z}_{j} \wedge \neg \left( \mathrm{z}^{\mathrm{mod}}_{j} > 0 \right) \right) \wedge \mathrm{prev}^{z}_{\xi,t,j} \wedge \mathrm{on}^{z}_{t,j} ``` ### `StorageUnit-ext-p_dispatch-lower` @@ -8601,12 +8586,12 @@ Process_p_ramp_limit_down: StorageUnit_ext_p_dispatch_lower: description: "`StorageUnit-ext-p_dispatch-lower` — dispatch is non-negative" dims: [scenario, snapshot, storage_unit] - where: StorageUnit_p_nom_extendable AND StorageUnit_active + where: StorageUnit_ext expression: StorageUnit_p_dispatch >= 0 ``` ```math -h^{+}_{\xi,t,s} \ge 0 \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ s \in \mathcal{S} \,:\, \mathrm{ext}^{h}_{s} \wedge \mathrm{on}^{h}_{t,s} +h^{+}_{\xi,t,s} \ge 0 \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ s \in \mathcal{S} \,:\, \mathrm{on}^{h,\mathrm{ext}}_{t,s} ``` ### `StorageUnit-ext-p_dispatch-upper` @@ -8617,12 +8602,12 @@ h^{+}_{\xi,t,s} \ge 0 \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ s \in \ StorageUnit_ext_p_dispatch_upper: description: "`StorageUnit-ext-p_dispatch-upper` — an extendable unit dispatches at most the chosen build" dims: [scenario, snapshot, storage_unit] - where: StorageUnit_p_nom_extendable AND StorageUnit_active + where: StorageUnit_ext expression: StorageUnit_p_dispatch <= StorageUnit_p_max_pu * StorageUnit_p_nom_ext ``` ```math -h^{+}_{\xi,t,s} \le \overline{\mathrm{h}}_{\xi,t,s} \cdot H_{s} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ s \in \mathcal{S} \,:\, \mathrm{ext}^{h}_{s} \wedge \mathrm{on}^{h}_{t,s} +h^{+}_{\xi,t,s} \le \overline{\mathrm{h}}_{\xi,t,s} \cdot H_{s} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ s \in \mathcal{S} \,:\, \mathrm{on}^{h,\mathrm{ext}}_{t,s} ``` ### `StorageUnit-ext-p_store-lower` @@ -8633,12 +8618,12 @@ h^{+}_{\xi,t,s} \le \overline{\mathrm{h}}_{\xi,t,s} \cdot H_{s} \qquad \forall\, StorageUnit_ext_p_store_lower: description: "`StorageUnit-ext-p_store-lower` — storing is non-negative" dims: [scenario, snapshot, storage_unit] - where: StorageUnit_p_nom_extendable AND StorageUnit_active + where: StorageUnit_ext expression: StorageUnit_p_store >= 0 ``` ```math -h^{-}_{\xi,t,s} \ge 0 \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ s \in \mathcal{S} \,:\, \mathrm{ext}^{h}_{s} \wedge \mathrm{on}^{h}_{t,s} +h^{-}_{\xi,t,s} \ge 0 \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ s \in \mathcal{S} \,:\, \mathrm{on}^{h,\mathrm{ext}}_{t,s} ``` ### `StorageUnit-ext-p_store-upper` @@ -8651,12 +8636,12 @@ StorageUnit_ext_p_store_upper: `StorageUnit-ext-p_store-upper` — an extendable unit stores at most the chosen build, the minimum-per-unit column carrying that cap negated dims: [scenario, snapshot, storage_unit] - where: StorageUnit_p_nom_extendable AND StorageUnit_active + where: StorageUnit_ext expression: StorageUnit_p_store <= -StorageUnit_p_min_pu * StorageUnit_p_nom_ext ``` ```math -h^{-}_{\xi,t,s} \le -\underline{\mathrm{h}}_{\xi,t,s} \cdot H_{s} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ s \in \mathcal{S} \,:\, \mathrm{ext}^{h}_{s} \wedge \mathrm{on}^{h}_{t,s} +h^{-}_{\xi,t,s} \le -\underline{\mathrm{h}}_{\xi,t,s} \cdot H_{s} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ s \in \mathcal{S} \,:\, \mathrm{on}^{h,\mathrm{ext}}_{t,s} ``` ### `StorageUnit-ext-state_of_charge-lower` @@ -8667,12 +8652,12 @@ h^{-}_{\xi,t,s} \le -\underline{\mathrm{h}}_{\xi,t,s} \cdot H_{s} \qquad \forall StorageUnit_ext_state_of_charge_lower: description: "`StorageUnit-ext-state_of_charge-lower` — charge is non-negative" dims: [scenario, snapshot, storage_unit] - where: StorageUnit_p_nom_extendable AND StorageUnit_active + where: StorageUnit_ext expression: StorageUnit_state_of_charge >= 0 ``` ```math -\mathit{soc}_{\xi,t,s} \ge 0 \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ s \in \mathcal{S} \,:\, \mathrm{ext}^{h}_{s} \wedge \mathrm{on}^{h}_{t,s} +\mathit{soc}_{\xi,t,s} \ge 0 \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ s \in \mathcal{S} \,:\, \mathrm{on}^{h,\mathrm{ext}}_{t,s} ``` ### `StorageUnit-ext-state_of_charge-upper` @@ -8683,12 +8668,12 @@ StorageUnit_ext_state_of_charge_lower: StorageUnit_ext_state_of_charge_upper: description: "`StorageUnit-ext-state_of_charge-upper` — an extendable unit holds at most its hours at the chosen build" dims: [scenario, snapshot, storage_unit] - where: StorageUnit_p_nom_extendable AND StorageUnit_active + where: StorageUnit_ext expression: StorageUnit_state_of_charge <= StorageUnit_max_hours * StorageUnit_p_nom_ext ``` ```math -\mathit{soc}_{\xi,t,s} \le \mathrm{T}^{h}_{\xi,s} \cdot H_{s} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ s \in \mathcal{S} \,:\, \mathrm{ext}^{h}_{s} \wedge \mathrm{on}^{h}_{t,s} +\mathit{soc}_{\xi,t,s} \le \mathrm{T}^{h}_{\xi,s} \cdot H_{s} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ s \in \mathcal{S} \,:\, \mathrm{on}^{h,\mathrm{ext}}_{t,s} ``` ### `StorageUnit-ext-p_nom-lower` @@ -11042,19 +11027,19 @@ N_{g} \ge 0, N_{g} \in \mathbb{Z} \qquad \forall\, g \in \mathcal{G} \,:\, \math **`Generator_status`** ```math -u_{\xi,t,g} \ge 0, u_{\xi,t,g} \in \mathbb{Z} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ g \in \mathcal{G} \,:\, \mathrm{com}_{g} \wedge \mathrm{on}_{t,g} +u_{\xi,t,g} \ge 0, u_{\xi,t,g} \in \mathbb{Z} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ g \in \mathcal{G} \,:\, \mathrm{on}^{\mathrm{com}}_{t,g} ``` **`Generator_start_up`** ```math -\mathit{up}_{\xi,t,g} \ge 0, \mathit{up}_{\xi,t,g} \in \mathbb{Z} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ g \in \mathcal{G} \,:\, \mathrm{com}_{g} \wedge \mathrm{on}_{t,g} +\mathit{up}_{\xi,t,g} \ge 0, \mathit{up}_{\xi,t,g} \in \mathbb{Z} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ g \in \mathcal{G} \,:\, \mathrm{on}^{\mathrm{com}}_{t,g} ``` **`Generator_shut_down`** ```math -\mathit{dn}_{\xi,t,g} \ge 0, \mathit{dn}_{\xi,t,g} \in \mathbb{Z} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ g \in \mathcal{G} \,:\, \mathrm{com}_{g} \wedge \mathrm{on}_{t,g} +\mathit{dn}_{\xi,t,g} \ge 0, \mathit{dn}_{\xi,t,g} \in \mathbb{Z} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ g \in \mathcal{G} \,:\, \mathrm{on}^{\mathrm{com}}_{t,g} ``` **`Generator_maintenance`** @@ -11072,13 +11057,13 @@ u_{\xi,t,g} \ge 0, u_{\xi,t,g} \in \mathbb{Z} \qquad \forall\, \xi \in \Xi,\ t \ **`Generator_maintenance_capacity`** ```math -\mu^{\mathrm{nom}}_{\xi,t,g} \ge 0 \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ g \in \mathcal{G} \,:\, \mathrm{mnt}_{g} \wedge \mathrm{ext}_{g} \wedge \neg \left( \mathrm{com}_{g} \wedge \mathrm{p}^{\mathrm{mod}}_{g} > 0 \right) \wedge \mathrm{on}_{t,g} +\mu^{\mathrm{nom}}_{\xi,t,g} \ge 0 \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ g \in \mathcal{G} \,:\, \mathrm{on}^{\mathrm{mnt,ext}}_{t,g} ``` **`Generator_maintenance_status`** ```math -\mu^{u}_{\xi,t,g} \ge 0 \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ g \in \mathcal{G} \,:\, \mathrm{mnt}_{g} \wedge \mathrm{com}_{g} \wedge \neg \left( \mathrm{ext}_{g} \wedge \neg \left( \mathrm{p}^{\mathrm{mod}}_{g} > 0 \right) \right) \wedge \mathrm{on}_{t,g} +\mu^{u}_{\xi,t,g} \ge 0 \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ g \in \mathcal{G} \,:\, \mathrm{mnt}_{g} \wedge \mathrm{on}^{\mathrm{com}}_{t,g} \wedge \neg \left( \mathrm{ext}_{g} \wedge \neg \left( \mathrm{p}^{\mathrm{mod}}_{g} > 0 \right) \right) ``` **`Link_n_mod`** @@ -11090,19 +11075,19 @@ N^{f}_{l} \ge 0, N^{f}_{l} \in \mathbb{Z} \qquad \forall\, l \in \mathcal{L} \,: **`Link_status`** ```math -u^{f}_{\xi,t,l} \ge 0, u^{f}_{\xi,t,l} \in \mathbb{Z} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ l \in \mathcal{L} \,:\, \mathrm{com}^{f}_{l} \wedge \mathrm{on}^{f}_{t,l} +u^{f}_{\xi,t,l} \ge 0, u^{f}_{\xi,t,l} \in \mathbb{Z} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ l \in \mathcal{L} \,:\, \mathrm{on}^{f,\mathrm{com}}_{t,l} ``` **`Link_start_up`** ```math -\mathit{up}^{f}_{\xi,t,l} \ge 0, \mathit{up}^{f}_{\xi,t,l} \in \mathbb{Z} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ l \in \mathcal{L} \,:\, \mathrm{com}^{f}_{l} \wedge \mathrm{on}^{f}_{t,l} +\mathit{up}^{f}_{\xi,t,l} \ge 0, \mathit{up}^{f}_{\xi,t,l} \in \mathbb{Z} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ l \in \mathcal{L} \,:\, \mathrm{on}^{f,\mathrm{com}}_{t,l} ``` **`Link_shut_down`** ```math -\mathit{dn}^{f}_{\xi,t,l} \ge 0, \mathit{dn}^{f}_{\xi,t,l} \in \mathbb{Z} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ l \in \mathcal{L} \,:\, \mathrm{com}^{f}_{l} \wedge \mathrm{on}^{f}_{t,l} +\mathit{dn}^{f}_{\xi,t,l} \ge 0, \mathit{dn}^{f}_{\xi,t,l} \in \mathbb{Z} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ l \in \mathcal{L} \,:\, \mathrm{on}^{f,\mathrm{com}}_{t,l} ``` **`Link_maintenance`** @@ -11120,13 +11105,13 @@ u^{f}_{\xi,t,l} \ge 0, u^{f}_{\xi,t,l} \in \mathbb{Z} \qquad \forall\, \xi \in \ **`Link_maintenance_capacity`** ```math -\mu^{f,\mathrm{nom}}_{\xi,t,l} \ge 0 \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ l \in \mathcal{L} \,:\, \mathrm{mnt}^{f}_{l} \wedge \mathrm{ext}^{f}_{l} \wedge \neg \left( \mathrm{com}^{f}_{l} \wedge \mathrm{f}^{\mathrm{mod}}_{l} > 0 \right) \wedge \mathrm{on}^{f}_{t,l} +\mu^{f,\mathrm{nom}}_{\xi,t,l} \ge 0 \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ l \in \mathcal{L} \,:\, \mathrm{on}^{f,\mathrm{mnt,ext}}_{t,l} ``` **`Link_maintenance_status`** ```math -\mu^{f,u}_{\xi,t,l} \ge 0 \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ l \in \mathcal{L} \,:\, \mathrm{mnt}^{f}_{l} \wedge \mathrm{com}^{f}_{l} \wedge \neg \left( \mathrm{ext}^{f}_{l} \wedge \neg \left( \mathrm{f}^{\mathrm{mod}}_{l} > 0 \right) \right) \wedge \mathrm{on}^{f}_{t,l} +\mu^{f,u}_{\xi,t,l} \ge 0 \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ l \in \mathcal{L} \,:\, \mathrm{mnt}^{f}_{l} \wedge \mathrm{on}^{f,\mathrm{com}}_{t,l} \wedge \neg \left( \mathrm{ext}^{f}_{l} \wedge \neg \left( \mathrm{f}^{\mathrm{mod}}_{l} > 0 \right) \right) ``` **`Process_n_mod`** @@ -11138,19 +11123,19 @@ N^{z}_{j} \ge 0, N^{z}_{j} \in \mathbb{Z} \qquad \forall\, j \in \mathcal{J} \,: **`Process_status`** ```math -u^{z}_{\xi,t,j} \ge 0, u^{z}_{\xi,t,j} \in \mathbb{Z} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ j \in \mathcal{J} \,:\, \mathrm{com}^{z}_{j} \wedge \mathrm{on}^{z}_{t,j} +u^{z}_{\xi,t,j} \ge 0, u^{z}_{\xi,t,j} \in \mathbb{Z} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ j \in \mathcal{J} \,:\, \mathrm{on}^{z,\mathrm{com}}_{t,j} ``` **`Process_start_up`** ```math -\mathit{up}^{z}_{\xi,t,j} \ge 0, \mathit{up}^{z}_{\xi,t,j} \in \mathbb{Z} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ j \in \mathcal{J} \,:\, \mathrm{com}^{z}_{j} \wedge \mathrm{on}^{z}_{t,j} +\mathit{up}^{z}_{\xi,t,j} \ge 0, \mathit{up}^{z}_{\xi,t,j} \in \mathbb{Z} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ j \in \mathcal{J} \,:\, \mathrm{on}^{z,\mathrm{com}}_{t,j} ``` **`Process_shut_down`** ```math -\mathit{dn}^{z}_{\xi,t,j} \ge 0, \mathit{dn}^{z}_{\xi,t,j} \in \mathbb{Z} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ j \in \mathcal{J} \,:\, \mathrm{com}^{z}_{j} \wedge \mathrm{on}^{z}_{t,j} +\mathit{dn}^{z}_{\xi,t,j} \ge 0, \mathit{dn}^{z}_{\xi,t,j} \in \mathbb{Z} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ j \in \mathcal{J} \,:\, \mathrm{on}^{z,\mathrm{com}}_{t,j} ``` **`Process_maintenance`** @@ -11168,13 +11153,13 @@ u^{z}_{\xi,t,j} \ge 0, u^{z}_{\xi,t,j} \in \mathbb{Z} \qquad \forall\, \xi \in \ **`Process_maintenance_capacity`** ```math -\mu^{z,\mathrm{nom}}_{\xi,t,j} \ge 0 \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ j \in \mathcal{J} \,:\, \mathrm{mnt}^{z}_{j} \wedge \mathrm{ext}^{z}_{j} \wedge \neg \left( \mathrm{com}^{z}_{j} \wedge \mathrm{z}^{\mathrm{mod}}_{j} > 0 \right) \wedge \mathrm{on}^{z}_{t,j} +\mu^{z,\mathrm{nom}}_{\xi,t,j} \ge 0 \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ j \in \mathcal{J} \,:\, \mathrm{on}^{z,\mathrm{mnt,ext}}_{t,j} ``` **`Process_maintenance_status`** ```math -\mu^{z,u}_{\xi,t,j} \ge 0 \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ j \in \mathcal{J} \,:\, \mathrm{mnt}^{z}_{j} \wedge \mathrm{com}^{z}_{j} \wedge \neg \left( \mathrm{ext}^{z}_{j} \wedge \neg \left( \mathrm{z}^{\mathrm{mod}}_{j} > 0 \right) \right) \wedge \mathrm{on}^{z}_{t,j} +\mu^{z,u}_{\xi,t,j} \ge 0 \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ j \in \mathcal{J} \,:\, \mathrm{mnt}^{z}_{j} \wedge \mathrm{on}^{z,\mathrm{com}}_{t,j} \wedge \neg \left( \mathrm{ext}^{z}_{j} \wedge \neg \left( \mathrm{z}^{\mathrm{mod}}_{j} > 0 \right) \right) ``` **`Line_s`** @@ -11186,7 +11171,7 @@ s_{\xi,t,k} \in \mathbb{R} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ k **`Line_loss`** ```math -\ell_{\xi,t,k} \ge 0 \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ k \in \mathcal{K} \,:\, \mathrm{lossy} \wedge \mathrm{on}^{s}_{t,k} +\ell_{\xi,t,k} \ge 0 \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ k \in \mathcal{K} \,:\, \mathrm{on}^{s,\mathrm{lossy}}_{t,k} ``` **`Transformer_s`** @@ -11198,7 +11183,7 @@ s_{\xi,t,k} \in \mathbb{R} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ k **`Transformer_loss`** ```math -\ell^{\sigma}_{\xi,t,m} \ge 0 \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ m \in \mathcal{M} \,:\, \mathrm{lossy} \wedge \mathrm{on}^{\sigma}_{t,m} +\ell^{\sigma}_{\xi,t,m} \ge 0 \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ m \in \mathcal{M} \,:\, \mathrm{on}^{\sigma,\mathrm{lossy}}_{t,m} ``` **`Transformer_phase_shift`** diff --git a/docs/examples/pypsa/generator.md b/docs/examples/pypsa/generator.md index 4e4b82ab0..2b0d67327 100644 --- a/docs/examples/pypsa/generator.md +++ b/docs/examples/pypsa/generator.md @@ -217,6 +217,13 @@ expressions: expression: sum(Generator_sign * Generator_p, by=Generator_bus, over=generator, into=bus) adds_to: Bus_injection +masks: + Generator_committed: + description: >- + a committable generator that stands in the snapshot's period — every + unit-commitment row's set + where: Generator_committable AND Generator_active + constraints: Generator_fix_p_lower: description: "`Generator-fix-p-lower` — a fixed generator outputs at least its minimum" @@ -369,6 +376,12 @@ assumptions: | $`\mathit{Generator\_additions}`$ | `Generator_additions` over $`\mathcal{Y} \times \mathcal{I}`$ | | $`\mathit{Generator\_injection}`$ | `Generator_injection` over $`\Xi \times \mathcal{T} \times \mathcal{N}`$ | +#### Masks + +| Symbol | Meaning | +|---|---| +| $`\mathrm{on}^{\mathrm{com}}`$ | `Generator_committed` over $`\mathcal{T} \times \mathcal{G}`$ — a committable generator that stands in the snapshot's period — every unit-commitment row's set | + #### Subject to **`Generator_fix_p_lower`** @@ -493,6 +506,14 @@ p_{\xi,t,g} = \mathrm{p}^{\mathrm{set}}_{\xi,t,g} \qquad \forall\, \xi \in \Xi,\ \mathit{Generator\_injection}_{\xi,t,n} = \sum_{g \in \mathcal{G} \,:\, \mathrm{Generator\_bus}(g) = n} \mathrm{sgn}_{g} \cdot p_{\xi,t,g} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ n \in \mathcal{N} ``` +#### Masks + +**`Generator_committed`** + +```math +\mathrm{on}^{\mathrm{com}}_{t,g} \iff \mathrm{com}_{g} \wedge \mathrm{on}_{t,g} \qquad \forall\, t \in \mathcal{T},\ g \in \mathcal{G} +``` + #### Variable domains **`Generator_p`** diff --git a/docs/examples/pypsa/generator_commitment.md b/docs/examples/pypsa/generator_commitment.md index 2384d6f35..e395d2dd0 100644 --- a/docs/examples/pypsa/generator_commitment.md +++ b/docs/examples/pypsa/generator_commitment.md @@ -78,21 +78,21 @@ variables: the rows below cap at one, or at the module count where the build is modular dims: [scenario, snapshot, generator] - where: Generator_committable AND Generator_active + where: Generator_committed domain: integer bounds: lower: 0 Generator_start_up: description: "`Generator-start_up` — how much of a committable unit turns on this snapshot, capped as the status is" dims: [scenario, snapshot, generator] - where: Generator_committable AND Generator_active + where: Generator_committed domain: integer bounds: lower: 0 Generator_shut_down: description: "`Generator-shut_down` — how much of a committable unit turns off this snapshot, capped as the status is" dims: [scenario, snapshot, generator] - where: Generator_committable AND Generator_active + where: Generator_committed domain: integer bounds: lower: 0 @@ -118,6 +118,8 @@ given: Generator_p_nom_ext: { dims: [generator] } expressions: scenario_opex: { dims: [scenario] } + masks: + Generator_committed: { dims: [snapshot, generator] } expressions: Generator_previous_status: @@ -135,26 +137,38 @@ expressions: + sum(sum(Generator_shut_down * Generator_shut_down_cost, over=generator), over=snapshot) adds_to: scenario_opex +masks: + Generator_com_ext: + description: >- + a committable generator with an extendable, non-modular build that + stands in the snapshot's period — PyPSA's `com-ext` rows, whose status + is relaxed against the chosen build + where: >- + Generator_committable + AND Generator_p_nom_extendable + AND NOT (Generator_p_nom_mod > 0) + AND Generator_active + constraints: Generator_com_p_lower: description: "`Generator-com-p-lower` — a committed unit outputs at least its minimum; off, at least nothing" dims: [scenario, snapshot, generator] - where: Generator_committable AND not Generator_p_nom_extendable AND Generator_active + where: Generator_committed AND NOT Generator_p_nom_extendable expression: Generator_p >= Generator_p_min_pu * Generator_p_nom * (Generator_status - Generator_maintenance_pu * Generator_maintenance_status) Generator_com_p_upper: description: "`Generator-com-p-upper` — a committed unit outputs at most what is available; off, at most nothing" dims: [scenario, snapshot, generator] - where: Generator_committable AND not Generator_p_nom_extendable AND Generator_active + where: Generator_committed AND NOT Generator_p_nom_extendable expression: Generator_p <= Generator_p_max_pu * Generator_p_nom * (Generator_status - Generator_maintenance_pu * Generator_maintenance_status) Generator_com_transition_start_up: description: "`Generator-com-transition-start-up` — turning on is a start, counted against the state the unit carried into the snapshot" dims: [scenario, snapshot, generator] - where: Generator_committable AND Generator_active + where: Generator_committed expression: Generator_start_up >= Generator_status - Generator_previous_status Generator_com_transition_shut_down: description: "`Generator-com-transition-shut-down` — turning off is a stop, counted against the state the unit carried into the snapshot" dims: [scenario, snapshot, generator] - where: Generator_committable AND Generator_active + where: Generator_committed expression: Generator_shut_down >= Generator_previous_status - Generator_status Generator_com_up_time: description: >- @@ -162,7 +176,7 @@ constraints: is still on. The first snapshot's share of the window is the brought-in up time's, which the must-stay-up mask carries dims: [scenario, snapshot, generator] - where: Generator_committable AND Generator_min_up_time > 0 AND position(snapshot) > 0 AND Generator_active + where: Generator_committed AND Generator_min_up_time > 0 AND position(snapshot) > 0 expression: sum_back(Generator_start_up, along=snapshot, window=Generator_min_up_time) <= Generator_status Generator_com_down_time: description: >- @@ -170,38 +184,38 @@ constraints: time is still off. The first snapshot's share of the window is the brought-in down time's, which the must-stay-down mask carries dims: [scenario, snapshot, generator] - where: Generator_committable AND Generator_min_down_time > 0 AND position(snapshot) > 0 AND Generator_active + where: Generator_committed AND Generator_min_down_time > 0 AND position(snapshot) > 0 expression: sum_back(Generator_shut_down, along=snapshot, window=Generator_min_down_time) <= 1 - Generator_status Generator_com_status_must_stay_up: description: "`Generator-com-status-min_up_time_must_stay_up` — a unit still serving the up time it brought in stays on" dims: [scenario, snapshot, generator] - where: Generator_committable AND Generator_must_stay_up AND Generator_active + where: Generator_committed AND Generator_must_stay_up expression: Generator_status == 1 Generator_com_status_must_stay_down: description: >- `Generator-com-status-min_down_time_must_stay_up` — a unit still serving the down time it brought in stays off; PyPSA names the row `_must_stay_up` dims: [scenario, snapshot, generator] - where: Generator_committable AND Generator_must_stay_down AND Generator_active + where: Generator_committed AND Generator_must_stay_down expression: Generator_status == 0 Generator_com_ext_p_upper_cap: description: >- `Generator-com-ext-p-upper-cap` — a committed extendable unit outputs at most what is available of the chosen build, whatever its status dims: [scenario, snapshot, generator] - where: Generator_committable AND Generator_p_nom_extendable AND NOT (Generator_p_nom_mod > 0) AND Generator_active + where: Generator_com_ext expression: Generator_p <= Generator_p_max_pu * (Generator_p_nom_ext - Generator_maintenance_pu * Generator_maintenance_capacity) Generator_com_ext_p_upper_big_m: description: "`Generator-com-ext-p-upper-bigM` — off, a unit outputs nothing; on, the big M is no bound" dims: [scenario, snapshot, generator] - where: Generator_committable AND Generator_p_nom_extendable AND NOT (Generator_p_nom_mod > 0) AND Generator_active + where: Generator_com_ext expression: Generator_p <= Generator_big_m * Generator_status Generator_com_ext_p_lower: description: >- `Generator-com-ext-p-lower` — a committed extendable unit outputs at least its minimum of the chosen build; off, the big M releases the row dims: [scenario, snapshot, generator] - where: Generator_committable AND Generator_p_nom_extendable AND NOT (Generator_p_nom_mod > 0) AND Generator_active + where: Generator_com_ext expression: >- Generator_p >= Generator_p_min_pu * (Generator_p_nom_ext - Generator_maintenance_pu * Generator_maintenance_capacity) @@ -212,23 +226,21 @@ constraints: negative, output is also plainly non-negative, a row the big-M lower cannot assert while the unit is off dims: [scenario, snapshot, generator] - where: >- - Generator_committable AND Generator_p_nom_extendable - AND Generator_p_min_pu_nonneg AND NOT (Generator_p_nom_mod > 0) AND Generator_active + where: Generator_com_ext AND Generator_p_min_pu_nonneg expression: Generator_p >= 0 Generator_com_mod_p_lower: description: >- `Generator-com-mod-p-lower` — a committed modular unit outputs at least its minimum of one module, whether the build is fixed or a decision dims: [scenario, snapshot, generator] - where: Generator_committable AND Generator_p_nom_mod > 0 AND Generator_active + where: Generator_committed AND Generator_p_nom_mod > 0 expression: Generator_p >= Generator_p_min_pu * Generator_p_nom_mod * (Generator_status - Generator_maintenance_pu * Generator_maintenance_status) Generator_com_mod_p_upper: description: >- `Generator-com-mod-p-upper` — a committed modular unit outputs at most one module's share, whether the build is fixed or a decision dims: [scenario, snapshot, generator] - where: Generator_committable AND Generator_p_nom_mod > 0 AND Generator_active + where: Generator_committed AND Generator_p_nom_mod > 0 expression: Generator_p <= Generator_p_max_pu * Generator_p_nom_mod * (Generator_status - Generator_maintenance_pu * Generator_maintenance_status) Generator_status_p_fixed_upper: description: >- @@ -236,7 +248,7 @@ constraints: place, an explicit row as PyPSA writes it: one where the build is not modular, and the fixed build's whole count of modules where it is dims: [scenario, snapshot, generator] - where: Generator_committable AND NOT (Generator_p_nom_extendable AND Generator_p_nom_mod > 0) AND Generator_active + where: Generator_committed AND NOT (Generator_p_nom_extendable AND Generator_p_nom_mod > 0) expression: Generator_status <= Generator_modules_installed Generator_start_up_p_fixed_upper: description: >- @@ -244,7 +256,7 @@ constraints: place, an explicit row as PyPSA writes it: one where the build is not modular, and the fixed build's whole count of modules where it is dims: [scenario, snapshot, generator] - where: Generator_committable AND NOT (Generator_p_nom_extendable AND Generator_p_nom_mod > 0) AND Generator_active + where: Generator_committed AND NOT (Generator_p_nom_extendable AND Generator_p_nom_mod > 0) expression: Generator_start_up <= Generator_modules_installed Generator_shut_down_p_fixed_upper: description: >- @@ -252,22 +264,22 @@ constraints: place, an explicit row as PyPSA writes it: one where the build is not modular, and the fixed build's whole count of modules where it is dims: [scenario, snapshot, generator] - where: Generator_committable AND NOT (Generator_p_nom_extendable AND Generator_p_nom_mod > 0) AND Generator_active + where: Generator_committed AND NOT (Generator_p_nom_extendable AND Generator_p_nom_mod > 0) expression: Generator_shut_down <= Generator_modules_installed Generator_status_p_nom_variable_upper: description: "`Generator-status-p_nom-variable-upper` — a modular unit is on only where a module is built" dims: [scenario, snapshot, generator] - where: Generator_committable AND Generator_p_nom_extendable AND Generator_p_nom_mod > 0 AND Generator_active + where: Generator_committed AND Generator_p_nom_extendable AND Generator_p_nom_mod > 0 expression: Generator_status <= Generator_n_mod Generator_start_up_p_nom_variable_upper: description: "`Generator-start_up-p_nom-variable-upper` — a modular unit starts only where a module is built" dims: [scenario, snapshot, generator] - where: Generator_committable AND Generator_p_nom_extendable AND Generator_p_nom_mod > 0 AND Generator_active + where: Generator_committed AND Generator_p_nom_extendable AND Generator_p_nom_mod > 0 expression: Generator_start_up <= Generator_n_mod Generator_shut_down_p_nom_variable_upper: description: "`Generator-shut_down-p_nom-variable-upper` — a modular unit stops only where a module is built" dims: [scenario, snapshot, generator] - where: Generator_committable AND Generator_p_nom_extendable AND Generator_p_nom_mod > 0 AND Generator_active + where: Generator_committed AND Generator_p_nom_extendable AND Generator_p_nom_mod > 0 expression: Generator_shut_down <= Generator_n_mod ``` @@ -324,6 +336,7 @@ constraints: | $`\mu^{u}`$ | `Generator_maintenance_status` over $`\Xi \times \mathcal{T} \times \mathcal{G}`$ | | $`P`$ | `Generator_p_nom_ext` over $`\mathcal{G}`$ | | $`\mathit{scenario\_opex}`$ | `scenario_opex` over $`\Xi`$, an expression this file adds `Generator_commitment_opex` to | +| $`\mathrm{on}^{\mathrm{com}}`$ | `Generator_committed` over $`\mathcal{T} \times \mathcal{G}`$, a mask another file defines | #### Definitions @@ -332,6 +345,12 @@ constraints: | $`\overleftarrow{u}`$ | `Generator_previous_status` over $`\Xi \times \mathcal{T} \times \mathcal{G}`$ — the commitment state a generator carries into a snapshot — the state it brought into the horizon at the first, the previous snapshot's after that | | $`\mathit{Generator\_commitment\_opex}`$ | `Generator_commitment_opex` over $`\Xi`$ | +#### Masks + +| Symbol | Meaning | +|---|---| +| $`\mathrm{on}^{\mathrm{com,ext}}`$ | `Generator_com_ext` over $`\mathcal{T} \times \mathcal{G}`$ — a committable generator with an extendable, non-modular build that stands in the snapshot's period — PyPSA's `com-ext` rows, whose status is relaxed against the chosen build | + $`\mathrm{pos}(t)`$ denotes where index $`t`$ sits along its dimension's own order — the order `shift` steps along, not the order labels sort in — counted from $`0`$. The index itself stays the coordinate, so $`t`$ compares against labels and $`\mathrm{pos}(t)`$ against positions. #### Subject to @@ -339,121 +358,121 @@ $`\mathrm{pos}(t)`$ denotes where index $`t`$ sits along its dimension's own ord **`Generator_com_p_lower`** ```math -p_{\xi,t,g} \ge \underline{\mathrm{p}}_{\xi,t,g} \cdot \mathrm{p}^{\mathrm{nom}}_{\xi,g} \cdot \left( u_{\xi,t,g} - \gamma_{\xi,g} \cdot \mu^{u}_{\xi,t,g} \right) \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ g \in \mathcal{G} \,:\, \mathrm{com}_{g} \wedge \neg \mathrm{ext}_{g} \wedge \mathrm{on}_{t,g} +p_{\xi,t,g} \ge \underline{\mathrm{p}}_{\xi,t,g} \cdot \mathrm{p}^{\mathrm{nom}}_{\xi,g} \cdot \left( u_{\xi,t,g} - \gamma_{\xi,g} \cdot \mu^{u}_{\xi,t,g} \right) \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ g \in \mathcal{G} \,:\, \mathrm{on}^{\mathrm{com}}_{t,g} \wedge \neg \mathrm{ext}_{g} ``` **`Generator_com_p_upper`** ```math -p_{\xi,t,g} \le \overline{\mathrm{p}}_{\xi,t,g} \cdot \mathrm{p}^{\mathrm{nom}}_{\xi,g} \cdot \left( u_{\xi,t,g} - \gamma_{\xi,g} \cdot \mu^{u}_{\xi,t,g} \right) \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ g \in \mathcal{G} \,:\, \mathrm{com}_{g} \wedge \neg \mathrm{ext}_{g} \wedge \mathrm{on}_{t,g} +p_{\xi,t,g} \le \overline{\mathrm{p}}_{\xi,t,g} \cdot \mathrm{p}^{\mathrm{nom}}_{\xi,g} \cdot \left( u_{\xi,t,g} - \gamma_{\xi,g} \cdot \mu^{u}_{\xi,t,g} \right) \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ g \in \mathcal{G} \,:\, \mathrm{on}^{\mathrm{com}}_{t,g} \wedge \neg \mathrm{ext}_{g} ``` **`Generator_com_transition_start_up`** ```math -\mathit{up}_{\xi,t,g} \ge u_{\xi,t,g} - \overleftarrow{u}_{\xi,t,g} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ g \in \mathcal{G} \,:\, \mathrm{com}_{g} \wedge \mathrm{on}_{t,g} +\mathit{up}_{\xi,t,g} \ge u_{\xi,t,g} - \overleftarrow{u}_{\xi,t,g} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ g \in \mathcal{G} \,:\, \mathrm{on}^{\mathrm{com}}_{t,g} ``` **`Generator_com_transition_shut_down`** ```math -\mathit{dn}_{\xi,t,g} \ge \overleftarrow{u}_{\xi,t,g} - u_{\xi,t,g} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ g \in \mathcal{G} \,:\, \mathrm{com}_{g} \wedge \mathrm{on}_{t,g} +\mathit{dn}_{\xi,t,g} \ge \overleftarrow{u}_{\xi,t,g} - u_{\xi,t,g} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ g \in \mathcal{G} \,:\, \mathrm{on}^{\mathrm{com}}_{t,g} ``` **`Generator_com_up_time`** ```math -\sum_{t' \in \mathcal{T} \,:\, 0 \le t - t' < \mathrm{UT}} \mathit{up}_{\xi,t',g} \le u_{\xi,t,g} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ g \in \mathcal{G} \,:\, \mathrm{com}_{g} \wedge \mathrm{UT}_{\xi,g} > 0 \wedge \mathrm{pos}(t) > 0 \wedge \mathrm{on}_{t,g} +\sum_{t' \in \mathcal{T} \,:\, 0 \le t - t' < \mathrm{UT}} \mathit{up}_{\xi,t',g} \le u_{\xi,t,g} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ g \in \mathcal{G} \,:\, \mathrm{on}^{\mathrm{com}}_{t,g} \wedge \mathrm{UT}_{\xi,g} > 0 \wedge \mathrm{pos}(t) > 0 ``` **`Generator_com_down_time`** ```math -\sum_{t' \in \mathcal{T} \,:\, 0 \le t - t' < \mathrm{DT}} \mathit{dn}_{\xi,t',g} \le 1 - u_{\xi,t,g} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ g \in \mathcal{G} \,:\, \mathrm{com}_{g} \wedge \mathrm{DT}_{\xi,g} > 0 \wedge \mathrm{pos}(t) > 0 \wedge \mathrm{on}_{t,g} +\sum_{t' \in \mathcal{T} \,:\, 0 \le t - t' < \mathrm{DT}} \mathit{dn}_{\xi,t',g} \le 1 - u_{\xi,t,g} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ g \in \mathcal{G} \,:\, \mathrm{on}^{\mathrm{com}}_{t,g} \wedge \mathrm{DT}_{\xi,g} > 0 \wedge \mathrm{pos}(t) > 0 ``` **`Generator_com_status_must_stay_up`** ```math -u_{\xi,t,g} = 1 \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ g \in \mathcal{G} \,:\, \mathrm{com}_{g} \wedge \mathrm{hold}_{\xi,t,g} \wedge \mathrm{on}_{t,g} +u_{\xi,t,g} = 1 \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ g \in \mathcal{G} \,:\, \mathrm{on}^{\mathrm{com}}_{t,g} \wedge \mathrm{hold}_{\xi,t,g} ``` **`Generator_com_status_must_stay_down`** ```math -u_{\xi,t,g} = 0 \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ g \in \mathcal{G} \,:\, \mathrm{com}_{g} \wedge \mathrm{rest}_{\xi,t,g} \wedge \mathrm{on}_{t,g} +u_{\xi,t,g} = 0 \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ g \in \mathcal{G} \,:\, \mathrm{on}^{\mathrm{com}}_{t,g} \wedge \mathrm{rest}_{\xi,t,g} ``` **`Generator_com_ext_p_upper_cap`** ```math -p_{\xi,t,g} \le \overline{\mathrm{p}}_{\xi,t,g} \cdot \left( P_{g} - \gamma_{\xi,g} \cdot \mu^{\mathrm{nom}}_{\xi,t,g} \right) \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ g \in \mathcal{G} \,:\, \mathrm{com}_{g} \wedge \mathrm{ext}_{g} \wedge \neg \left( \mathrm{p}^{\mathrm{mod}}_{g} > 0 \right) \wedge \mathrm{on}_{t,g} +p_{\xi,t,g} \le \overline{\mathrm{p}}_{\xi,t,g} \cdot \left( P_{g} - \gamma_{\xi,g} \cdot \mu^{\mathrm{nom}}_{\xi,t,g} \right) \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ g \in \mathcal{G} \,:\, \mathrm{on}^{\mathrm{com,ext}}_{t,g} ``` **`Generator_com_ext_p_upper_big_m`** ```math -p_{\xi,t,g} \le \mathrm{M}_{\xi,g} \cdot u_{\xi,t,g} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ g \in \mathcal{G} \,:\, \mathrm{com}_{g} \wedge \mathrm{ext}_{g} \wedge \neg \left( \mathrm{p}^{\mathrm{mod}}_{g} > 0 \right) \wedge \mathrm{on}_{t,g} +p_{\xi,t,g} \le \mathrm{M}_{\xi,g} \cdot u_{\xi,t,g} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ g \in \mathcal{G} \,:\, \mathrm{on}^{\mathrm{com,ext}}_{t,g} ``` **`Generator_com_ext_p_lower`** ```math -p_{\xi,t,g} \ge \underline{\mathrm{p}}_{\xi,t,g} \cdot \left( P_{g} - \gamma_{\xi,g} \cdot \mu^{\mathrm{nom}}_{\xi,t,g} \right) + \mathrm{M}_{\xi,g} \cdot u_{\xi,t,g} - \mathrm{M}_{\xi,g} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ g \in \mathcal{G} \,:\, \mathrm{com}_{g} \wedge \mathrm{ext}_{g} \wedge \neg \left( \mathrm{p}^{\mathrm{mod}}_{g} > 0 \right) \wedge \mathrm{on}_{t,g} +p_{\xi,t,g} \ge \underline{\mathrm{p}}_{\xi,t,g} \cdot \left( P_{g} - \gamma_{\xi,g} \cdot \mu^{\mathrm{nom}}_{\xi,t,g} \right) + \mathrm{M}_{\xi,g} \cdot u_{\xi,t,g} - \mathrm{M}_{\xi,g} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ g \in \mathcal{G} \,:\, \mathrm{on}^{\mathrm{com,ext}}_{t,g} ``` **`Generator_com_ext_p_lower_nonneg`** ```math -p_{\xi,t,g} \ge 0 \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ g \in \mathcal{G} \,:\, \mathrm{com}_{g} \wedge \mathrm{ext}_{g} \wedge \mathrm{nonneg}_{g} \wedge \neg \left( \mathrm{p}^{\mathrm{mod}}_{g} > 0 \right) \wedge \mathrm{on}_{t,g} +p_{\xi,t,g} \ge 0 \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ g \in \mathcal{G} \,:\, \mathrm{on}^{\mathrm{com,ext}}_{t,g} \wedge \mathrm{nonneg}_{g} ``` **`Generator_com_mod_p_lower`** ```math -p_{\xi,t,g} \ge \underline{\mathrm{p}}_{\xi,t,g} \cdot \mathrm{p}^{\mathrm{mod}}_{g} \cdot \left( u_{\xi,t,g} - \gamma_{\xi,g} \cdot \mu^{u}_{\xi,t,g} \right) \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ g \in \mathcal{G} \,:\, \mathrm{com}_{g} \wedge \mathrm{p}^{\mathrm{mod}}_{g} > 0 \wedge \mathrm{on}_{t,g} +p_{\xi,t,g} \ge \underline{\mathrm{p}}_{\xi,t,g} \cdot \mathrm{p}^{\mathrm{mod}}_{g} \cdot \left( u_{\xi,t,g} - \gamma_{\xi,g} \cdot \mu^{u}_{\xi,t,g} \right) \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ g \in \mathcal{G} \,:\, \mathrm{on}^{\mathrm{com}}_{t,g} \wedge \mathrm{p}^{\mathrm{mod}}_{g} > 0 ``` **`Generator_com_mod_p_upper`** ```math -p_{\xi,t,g} \le \overline{\mathrm{p}}_{\xi,t,g} \cdot \mathrm{p}^{\mathrm{mod}}_{g} \cdot \left( u_{\xi,t,g} - \gamma_{\xi,g} \cdot \mu^{u}_{\xi,t,g} \right) \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ g \in \mathcal{G} \,:\, \mathrm{com}_{g} \wedge \mathrm{p}^{\mathrm{mod}}_{g} > 0 \wedge \mathrm{on}_{t,g} +p_{\xi,t,g} \le \overline{\mathrm{p}}_{\xi,t,g} \cdot \mathrm{p}^{\mathrm{mod}}_{g} \cdot \left( u_{\xi,t,g} - \gamma_{\xi,g} \cdot \mu^{u}_{\xi,t,g} \right) \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ g \in \mathcal{G} \,:\, \mathrm{on}^{\mathrm{com}}_{t,g} \wedge \mathrm{p}^{\mathrm{mod}}_{g} > 0 ``` **`Generator_status_p_fixed_upper`** ```math -u_{\xi,t,g} \le \mathrm{N}^{\mathrm{fix}}_{\xi,g} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ g \in \mathcal{G} \,:\, \mathrm{com}_{g} \wedge \neg \left( \mathrm{ext}_{g} \wedge \mathrm{p}^{\mathrm{mod}}_{g} > 0 \right) \wedge \mathrm{on}_{t,g} +u_{\xi,t,g} \le \mathrm{N}^{\mathrm{fix}}_{\xi,g} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ g \in \mathcal{G} \,:\, \mathrm{on}^{\mathrm{com}}_{t,g} \wedge \neg \left( \mathrm{ext}_{g} \wedge \mathrm{p}^{\mathrm{mod}}_{g} > 0 \right) ``` **`Generator_start_up_p_fixed_upper`** ```math -\mathit{up}_{\xi,t,g} \le \mathrm{N}^{\mathrm{fix}}_{\xi,g} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ g \in \mathcal{G} \,:\, \mathrm{com}_{g} \wedge \neg \left( \mathrm{ext}_{g} \wedge \mathrm{p}^{\mathrm{mod}}_{g} > 0 \right) \wedge \mathrm{on}_{t,g} +\mathit{up}_{\xi,t,g} \le \mathrm{N}^{\mathrm{fix}}_{\xi,g} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ g \in \mathcal{G} \,:\, \mathrm{on}^{\mathrm{com}}_{t,g} \wedge \neg \left( \mathrm{ext}_{g} \wedge \mathrm{p}^{\mathrm{mod}}_{g} > 0 \right) ``` **`Generator_shut_down_p_fixed_upper`** ```math -\mathit{dn}_{\xi,t,g} \le \mathrm{N}^{\mathrm{fix}}_{\xi,g} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ g \in \mathcal{G} \,:\, \mathrm{com}_{g} \wedge \neg \left( \mathrm{ext}_{g} \wedge \mathrm{p}^{\mathrm{mod}}_{g} > 0 \right) \wedge \mathrm{on}_{t,g} +\mathit{dn}_{\xi,t,g} \le \mathrm{N}^{\mathrm{fix}}_{\xi,g} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ g \in \mathcal{G} \,:\, \mathrm{on}^{\mathrm{com}}_{t,g} \wedge \neg \left( \mathrm{ext}_{g} \wedge \mathrm{p}^{\mathrm{mod}}_{g} > 0 \right) ``` **`Generator_status_p_nom_variable_upper`** ```math -u_{\xi,t,g} \le N_{g} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ g \in \mathcal{G} \,:\, \mathrm{com}_{g} \wedge \mathrm{ext}_{g} \wedge \mathrm{p}^{\mathrm{mod}}_{g} > 0 \wedge \mathrm{on}_{t,g} +u_{\xi,t,g} \le N_{g} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ g \in \mathcal{G} \,:\, \mathrm{on}^{\mathrm{com}}_{t,g} \wedge \mathrm{ext}_{g} \wedge \mathrm{p}^{\mathrm{mod}}_{g} > 0 ``` **`Generator_start_up_p_nom_variable_upper`** ```math -\mathit{up}_{\xi,t,g} \le N_{g} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ g \in \mathcal{G} \,:\, \mathrm{com}_{g} \wedge \mathrm{ext}_{g} \wedge \mathrm{p}^{\mathrm{mod}}_{g} > 0 \wedge \mathrm{on}_{t,g} +\mathit{up}_{\xi,t,g} \le N_{g} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ g \in \mathcal{G} \,:\, \mathrm{on}^{\mathrm{com}}_{t,g} \wedge \mathrm{ext}_{g} \wedge \mathrm{p}^{\mathrm{mod}}_{g} > 0 ``` **`Generator_shut_down_p_nom_variable_upper`** ```math -\mathit{dn}_{\xi,t,g} \le N_{g} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ g \in \mathcal{G} \,:\, \mathrm{com}_{g} \wedge \mathrm{ext}_{g} \wedge \mathrm{p}^{\mathrm{mod}}_{g} > 0 \wedge \mathrm{on}_{t,g} +\mathit{dn}_{\xi,t,g} \le N_{g} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ g \in \mathcal{G} \,:\, \mathrm{on}^{\mathrm{com}}_{t,g} \wedge \mathrm{ext}_{g} \wedge \mathrm{p}^{\mathrm{mod}}_{g} > 0 ``` #### Definitions @@ -470,23 +489,31 @@ u_{\xi,t,g} \le N_{g} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ g \in \ \mathit{Generator\_commitment\_opex}_{\xi} = \sum_{t \in \mathcal{T}} \sum_{g \in \mathcal{G}} u_{\xi,t,g} \cdot \mathrm{c}^{\mathrm{on}}_{\xi,t,g} \cdot \mathrm{w}_{t} \cdot \mathrm{w}^{y}_{\mathrm{snapshot\_period}(t)} + \sum_{t \in \mathcal{T}} \sum_{g \in \mathcal{G}} \mathit{up}_{\xi,t,g} \cdot \mathrm{c}^{\mathrm{up}}_{\xi,g} + \sum_{t \in \mathcal{T}} \sum_{g \in \mathcal{G}} \mathit{dn}_{\xi,t,g} \cdot \mathrm{c}^{\mathrm{dn}}_{\xi,g} \qquad \forall\, \xi \in \Xi ``` +#### Masks + +**`Generator_com_ext`** + +```math +\mathrm{on}^{\mathrm{com,ext}}_{t,g} \iff \mathrm{com}_{g} \wedge \mathrm{ext}_{g} \wedge \neg \left( \mathrm{p}^{\mathrm{mod}}_{g} > 0 \right) \wedge \mathrm{on}_{t,g} \qquad \forall\, t \in \mathcal{T},\ g \in \mathcal{G} +``` + #### Variable domains **`Generator_status`** ```math -u_{\xi,t,g} \ge 0, u_{\xi,t,g} \in \mathbb{Z} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ g \in \mathcal{G} \,:\, \mathrm{com}_{g} \wedge \mathrm{on}_{t,g} +u_{\xi,t,g} \ge 0, u_{\xi,t,g} \in \mathbb{Z} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ g \in \mathcal{G} \,:\, \mathrm{on}^{\mathrm{com}}_{t,g} ``` **`Generator_start_up`** ```math -\mathit{up}_{\xi,t,g} \ge 0, \mathit{up}_{\xi,t,g} \in \mathbb{Z} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ g \in \mathcal{G} \,:\, \mathrm{com}_{g} \wedge \mathrm{on}_{t,g} +\mathit{up}_{\xi,t,g} \ge 0, \mathit{up}_{\xi,t,g} \in \mathbb{Z} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ g \in \mathcal{G} \,:\, \mathrm{on}^{\mathrm{com}}_{t,g} ``` **`Generator_shut_down`** ```math -\mathit{dn}_{\xi,t,g} \ge 0, \mathit{dn}_{\xi,t,g} \in \mathbb{Z} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ g \in \mathcal{G} \,:\, \mathrm{com}_{g} \wedge \mathrm{on}_{t,g} +\mathit{dn}_{\xi,t,g} \ge 0, \mathit{dn}_{\xi,t,g} \in \mathbb{Z} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ g \in \mathcal{G} \,:\, \mathrm{on}^{\mathrm{com}}_{t,g} ``` diff --git a/docs/examples/pypsa/generator_maintenance.md b/docs/examples/pypsa/generator_maintenance.md index de4168778..2bb7e9fc5 100644 --- a/docs/examples/pypsa/generator_maintenance.md +++ b/docs/examples/pypsa/generator_maintenance.md @@ -81,9 +81,7 @@ variables: `Generator-maintenance_capacity` — the chosen build while in maintenance, zero otherwise: the product the `maintcap` rows linearize dims: [scenario, snapshot, generator] - where: >- - Generator_maintainable AND Generator_p_nom_extendable - AND NOT (Generator_committable AND Generator_p_nom_mod > 0) AND Generator_active + where: Generator_maint_ext absence: zero bounds: lower: 0 @@ -94,8 +92,9 @@ variables: maintenance may also be off dims: [scenario, snapshot, generator] where: >- - Generator_maintainable AND Generator_committable - AND NOT (Generator_p_nom_extendable AND NOT (Generator_p_nom_mod > 0)) AND Generator_active + Generator_maintainable + AND Generator_committed + AND NOT (Generator_p_nom_extendable AND NOT (Generator_p_nom_mod > 0)) absence: zero bounds: lower: 0 @@ -112,6 +111,20 @@ given: variables: Generator_status: { dims: [scenario, snapshot, generator], domain: integer } Generator_p_nom_ext: { dims: [generator] } + masks: + Generator_committed: { dims: [snapshot, generator] } + +masks: + Generator_maint_ext: + description: >- + a maintainable generator with an extendable build, unless it is + committable and modular, that stands in the snapshot's period — the + maintenance rows against the chosen build + where: >- + Generator_maintainable + AND Generator_p_nom_extendable + AND NOT (Generator_committable AND Generator_p_nom_mod > 0) + AND Generator_active constraints: Generator_maint_event_count: @@ -137,54 +150,54 @@ constraints: `Generator-maintcap_upper` — the build taken off is at most the chosen build in maintenance, and at most the build less its floor out of it dims: [scenario, snapshot, generator] - where: Generator_maintainable AND Generator_p_nom_extendable AND NOT (Generator_committable AND Generator_p_nom_mod > 0) AND Generator_active + where: Generator_maint_ext expression: Generator_maintenance_capacity <= Generator_p_nom_ext - Generator_p_nom_min * (1 - Generator_maintenance) Generator_maintcap_upper_nommax: description: "`Generator-maintcap_upper_nommax` — out of maintenance, no build is taken off" dims: [scenario, snapshot, generator] - where: Generator_maintainable AND Generator_p_nom_extendable AND NOT (Generator_committable AND Generator_p_nom_mod > 0) AND Generator_active + where: Generator_maint_ext expression: Generator_maintenance_capacity <= Generator_p_nom_max * Generator_maintenance Generator_maintcap_lower_nommax: description: "`Generator-maintcap_lower_nommax` — in maintenance, the whole chosen build is taken off" dims: [scenario, snapshot, generator] - where: Generator_maintainable AND Generator_p_nom_extendable AND NOT (Generator_committable AND Generator_p_nom_mod > 0) AND Generator_active + where: Generator_maint_ext expression: Generator_maintenance_capacity >= Generator_p_nom_ext - Generator_p_nom_max * (1 - Generator_maintenance) Generator_maintcap_lower_nommin: description: "`Generator-maintcap_lower_nommin` — in maintenance, at least the floor of the build is taken off" dims: [scenario, snapshot, generator] - where: Generator_maintainable AND Generator_p_nom_extendable AND NOT (Generator_committable AND Generator_p_nom_mod > 0) AND Generator_active AND Generator_p_nom_min > 0 + where: Generator_maint_ext AND Generator_p_nom_min > 0 expression: Generator_maintenance_capacity >= Generator_p_nom_min * Generator_maintenance Generator_maint_status_le_status: description: "`Generator-maint-status-le-status` — the status in maintenance is at most the status" dims: [scenario, snapshot, generator] - where: Generator_maintainable AND Generator_committable AND NOT Generator_p_nom_extendable AND Generator_active + where: Generator_maintainable AND Generator_committed AND NOT Generator_p_nom_extendable expression: Generator_maintenance_status <= Generator_status Generator_maint_status_le_maint: description: "`Generator-maint-status-le-maint` — out of maintenance, the status in maintenance is zero" dims: [scenario, snapshot, generator] - where: Generator_maintainable AND Generator_committable AND NOT Generator_p_nom_extendable AND Generator_active + where: Generator_maintainable AND Generator_committed AND NOT Generator_p_nom_extendable expression: Generator_maintenance_status <= Generator_maintenance Generator_maint_status_lb: description: "`Generator-maint-status-lb` — on and in maintenance, the status in maintenance is one" dims: [scenario, snapshot, generator] - where: Generator_maintainable AND Generator_committable AND NOT Generator_p_nom_extendable AND Generator_active + where: Generator_maintainable AND Generator_committed AND NOT Generator_p_nom_extendable expression: Generator_maintenance_status >= Generator_status + Generator_maintenance - 1 Generator_maint_modstatus_le_status: description: "`Generator-maint-modstatus-le-status` — the modules on in maintenance are at most the modules on" dims: [scenario, snapshot, generator] - where: Generator_maintainable AND Generator_committable AND Generator_p_nom_mod > 0 AND Generator_active + where: Generator_maintainable AND Generator_committed AND Generator_p_nom_mod > 0 expression: Generator_maintenance_status <= Generator_status Generator_maint_modstatus_le_maint: description: >- `Generator-maint-modstatus-le-maint` — out of maintenance, no module is on in maintenance; in it, at most the modules the build cap holds dims: [scenario, snapshot, generator] - where: Generator_maintainable AND Generator_committable AND Generator_p_nom_mod > 0 AND Generator_active + where: Generator_maintainable AND Generator_committed AND Generator_p_nom_mod > 0 expression: Generator_maintenance_status <= Generator_p_nom_max / Generator_p_nom_mod * Generator_maintenance Generator_maint_modstatus_lb: description: "`Generator-maint-modstatus-lb` — in maintenance, every module on is on in maintenance" dims: [scenario, snapshot, generator] - where: Generator_maintainable AND Generator_committable AND Generator_p_nom_mod > 0 AND Generator_active + where: Generator_maintainable AND Generator_committed AND Generator_p_nom_mod > 0 expression: Generator_maintenance_status >= Generator_status - Generator_p_nom_max / Generator_p_nom_mod * (1 - Generator_maintenance) assumptions: @@ -271,6 +284,13 @@ assumptions: | $`\overline{\mathrm{p}}^{\mathrm{nom}}`$ | `Generator_p_nom_max` over $`\Xi \times \mathcal{G}`$, data another file declares | | $`u`$ | `Generator_status` over $`\Xi \times \mathcal{T} \times \mathcal{G}`$ | | $`P`$ | `Generator_p_nom_ext` over $`\mathcal{G}`$ | +| $`\mathrm{on}^{\mathrm{com}}`$ | `Generator_committed` over $`\mathcal{T} \times \mathcal{G}`$, a mask another file defines | + +#### Masks + +| Symbol | Meaning | +|---|---| +| $`\mathrm{on}^{\mathrm{mnt,ext}}`$ | `Generator_maint_ext` over $`\mathcal{T} \times \mathcal{G}`$ — a maintainable generator with an extendable build, unless it is committable and modular, that stands in the snapshot's period — the maintenance rows against the chosen build | #### Subject to @@ -295,61 +315,69 @@ assumptions: **`Generator_maintcap_upper`** ```math -\mu^{\mathrm{nom}}_{\xi,t,g} \le P_{g} - \underline{\mathrm{p}}^{\mathrm{nom}}_{\xi,g} \cdot \left( 1 - \mu_{\xi,t,g} \right) \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ g \in \mathcal{G} \,:\, \mathrm{mnt}_{g} \wedge \mathrm{ext}_{g} \wedge \neg \left( \mathrm{com}_{g} \wedge \mathrm{p}^{\mathrm{mod}}_{g} > 0 \right) \wedge \mathrm{on}_{t,g} +\mu^{\mathrm{nom}}_{\xi,t,g} \le P_{g} - \underline{\mathrm{p}}^{\mathrm{nom}}_{\xi,g} \cdot \left( 1 - \mu_{\xi,t,g} \right) \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ g \in \mathcal{G} \,:\, \mathrm{on}^{\mathrm{mnt,ext}}_{t,g} ``` **`Generator_maintcap_upper_nommax`** ```math -\mu^{\mathrm{nom}}_{\xi,t,g} \le \overline{\mathrm{p}}^{\mathrm{nom}}_{\xi,g} \cdot \mu_{\xi,t,g} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ g \in \mathcal{G} \,:\, \mathrm{mnt}_{g} \wedge \mathrm{ext}_{g} \wedge \neg \left( \mathrm{com}_{g} \wedge \mathrm{p}^{\mathrm{mod}}_{g} > 0 \right) \wedge \mathrm{on}_{t,g} +\mu^{\mathrm{nom}}_{\xi,t,g} \le \overline{\mathrm{p}}^{\mathrm{nom}}_{\xi,g} \cdot \mu_{\xi,t,g} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ g \in \mathcal{G} \,:\, \mathrm{on}^{\mathrm{mnt,ext}}_{t,g} ``` **`Generator_maintcap_lower_nommax`** ```math -\mu^{\mathrm{nom}}_{\xi,t,g} \ge P_{g} - \overline{\mathrm{p}}^{\mathrm{nom}}_{\xi,g} \cdot \left( 1 - \mu_{\xi,t,g} \right) \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ g \in \mathcal{G} \,:\, \mathrm{mnt}_{g} \wedge \mathrm{ext}_{g} \wedge \neg \left( \mathrm{com}_{g} \wedge \mathrm{p}^{\mathrm{mod}}_{g} > 0 \right) \wedge \mathrm{on}_{t,g} +\mu^{\mathrm{nom}}_{\xi,t,g} \ge P_{g} - \overline{\mathrm{p}}^{\mathrm{nom}}_{\xi,g} \cdot \left( 1 - \mu_{\xi,t,g} \right) \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ g \in \mathcal{G} \,:\, \mathrm{on}^{\mathrm{mnt,ext}}_{t,g} ``` **`Generator_maintcap_lower_nommin`** ```math -\mu^{\mathrm{nom}}_{\xi,t,g} \ge \underline{\mathrm{p}}^{\mathrm{nom}}_{\xi,g} \cdot \mu_{\xi,t,g} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ g \in \mathcal{G} \,:\, \mathrm{mnt}_{g} \wedge \mathrm{ext}_{g} \wedge \neg \left( \mathrm{com}_{g} \wedge \mathrm{p}^{\mathrm{mod}}_{g} > 0 \right) \wedge \mathrm{on}_{t,g} \wedge \underline{\mathrm{p}}^{\mathrm{nom}}_{\xi,g} > 0 +\mu^{\mathrm{nom}}_{\xi,t,g} \ge \underline{\mathrm{p}}^{\mathrm{nom}}_{\xi,g} \cdot \mu_{\xi,t,g} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ g \in \mathcal{G} \,:\, \mathrm{on}^{\mathrm{mnt,ext}}_{t,g} \wedge \underline{\mathrm{p}}^{\mathrm{nom}}_{\xi,g} > 0 ``` **`Generator_maint_status_le_status`** ```math -\mu^{u}_{\xi,t,g} \le u_{\xi,t,g} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ g \in \mathcal{G} \,:\, \mathrm{mnt}_{g} \wedge \mathrm{com}_{g} \wedge \neg \mathrm{ext}_{g} \wedge \mathrm{on}_{t,g} +\mu^{u}_{\xi,t,g} \le u_{\xi,t,g} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ g \in \mathcal{G} \,:\, \mathrm{mnt}_{g} \wedge \mathrm{on}^{\mathrm{com}}_{t,g} \wedge \neg \mathrm{ext}_{g} ``` **`Generator_maint_status_le_maint`** ```math -\mu^{u}_{\xi,t,g} \le \mu_{\xi,t,g} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ g \in \mathcal{G} \,:\, \mathrm{mnt}_{g} \wedge \mathrm{com}_{g} \wedge \neg \mathrm{ext}_{g} \wedge \mathrm{on}_{t,g} +\mu^{u}_{\xi,t,g} \le \mu_{\xi,t,g} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ g \in \mathcal{G} \,:\, \mathrm{mnt}_{g} \wedge \mathrm{on}^{\mathrm{com}}_{t,g} \wedge \neg \mathrm{ext}_{g} ``` **`Generator_maint_status_lb`** ```math -\mu^{u}_{\xi,t,g} \ge u_{\xi,t,g} + \mu_{\xi,t,g} - 1 \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ g \in \mathcal{G} \,:\, \mathrm{mnt}_{g} \wedge \mathrm{com}_{g} \wedge \neg \mathrm{ext}_{g} \wedge \mathrm{on}_{t,g} +\mu^{u}_{\xi,t,g} \ge u_{\xi,t,g} + \mu_{\xi,t,g} - 1 \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ g \in \mathcal{G} \,:\, \mathrm{mnt}_{g} \wedge \mathrm{on}^{\mathrm{com}}_{t,g} \wedge \neg \mathrm{ext}_{g} ``` **`Generator_maint_modstatus_le_status`** ```math -\mu^{u}_{\xi,t,g} \le u_{\xi,t,g} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ g \in \mathcal{G} \,:\, \mathrm{mnt}_{g} \wedge \mathrm{com}_{g} \wedge \mathrm{p}^{\mathrm{mod}}_{g} > 0 \wedge \mathrm{on}_{t,g} +\mu^{u}_{\xi,t,g} \le u_{\xi,t,g} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ g \in \mathcal{G} \,:\, \mathrm{mnt}_{g} \wedge \mathrm{on}^{\mathrm{com}}_{t,g} \wedge \mathrm{p}^{\mathrm{mod}}_{g} > 0 ``` **`Generator_maint_modstatus_le_maint`** ```math -\mu^{u}_{\xi,t,g} \le \frac{\overline{\mathrm{p}}^{\mathrm{nom}}_{\xi,g}}{\mathrm{p}^{\mathrm{mod}}_{g}} \cdot \mu_{\xi,t,g} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ g \in \mathcal{G} \,:\, \mathrm{mnt}_{g} \wedge \mathrm{com}_{g} \wedge \mathrm{p}^{\mathrm{mod}}_{g} > 0 \wedge \mathrm{on}_{t,g} +\mu^{u}_{\xi,t,g} \le \frac{\overline{\mathrm{p}}^{\mathrm{nom}}_{\xi,g}}{\mathrm{p}^{\mathrm{mod}}_{g}} \cdot \mu_{\xi,t,g} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ g \in \mathcal{G} \,:\, \mathrm{mnt}_{g} \wedge \mathrm{on}^{\mathrm{com}}_{t,g} \wedge \mathrm{p}^{\mathrm{mod}}_{g} > 0 ``` **`Generator_maint_modstatus_lb`** ```math -\mu^{u}_{\xi,t,g} \ge u_{\xi,t,g} - \frac{\overline{\mathrm{p}}^{\mathrm{nom}}_{\xi,g}}{\mathrm{p}^{\mathrm{mod}}_{g}} \cdot \left( 1 - \mu_{\xi,t,g} \right) \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ g \in \mathcal{G} \,:\, \mathrm{mnt}_{g} \wedge \mathrm{com}_{g} \wedge \mathrm{p}^{\mathrm{mod}}_{g} > 0 \wedge \mathrm{on}_{t,g} +\mu^{u}_{\xi,t,g} \ge u_{\xi,t,g} - \frac{\overline{\mathrm{p}}^{\mathrm{nom}}_{\xi,g}}{\mathrm{p}^{\mathrm{mod}}_{g}} \cdot \left( 1 - \mu_{\xi,t,g} \right) \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ g \in \mathcal{G} \,:\, \mathrm{mnt}_{g} \wedge \mathrm{on}^{\mathrm{com}}_{t,g} \wedge \mathrm{p}^{\mathrm{mod}}_{g} > 0 +``` + +#### Masks + +**`Generator_maint_ext`** + +```math +\mathrm{on}^{\mathrm{mnt,ext}}_{t,g} \iff \mathrm{mnt}_{g} \wedge \mathrm{ext}_{g} \wedge \neg \left( \mathrm{com}_{g} \wedge \mathrm{p}^{\mathrm{mod}}_{g} > 0 \right) \wedge \mathrm{on}_{t,g} \qquad \forall\, t \in \mathcal{T},\ g \in \mathcal{G} ``` #### Variable domains @@ -369,13 +397,13 @@ assumptions: **`Generator_maintenance_capacity`** ```math -\mu^{\mathrm{nom}}_{\xi,t,g} \ge 0 \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ g \in \mathcal{G} \,:\, \mathrm{mnt}_{g} \wedge \mathrm{ext}_{g} \wedge \neg \left( \mathrm{com}_{g} \wedge \mathrm{p}^{\mathrm{mod}}_{g} > 0 \right) \wedge \mathrm{on}_{t,g} +\mu^{\mathrm{nom}}_{\xi,t,g} \ge 0 \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ g \in \mathcal{G} \,:\, \mathrm{on}^{\mathrm{mnt,ext}}_{t,g} ``` **`Generator_maintenance_status`** ```math -\mu^{u}_{\xi,t,g} \ge 0 \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ g \in \mathcal{G} \,:\, \mathrm{mnt}_{g} \wedge \mathrm{com}_{g} \wedge \neg \left( \mathrm{ext}_{g} \wedge \neg \left( \mathrm{p}^{\mathrm{mod}}_{g} > 0 \right) \right) \wedge \mathrm{on}_{t,g} +\mu^{u}_{\xi,t,g} \ge 0 \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ g \in \mathcal{G} \,:\, \mathrm{mnt}_{g} \wedge \mathrm{on}^{\mathrm{com}}_{t,g} \wedge \neg \left( \mathrm{ext}_{g} \wedge \neg \left( \mathrm{p}^{\mathrm{mod}}_{g} > 0 \right) \right) ``` #### Assumptions diff --git a/docs/examples/pypsa/generator_ramping.md b/docs/examples/pypsa/generator_ramping.md index bcb55e430..60da7bc02 100644 --- a/docs/examples/pypsa/generator_ramping.md +++ b/docs/examples/pypsa/generator_ramping.md @@ -65,6 +65,8 @@ given: Generator_previous_status: { dims: [scenario, snapshot, generator] } Generator_p_nom_effective: { dims: [scenario, generator] } Generator_p_nom_committed: { dims: [scenario, generator] } + masks: + Generator_com_ext: { dims: [snapshot, generator] } expressions: Generator_previous_p: @@ -137,6 +139,16 @@ expressions: * (Generator_previous_status - Generator_status) otherwise: Generator_ramp_down_rate * Generator_p_nom_effective +masks: + Generator_ramps_from_previous: + description: >- + a snapshot whose ramp reads a previous output — any snapshot but its + period's first, and the horizon's first where the generator comes in off + or carries an initial output + where: >- + position(snapshot, by=snapshot_period, within=period) > 0 OR (position(snapshot) == 0 AND + (Generator_status_initial == 0 OR Generator_p_init)) + constraints: Generator_p_ramp_limit_up_run_big_m: description: >- @@ -145,10 +157,9 @@ constraints: releases the row in the snapshot it turns on dims: [scenario, snapshot, generator] where: >- - Generator_committable AND Generator_p_nom_extendable AND NOT (Generator_p_nom_mod > 0) + Generator_com_ext AND (Generator_ramp_limit_up OR Generator_ramp_limit_start_up) - AND (position(snapshot, by=snapshot_period, within=period) > 0 OR (position(snapshot) == 0 AND (Generator_status_initial == 0 OR Generator_p_init))) - AND Generator_active + AND Generator_ramps_from_previous expression: >- Generator_p - Generator_previous_p <= Generator_ramp_up_rate * Generator_p_nom_ext @@ -160,10 +171,9 @@ constraints: the chosen build; the big M releases the row everywhere else dims: [scenario, snapshot, generator] where: >- - Generator_committable AND Generator_p_nom_extendable AND NOT (Generator_p_nom_mod > 0) + Generator_com_ext AND (Generator_ramp_limit_up OR Generator_ramp_limit_start_up) - AND (position(snapshot, by=snapshot_period, within=period) > 0 OR (position(snapshot) == 0 AND (Generator_status_initial == 0 OR Generator_p_init))) - AND Generator_active + AND Generator_ramps_from_previous expression: >- Generator_p - Generator_previous_p <= Generator_start_up_rate * Generator_p_nom_ext @@ -175,10 +185,9 @@ constraints: releases the row in the snapshot it turns off dims: [scenario, snapshot, generator] where: >- - Generator_committable AND Generator_p_nom_extendable AND NOT (Generator_p_nom_mod > 0) + Generator_com_ext AND (Generator_ramp_limit_down OR Generator_ramp_limit_shut_down) - AND (position(snapshot, by=snapshot_period, within=period) > 0 OR (position(snapshot) == 0 AND (Generator_status_initial == 0 OR Generator_p_init))) - AND Generator_active + AND Generator_ramps_from_previous expression: >- Generator_previous_p - Generator_p <= Generator_ramp_down_rate * Generator_p_nom_ext @@ -190,10 +199,9 @@ constraints: the chosen build; the big M releases the row everywhere else dims: [scenario, snapshot, generator] where: >- - Generator_committable AND Generator_p_nom_extendable AND NOT (Generator_p_nom_mod > 0) + Generator_com_ext AND (Generator_ramp_limit_down OR Generator_ramp_limit_shut_down) - AND (position(snapshot, by=snapshot_period, within=period) > 0 OR (position(snapshot) == 0 AND (Generator_status_initial == 0 OR Generator_p_init))) - AND Generator_active + AND Generator_ramps_from_previous expression: >- Generator_previous_p - Generator_p <= Generator_shut_down_rate * Generator_p_nom_ext @@ -210,7 +218,7 @@ constraints: where: >- (Generator_ramp_limit_up OR Generator_ramp_limit_start_up) AND NOT (Generator_committable AND Generator_p_nom_extendable AND NOT (Generator_p_nom_mod > 0)) - AND (position(snapshot, by=snapshot_period, within=period) > 0 OR (position(snapshot) == 0 AND (Generator_status_initial == 0 OR Generator_p_init))) + AND Generator_ramps_from_previous AND Generator_active expression: Generator_p - Generator_previous_p <= Generator_ramp_up_allowance Generator_p_ramp_limit_down: @@ -225,7 +233,7 @@ constraints: where: >- (Generator_ramp_limit_down OR Generator_ramp_limit_shut_down) AND NOT (Generator_committable AND Generator_p_nom_extendable AND NOT (Generator_p_nom_mod > 0)) - AND (position(snapshot, by=snapshot_period, within=period) > 0 OR (position(snapshot) == 0 AND (Generator_status_initial == 0 OR Generator_p_init))) + AND Generator_ramps_from_previous AND Generator_active expression: Generator_previous_p - Generator_p <= Generator_ramp_down_allowance @@ -281,6 +289,7 @@ assumptions: | $`\overleftarrow{u}`$ | `Generator_previous_status` over $`\Xi \times \mathcal{T} \times \mathcal{G}`$, an expression another file defines | | $`\widetilde{\mathrm{p}}^{\mathrm{nom}}`$ | `Generator_p_nom_effective` over $`\Xi \times \mathcal{G}`$, an expression another file defines | | $`\widehat{\mathrm{p}}^{\mathrm{nom}}`$ | `Generator_p_nom_committed` over $`\Xi \times \mathcal{G}`$, an expression another file defines | +| $`\mathrm{on}^{\mathrm{com,ext}}`$ | `Generator_com_ext` over $`\mathcal{T} \times \mathcal{G}`$, a mask another file defines | #### Definitions @@ -294,6 +303,12 @@ assumptions: | $`\Delta^{+}`$ | `Generator_ramp_up_allowance` over $`\Xi \times \mathcal{T} \times \mathcal{G}`$ — how far a generator may raise output between two snapshots — its ramp limit of the build while it stays on, plus its start-up ramp in the snapshot it turns on | | $`\Delta^{-}`$ | `Generator_ramp_down_allowance` over $`\Xi \times \mathcal{T} \times \mathcal{G}`$ — how far a generator may lower output between two snapshots — its ramp limit of the build while it stays on, plus its shut-down ramp in the snapshot it turns off | +#### Masks + +| Symbol | Meaning | +|---|---| +| $`\mathrm{prev}`$ | `Generator_ramps_from_previous` over $`\Xi \times \mathcal{T} \times \mathcal{G}`$ — a snapshot whose ramp reads a previous output — any snapshot but its period's first, and the horizon's first where the generator comes in off or carries an initial output | + $`\mathrm{pos}(t)`$ denotes where index $`t`$ sits along its dimension's own order — the order `shift` steps along, not the order labels sort in — counted from $`0`$. The index itself stays the coordinate, so $`t`$ compares against labels and $`\mathrm{pos}(t)`$ against positions. $`\mathrm{pos}_{\mathrm{relation}(t)}(t)`$ counts within the group a relation puts $`t`$ in: the subscript names the map, $`\mathcal{T}_{\mathrm{relation}(t)}`$ is the group it lands in, and that group has a first position of its own. @@ -303,37 +318,37 @@ $`\mathrm{pos}_{\mathrm{relation}(t)}(t)`$ counts within the group a relation pu **`Generator_p_ramp_limit_up_run_big_m`** ```math -p_{\xi,t,g} - \overleftarrow{p}_{\xi,t,g} \le \widetilde{\mathrm{ru}}_{\xi,t,g} \cdot P_{g} + \mathrm{M}_{\xi,g} - \mathrm{M}_{\xi,g} \cdot \overleftarrow{u}_{\xi,t,g} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ g \in \mathcal{G} \,:\, \mathrm{com}_{g} \wedge \mathrm{ext}_{g} \wedge \neg \left( \mathrm{p}^{\mathrm{mod}}_{g} > 0 \right) \wedge \left( \mathrm{ru}_{\xi,t,g} \text{ is defined} \vee \mathrm{ru}^{\mathrm{up}}_{\xi,g} \text{ is defined} \right) \wedge \left( \mathrm{pos}_{\mathrm{snapshot\_period}(t)}(t) > 0 \vee \mathrm{pos}(t) = 0 \wedge \left( \mathrm{u}^{0}_{\xi,g} = 0 \vee \mathrm{p}^{0}_{\xi,g} \text{ is defined} \right) \right) \wedge \mathrm{on}_{t,g} +p_{\xi,t,g} - \overleftarrow{p}_{\xi,t,g} \le \widetilde{\mathrm{ru}}_{\xi,t,g} \cdot P_{g} + \mathrm{M}_{\xi,g} - \mathrm{M}_{\xi,g} \cdot \overleftarrow{u}_{\xi,t,g} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ g \in \mathcal{G} \,:\, \mathrm{on}^{\mathrm{com,ext}}_{t,g} \wedge \left( \mathrm{ru}_{\xi,t,g} \text{ is defined} \vee \mathrm{ru}^{\mathrm{up}}_{\xi,g} \text{ is defined} \right) \wedge \mathrm{prev}_{\xi,t,g} ``` **`Generator_p_ramp_limit_up_start_big_m`** ```math -p_{\xi,t,g} - \overleftarrow{p}_{\xi,t,g} \le \widetilde{\mathrm{ru}}^{\mathrm{up}}_{\xi,g} \cdot P_{g} + \mathrm{M}_{\xi,g} - \mathrm{M}_{\xi,g} \cdot \mathit{up}_{\xi,t,g} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ g \in \mathcal{G} \,:\, \mathrm{com}_{g} \wedge \mathrm{ext}_{g} \wedge \neg \left( \mathrm{p}^{\mathrm{mod}}_{g} > 0 \right) \wedge \left( \mathrm{ru}_{\xi,t,g} \text{ is defined} \vee \mathrm{ru}^{\mathrm{up}}_{\xi,g} \text{ is defined} \right) \wedge \left( \mathrm{pos}_{\mathrm{snapshot\_period}(t)}(t) > 0 \vee \mathrm{pos}(t) = 0 \wedge \left( \mathrm{u}^{0}_{\xi,g} = 0 \vee \mathrm{p}^{0}_{\xi,g} \text{ is defined} \right) \right) \wedge \mathrm{on}_{t,g} +p_{\xi,t,g} - \overleftarrow{p}_{\xi,t,g} \le \widetilde{\mathrm{ru}}^{\mathrm{up}}_{\xi,g} \cdot P_{g} + \mathrm{M}_{\xi,g} - \mathrm{M}_{\xi,g} \cdot \mathit{up}_{\xi,t,g} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ g \in \mathcal{G} \,:\, \mathrm{on}^{\mathrm{com,ext}}_{t,g} \wedge \left( \mathrm{ru}_{\xi,t,g} \text{ is defined} \vee \mathrm{ru}^{\mathrm{up}}_{\xi,g} \text{ is defined} \right) \wedge \mathrm{prev}_{\xi,t,g} ``` **`Generator_p_ramp_limit_down_run_big_m`** ```math -\overleftarrow{p}_{\xi,t,g} - p_{\xi,t,g} \le \widetilde{\mathrm{rd}}_{\xi,t,g} \cdot P_{g} + \mathrm{M}_{\xi,g} - \mathrm{M}_{\xi,g} \cdot u_{\xi,t,g} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ g \in \mathcal{G} \,:\, \mathrm{com}_{g} \wedge \mathrm{ext}_{g} \wedge \neg \left( \mathrm{p}^{\mathrm{mod}}_{g} > 0 \right) \wedge \left( \mathrm{rd}_{\xi,t,g} \text{ is defined} \vee \mathrm{rd}^{\mathrm{dn}}_{\xi,g} \text{ is defined} \right) \wedge \left( \mathrm{pos}_{\mathrm{snapshot\_period}(t)}(t) > 0 \vee \mathrm{pos}(t) = 0 \wedge \left( \mathrm{u}^{0}_{\xi,g} = 0 \vee \mathrm{p}^{0}_{\xi,g} \text{ is defined} \right) \right) \wedge \mathrm{on}_{t,g} +\overleftarrow{p}_{\xi,t,g} - p_{\xi,t,g} \le \widetilde{\mathrm{rd}}_{\xi,t,g} \cdot P_{g} + \mathrm{M}_{\xi,g} - \mathrm{M}_{\xi,g} \cdot u_{\xi,t,g} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ g \in \mathcal{G} \,:\, \mathrm{on}^{\mathrm{com,ext}}_{t,g} \wedge \left( \mathrm{rd}_{\xi,t,g} \text{ is defined} \vee \mathrm{rd}^{\mathrm{dn}}_{\xi,g} \text{ is defined} \right) \wedge \mathrm{prev}_{\xi,t,g} ``` **`Generator_p_ramp_limit_down_shut_big_m`** ```math -\overleftarrow{p}_{\xi,t,g} - p_{\xi,t,g} \le \widetilde{\mathrm{rd}}^{\mathrm{dn}}_{\xi,g} \cdot P_{g} + \mathrm{M}_{\xi,g} - \mathrm{M}_{\xi,g} \cdot \mathit{dn}_{\xi,t,g} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ g \in \mathcal{G} \,:\, \mathrm{com}_{g} \wedge \mathrm{ext}_{g} \wedge \neg \left( \mathrm{p}^{\mathrm{mod}}_{g} > 0 \right) \wedge \left( \mathrm{rd}_{\xi,t,g} \text{ is defined} \vee \mathrm{rd}^{\mathrm{dn}}_{\xi,g} \text{ is defined} \right) \wedge \left( \mathrm{pos}_{\mathrm{snapshot\_period}(t)}(t) > 0 \vee \mathrm{pos}(t) = 0 \wedge \left( \mathrm{u}^{0}_{\xi,g} = 0 \vee \mathrm{p}^{0}_{\xi,g} \text{ is defined} \right) \right) \wedge \mathrm{on}_{t,g} +\overleftarrow{p}_{\xi,t,g} - p_{\xi,t,g} \le \widetilde{\mathrm{rd}}^{\mathrm{dn}}_{\xi,g} \cdot P_{g} + \mathrm{M}_{\xi,g} - \mathrm{M}_{\xi,g} \cdot \mathit{dn}_{\xi,t,g} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ g \in \mathcal{G} \,:\, \mathrm{on}^{\mathrm{com,ext}}_{t,g} \wedge \left( \mathrm{rd}_{\xi,t,g} \text{ is defined} \vee \mathrm{rd}^{\mathrm{dn}}_{\xi,g} \text{ is defined} \right) \wedge \mathrm{prev}_{\xi,t,g} ``` **`Generator_p_ramp_limit_up`** ```math -p_{\xi,t,g} - \overleftarrow{p}_{\xi,t,g} \le \Delta^{+}_{\xi,t,g} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ g \in \mathcal{G} \,:\, \left( \mathrm{ru}_{\xi,t,g} \text{ is defined} \vee \mathrm{ru}^{\mathrm{up}}_{\xi,g} \text{ is defined} \right) \wedge \neg \left( \mathrm{com}_{g} \wedge \mathrm{ext}_{g} \wedge \neg \left( \mathrm{p}^{\mathrm{mod}}_{g} > 0 \right) \right) \wedge \left( \mathrm{pos}_{\mathrm{snapshot\_period}(t)}(t) > 0 \vee \mathrm{pos}(t) = 0 \wedge \left( \mathrm{u}^{0}_{\xi,g} = 0 \vee \mathrm{p}^{0}_{\xi,g} \text{ is defined} \right) \right) \wedge \mathrm{on}_{t,g} +p_{\xi,t,g} - \overleftarrow{p}_{\xi,t,g} \le \Delta^{+}_{\xi,t,g} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ g \in \mathcal{G} \,:\, \left( \mathrm{ru}_{\xi,t,g} \text{ is defined} \vee \mathrm{ru}^{\mathrm{up}}_{\xi,g} \text{ is defined} \right) \wedge \neg \left( \mathrm{com}_{g} \wedge \mathrm{ext}_{g} \wedge \neg \left( \mathrm{p}^{\mathrm{mod}}_{g} > 0 \right) \right) \wedge \mathrm{prev}_{\xi,t,g} \wedge \mathrm{on}_{t,g} ``` **`Generator_p_ramp_limit_down`** ```math -\overleftarrow{p}_{\xi,t,g} - p_{\xi,t,g} \le \Delta^{-}_{\xi,t,g} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ g \in \mathcal{G} \,:\, \left( \mathrm{rd}_{\xi,t,g} \text{ is defined} \vee \mathrm{rd}^{\mathrm{dn}}_{\xi,g} \text{ is defined} \right) \wedge \neg \left( \mathrm{com}_{g} \wedge \mathrm{ext}_{g} \wedge \neg \left( \mathrm{p}^{\mathrm{mod}}_{g} > 0 \right) \right) \wedge \left( \mathrm{pos}_{\mathrm{snapshot\_period}(t)}(t) > 0 \vee \mathrm{pos}(t) = 0 \wedge \left( \mathrm{u}^{0}_{\xi,g} = 0 \vee \mathrm{p}^{0}_{\xi,g} \text{ is defined} \right) \right) \wedge \mathrm{on}_{t,g} +\overleftarrow{p}_{\xi,t,g} - p_{\xi,t,g} \le \Delta^{-}_{\xi,t,g} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ g \in \mathcal{G} \,:\, \left( \mathrm{rd}_{\xi,t,g} \text{ is defined} \vee \mathrm{rd}^{\mathrm{dn}}_{\xi,g} \text{ is defined} \right) \wedge \neg \left( \mathrm{com}_{g} \wedge \mathrm{ext}_{g} \wedge \neg \left( \mathrm{p}^{\mathrm{mod}}_{g} > 0 \right) \right) \wedge \mathrm{prev}_{\xi,t,g} \wedge \mathrm{on}_{t,g} ``` #### Definitions @@ -380,6 +395,14 @@ p_{\xi,t,g} - \overleftarrow{p}_{\xi,t,g} \le \Delta^{+}_{\xi,t,g} \qquad \foral \Delta^{-}_{\xi,t,g} = \begin{cases} \widetilde{\mathrm{rd}}_{\xi,t,g} \cdot \widehat{\mathrm{p}}^{\mathrm{nom}}_{\xi,g} \cdot u_{\xi,t,g} + \widetilde{\mathrm{rd}}^{\mathrm{dn}}_{\xi,g} \cdot \widehat{\mathrm{p}}^{\mathrm{nom}}_{\xi,g} \cdot \left( \overleftarrow{u}_{\xi,t,g} - u_{\xi,t,g} \right) & \text{if } \mathrm{com}_{g} \\ \widetilde{\mathrm{rd}}_{\xi,t,g} \cdot \widetilde{\mathrm{p}}^{\mathrm{nom}}_{\xi,g} & \text{otherwise} \end{cases} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ g \in \mathcal{G} ``` +#### Masks + +**`Generator_ramps_from_previous`** + +```math +\mathrm{prev}_{\xi,t,g} \iff \mathrm{pos}_{\mathrm{snapshot\_period}(t)}(t) > 0 \vee \mathrm{pos}(t) = 0 \wedge \left( \mathrm{u}^{0}_{\xi,g} = 0 \vee \mathrm{p}^{0}_{\xi,g} \text{ is defined} \right) \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ g \in \mathcal{G} +``` + #### Assumptions **`Generator_came_in_running_unless_committable`** diff --git a/docs/examples/pypsa/line.md b/docs/examples/pypsa/line.md index 7d980d8f8..d78db3925 100644 --- a/docs/examples/pypsa/line.md +++ b/docs/examples/pypsa/line.md @@ -145,7 +145,7 @@ variables: cost and held up by the cuts; absent, and zero in the balance, where the network is lossless dims: [scenario, snapshot, line] - where: transmission_losses AND Line_active + where: Line_lossy absence: zero bounds: lower: 0 @@ -206,6 +206,13 @@ expressions: expression: sum(Line_s * Line_cycle_weight, over=line) adds_to: Cycle_angle_sum +masks: + Line_lossy: + description: >- + a line that stands in the snapshot's period, where the run models + transmission losses + where: transmission_losses AND Line_active + constraints: Line_fix_s_lower: description: "`Line-fix-s-lower` — a fixed line carries at least the negative of its rating, the loss counted against it" @@ -250,7 +257,7 @@ constraints: Line_loss_upper: description: "`Line-loss_upper` — a line dissipates at most the loss at its rating" dims: [scenario, snapshot, line] - where: transmission_losses AND Line_active + where: Line_lossy expression: Line_loss <= Line_loss_max Line_loss_tangents_forward: description: >- @@ -259,14 +266,14 @@ constraints: `k`, or one row stacked over its `secant` axis, and this block states them all over the segment dimension dims: [scenario, snapshot, line, segment] - where: transmission_losses AND Line_active + where: Line_lossy expression: Line_loss + Line_loss_slope * Line_s >= Line_loss_offset Line_loss_tangents_reverse: description: >- `Line-loss_tangents-{k}--1`, `Line-loss_secants-neg` — the same fan mirrored, the loss depending on the flow's magnitude dims: [scenario, snapshot, line, segment] - where: transmission_losses AND Line_active + where: Line_lossy expression: Line_loss - Line_loss_slope * Line_s >= Line_loss_offset ``` @@ -342,6 +349,12 @@ constraints: | $`\mathit{Line\_injection}`$ | `Line_injection` over $`\Xi \times \mathcal{T} \times \mathcal{N}`$ | | $`\mathit{Line\_angle\_sum}`$ | `Line_angle_sum` over $`\Xi \times \mathcal{T} \times \mathcal{C}`$ | +#### Masks + +| Symbol | Meaning | +|---|---| +| $`\mathrm{on}^{s,\mathrm{lossy}}`$ | `Line_lossy` over $`\mathcal{T} \times \mathcal{K}`$ — a line that stands in the snapshot's period, where the run models transmission losses | + #### Subject to **`Line_fix_s_lower`** @@ -395,19 +408,19 @@ s_{\xi,t,k} = \mathrm{s}^{\mathrm{set}}_{\xi,t,k} \qquad \forall\, \xi \in \Xi,\ **`Line_loss_upper`** ```math -\ell_{\xi,t,k} \le \overline{\ell}_{\xi,t,k} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ k \in \mathcal{K} \,:\, \mathrm{lossy} \wedge \mathrm{on}^{s}_{t,k} +\ell_{\xi,t,k} \le \overline{\ell}_{\xi,t,k} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ k \in \mathcal{K} \,:\, \mathrm{on}^{s,\mathrm{lossy}}_{t,k} ``` **`Line_loss_tangents_forward`** ```math -\ell_{\xi,t,k} + \mathrm{a}_{\xi,t,k,e} \cdot s_{\xi,t,k} \ge \mathrm{b}_{\xi,t,k,e} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ k \in \mathcal{K},\ e \in \mathcal{E} \,:\, \mathrm{lossy} \wedge \mathrm{on}^{s}_{t,k} +\ell_{\xi,t,k} + \mathrm{a}_{\xi,t,k,e} \cdot s_{\xi,t,k} \ge \mathrm{b}_{\xi,t,k,e} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ k \in \mathcal{K},\ e \in \mathcal{E} \,:\, \mathrm{on}^{s,\mathrm{lossy}}_{t,k} ``` **`Line_loss_tangents_reverse`** ```math -\ell_{\xi,t,k} - \mathrm{a}_{\xi,t,k,e} \cdot s_{\xi,t,k} \ge \mathrm{b}_{\xi,t,k,e} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ k \in \mathcal{K},\ e \in \mathcal{E} \,:\, \mathrm{lossy} \wedge \mathrm{on}^{s}_{t,k} +\ell_{\xi,t,k} - \mathrm{a}_{\xi,t,k,e} \cdot s_{\xi,t,k} \ge \mathrm{b}_{\xi,t,k,e} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ k \in \mathcal{K},\ e \in \mathcal{E} \,:\, \mathrm{on}^{s,\mathrm{lossy}}_{t,k} ``` #### Definitions @@ -460,6 +473,14 @@ s_{\xi,t,k} = \mathrm{s}^{\mathrm{set}}_{\xi,t,k} \qquad \forall\, \xi \in \Xi,\ \mathit{Line\_angle\_sum}_{\xi,t,c} = \sum_{k \in \mathcal{K}} s_{\xi,t,k} \cdot \mathrm{x}_{k,c} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ c \in \mathcal{C} ``` +#### Masks + +**`Line_lossy`** + +```math +\mathrm{on}^{s,\mathrm{lossy}}_{t,k} \iff \mathrm{lossy} \wedge \mathrm{on}^{s}_{t,k} \qquad \forall\, t \in \mathcal{T},\ k \in \mathcal{K} +``` + #### Variable domains **`Line_s`** @@ -471,7 +492,7 @@ s_{\xi,t,k} \in \mathbb{R} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ k **`Line_loss`** ```math -\ell_{\xi,t,k} \ge 0 \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ k \in \mathcal{K} \,:\, \mathrm{lossy} \wedge \mathrm{on}^{s}_{t,k} +\ell_{\xi,t,k} \ge 0 \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ k \in \mathcal{K} \,:\, \mathrm{on}^{s,\mathrm{lossy}}_{t,k} ``` **`Line_s_nom_ext`** diff --git a/docs/examples/pypsa/link.md b/docs/examples/pypsa/link.md index 77f20182d..966f8e9f2 100644 --- a/docs/examples/pypsa/link.md +++ b/docs/examples/pypsa/link.md @@ -270,6 +270,13 @@ expressions: + sum(Link_output_arrival, by=Link_output_bus, over=link_output, into=bus) adds_to: Bus_injection +masks: + Link_committed: + description: >- + a committable link that stands in the snapshot's period — every + unit-commitment row's set + where: Link_committable AND Link_active + constraints: Link_fix_p_lower: description: "`Link-fix-p-lower` — a fixed link carries at least its minimum, negative for the other way" @@ -412,6 +419,12 @@ assumptions: | $`\mathit{Link\_additions}`$ | `Link_additions` over $`\mathcal{Y} \times \mathcal{I}`$ | | $`\mathit{Link\_injection}`$ | `Link_injection` over $`\Xi \times \mathcal{T} \times \mathcal{N}`$ | +#### Masks + +| Symbol | Meaning | +|---|---| +| $`\mathrm{on}^{f,\mathrm{com}}`$ | `Link_committed` over $`\mathcal{T} \times \mathcal{L}`$ — a committable link that stands in the snapshot's period — every unit-commitment row's set | + $`t \ominus k`$ denotes cyclic translation: index $`t-k`$ taken modulo the size of the dimension (`roll`). Plain $`t-k`$ (`shift`) has no wraparound — terms translated past the edge are simply absent. $`t \boxminus_{v} k`$ denotes translation with $`v`$ standing where index $`t-k`$ leaves the dimension (`shift(edge=v)`), so the row at that boundary is built and carries $`v`$ rather than being dropped. @@ -536,6 +549,14 @@ f_{\xi,t,l} = \mathrm{f}^{\mathrm{set}}_{\xi,t,l} \qquad \forall\, \xi \in \Xi,\ \mathit{Link\_injection}_{\xi,t,n} = -\left( \sum_{l \in \mathcal{L} \,:\, \mathrm{Link\_bus0}(l) = n} f_{\xi,t,l} \right) + \sum_{o \in \mathcal{O} \,:\, \mathrm{Link\_output\_bus}(o) = n} \overrightarrow{f}_{\xi,t,o} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ n \in \mathcal{N} ``` +#### Masks + +**`Link_committed`** + +```math +\mathrm{on}^{f,\mathrm{com}}_{t,l} \iff \mathrm{com}^{f}_{l} \wedge \mathrm{on}^{f}_{t,l} \qquad \forall\, t \in \mathcal{T},\ l \in \mathcal{L} +``` + #### Variable domains **`Link_p`** diff --git a/docs/examples/pypsa/link_commitment.md b/docs/examples/pypsa/link_commitment.md index 0f76a073c..fbdec69e6 100644 --- a/docs/examples/pypsa/link_commitment.md +++ b/docs/examples/pypsa/link_commitment.md @@ -78,21 +78,21 @@ variables: the rows below cap at one, or at the module count where the build is modular dims: [scenario, snapshot, link] - where: Link_committable AND Link_active + where: Link_committed domain: integer bounds: lower: 0 Link_start_up: description: "`Link-start_up` — how much of a committable link turns on this snapshot, capped as the status is" dims: [scenario, snapshot, link] - where: Link_committable AND Link_active + where: Link_committed domain: integer bounds: lower: 0 Link_shut_down: description: "`Link-shut_down` — how much of a committable link turns off this snapshot, capped as the status is" dims: [scenario, snapshot, link] - where: Link_committable AND Link_active + where: Link_committed domain: integer bounds: lower: 0 @@ -118,6 +118,8 @@ given: Link_p_nom_ext: { dims: [link] } expressions: scenario_opex: { dims: [scenario] } + masks: + Link_committed: { dims: [snapshot, link] } expressions: Link_previous_status: @@ -135,26 +137,38 @@ expressions: + sum(sum(Link_shut_down * Link_shut_down_cost, over=link), over=snapshot) adds_to: scenario_opex +masks: + Link_com_ext: + description: >- + a committable link with an extendable, non-modular build that stands in + the snapshot's period — PyPSA's `com-ext` rows, whose status is relaxed + against the chosen build + where: >- + Link_committable + AND Link_p_nom_extendable + AND NOT (Link_p_nom_mod > 0) + AND Link_active + constraints: Link_com_p_lower: description: "`Link-com-p-lower` — a committed link flows at least its minimum; off, at least nothing" dims: [scenario, snapshot, link] - where: Link_committable AND not Link_p_nom_extendable AND Link_active + where: Link_committed AND NOT Link_p_nom_extendable expression: Link_p >= Link_p_min_pu * Link_p_nom * (Link_status - Link_maintenance_pu * Link_maintenance_status) Link_com_p_upper: description: "`Link-com-p-upper` — a committed link flows at most what is available; off, at most nothing" dims: [scenario, snapshot, link] - where: Link_committable AND not Link_p_nom_extendable AND Link_active + where: Link_committed AND NOT Link_p_nom_extendable expression: Link_p <= Link_p_max_pu * Link_p_nom * (Link_status - Link_maintenance_pu * Link_maintenance_status) Link_com_transition_start_up: description: "`Link-com-transition-start-up` — turning on is a start, counted against the state the link carried into the snapshot" dims: [scenario, snapshot, link] - where: Link_committable AND Link_active + where: Link_committed expression: Link_start_up >= Link_status - Link_previous_status Link_com_transition_shut_down: description: "`Link-com-transition-shut-down` — turning off is a stop, counted against the state the link carried into the snapshot" dims: [scenario, snapshot, link] - where: Link_committable AND Link_active + where: Link_committed expression: Link_shut_down >= Link_previous_status - Link_status Link_com_up_time: description: >- @@ -162,7 +176,7 @@ constraints: is still on. The first snapshot's share of the window is the brought-in up time's, which the must-stay-up mask carries dims: [scenario, snapshot, link] - where: Link_committable AND Link_min_up_time > 0 AND position(snapshot) > 0 AND Link_active + where: Link_committed AND Link_min_up_time > 0 AND position(snapshot) > 0 expression: sum_back(Link_start_up, along=snapshot, window=Link_min_up_time) <= Link_status Link_com_down_time: description: >- @@ -170,38 +184,38 @@ constraints: time is still off. The first snapshot's share of the window is the brought-in down time's, which the must-stay-down mask carries dims: [scenario, snapshot, link] - where: Link_committable AND Link_min_down_time > 0 AND position(snapshot) > 0 AND Link_active + where: Link_committed AND Link_min_down_time > 0 AND position(snapshot) > 0 expression: sum_back(Link_shut_down, along=snapshot, window=Link_min_down_time) <= 1 - Link_status Link_com_status_must_stay_up: description: "`Link-com-status-min_up_time_must_stay_up` — a link still serving the up time it brought in stays on" dims: [scenario, snapshot, link] - where: Link_committable AND Link_must_stay_up AND Link_active + where: Link_committed AND Link_must_stay_up expression: Link_status == 1 Link_com_status_must_stay_down: description: >- `Link-com-status-min_down_time_must_stay_up` — a link still serving the down time it brought in stays off; PyPSA names the row `_must_stay_up` dims: [scenario, snapshot, link] - where: Link_committable AND Link_must_stay_down AND Link_active + where: Link_committed AND Link_must_stay_down expression: Link_status == 0 Link_com_ext_p_upper_cap: description: >- `Link-com-ext-p-upper-cap` — a committed extendable link flows at most what is available of the chosen build, whatever its status dims: [scenario, snapshot, link] - where: Link_committable AND Link_p_nom_extendable AND NOT (Link_p_nom_mod > 0) AND Link_active + where: Link_com_ext expression: Link_p <= Link_p_max_pu * (Link_p_nom_ext - Link_maintenance_pu * Link_maintenance_capacity) Link_com_ext_p_upper_big_m: description: "`Link-com-ext-p-upper-bigM` — off, a link flows nothing; on, the big M is no bound" dims: [scenario, snapshot, link] - where: Link_committable AND Link_p_nom_extendable AND NOT (Link_p_nom_mod > 0) AND Link_active + where: Link_com_ext expression: Link_p <= Link_big_m * Link_status Link_com_ext_p_lower: description: >- `Link-com-ext-p-lower` — a committed extendable link flows at least its minimum of the chosen build; off, the big M releases the row dims: [scenario, snapshot, link] - where: Link_committable AND Link_p_nom_extendable AND NOT (Link_p_nom_mod > 0) AND Link_active + where: Link_com_ext expression: >- Link_p >= Link_p_min_pu * (Link_p_nom_ext - Link_maintenance_pu * Link_maintenance_capacity) @@ -212,23 +226,21 @@ constraints: negative, flow is also plainly non-negative, a row the big-M lower cannot assert while the link is off dims: [scenario, snapshot, link] - where: >- - Link_committable AND Link_p_nom_extendable - AND Link_p_min_pu_nonneg AND NOT (Link_p_nom_mod > 0) AND Link_active + where: Link_com_ext AND Link_p_min_pu_nonneg expression: Link_p >= 0 Link_com_mod_p_lower: description: >- `Link-com-mod-p-lower` — a committed modular link flows at least its minimum of one module, whether the build is fixed or a decision dims: [scenario, snapshot, link] - where: Link_committable AND Link_p_nom_mod > 0 AND Link_active + where: Link_committed AND Link_p_nom_mod > 0 expression: Link_p >= Link_p_min_pu * Link_p_nom_mod * (Link_status - Link_maintenance_pu * Link_maintenance_status) Link_com_mod_p_upper: description: >- `Link-com-mod-p-upper` — a committed modular link flows at most one module's share, whether the build is fixed or a decision dims: [scenario, snapshot, link] - where: Link_committable AND Link_p_nom_mod > 0 AND Link_active + where: Link_committed AND Link_p_nom_mod > 0 expression: Link_p <= Link_p_max_pu * Link_p_nom_mod * (Link_status - Link_maintenance_pu * Link_maintenance_status) Link_status_p_fixed_upper: description: >- @@ -236,7 +248,7 @@ constraints: place, an explicit row as PyPSA writes it: one where the build is not modular, and the fixed build's whole count of modules where it is dims: [scenario, snapshot, link] - where: Link_committable AND NOT (Link_p_nom_extendable AND Link_p_nom_mod > 0) AND Link_active + where: Link_committed AND NOT (Link_p_nom_extendable AND Link_p_nom_mod > 0) expression: Link_status <= Link_modules_installed Link_start_up_p_fixed_upper: description: >- @@ -244,7 +256,7 @@ constraints: place, an explicit row as PyPSA writes it: one where the build is not modular, and the fixed build's whole count of modules where it is dims: [scenario, snapshot, link] - where: Link_committable AND NOT (Link_p_nom_extendable AND Link_p_nom_mod > 0) AND Link_active + where: Link_committed AND NOT (Link_p_nom_extendable AND Link_p_nom_mod > 0) expression: Link_start_up <= Link_modules_installed Link_shut_down_p_fixed_upper: description: >- @@ -252,22 +264,22 @@ constraints: place, an explicit row as PyPSA writes it: one where the build is not modular, and the fixed build's whole count of modules where it is dims: [scenario, snapshot, link] - where: Link_committable AND NOT (Link_p_nom_extendable AND Link_p_nom_mod > 0) AND Link_active + where: Link_committed AND NOT (Link_p_nom_extendable AND Link_p_nom_mod > 0) expression: Link_shut_down <= Link_modules_installed Link_status_p_nom_variable_upper: description: "`Link-status-p_nom-variable-upper` — a modular link is on only where a module is built" dims: [scenario, snapshot, link] - where: Link_committable AND Link_p_nom_extendable AND Link_p_nom_mod > 0 AND Link_active + where: Link_committed AND Link_p_nom_extendable AND Link_p_nom_mod > 0 expression: Link_status <= Link_n_mod Link_start_up_p_nom_variable_upper: description: "`Link-start_up-p_nom-variable-upper` — a modular link starts only where a module is built" dims: [scenario, snapshot, link] - where: Link_committable AND Link_p_nom_extendable AND Link_p_nom_mod > 0 AND Link_active + where: Link_committed AND Link_p_nom_extendable AND Link_p_nom_mod > 0 expression: Link_start_up <= Link_n_mod Link_shut_down_p_nom_variable_upper: description: "`Link-shut_down-p_nom-variable-upper` — a modular link stops only where a module is built" dims: [scenario, snapshot, link] - where: Link_committable AND Link_p_nom_extendable AND Link_p_nom_mod > 0 AND Link_active + where: Link_committed AND Link_p_nom_extendable AND Link_p_nom_mod > 0 expression: Link_shut_down <= Link_n_mod ``` @@ -324,6 +336,7 @@ constraints: | $`\mu^{f,u}`$ | `Link_maintenance_status` over $`\Xi \times \mathcal{T} \times \mathcal{L}`$ | | $`F`$ | `Link_p_nom_ext` over $`\mathcal{L}`$ | | $`\mathit{scenario\_opex}`$ | `scenario_opex` over $`\Xi`$, an expression this file adds `Link_commitment_opex` to | +| $`\mathrm{on}^{f,\mathrm{com}}`$ | `Link_committed` over $`\mathcal{T} \times \mathcal{L}`$, a mask another file defines | #### Definitions @@ -332,6 +345,12 @@ constraints: | $`\overleftarrow{u}^{f}`$ | `Link_previous_status` over $`\Xi \times \mathcal{T} \times \mathcal{L}`$ — the commitment state a link carries into a snapshot — the state it brought into the horizon at the first, the previous snapshot's after that | | $`\mathit{Link\_commitment\_opex}`$ | `Link_commitment_opex` over $`\Xi`$ | +#### Masks + +| Symbol | Meaning | +|---|---| +| $`\mathrm{on}^{f,\mathrm{com,ext}}`$ | `Link_com_ext` over $`\mathcal{T} \times \mathcal{L}`$ — a committable link with an extendable, non-modular build that stands in the snapshot's period — PyPSA's `com-ext` rows, whose status is relaxed against the chosen build | + $`\mathrm{pos}(t)`$ denotes where index $`t`$ sits along its dimension's own order — the order `shift` steps along, not the order labels sort in — counted from $`0`$. The index itself stays the coordinate, so $`t`$ compares against labels and $`\mathrm{pos}(t)`$ against positions. #### Subject to @@ -339,121 +358,121 @@ $`\mathrm{pos}(t)`$ denotes where index $`t`$ sits along its dimension's own ord **`Link_com_p_lower`** ```math -f_{\xi,t,l} \ge \underline{\mathrm{f}}_{\xi,t,l} \cdot \mathrm{f}^{\mathrm{nom}}_{\xi,l} \cdot \left( u^{f}_{\xi,t,l} - \gamma^{f}_{\xi,l} \cdot \mu^{f,u}_{\xi,t,l} \right) \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ l \in \mathcal{L} \,:\, \mathrm{com}^{f}_{l} \wedge \neg \mathrm{ext}^{f}_{l} \wedge \mathrm{on}^{f}_{t,l} +f_{\xi,t,l} \ge \underline{\mathrm{f}}_{\xi,t,l} \cdot \mathrm{f}^{\mathrm{nom}}_{\xi,l} \cdot \left( u^{f}_{\xi,t,l} - \gamma^{f}_{\xi,l} \cdot \mu^{f,u}_{\xi,t,l} \right) \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ l \in \mathcal{L} \,:\, \mathrm{on}^{f,\mathrm{com}}_{t,l} \wedge \neg \mathrm{ext}^{f}_{l} ``` **`Link_com_p_upper`** ```math -f_{\xi,t,l} \le \overline{\mathrm{f}}_{\xi,t,l} \cdot \mathrm{f}^{\mathrm{nom}}_{\xi,l} \cdot \left( u^{f}_{\xi,t,l} - \gamma^{f}_{\xi,l} \cdot \mu^{f,u}_{\xi,t,l} \right) \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ l \in \mathcal{L} \,:\, \mathrm{com}^{f}_{l} \wedge \neg \mathrm{ext}^{f}_{l} \wedge \mathrm{on}^{f}_{t,l} +f_{\xi,t,l} \le \overline{\mathrm{f}}_{\xi,t,l} \cdot \mathrm{f}^{\mathrm{nom}}_{\xi,l} \cdot \left( u^{f}_{\xi,t,l} - \gamma^{f}_{\xi,l} \cdot \mu^{f,u}_{\xi,t,l} \right) \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ l \in \mathcal{L} \,:\, \mathrm{on}^{f,\mathrm{com}}_{t,l} \wedge \neg \mathrm{ext}^{f}_{l} ``` **`Link_com_transition_start_up`** ```math -\mathit{up}^{f}_{\xi,t,l} \ge u^{f}_{\xi,t,l} - \overleftarrow{u}^{f}_{\xi,t,l} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ l \in \mathcal{L} \,:\, \mathrm{com}^{f}_{l} \wedge \mathrm{on}^{f}_{t,l} +\mathit{up}^{f}_{\xi,t,l} \ge u^{f}_{\xi,t,l} - \overleftarrow{u}^{f}_{\xi,t,l} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ l \in \mathcal{L} \,:\, \mathrm{on}^{f,\mathrm{com}}_{t,l} ``` **`Link_com_transition_shut_down`** ```math -\mathit{dn}^{f}_{\xi,t,l} \ge \overleftarrow{u}^{f}_{\xi,t,l} - u^{f}_{\xi,t,l} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ l \in \mathcal{L} \,:\, \mathrm{com}^{f}_{l} \wedge \mathrm{on}^{f}_{t,l} +\mathit{dn}^{f}_{\xi,t,l} \ge \overleftarrow{u}^{f}_{\xi,t,l} - u^{f}_{\xi,t,l} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ l \in \mathcal{L} \,:\, \mathrm{on}^{f,\mathrm{com}}_{t,l} ``` **`Link_com_up_time`** ```math -\sum_{t' \in \mathcal{T} \,:\, 0 \le t - t' < \mathrm{UT}^{f}} \mathit{up}^{f}_{\xi,t',l} \le u^{f}_{\xi,t,l} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ l \in \mathcal{L} \,:\, \mathrm{com}^{f}_{l} \wedge \mathrm{UT}^{f}_{\xi,l} > 0 \wedge \mathrm{pos}(t) > 0 \wedge \mathrm{on}^{f}_{t,l} +\sum_{t' \in \mathcal{T} \,:\, 0 \le t - t' < \mathrm{UT}^{f}} \mathit{up}^{f}_{\xi,t',l} \le u^{f}_{\xi,t,l} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ l \in \mathcal{L} \,:\, \mathrm{on}^{f,\mathrm{com}}_{t,l} \wedge \mathrm{UT}^{f}_{\xi,l} > 0 \wedge \mathrm{pos}(t) > 0 ``` **`Link_com_down_time`** ```math -\sum_{t' \in \mathcal{T} \,:\, 0 \le t - t' < \mathrm{DT}^{f}} \mathit{dn}^{f}_{\xi,t',l} \le 1 - u^{f}_{\xi,t,l} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ l \in \mathcal{L} \,:\, \mathrm{com}^{f}_{l} \wedge \mathrm{DT}^{f}_{\xi,l} > 0 \wedge \mathrm{pos}(t) > 0 \wedge \mathrm{on}^{f}_{t,l} +\sum_{t' \in \mathcal{T} \,:\, 0 \le t - t' < \mathrm{DT}^{f}} \mathit{dn}^{f}_{\xi,t',l} \le 1 - u^{f}_{\xi,t,l} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ l \in \mathcal{L} \,:\, \mathrm{on}^{f,\mathrm{com}}_{t,l} \wedge \mathrm{DT}^{f}_{\xi,l} > 0 \wedge \mathrm{pos}(t) > 0 ``` **`Link_com_status_must_stay_up`** ```math -u^{f}_{\xi,t,l} = 1 \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ l \in \mathcal{L} \,:\, \mathrm{com}^{f}_{l} \wedge \mathrm{hold}^{f}_{\xi,t,l} \wedge \mathrm{on}^{f}_{t,l} +u^{f}_{\xi,t,l} = 1 \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ l \in \mathcal{L} \,:\, \mathrm{on}^{f,\mathrm{com}}_{t,l} \wedge \mathrm{hold}^{f}_{\xi,t,l} ``` **`Link_com_status_must_stay_down`** ```math -u^{f}_{\xi,t,l} = 0 \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ l \in \mathcal{L} \,:\, \mathrm{com}^{f}_{l} \wedge \mathrm{rest}^{f}_{\xi,t,l} \wedge \mathrm{on}^{f}_{t,l} +u^{f}_{\xi,t,l} = 0 \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ l \in \mathcal{L} \,:\, \mathrm{on}^{f,\mathrm{com}}_{t,l} \wedge \mathrm{rest}^{f}_{\xi,t,l} ``` **`Link_com_ext_p_upper_cap`** ```math -f_{\xi,t,l} \le \overline{\mathrm{f}}_{\xi,t,l} \cdot \left( F_{l} - \gamma^{f}_{\xi,l} \cdot \mu^{f,\mathrm{nom}}_{\xi,t,l} \right) \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ l \in \mathcal{L} \,:\, \mathrm{com}^{f}_{l} \wedge \mathrm{ext}^{f}_{l} \wedge \neg \left( \mathrm{f}^{\mathrm{mod}}_{l} > 0 \right) \wedge \mathrm{on}^{f}_{t,l} +f_{\xi,t,l} \le \overline{\mathrm{f}}_{\xi,t,l} \cdot \left( F_{l} - \gamma^{f}_{\xi,l} \cdot \mu^{f,\mathrm{nom}}_{\xi,t,l} \right) \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ l \in \mathcal{L} \,:\, \mathrm{on}^{f,\mathrm{com,ext}}_{t,l} ``` **`Link_com_ext_p_upper_big_m`** ```math -f_{\xi,t,l} \le \mathrm{M}^{f}_{\xi,l} \cdot u^{f}_{\xi,t,l} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ l \in \mathcal{L} \,:\, \mathrm{com}^{f}_{l} \wedge \mathrm{ext}^{f}_{l} \wedge \neg \left( \mathrm{f}^{\mathrm{mod}}_{l} > 0 \right) \wedge \mathrm{on}^{f}_{t,l} +f_{\xi,t,l} \le \mathrm{M}^{f}_{\xi,l} \cdot u^{f}_{\xi,t,l} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ l \in \mathcal{L} \,:\, \mathrm{on}^{f,\mathrm{com,ext}}_{t,l} ``` **`Link_com_ext_p_lower`** ```math -f_{\xi,t,l} \ge \underline{\mathrm{f}}_{\xi,t,l} \cdot \left( F_{l} - \gamma^{f}_{\xi,l} \cdot \mu^{f,\mathrm{nom}}_{\xi,t,l} \right) + \mathrm{M}^{f}_{\xi,l} \cdot u^{f}_{\xi,t,l} - \mathrm{M}^{f}_{\xi,l} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ l \in \mathcal{L} \,:\, \mathrm{com}^{f}_{l} \wedge \mathrm{ext}^{f}_{l} \wedge \neg \left( \mathrm{f}^{\mathrm{mod}}_{l} > 0 \right) \wedge \mathrm{on}^{f}_{t,l} +f_{\xi,t,l} \ge \underline{\mathrm{f}}_{\xi,t,l} \cdot \left( F_{l} - \gamma^{f}_{\xi,l} \cdot \mu^{f,\mathrm{nom}}_{\xi,t,l} \right) + \mathrm{M}^{f}_{\xi,l} \cdot u^{f}_{\xi,t,l} - \mathrm{M}^{f}_{\xi,l} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ l \in \mathcal{L} \,:\, \mathrm{on}^{f,\mathrm{com,ext}}_{t,l} ``` **`Link_com_ext_p_lower_nonneg`** ```math -f_{\xi,t,l} \ge 0 \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ l \in \mathcal{L} \,:\, \mathrm{com}^{f}_{l} \wedge \mathrm{ext}^{f}_{l} \wedge \mathrm{nonneg}^{f}_{l} \wedge \neg \left( \mathrm{f}^{\mathrm{mod}}_{l} > 0 \right) \wedge \mathrm{on}^{f}_{t,l} +f_{\xi,t,l} \ge 0 \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ l \in \mathcal{L} \,:\, \mathrm{on}^{f,\mathrm{com,ext}}_{t,l} \wedge \mathrm{nonneg}^{f}_{l} ``` **`Link_com_mod_p_lower`** ```math -f_{\xi,t,l} \ge \underline{\mathrm{f}}_{\xi,t,l} \cdot \mathrm{f}^{\mathrm{mod}}_{l} \cdot \left( u^{f}_{\xi,t,l} - \gamma^{f}_{\xi,l} \cdot \mu^{f,u}_{\xi,t,l} \right) \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ l \in \mathcal{L} \,:\, \mathrm{com}^{f}_{l} \wedge \mathrm{f}^{\mathrm{mod}}_{l} > 0 \wedge \mathrm{on}^{f}_{t,l} +f_{\xi,t,l} \ge \underline{\mathrm{f}}_{\xi,t,l} \cdot \mathrm{f}^{\mathrm{mod}}_{l} \cdot \left( u^{f}_{\xi,t,l} - \gamma^{f}_{\xi,l} \cdot \mu^{f,u}_{\xi,t,l} \right) \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ l \in \mathcal{L} \,:\, \mathrm{on}^{f,\mathrm{com}}_{t,l} \wedge \mathrm{f}^{\mathrm{mod}}_{l} > 0 ``` **`Link_com_mod_p_upper`** ```math -f_{\xi,t,l} \le \overline{\mathrm{f}}_{\xi,t,l} \cdot \mathrm{f}^{\mathrm{mod}}_{l} \cdot \left( u^{f}_{\xi,t,l} - \gamma^{f}_{\xi,l} \cdot \mu^{f,u}_{\xi,t,l} \right) \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ l \in \mathcal{L} \,:\, \mathrm{com}^{f}_{l} \wedge \mathrm{f}^{\mathrm{mod}}_{l} > 0 \wedge \mathrm{on}^{f}_{t,l} +f_{\xi,t,l} \le \overline{\mathrm{f}}_{\xi,t,l} \cdot \mathrm{f}^{\mathrm{mod}}_{l} \cdot \left( u^{f}_{\xi,t,l} - \gamma^{f}_{\xi,l} \cdot \mu^{f,u}_{\xi,t,l} \right) \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ l \in \mathcal{L} \,:\, \mathrm{on}^{f,\mathrm{com}}_{t,l} \wedge \mathrm{f}^{\mathrm{mod}}_{l} > 0 ``` **`Link_status_p_fixed_upper`** ```math -u^{f}_{\xi,t,l} \le \mathrm{N}^{f,\mathrm{fix}}_{\xi,l} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ l \in \mathcal{L} \,:\, \mathrm{com}^{f}_{l} \wedge \neg \left( \mathrm{ext}^{f}_{l} \wedge \mathrm{f}^{\mathrm{mod}}_{l} > 0 \right) \wedge \mathrm{on}^{f}_{t,l} +u^{f}_{\xi,t,l} \le \mathrm{N}^{f,\mathrm{fix}}_{\xi,l} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ l \in \mathcal{L} \,:\, \mathrm{on}^{f,\mathrm{com}}_{t,l} \wedge \neg \left( \mathrm{ext}^{f}_{l} \wedge \mathrm{f}^{\mathrm{mod}}_{l} > 0 \right) ``` **`Link_start_up_p_fixed_upper`** ```math -\mathit{up}^{f}_{\xi,t,l} \le \mathrm{N}^{f,\mathrm{fix}}_{\xi,l} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ l \in \mathcal{L} \,:\, \mathrm{com}^{f}_{l} \wedge \neg \left( \mathrm{ext}^{f}_{l} \wedge \mathrm{f}^{\mathrm{mod}}_{l} > 0 \right) \wedge \mathrm{on}^{f}_{t,l} +\mathit{up}^{f}_{\xi,t,l} \le \mathrm{N}^{f,\mathrm{fix}}_{\xi,l} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ l \in \mathcal{L} \,:\, \mathrm{on}^{f,\mathrm{com}}_{t,l} \wedge \neg \left( \mathrm{ext}^{f}_{l} \wedge \mathrm{f}^{\mathrm{mod}}_{l} > 0 \right) ``` **`Link_shut_down_p_fixed_upper`** ```math -\mathit{dn}^{f}_{\xi,t,l} \le \mathrm{N}^{f,\mathrm{fix}}_{\xi,l} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ l \in \mathcal{L} \,:\, \mathrm{com}^{f}_{l} \wedge \neg \left( \mathrm{ext}^{f}_{l} \wedge \mathrm{f}^{\mathrm{mod}}_{l} > 0 \right) \wedge \mathrm{on}^{f}_{t,l} +\mathit{dn}^{f}_{\xi,t,l} \le \mathrm{N}^{f,\mathrm{fix}}_{\xi,l} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ l \in \mathcal{L} \,:\, \mathrm{on}^{f,\mathrm{com}}_{t,l} \wedge \neg \left( \mathrm{ext}^{f}_{l} \wedge \mathrm{f}^{\mathrm{mod}}_{l} > 0 \right) ``` **`Link_status_p_nom_variable_upper`** ```math -u^{f}_{\xi,t,l} \le N^{f}_{l} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ l \in \mathcal{L} \,:\, \mathrm{com}^{f}_{l} \wedge \mathrm{ext}^{f}_{l} \wedge \mathrm{f}^{\mathrm{mod}}_{l} > 0 \wedge \mathrm{on}^{f}_{t,l} +u^{f}_{\xi,t,l} \le N^{f}_{l} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ l \in \mathcal{L} \,:\, \mathrm{on}^{f,\mathrm{com}}_{t,l} \wedge \mathrm{ext}^{f}_{l} \wedge \mathrm{f}^{\mathrm{mod}}_{l} > 0 ``` **`Link_start_up_p_nom_variable_upper`** ```math -\mathit{up}^{f}_{\xi,t,l} \le N^{f}_{l} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ l \in \mathcal{L} \,:\, \mathrm{com}^{f}_{l} \wedge \mathrm{ext}^{f}_{l} \wedge \mathrm{f}^{\mathrm{mod}}_{l} > 0 \wedge \mathrm{on}^{f}_{t,l} +\mathit{up}^{f}_{\xi,t,l} \le N^{f}_{l} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ l \in \mathcal{L} \,:\, \mathrm{on}^{f,\mathrm{com}}_{t,l} \wedge \mathrm{ext}^{f}_{l} \wedge \mathrm{f}^{\mathrm{mod}}_{l} > 0 ``` **`Link_shut_down_p_nom_variable_upper`** ```math -\mathit{dn}^{f}_{\xi,t,l} \le N^{f}_{l} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ l \in \mathcal{L} \,:\, \mathrm{com}^{f}_{l} \wedge \mathrm{ext}^{f}_{l} \wedge \mathrm{f}^{\mathrm{mod}}_{l} > 0 \wedge \mathrm{on}^{f}_{t,l} +\mathit{dn}^{f}_{\xi,t,l} \le N^{f}_{l} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ l \in \mathcal{L} \,:\, \mathrm{on}^{f,\mathrm{com}}_{t,l} \wedge \mathrm{ext}^{f}_{l} \wedge \mathrm{f}^{\mathrm{mod}}_{l} > 0 ``` #### Definitions @@ -470,23 +489,31 @@ u^{f}_{\xi,t,l} \le N^{f}_{l} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ \mathit{Link\_commitment\_opex}_{\xi} = \sum_{t \in \mathcal{T}} \sum_{l \in \mathcal{L}} u^{f}_{\xi,t,l} \cdot \mathrm{c}^{f,\mathrm{on}}_{\xi,t,l} \cdot \mathrm{w}_{t} \cdot \mathrm{w}^{y}_{\mathrm{snapshot\_period}(t)} + \sum_{t \in \mathcal{T}} \sum_{l \in \mathcal{L}} \mathit{up}^{f}_{\xi,t,l} \cdot \mathrm{c}^{f,\mathrm{up}}_{\xi,l} + \sum_{t \in \mathcal{T}} \sum_{l \in \mathcal{L}} \mathit{dn}^{f}_{\xi,t,l} \cdot \mathrm{c}^{f,\mathrm{dn}}_{\xi,l} \qquad \forall\, \xi \in \Xi ``` +#### Masks + +**`Link_com_ext`** + +```math +\mathrm{on}^{f,\mathrm{com,ext}}_{t,l} \iff \mathrm{com}^{f}_{l} \wedge \mathrm{ext}^{f}_{l} \wedge \neg \left( \mathrm{f}^{\mathrm{mod}}_{l} > 0 \right) \wedge \mathrm{on}^{f}_{t,l} \qquad \forall\, t \in \mathcal{T},\ l \in \mathcal{L} +``` + #### Variable domains **`Link_status`** ```math -u^{f}_{\xi,t,l} \ge 0, u^{f}_{\xi,t,l} \in \mathbb{Z} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ l \in \mathcal{L} \,:\, \mathrm{com}^{f}_{l} \wedge \mathrm{on}^{f}_{t,l} +u^{f}_{\xi,t,l} \ge 0, u^{f}_{\xi,t,l} \in \mathbb{Z} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ l \in \mathcal{L} \,:\, \mathrm{on}^{f,\mathrm{com}}_{t,l} ``` **`Link_start_up`** ```math -\mathit{up}^{f}_{\xi,t,l} \ge 0, \mathit{up}^{f}_{\xi,t,l} \in \mathbb{Z} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ l \in \mathcal{L} \,:\, \mathrm{com}^{f}_{l} \wedge \mathrm{on}^{f}_{t,l} +\mathit{up}^{f}_{\xi,t,l} \ge 0, \mathit{up}^{f}_{\xi,t,l} \in \mathbb{Z} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ l \in \mathcal{L} \,:\, \mathrm{on}^{f,\mathrm{com}}_{t,l} ``` **`Link_shut_down`** ```math -\mathit{dn}^{f}_{\xi,t,l} \ge 0, \mathit{dn}^{f}_{\xi,t,l} \in \mathbb{Z} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ l \in \mathcal{L} \,:\, \mathrm{com}^{f}_{l} \wedge \mathrm{on}^{f}_{t,l} +\mathit{dn}^{f}_{\xi,t,l} \ge 0, \mathit{dn}^{f}_{\xi,t,l} \in \mathbb{Z} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ l \in \mathcal{L} \,:\, \mathrm{on}^{f,\mathrm{com}}_{t,l} ``` diff --git a/docs/examples/pypsa/link_maintenance.md b/docs/examples/pypsa/link_maintenance.md index d8b5ed3de..419d527dd 100644 --- a/docs/examples/pypsa/link_maintenance.md +++ b/docs/examples/pypsa/link_maintenance.md @@ -81,9 +81,7 @@ variables: `Link-maintenance_capacity` — the chosen build while in maintenance, zero otherwise: the product the `maintcap` rows linearize dims: [scenario, snapshot, link] - where: >- - Link_maintainable AND Link_p_nom_extendable - AND NOT (Link_committable AND Link_p_nom_mod > 0) AND Link_active + where: Link_maint_ext absence: zero bounds: lower: 0 @@ -93,9 +91,7 @@ variables: otherwise: the product the `maint-status` rows linearize, so a unit in maintenance may also be off dims: [scenario, snapshot, link] - where: >- - Link_maintainable AND Link_committable - AND NOT (Link_p_nom_extendable AND NOT (Link_p_nom_mod > 0)) AND Link_active + where: Link_maintainable AND Link_committed AND NOT (Link_p_nom_extendable AND NOT (Link_p_nom_mod > 0)) absence: zero bounds: lower: 0 @@ -112,6 +108,20 @@ given: variables: Link_status: { dims: [scenario, snapshot, link], domain: integer } Link_p_nom_ext: { dims: [link] } + masks: + Link_committed: { dims: [snapshot, link] } + +masks: + Link_maint_ext: + description: >- + a maintainable link with an extendable build, unless it is committable + and modular, that stands in the snapshot's period — the maintenance rows + against the chosen build + where: >- + Link_maintainable + AND Link_p_nom_extendable + AND NOT (Link_committable AND Link_p_nom_mod > 0) + AND Link_active constraints: Link_maint_event_count: @@ -137,54 +147,54 @@ constraints: `Link-maintcap_upper` — the build taken off is at most the chosen build in maintenance, and at most the build less its floor out of it dims: [scenario, snapshot, link] - where: Link_maintainable AND Link_p_nom_extendable AND NOT (Link_committable AND Link_p_nom_mod > 0) AND Link_active + where: Link_maint_ext expression: Link_maintenance_capacity <= Link_p_nom_ext - Link_p_nom_min * (1 - Link_maintenance) Link_maintcap_upper_nommax: description: "`Link-maintcap_upper_nommax` — out of maintenance, no build is taken off" dims: [scenario, snapshot, link] - where: Link_maintainable AND Link_p_nom_extendable AND NOT (Link_committable AND Link_p_nom_mod > 0) AND Link_active + where: Link_maint_ext expression: Link_maintenance_capacity <= Link_p_nom_max * Link_maintenance Link_maintcap_lower_nommax: description: "`Link-maintcap_lower_nommax` — in maintenance, the whole chosen build is taken off" dims: [scenario, snapshot, link] - where: Link_maintainable AND Link_p_nom_extendable AND NOT (Link_committable AND Link_p_nom_mod > 0) AND Link_active + where: Link_maint_ext expression: Link_maintenance_capacity >= Link_p_nom_ext - Link_p_nom_max * (1 - Link_maintenance) Link_maintcap_lower_nommin: description: "`Link-maintcap_lower_nommin` — in maintenance, at least the floor of the build is taken off" dims: [scenario, snapshot, link] - where: Link_maintainable AND Link_p_nom_extendable AND NOT (Link_committable AND Link_p_nom_mod > 0) AND Link_active AND Link_p_nom_min > 0 + where: Link_maint_ext AND Link_p_nom_min > 0 expression: Link_maintenance_capacity >= Link_p_nom_min * Link_maintenance Link_maint_status_le_status: description: "`Link-maint-status-le-status` — the status in maintenance is at most the status" dims: [scenario, snapshot, link] - where: Link_maintainable AND Link_committable AND NOT Link_p_nom_extendable AND Link_active + where: Link_maintainable AND Link_committed AND NOT Link_p_nom_extendable expression: Link_maintenance_status <= Link_status Link_maint_status_le_maint: description: "`Link-maint-status-le-maint` — out of maintenance, the status in maintenance is zero" dims: [scenario, snapshot, link] - where: Link_maintainable AND Link_committable AND NOT Link_p_nom_extendable AND Link_active + where: Link_maintainable AND Link_committed AND NOT Link_p_nom_extendable expression: Link_maintenance_status <= Link_maintenance Link_maint_status_lb: description: "`Link-maint-status-lb` — on and in maintenance, the status in maintenance is one" dims: [scenario, snapshot, link] - where: Link_maintainable AND Link_committable AND NOT Link_p_nom_extendable AND Link_active + where: Link_maintainable AND Link_committed AND NOT Link_p_nom_extendable expression: Link_maintenance_status >= Link_status + Link_maintenance - 1 Link_maint_modstatus_le_status: description: "`Link-maint-modstatus-le-status` — the modules on in maintenance are at most the modules on" dims: [scenario, snapshot, link] - where: Link_maintainable AND Link_committable AND Link_p_nom_mod > 0 AND Link_active + where: Link_maintainable AND Link_committed AND Link_p_nom_mod > 0 expression: Link_maintenance_status <= Link_status Link_maint_modstatus_le_maint: description: >- `Link-maint-modstatus-le-maint` — out of maintenance, no module is on in maintenance; in it, at most the modules the build cap holds dims: [scenario, snapshot, link] - where: Link_maintainable AND Link_committable AND Link_p_nom_mod > 0 AND Link_active + where: Link_maintainable AND Link_committed AND Link_p_nom_mod > 0 expression: Link_maintenance_status <= Link_p_nom_max / Link_p_nom_mod * Link_maintenance Link_maint_modstatus_lb: description: "`Link-maint-modstatus-lb` — in maintenance, every module on is on in maintenance" dims: [scenario, snapshot, link] - where: Link_maintainable AND Link_committable AND Link_p_nom_mod > 0 AND Link_active + where: Link_maintainable AND Link_committed AND Link_p_nom_mod > 0 expression: Link_maintenance_status >= Link_status - Link_p_nom_max / Link_p_nom_mod * (1 - Link_maintenance) assumptions: @@ -271,6 +281,13 @@ assumptions: | $`\overline{\mathrm{f}}^{\mathrm{nom}}`$ | `Link_p_nom_max` over $`\Xi \times \mathcal{L}`$, data another file declares | | $`u^{f}`$ | `Link_status` over $`\Xi \times \mathcal{T} \times \mathcal{L}`$ | | $`F`$ | `Link_p_nom_ext` over $`\mathcal{L}`$ | +| $`\mathrm{on}^{f,\mathrm{com}}`$ | `Link_committed` over $`\mathcal{T} \times \mathcal{L}`$, a mask another file defines | + +#### Masks + +| Symbol | Meaning | +|---|---| +| $`\mathrm{on}^{f,\mathrm{mnt,ext}}`$ | `Link_maint_ext` over $`\mathcal{T} \times \mathcal{L}`$ — a maintainable link with an extendable build, unless it is committable and modular, that stands in the snapshot's period — the maintenance rows against the chosen build | #### Subject to @@ -295,61 +312,69 @@ assumptions: **`Link_maintcap_upper`** ```math -\mu^{f,\mathrm{nom}}_{\xi,t,l} \le F_{l} - \underline{\mathrm{f}}^{\mathrm{nom}}_{\xi,l} \cdot \left( 1 - \mu^{f}_{\xi,t,l} \right) \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ l \in \mathcal{L} \,:\, \mathrm{mnt}^{f}_{l} \wedge \mathrm{ext}^{f}_{l} \wedge \neg \left( \mathrm{com}^{f}_{l} \wedge \mathrm{f}^{\mathrm{mod}}_{l} > 0 \right) \wedge \mathrm{on}^{f}_{t,l} +\mu^{f,\mathrm{nom}}_{\xi,t,l} \le F_{l} - \underline{\mathrm{f}}^{\mathrm{nom}}_{\xi,l} \cdot \left( 1 - \mu^{f}_{\xi,t,l} \right) \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ l \in \mathcal{L} \,:\, \mathrm{on}^{f,\mathrm{mnt,ext}}_{t,l} ``` **`Link_maintcap_upper_nommax`** ```math -\mu^{f,\mathrm{nom}}_{\xi,t,l} \le \overline{\mathrm{f}}^{\mathrm{nom}}_{\xi,l} \cdot \mu^{f}_{\xi,t,l} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ l \in \mathcal{L} \,:\, \mathrm{mnt}^{f}_{l} \wedge \mathrm{ext}^{f}_{l} \wedge \neg \left( \mathrm{com}^{f}_{l} \wedge \mathrm{f}^{\mathrm{mod}}_{l} > 0 \right) \wedge \mathrm{on}^{f}_{t,l} +\mu^{f,\mathrm{nom}}_{\xi,t,l} \le \overline{\mathrm{f}}^{\mathrm{nom}}_{\xi,l} \cdot \mu^{f}_{\xi,t,l} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ l \in \mathcal{L} \,:\, \mathrm{on}^{f,\mathrm{mnt,ext}}_{t,l} ``` **`Link_maintcap_lower_nommax`** ```math -\mu^{f,\mathrm{nom}}_{\xi,t,l} \ge F_{l} - \overline{\mathrm{f}}^{\mathrm{nom}}_{\xi,l} \cdot \left( 1 - \mu^{f}_{\xi,t,l} \right) \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ l \in \mathcal{L} \,:\, \mathrm{mnt}^{f}_{l} \wedge \mathrm{ext}^{f}_{l} \wedge \neg \left( \mathrm{com}^{f}_{l} \wedge \mathrm{f}^{\mathrm{mod}}_{l} > 0 \right) \wedge \mathrm{on}^{f}_{t,l} +\mu^{f,\mathrm{nom}}_{\xi,t,l} \ge F_{l} - \overline{\mathrm{f}}^{\mathrm{nom}}_{\xi,l} \cdot \left( 1 - \mu^{f}_{\xi,t,l} \right) \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ l \in \mathcal{L} \,:\, \mathrm{on}^{f,\mathrm{mnt,ext}}_{t,l} ``` **`Link_maintcap_lower_nommin`** ```math -\mu^{f,\mathrm{nom}}_{\xi,t,l} \ge \underline{\mathrm{f}}^{\mathrm{nom}}_{\xi,l} \cdot \mu^{f}_{\xi,t,l} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ l \in \mathcal{L} \,:\, \mathrm{mnt}^{f}_{l} \wedge \mathrm{ext}^{f}_{l} \wedge \neg \left( \mathrm{com}^{f}_{l} \wedge \mathrm{f}^{\mathrm{mod}}_{l} > 0 \right) \wedge \mathrm{on}^{f}_{t,l} \wedge \underline{\mathrm{f}}^{\mathrm{nom}}_{\xi,l} > 0 +\mu^{f,\mathrm{nom}}_{\xi,t,l} \ge \underline{\mathrm{f}}^{\mathrm{nom}}_{\xi,l} \cdot \mu^{f}_{\xi,t,l} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ l \in \mathcal{L} \,:\, \mathrm{on}^{f,\mathrm{mnt,ext}}_{t,l} \wedge \underline{\mathrm{f}}^{\mathrm{nom}}_{\xi,l} > 0 ``` **`Link_maint_status_le_status`** ```math -\mu^{f,u}_{\xi,t,l} \le u^{f}_{\xi,t,l} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ l \in \mathcal{L} \,:\, \mathrm{mnt}^{f}_{l} \wedge \mathrm{com}^{f}_{l} \wedge \neg \mathrm{ext}^{f}_{l} \wedge \mathrm{on}^{f}_{t,l} +\mu^{f,u}_{\xi,t,l} \le u^{f}_{\xi,t,l} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ l \in \mathcal{L} \,:\, \mathrm{mnt}^{f}_{l} \wedge \mathrm{on}^{f,\mathrm{com}}_{t,l} \wedge \neg \mathrm{ext}^{f}_{l} ``` **`Link_maint_status_le_maint`** ```math -\mu^{f,u}_{\xi,t,l} \le \mu^{f}_{\xi,t,l} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ l \in \mathcal{L} \,:\, \mathrm{mnt}^{f}_{l} \wedge \mathrm{com}^{f}_{l} \wedge \neg \mathrm{ext}^{f}_{l} \wedge \mathrm{on}^{f}_{t,l} +\mu^{f,u}_{\xi,t,l} \le \mu^{f}_{\xi,t,l} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ l \in \mathcal{L} \,:\, \mathrm{mnt}^{f}_{l} \wedge \mathrm{on}^{f,\mathrm{com}}_{t,l} \wedge \neg \mathrm{ext}^{f}_{l} ``` **`Link_maint_status_lb`** ```math -\mu^{f,u}_{\xi,t,l} \ge u^{f}_{\xi,t,l} + \mu^{f}_{\xi,t,l} - 1 \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ l \in \mathcal{L} \,:\, \mathrm{mnt}^{f}_{l} \wedge \mathrm{com}^{f}_{l} \wedge \neg \mathrm{ext}^{f}_{l} \wedge \mathrm{on}^{f}_{t,l} +\mu^{f,u}_{\xi,t,l} \ge u^{f}_{\xi,t,l} + \mu^{f}_{\xi,t,l} - 1 \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ l \in \mathcal{L} \,:\, \mathrm{mnt}^{f}_{l} \wedge \mathrm{on}^{f,\mathrm{com}}_{t,l} \wedge \neg \mathrm{ext}^{f}_{l} ``` **`Link_maint_modstatus_le_status`** ```math -\mu^{f,u}_{\xi,t,l} \le u^{f}_{\xi,t,l} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ l \in \mathcal{L} \,:\, \mathrm{mnt}^{f}_{l} \wedge \mathrm{com}^{f}_{l} \wedge \mathrm{f}^{\mathrm{mod}}_{l} > 0 \wedge \mathrm{on}^{f}_{t,l} +\mu^{f,u}_{\xi,t,l} \le u^{f}_{\xi,t,l} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ l \in \mathcal{L} \,:\, \mathrm{mnt}^{f}_{l} \wedge \mathrm{on}^{f,\mathrm{com}}_{t,l} \wedge \mathrm{f}^{\mathrm{mod}}_{l} > 0 ``` **`Link_maint_modstatus_le_maint`** ```math -\mu^{f,u}_{\xi,t,l} \le \frac{\overline{\mathrm{f}}^{\mathrm{nom}}_{\xi,l}}{\mathrm{f}^{\mathrm{mod}}_{l}} \cdot \mu^{f}_{\xi,t,l} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ l \in \mathcal{L} \,:\, \mathrm{mnt}^{f}_{l} \wedge \mathrm{com}^{f}_{l} \wedge \mathrm{f}^{\mathrm{mod}}_{l} > 0 \wedge \mathrm{on}^{f}_{t,l} +\mu^{f,u}_{\xi,t,l} \le \frac{\overline{\mathrm{f}}^{\mathrm{nom}}_{\xi,l}}{\mathrm{f}^{\mathrm{mod}}_{l}} \cdot \mu^{f}_{\xi,t,l} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ l \in \mathcal{L} \,:\, \mathrm{mnt}^{f}_{l} \wedge \mathrm{on}^{f,\mathrm{com}}_{t,l} \wedge \mathrm{f}^{\mathrm{mod}}_{l} > 0 ``` **`Link_maint_modstatus_lb`** ```math -\mu^{f,u}_{\xi,t,l} \ge u^{f}_{\xi,t,l} - \frac{\overline{\mathrm{f}}^{\mathrm{nom}}_{\xi,l}}{\mathrm{f}^{\mathrm{mod}}_{l}} \cdot \left( 1 - \mu^{f}_{\xi,t,l} \right) \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ l \in \mathcal{L} \,:\, \mathrm{mnt}^{f}_{l} \wedge \mathrm{com}^{f}_{l} \wedge \mathrm{f}^{\mathrm{mod}}_{l} > 0 \wedge \mathrm{on}^{f}_{t,l} +\mu^{f,u}_{\xi,t,l} \ge u^{f}_{\xi,t,l} - \frac{\overline{\mathrm{f}}^{\mathrm{nom}}_{\xi,l}}{\mathrm{f}^{\mathrm{mod}}_{l}} \cdot \left( 1 - \mu^{f}_{\xi,t,l} \right) \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ l \in \mathcal{L} \,:\, \mathrm{mnt}^{f}_{l} \wedge \mathrm{on}^{f,\mathrm{com}}_{t,l} \wedge \mathrm{f}^{\mathrm{mod}}_{l} > 0 +``` + +#### Masks + +**`Link_maint_ext`** + +```math +\mathrm{on}^{f,\mathrm{mnt,ext}}_{t,l} \iff \mathrm{mnt}^{f}_{l} \wedge \mathrm{ext}^{f}_{l} \wedge \neg \left( \mathrm{com}^{f}_{l} \wedge \mathrm{f}^{\mathrm{mod}}_{l} > 0 \right) \wedge \mathrm{on}^{f}_{t,l} \qquad \forall\, t \in \mathcal{T},\ l \in \mathcal{L} ``` #### Variable domains @@ -369,13 +394,13 @@ assumptions: **`Link_maintenance_capacity`** ```math -\mu^{f,\mathrm{nom}}_{\xi,t,l} \ge 0 \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ l \in \mathcal{L} \,:\, \mathrm{mnt}^{f}_{l} \wedge \mathrm{ext}^{f}_{l} \wedge \neg \left( \mathrm{com}^{f}_{l} \wedge \mathrm{f}^{\mathrm{mod}}_{l} > 0 \right) \wedge \mathrm{on}^{f}_{t,l} +\mu^{f,\mathrm{nom}}_{\xi,t,l} \ge 0 \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ l \in \mathcal{L} \,:\, \mathrm{on}^{f,\mathrm{mnt,ext}}_{t,l} ``` **`Link_maintenance_status`** ```math -\mu^{f,u}_{\xi,t,l} \ge 0 \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ l \in \mathcal{L} \,:\, \mathrm{mnt}^{f}_{l} \wedge \mathrm{com}^{f}_{l} \wedge \neg \left( \mathrm{ext}^{f}_{l} \wedge \neg \left( \mathrm{f}^{\mathrm{mod}}_{l} > 0 \right) \right) \wedge \mathrm{on}^{f}_{t,l} +\mu^{f,u}_{\xi,t,l} \ge 0 \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ l \in \mathcal{L} \,:\, \mathrm{mnt}^{f}_{l} \wedge \mathrm{on}^{f,\mathrm{com}}_{t,l} \wedge \neg \left( \mathrm{ext}^{f}_{l} \wedge \neg \left( \mathrm{f}^{\mathrm{mod}}_{l} > 0 \right) \right) ``` #### Assumptions diff --git a/docs/examples/pypsa/link_ramping.md b/docs/examples/pypsa/link_ramping.md index 0b55db30b..19dfe2d79 100644 --- a/docs/examples/pypsa/link_ramping.md +++ b/docs/examples/pypsa/link_ramping.md @@ -65,6 +65,8 @@ given: Link_p_nom_effective: { dims: [scenario, link] } Link_previous_status: { dims: [scenario, snapshot, link] } Link_p_nom_committed: { dims: [scenario, link] } + masks: + Link_com_ext: { dims: [snapshot, link] } expressions: Link_previous_p: @@ -137,6 +139,16 @@ expressions: * (Link_previous_status - Link_status) otherwise: Link_ramp_down_rate * Link_p_nom_effective +masks: + Link_ramps_from_previous: + description: >- + a snapshot whose ramp reads a previous output — any snapshot but its + period's first, and the horizon's first where the link comes in off or + carries an initial output + where: >- + position(snapshot, by=snapshot_period, within=period) > 0 OR (position(snapshot) == 0 AND + (Link_status_initial == 0 OR Link_p_init)) + constraints: Link_p_ramp_limit_up_run_big_m: description: >- @@ -144,11 +156,7 @@ constraints: raises flow no faster than its limit of the chosen build; the big M releases the row in the snapshot it turns on dims: [scenario, snapshot, link] - where: >- - Link_committable AND Link_p_nom_extendable AND NOT (Link_p_nom_mod > 0) - AND (Link_ramp_limit_up OR Link_ramp_limit_start_up) - AND (position(snapshot, by=snapshot_period, within=period) > 0 OR (position(snapshot) == 0 AND (Link_status_initial == 0 OR Link_p_init))) - AND Link_active + where: Link_com_ext AND (Link_ramp_limit_up OR Link_ramp_limit_start_up) AND Link_ramps_from_previous expression: >- Link_p - Link_previous_p <= Link_ramp_up_rate * Link_p_nom_ext @@ -159,11 +167,7 @@ constraints: committed extendable link ramps no further than its start-up ramp of the chosen build; the big M releases the row everywhere else dims: [scenario, snapshot, link] - where: >- - Link_committable AND Link_p_nom_extendable AND NOT (Link_p_nom_mod > 0) - AND (Link_ramp_limit_up OR Link_ramp_limit_start_up) - AND (position(snapshot, by=snapshot_period, within=period) > 0 OR (position(snapshot) == 0 AND (Link_status_initial == 0 OR Link_p_init))) - AND Link_active + where: Link_com_ext AND (Link_ramp_limit_up OR Link_ramp_limit_start_up) AND Link_ramps_from_previous expression: >- Link_p - Link_previous_p <= Link_start_up_rate * Link_p_nom_ext @@ -174,11 +178,7 @@ constraints: lowers flow no faster than its limit of the chosen build; the big M releases the row in the snapshot it turns off dims: [scenario, snapshot, link] - where: >- - Link_committable AND Link_p_nom_extendable AND NOT (Link_p_nom_mod > 0) - AND (Link_ramp_limit_down OR Link_ramp_limit_shut_down) - AND (position(snapshot, by=snapshot_period, within=period) > 0 OR (position(snapshot) == 0 AND (Link_status_initial == 0 OR Link_p_init))) - AND Link_active + where: Link_com_ext AND (Link_ramp_limit_down OR Link_ramp_limit_shut_down) AND Link_ramps_from_previous expression: >- Link_previous_p - Link_p <= Link_ramp_down_rate * Link_p_nom_ext @@ -189,11 +189,7 @@ constraints: a committed extendable link ramps no further than its shut-down ramp of the chosen build; the big M releases the row everywhere else dims: [scenario, snapshot, link] - where: >- - Link_committable AND Link_p_nom_extendable AND NOT (Link_p_nom_mod > 0) - AND (Link_ramp_limit_down OR Link_ramp_limit_shut_down) - AND (position(snapshot, by=snapshot_period, within=period) > 0 OR (position(snapshot) == 0 AND (Link_status_initial == 0 OR Link_p_init))) - AND Link_active + where: Link_com_ext AND (Link_ramp_limit_down OR Link_ramp_limit_shut_down) AND Link_ramps_from_previous expression: >- Link_previous_p - Link_p <= Link_shut_down_rate * Link_p_nom_ext @@ -210,7 +206,7 @@ constraints: where: >- (Link_ramp_limit_up OR Link_ramp_limit_start_up) AND NOT (Link_committable AND Link_p_nom_extendable AND NOT (Link_p_nom_mod > 0)) - AND (position(snapshot, by=snapshot_period, within=period) > 0 OR (position(snapshot) == 0 AND (Link_status_initial == 0 OR Link_p_init))) + AND Link_ramps_from_previous AND Link_active expression: Link_p - Link_previous_p <= Link_ramp_up_allowance Link_p_ramp_limit_down: @@ -225,7 +221,7 @@ constraints: where: >- (Link_ramp_limit_down OR Link_ramp_limit_shut_down) AND NOT (Link_committable AND Link_p_nom_extendable AND NOT (Link_p_nom_mod > 0)) - AND (position(snapshot, by=snapshot_period, within=period) > 0 OR (position(snapshot) == 0 AND (Link_status_initial == 0 OR Link_p_init))) + AND Link_ramps_from_previous AND Link_active expression: Link_previous_p - Link_p <= Link_ramp_down_allowance @@ -281,6 +277,7 @@ assumptions: | $`\widetilde{\mathrm{f}}^{\mathrm{nom}}`$ | `Link_p_nom_effective` over $`\Xi \times \mathcal{L}`$, an expression another file defines | | $`\overleftarrow{u}^{f}`$ | `Link_previous_status` over $`\Xi \times \mathcal{T} \times \mathcal{L}`$, an expression another file defines | | $`\widehat{\mathrm{f}}^{\mathrm{nom}}`$ | `Link_p_nom_committed` over $`\Xi \times \mathcal{L}`$, an expression another file defines | +| $`\mathrm{on}^{f,\mathrm{com,ext}}`$ | `Link_com_ext` over $`\mathcal{T} \times \mathcal{L}`$, a mask another file defines | #### Definitions @@ -294,6 +291,12 @@ assumptions: | $`\Delta^{f,+}`$ | `Link_ramp_up_allowance` over $`\Xi \times \mathcal{T} \times \mathcal{L}`$ — how far a link may raise flow between two snapshots — its ramp limit of the build while it stays on, plus its start-up ramp in the snapshot it turns on | | $`\Delta^{f,-}`$ | `Link_ramp_down_allowance` over $`\Xi \times \mathcal{T} \times \mathcal{L}`$ — how far a link may lower flow between two snapshots — its ramp limit of the build while it stays on, plus its shut-down ramp in the snapshot it turns off | +#### Masks + +| Symbol | Meaning | +|---|---| +| $`\mathrm{prev}^{f}`$ | `Link_ramps_from_previous` over $`\Xi \times \mathcal{T} \times \mathcal{L}`$ — a snapshot whose ramp reads a previous output — any snapshot but its period's first, and the horizon's first where the link comes in off or carries an initial output | + $`\mathrm{pos}(t)`$ denotes where index $`t`$ sits along its dimension's own order — the order `shift` steps along, not the order labels sort in — counted from $`0`$. The index itself stays the coordinate, so $`t`$ compares against labels and $`\mathrm{pos}(t)`$ against positions. $`\mathrm{pos}_{\mathrm{relation}(t)}(t)`$ counts within the group a relation puts $`t`$ in: the subscript names the map, $`\mathcal{T}_{\mathrm{relation}(t)}`$ is the group it lands in, and that group has a first position of its own. @@ -303,37 +306,37 @@ $`\mathrm{pos}_{\mathrm{relation}(t)}(t)`$ counts within the group a relation pu **`Link_p_ramp_limit_up_run_big_m`** ```math -f_{\xi,t,l} - \overleftarrow{f}_{\xi,t,l} \le \widetilde{\mathrm{ru}}^{f}_{\xi,t,l} \cdot F_{l} + \mathrm{M}^{f}_{\xi,l} - \mathrm{M}^{f}_{\xi,l} \cdot \overleftarrow{u}^{f}_{\xi,t,l} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ l \in \mathcal{L} \,:\, \mathrm{com}^{f}_{l} \wedge \mathrm{ext}^{f}_{l} \wedge \neg \left( \mathrm{f}^{\mathrm{mod}}_{l} > 0 \right) \wedge \left( \mathrm{ru}^{f}_{\xi,t,l} \text{ is defined} \vee \mathrm{ru}^{f,\mathrm{up}}_{\xi,l} \text{ is defined} \right) \wedge \left( \mathrm{pos}_{\mathrm{snapshot\_period}(t)}(t) > 0 \vee \mathrm{pos}(t) = 0 \wedge \left( \mathrm{u}^{f,0}_{\xi,l} = 0 \vee \mathrm{f}^{0}_{\xi,l} \text{ is defined} \right) \right) \wedge \mathrm{on}^{f}_{t,l} +f_{\xi,t,l} - \overleftarrow{f}_{\xi,t,l} \le \widetilde{\mathrm{ru}}^{f}_{\xi,t,l} \cdot F_{l} + \mathrm{M}^{f}_{\xi,l} - \mathrm{M}^{f}_{\xi,l} \cdot \overleftarrow{u}^{f}_{\xi,t,l} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ l \in \mathcal{L} \,:\, \mathrm{on}^{f,\mathrm{com,ext}}_{t,l} \wedge \left( \mathrm{ru}^{f}_{\xi,t,l} \text{ is defined} \vee \mathrm{ru}^{f,\mathrm{up}}_{\xi,l} \text{ is defined} \right) \wedge \mathrm{prev}^{f}_{\xi,t,l} ``` **`Link_p_ramp_limit_up_start_big_m`** ```math -f_{\xi,t,l} - \overleftarrow{f}_{\xi,t,l} \le \widetilde{\mathrm{ru}}^{f,\mathrm{up}}_{\xi,l} \cdot F_{l} + \mathrm{M}^{f}_{\xi,l} - \mathrm{M}^{f}_{\xi,l} \cdot \mathit{up}^{f}_{\xi,t,l} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ l \in \mathcal{L} \,:\, \mathrm{com}^{f}_{l} \wedge \mathrm{ext}^{f}_{l} \wedge \neg \left( \mathrm{f}^{\mathrm{mod}}_{l} > 0 \right) \wedge \left( \mathrm{ru}^{f}_{\xi,t,l} \text{ is defined} \vee \mathrm{ru}^{f,\mathrm{up}}_{\xi,l} \text{ is defined} \right) \wedge \left( \mathrm{pos}_{\mathrm{snapshot\_period}(t)}(t) > 0 \vee \mathrm{pos}(t) = 0 \wedge \left( \mathrm{u}^{f,0}_{\xi,l} = 0 \vee \mathrm{f}^{0}_{\xi,l} \text{ is defined} \right) \right) \wedge \mathrm{on}^{f}_{t,l} +f_{\xi,t,l} - \overleftarrow{f}_{\xi,t,l} \le \widetilde{\mathrm{ru}}^{f,\mathrm{up}}_{\xi,l} \cdot F_{l} + \mathrm{M}^{f}_{\xi,l} - \mathrm{M}^{f}_{\xi,l} \cdot \mathit{up}^{f}_{\xi,t,l} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ l \in \mathcal{L} \,:\, \mathrm{on}^{f,\mathrm{com,ext}}_{t,l} \wedge \left( \mathrm{ru}^{f}_{\xi,t,l} \text{ is defined} \vee \mathrm{ru}^{f,\mathrm{up}}_{\xi,l} \text{ is defined} \right) \wedge \mathrm{prev}^{f}_{\xi,t,l} ``` **`Link_p_ramp_limit_down_run_big_m`** ```math -\overleftarrow{f}_{\xi,t,l} - f_{\xi,t,l} \le \widetilde{\mathrm{rd}}^{f}_{\xi,t,l} \cdot F_{l} + \mathrm{M}^{f}_{\xi,l} - \mathrm{M}^{f}_{\xi,l} \cdot u^{f}_{\xi,t,l} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ l \in \mathcal{L} \,:\, \mathrm{com}^{f}_{l} \wedge \mathrm{ext}^{f}_{l} \wedge \neg \left( \mathrm{f}^{\mathrm{mod}}_{l} > 0 \right) \wedge \left( \mathrm{rd}^{f}_{\xi,t,l} \text{ is defined} \vee \mathrm{rd}^{f,\mathrm{dn}}_{\xi,l} \text{ is defined} \right) \wedge \left( \mathrm{pos}_{\mathrm{snapshot\_period}(t)}(t) > 0 \vee \mathrm{pos}(t) = 0 \wedge \left( \mathrm{u}^{f,0}_{\xi,l} = 0 \vee \mathrm{f}^{0}_{\xi,l} \text{ is defined} \right) \right) \wedge \mathrm{on}^{f}_{t,l} +\overleftarrow{f}_{\xi,t,l} - f_{\xi,t,l} \le \widetilde{\mathrm{rd}}^{f}_{\xi,t,l} \cdot F_{l} + \mathrm{M}^{f}_{\xi,l} - \mathrm{M}^{f}_{\xi,l} \cdot u^{f}_{\xi,t,l} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ l \in \mathcal{L} \,:\, \mathrm{on}^{f,\mathrm{com,ext}}_{t,l} \wedge \left( \mathrm{rd}^{f}_{\xi,t,l} \text{ is defined} \vee \mathrm{rd}^{f,\mathrm{dn}}_{\xi,l} \text{ is defined} \right) \wedge \mathrm{prev}^{f}_{\xi,t,l} ``` **`Link_p_ramp_limit_down_shut_big_m`** ```math -\overleftarrow{f}_{\xi,t,l} - f_{\xi,t,l} \le \widetilde{\mathrm{rd}}^{f,\mathrm{dn}}_{\xi,l} \cdot F_{l} + \mathrm{M}^{f}_{\xi,l} - \mathrm{M}^{f}_{\xi,l} \cdot \mathit{dn}^{f}_{\xi,t,l} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ l \in \mathcal{L} \,:\, \mathrm{com}^{f}_{l} \wedge \mathrm{ext}^{f}_{l} \wedge \neg \left( \mathrm{f}^{\mathrm{mod}}_{l} > 0 \right) \wedge \left( \mathrm{rd}^{f}_{\xi,t,l} \text{ is defined} \vee \mathrm{rd}^{f,\mathrm{dn}}_{\xi,l} \text{ is defined} \right) \wedge \left( \mathrm{pos}_{\mathrm{snapshot\_period}(t)}(t) > 0 \vee \mathrm{pos}(t) = 0 \wedge \left( \mathrm{u}^{f,0}_{\xi,l} = 0 \vee \mathrm{f}^{0}_{\xi,l} \text{ is defined} \right) \right) \wedge \mathrm{on}^{f}_{t,l} +\overleftarrow{f}_{\xi,t,l} - f_{\xi,t,l} \le \widetilde{\mathrm{rd}}^{f,\mathrm{dn}}_{\xi,l} \cdot F_{l} + \mathrm{M}^{f}_{\xi,l} - \mathrm{M}^{f}_{\xi,l} \cdot \mathit{dn}^{f}_{\xi,t,l} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ l \in \mathcal{L} \,:\, \mathrm{on}^{f,\mathrm{com,ext}}_{t,l} \wedge \left( \mathrm{rd}^{f}_{\xi,t,l} \text{ is defined} \vee \mathrm{rd}^{f,\mathrm{dn}}_{\xi,l} \text{ is defined} \right) \wedge \mathrm{prev}^{f}_{\xi,t,l} ``` **`Link_p_ramp_limit_up`** ```math -f_{\xi,t,l} - \overleftarrow{f}_{\xi,t,l} \le \Delta^{f,+}_{\xi,t,l} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ l \in \mathcal{L} \,:\, \left( \mathrm{ru}^{f}_{\xi,t,l} \text{ is defined} \vee \mathrm{ru}^{f,\mathrm{up}}_{\xi,l} \text{ is defined} \right) \wedge \neg \left( \mathrm{com}^{f}_{l} \wedge \mathrm{ext}^{f}_{l} \wedge \neg \left( \mathrm{f}^{\mathrm{mod}}_{l} > 0 \right) \right) \wedge \left( \mathrm{pos}_{\mathrm{snapshot\_period}(t)}(t) > 0 \vee \mathrm{pos}(t) = 0 \wedge \left( \mathrm{u}^{f,0}_{\xi,l} = 0 \vee \mathrm{f}^{0}_{\xi,l} \text{ is defined} \right) \right) \wedge \mathrm{on}^{f}_{t,l} +f_{\xi,t,l} - \overleftarrow{f}_{\xi,t,l} \le \Delta^{f,+}_{\xi,t,l} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ l \in \mathcal{L} \,:\, \left( \mathrm{ru}^{f}_{\xi,t,l} \text{ is defined} \vee \mathrm{ru}^{f,\mathrm{up}}_{\xi,l} \text{ is defined} \right) \wedge \neg \left( \mathrm{com}^{f}_{l} \wedge \mathrm{ext}^{f}_{l} \wedge \neg \left( \mathrm{f}^{\mathrm{mod}}_{l} > 0 \right) \right) \wedge \mathrm{prev}^{f}_{\xi,t,l} \wedge \mathrm{on}^{f}_{t,l} ``` **`Link_p_ramp_limit_down`** ```math -\overleftarrow{f}_{\xi,t,l} - f_{\xi,t,l} \le \Delta^{f,-}_{\xi,t,l} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ l \in \mathcal{L} \,:\, \left( \mathrm{rd}^{f}_{\xi,t,l} \text{ is defined} \vee \mathrm{rd}^{f,\mathrm{dn}}_{\xi,l} \text{ is defined} \right) \wedge \neg \left( \mathrm{com}^{f}_{l} \wedge \mathrm{ext}^{f}_{l} \wedge \neg \left( \mathrm{f}^{\mathrm{mod}}_{l} > 0 \right) \right) \wedge \left( \mathrm{pos}_{\mathrm{snapshot\_period}(t)}(t) > 0 \vee \mathrm{pos}(t) = 0 \wedge \left( \mathrm{u}^{f,0}_{\xi,l} = 0 \vee \mathrm{f}^{0}_{\xi,l} \text{ is defined} \right) \right) \wedge \mathrm{on}^{f}_{t,l} +\overleftarrow{f}_{\xi,t,l} - f_{\xi,t,l} \le \Delta^{f,-}_{\xi,t,l} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ l \in \mathcal{L} \,:\, \left( \mathrm{rd}^{f}_{\xi,t,l} \text{ is defined} \vee \mathrm{rd}^{f,\mathrm{dn}}_{\xi,l} \text{ is defined} \right) \wedge \neg \left( \mathrm{com}^{f}_{l} \wedge \mathrm{ext}^{f}_{l} \wedge \neg \left( \mathrm{f}^{\mathrm{mod}}_{l} > 0 \right) \right) \wedge \mathrm{prev}^{f}_{\xi,t,l} \wedge \mathrm{on}^{f}_{t,l} ``` #### Definitions @@ -380,6 +383,14 @@ f_{\xi,t,l} - \overleftarrow{f}_{\xi,t,l} \le \Delta^{f,+}_{\xi,t,l} \qquad \for \Delta^{f,-}_{\xi,t,l} = \begin{cases} \widetilde{\mathrm{rd}}^{f}_{\xi,t,l} \cdot \widehat{\mathrm{f}}^{\mathrm{nom}}_{\xi,l} \cdot u^{f}_{\xi,t,l} + \widetilde{\mathrm{rd}}^{f,\mathrm{dn}}_{\xi,l} \cdot \widehat{\mathrm{f}}^{\mathrm{nom}}_{\xi,l} \cdot \left( \overleftarrow{u}^{f}_{\xi,t,l} - u^{f}_{\xi,t,l} \right) & \text{if } \mathrm{com}^{f}_{l} \\ \widetilde{\mathrm{rd}}^{f}_{\xi,t,l} \cdot \widetilde{\mathrm{f}}^{\mathrm{nom}}_{\xi,l} & \text{otherwise} \end{cases} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ l \in \mathcal{L} ``` +#### Masks + +**`Link_ramps_from_previous`** + +```math +\mathrm{prev}^{f}_{\xi,t,l} \iff \mathrm{pos}_{\mathrm{snapshot\_period}(t)}(t) > 0 \vee \mathrm{pos}(t) = 0 \wedge \left( \mathrm{u}^{f,0}_{\xi,l} = 0 \vee \mathrm{f}^{0}_{\xi,l} \text{ is defined} \right) \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ l \in \mathcal{L} +``` + #### Assumptions **`Link_came_in_running_unless_committable`** diff --git a/docs/examples/pypsa/process.md b/docs/examples/pypsa/process.md index 00711b99b..5bb52b608 100644 --- a/docs/examples/pypsa/process.md +++ b/docs/examples/pypsa/process.md @@ -240,6 +240,13 @@ expressions: sum(Process_output_arrival, by=Process_output_bus, over=process_output, into=bus) adds_to: Bus_injection +masks: + Process_committed: + description: >- + a committable process that stands in the snapshot's period — every + unit-commitment row's set + where: Process_committable AND Process_active + constraints: Process_fix_p_lower: description: "`Process-fix-p-lower` — a fixed process runs at least its minimum, negative for the other way" @@ -376,6 +383,12 @@ assumptions: | $`\mathit{Process\_additions}`$ | `Process_additions` over $`\mathcal{Y} \times \mathcal{I}`$ | | $`\mathit{Process\_injection}`$ | `Process_injection` over $`\Xi \times \mathcal{T} \times \mathcal{N}`$ | +#### Masks + +| Symbol | Meaning | +|---|---| +| $`\mathrm{on}^{z,\mathrm{com}}`$ | `Process_committed` over $`\mathcal{T} \times \mathcal{J}`$ — a committable process that stands in the snapshot's period — every unit-commitment row's set | + $`t \ominus k`$ denotes cyclic translation: index $`t-k`$ taken modulo the size of the dimension (`roll`). Plain $`t-k`$ (`shift`) has no wraparound — terms translated past the edge are simply absent. $`t \boxminus_{v} k`$ denotes translation with $`v`$ standing where index $`t-k`$ leaves the dimension (`shift(edge=v)`), so the row at that boundary is built and carries $`v`$ rather than being dropped. @@ -488,6 +501,14 @@ z_{\xi,t,j} = \mathrm{z}^{\mathrm{set}}_{\xi,t,j} \qquad \forall\, \xi \in \Xi,\ \mathit{Process\_injection}_{\xi,t,n} = \sum_{r \in \mathcal{R} \,:\, \mathrm{Process\_output\_bus}(r) = n} \overrightarrow{z}_{\xi,t,r} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ n \in \mathcal{N} ``` +#### Masks + +**`Process_committed`** + +```math +\mathrm{on}^{z,\mathrm{com}}_{t,j} \iff \mathrm{com}^{z}_{j} \wedge \mathrm{on}^{z}_{t,j} \qquad \forall\, t \in \mathcal{T},\ j \in \mathcal{J} +``` + #### Variable domains **`Process_p`** diff --git a/docs/examples/pypsa/process_commitment.md b/docs/examples/pypsa/process_commitment.md index f2087dc24..d8934db9b 100644 --- a/docs/examples/pypsa/process_commitment.md +++ b/docs/examples/pypsa/process_commitment.md @@ -78,21 +78,21 @@ variables: the rows below cap at one, or at the module count where the build is modular dims: [scenario, snapshot, process] - where: Process_committable AND Process_active + where: Process_committed domain: integer bounds: lower: 0 Process_start_up: description: "`Process-start_up` — how much of a committable process turns on this snapshot, capped as the status is" dims: [scenario, snapshot, process] - where: Process_committable AND Process_active + where: Process_committed domain: integer bounds: lower: 0 Process_shut_down: description: "`Process-shut_down` — how much of a committable process turns off this snapshot, capped as the status is" dims: [scenario, snapshot, process] - where: Process_committable AND Process_active + where: Process_committed domain: integer bounds: lower: 0 @@ -118,6 +118,8 @@ given: Process_p_nom_ext: { dims: [process] } expressions: scenario_opex: { dims: [scenario] } + masks: + Process_committed: { dims: [snapshot, process] } expressions: Process_previous_status: @@ -135,26 +137,38 @@ expressions: + sum(sum(Process_shut_down * Process_shut_down_cost, over=process), over=snapshot) adds_to: scenario_opex +masks: + Process_com_ext: + description: >- + a committable process with an extendable, non-modular build that stands + in the snapshot's period — PyPSA's `com-ext` rows, whose status is + relaxed against the chosen build + where: >- + Process_committable + AND Process_p_nom_extendable + AND NOT (Process_p_nom_mod > 0) + AND Process_active + constraints: Process_com_p_lower: description: "`Process-com-p-lower` — a committed process runs at least its minimum; off, at least nothing" dims: [scenario, snapshot, process] - where: Process_committable AND not Process_p_nom_extendable AND Process_active + where: Process_committed AND NOT Process_p_nom_extendable expression: Process_p >= Process_p_min_pu * Process_p_nom * (Process_status - Process_maintenance_pu * Process_maintenance_status) Process_com_p_upper: description: "`Process-com-p-upper` — a committed process runs at most what is available; off, at most nothing" dims: [scenario, snapshot, process] - where: Process_committable AND not Process_p_nom_extendable AND Process_active + where: Process_committed AND NOT Process_p_nom_extendable expression: Process_p <= Process_p_max_pu * Process_p_nom * (Process_status - Process_maintenance_pu * Process_maintenance_status) Process_com_transition_start_up: description: "`Process-com-transition-start-up` — turning on is a start, counted against the state the process carried into the snapshot" dims: [scenario, snapshot, process] - where: Process_committable AND Process_active + where: Process_committed expression: Process_start_up >= Process_status - Process_previous_status Process_com_transition_shut_down: description: "`Process-com-transition-shut-down` — turning off is a stop, counted against the state the process carried into the snapshot" dims: [scenario, snapshot, process] - where: Process_committable AND Process_active + where: Process_committed expression: Process_shut_down >= Process_previous_status - Process_status Process_com_up_time: description: >- @@ -162,7 +176,7 @@ constraints: is still on. The first snapshot's share of the window is the brought-in up time's, which the must-stay-up mask carries dims: [scenario, snapshot, process] - where: Process_committable AND Process_min_up_time > 0 AND position(snapshot) > 0 AND Process_active + where: Process_committed AND Process_min_up_time > 0 AND position(snapshot) > 0 expression: sum_back(Process_start_up, along=snapshot, window=Process_min_up_time) <= Process_status Process_com_down_time: description: >- @@ -170,38 +184,38 @@ constraints: time is still off. The first snapshot's share of the window is the brought-in down time's, which the must-stay-down mask carries dims: [scenario, snapshot, process] - where: Process_committable AND Process_min_down_time > 0 AND position(snapshot) > 0 AND Process_active + where: Process_committed AND Process_min_down_time > 0 AND position(snapshot) > 0 expression: sum_back(Process_shut_down, along=snapshot, window=Process_min_down_time) <= 1 - Process_status Process_com_status_must_stay_up: description: "`Process-com-status-min_up_time_must_stay_up` — a process still serving the up time it brought in stays on" dims: [scenario, snapshot, process] - where: Process_committable AND Process_must_stay_up AND Process_active + where: Process_committed AND Process_must_stay_up expression: Process_status == 1 Process_com_status_must_stay_down: description: >- `Process-com-status-min_down_time_must_stay_up` — a process still serving the down time it brought in stays off; PyPSA names the row `_must_stay_up` dims: [scenario, snapshot, process] - where: Process_committable AND Process_must_stay_down AND Process_active + where: Process_committed AND Process_must_stay_down expression: Process_status == 0 Process_com_ext_p_upper_cap: description: >- `Process-com-ext-p-upper-cap` — a committed extendable process runs at most what is available of the chosen build, whatever its status dims: [scenario, snapshot, process] - where: Process_committable AND Process_p_nom_extendable AND NOT (Process_p_nom_mod > 0) AND Process_active + where: Process_com_ext expression: Process_p <= Process_p_max_pu * (Process_p_nom_ext - Process_maintenance_pu * Process_maintenance_capacity) Process_com_ext_p_upper_big_m: description: "`Process-com-ext-p-upper-bigM` — off, a process does not run; on, the big M is no bound" dims: [scenario, snapshot, process] - where: Process_committable AND Process_p_nom_extendable AND NOT (Process_p_nom_mod > 0) AND Process_active + where: Process_com_ext expression: Process_p <= Process_big_m * Process_status Process_com_ext_p_lower: description: >- `Process-com-ext-p-lower` — a committed extendable process runs at least its minimum of the chosen build; off, the big M releases the row dims: [scenario, snapshot, process] - where: Process_committable AND Process_p_nom_extendable AND NOT (Process_p_nom_mod > 0) AND Process_active + where: Process_com_ext expression: >- Process_p >= Process_p_min_pu * (Process_p_nom_ext - Process_maintenance_pu * Process_maintenance_capacity) @@ -212,23 +226,21 @@ constraints: negative, internal power is also plainly non-negative, a row the big-M lower cannot assert while the process is off dims: [scenario, snapshot, process] - where: >- - Process_committable AND Process_p_nom_extendable - AND Process_p_min_pu_nonneg AND NOT (Process_p_nom_mod > 0) AND Process_active + where: Process_com_ext AND Process_p_min_pu_nonneg expression: Process_p >= 0 Process_com_mod_p_lower: description: >- `Process-com-mod-p-lower` — a committed modular process runs at least its minimum of one module, whether the build is fixed or a decision dims: [scenario, snapshot, process] - where: Process_committable AND Process_p_nom_mod > 0 AND Process_active + where: Process_committed AND Process_p_nom_mod > 0 expression: Process_p >= Process_p_min_pu * Process_p_nom_mod * (Process_status - Process_maintenance_pu * Process_maintenance_status) Process_com_mod_p_upper: description: >- `Process-com-mod-p-upper` — a committed modular process runs at most one module's share, whether the build is fixed or a decision dims: [scenario, snapshot, process] - where: Process_committable AND Process_p_nom_mod > 0 AND Process_active + where: Process_committed AND Process_p_nom_mod > 0 expression: Process_p <= Process_p_max_pu * Process_p_nom_mod * (Process_status - Process_maintenance_pu * Process_maintenance_status) Process_status_p_fixed_upper: description: >- @@ -236,7 +248,7 @@ constraints: place, an explicit row as PyPSA writes it: one where the build is not modular, and the fixed build's whole count of modules where it is dims: [scenario, snapshot, process] - where: Process_committable AND NOT (Process_p_nom_extendable AND Process_p_nom_mod > 0) AND Process_active + where: Process_committed AND NOT (Process_p_nom_extendable AND Process_p_nom_mod > 0) expression: Process_status <= Process_modules_installed Process_start_up_p_fixed_upper: description: >- @@ -244,7 +256,7 @@ constraints: place, an explicit row as PyPSA writes it: one where the build is not modular, and the fixed build's whole count of modules where it is dims: [scenario, snapshot, process] - where: Process_committable AND NOT (Process_p_nom_extendable AND Process_p_nom_mod > 0) AND Process_active + where: Process_committed AND NOT (Process_p_nom_extendable AND Process_p_nom_mod > 0) expression: Process_start_up <= Process_modules_installed Process_shut_down_p_fixed_upper: description: >- @@ -252,22 +264,22 @@ constraints: place, an explicit row as PyPSA writes it: one where the build is not modular, and the fixed build's whole count of modules where it is dims: [scenario, snapshot, process] - where: Process_committable AND NOT (Process_p_nom_extendable AND Process_p_nom_mod > 0) AND Process_active + where: Process_committed AND NOT (Process_p_nom_extendable AND Process_p_nom_mod > 0) expression: Process_shut_down <= Process_modules_installed Process_status_p_nom_variable_upper: description: "`Process-status-p_nom-variable-upper` — a modular process is on only where a module is built" dims: [scenario, snapshot, process] - where: Process_committable AND Process_p_nom_extendable AND Process_p_nom_mod > 0 AND Process_active + where: Process_committed AND Process_p_nom_extendable AND Process_p_nom_mod > 0 expression: Process_status <= Process_n_mod Process_start_up_p_nom_variable_upper: description: "`Process-start_up-p_nom-variable-upper` — a modular process starts only where a module is built" dims: [scenario, snapshot, process] - where: Process_committable AND Process_p_nom_extendable AND Process_p_nom_mod > 0 AND Process_active + where: Process_committed AND Process_p_nom_extendable AND Process_p_nom_mod > 0 expression: Process_start_up <= Process_n_mod Process_shut_down_p_nom_variable_upper: description: "`Process-shut_down-p_nom-variable-upper` — a modular process stops only where a module is built" dims: [scenario, snapshot, process] - where: Process_committable AND Process_p_nom_extendable AND Process_p_nom_mod > 0 AND Process_active + where: Process_committed AND Process_p_nom_extendable AND Process_p_nom_mod > 0 expression: Process_shut_down <= Process_n_mod ``` @@ -324,6 +336,7 @@ constraints: | $`\mu^{z,u}`$ | `Process_maintenance_status` over $`\Xi \times \mathcal{T} \times \mathcal{J}`$ | | $`Z`$ | `Process_p_nom_ext` over $`\mathcal{J}`$ | | $`\mathit{scenario\_opex}`$ | `scenario_opex` over $`\Xi`$, an expression this file adds `Process_commitment_opex` to | +| $`\mathrm{on}^{z,\mathrm{com}}`$ | `Process_committed` over $`\mathcal{T} \times \mathcal{J}`$, a mask another file defines | #### Definitions @@ -332,6 +345,12 @@ constraints: | $`\overleftarrow{u}^{z}`$ | `Process_previous_status` over $`\Xi \times \mathcal{T} \times \mathcal{J}`$ — the commitment state a process carries into a snapshot — the state it brought into the horizon at the first, the previous snapshot's after that | | $`\mathit{Process\_commitment\_opex}`$ | `Process_commitment_opex` over $`\Xi`$ | +#### Masks + +| Symbol | Meaning | +|---|---| +| $`\mathrm{on}^{z,\mathrm{com,ext}}`$ | `Process_com_ext` over $`\mathcal{T} \times \mathcal{J}`$ — a committable process with an extendable, non-modular build that stands in the snapshot's period — PyPSA's `com-ext` rows, whose status is relaxed against the chosen build | + $`\mathrm{pos}(t)`$ denotes where index $`t`$ sits along its dimension's own order — the order `shift` steps along, not the order labels sort in — counted from $`0`$. The index itself stays the coordinate, so $`t`$ compares against labels and $`\mathrm{pos}(t)`$ against positions. #### Subject to @@ -339,121 +358,121 @@ $`\mathrm{pos}(t)`$ denotes where index $`t`$ sits along its dimension's own ord **`Process_com_p_lower`** ```math -z_{\xi,t,j} \ge \underline{\mathrm{z}}_{\xi,t,j} \cdot \mathrm{z}^{\mathrm{nom}}_{\xi,j} \cdot \left( u^{z}_{\xi,t,j} - \gamma^{z}_{\xi,j} \cdot \mu^{z,u}_{\xi,t,j} \right) \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ j \in \mathcal{J} \,:\, \mathrm{com}^{z}_{j} \wedge \neg \mathrm{ext}^{z}_{j} \wedge \mathrm{on}^{z}_{t,j} +z_{\xi,t,j} \ge \underline{\mathrm{z}}_{\xi,t,j} \cdot \mathrm{z}^{\mathrm{nom}}_{\xi,j} \cdot \left( u^{z}_{\xi,t,j} - \gamma^{z}_{\xi,j} \cdot \mu^{z,u}_{\xi,t,j} \right) \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ j \in \mathcal{J} \,:\, \mathrm{on}^{z,\mathrm{com}}_{t,j} \wedge \neg \mathrm{ext}^{z}_{j} ``` **`Process_com_p_upper`** ```math -z_{\xi,t,j} \le \overline{\mathrm{z}}_{\xi,t,j} \cdot \mathrm{z}^{\mathrm{nom}}_{\xi,j} \cdot \left( u^{z}_{\xi,t,j} - \gamma^{z}_{\xi,j} \cdot \mu^{z,u}_{\xi,t,j} \right) \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ j \in \mathcal{J} \,:\, \mathrm{com}^{z}_{j} \wedge \neg \mathrm{ext}^{z}_{j} \wedge \mathrm{on}^{z}_{t,j} +z_{\xi,t,j} \le \overline{\mathrm{z}}_{\xi,t,j} \cdot \mathrm{z}^{\mathrm{nom}}_{\xi,j} \cdot \left( u^{z}_{\xi,t,j} - \gamma^{z}_{\xi,j} \cdot \mu^{z,u}_{\xi,t,j} \right) \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ j \in \mathcal{J} \,:\, \mathrm{on}^{z,\mathrm{com}}_{t,j} \wedge \neg \mathrm{ext}^{z}_{j} ``` **`Process_com_transition_start_up`** ```math -\mathit{up}^{z}_{\xi,t,j} \ge u^{z}_{\xi,t,j} - \overleftarrow{u}^{z}_{\xi,t,j} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ j \in \mathcal{J} \,:\, \mathrm{com}^{z}_{j} \wedge \mathrm{on}^{z}_{t,j} +\mathit{up}^{z}_{\xi,t,j} \ge u^{z}_{\xi,t,j} - \overleftarrow{u}^{z}_{\xi,t,j} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ j \in \mathcal{J} \,:\, \mathrm{on}^{z,\mathrm{com}}_{t,j} ``` **`Process_com_transition_shut_down`** ```math -\mathit{dn}^{z}_{\xi,t,j} \ge \overleftarrow{u}^{z}_{\xi,t,j} - u^{z}_{\xi,t,j} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ j \in \mathcal{J} \,:\, \mathrm{com}^{z}_{j} \wedge \mathrm{on}^{z}_{t,j} +\mathit{dn}^{z}_{\xi,t,j} \ge \overleftarrow{u}^{z}_{\xi,t,j} - u^{z}_{\xi,t,j} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ j \in \mathcal{J} \,:\, \mathrm{on}^{z,\mathrm{com}}_{t,j} ``` **`Process_com_up_time`** ```math -\sum_{t' \in \mathcal{T} \,:\, 0 \le t - t' < \mathrm{UT}^{z}} \mathit{up}^{z}_{\xi,t',j} \le u^{z}_{\xi,t,j} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ j \in \mathcal{J} \,:\, \mathrm{com}^{z}_{j} \wedge \mathrm{UT}^{z}_{\xi,j} > 0 \wedge \mathrm{pos}(t) > 0 \wedge \mathrm{on}^{z}_{t,j} +\sum_{t' \in \mathcal{T} \,:\, 0 \le t - t' < \mathrm{UT}^{z}} \mathit{up}^{z}_{\xi,t',j} \le u^{z}_{\xi,t,j} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ j \in \mathcal{J} \,:\, \mathrm{on}^{z,\mathrm{com}}_{t,j} \wedge \mathrm{UT}^{z}_{\xi,j} > 0 \wedge \mathrm{pos}(t) > 0 ``` **`Process_com_down_time`** ```math -\sum_{t' \in \mathcal{T} \,:\, 0 \le t - t' < \mathrm{DT}^{z}} \mathit{dn}^{z}_{\xi,t',j} \le 1 - u^{z}_{\xi,t,j} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ j \in \mathcal{J} \,:\, \mathrm{com}^{z}_{j} \wedge \mathrm{DT}^{z}_{\xi,j} > 0 \wedge \mathrm{pos}(t) > 0 \wedge \mathrm{on}^{z}_{t,j} +\sum_{t' \in \mathcal{T} \,:\, 0 \le t - t' < \mathrm{DT}^{z}} \mathit{dn}^{z}_{\xi,t',j} \le 1 - u^{z}_{\xi,t,j} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ j \in \mathcal{J} \,:\, \mathrm{on}^{z,\mathrm{com}}_{t,j} \wedge \mathrm{DT}^{z}_{\xi,j} > 0 \wedge \mathrm{pos}(t) > 0 ``` **`Process_com_status_must_stay_up`** ```math -u^{z}_{\xi,t,j} = 1 \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ j \in \mathcal{J} \,:\, \mathrm{com}^{z}_{j} \wedge \mathrm{hold}^{z}_{\xi,t,j} \wedge \mathrm{on}^{z}_{t,j} +u^{z}_{\xi,t,j} = 1 \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ j \in \mathcal{J} \,:\, \mathrm{on}^{z,\mathrm{com}}_{t,j} \wedge \mathrm{hold}^{z}_{\xi,t,j} ``` **`Process_com_status_must_stay_down`** ```math -u^{z}_{\xi,t,j} = 0 \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ j \in \mathcal{J} \,:\, \mathrm{com}^{z}_{j} \wedge \mathrm{rest}^{z}_{\xi,t,j} \wedge \mathrm{on}^{z}_{t,j} +u^{z}_{\xi,t,j} = 0 \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ j \in \mathcal{J} \,:\, \mathrm{on}^{z,\mathrm{com}}_{t,j} \wedge \mathrm{rest}^{z}_{\xi,t,j} ``` **`Process_com_ext_p_upper_cap`** ```math -z_{\xi,t,j} \le \overline{\mathrm{z}}_{\xi,t,j} \cdot \left( Z_{j} - \gamma^{z}_{\xi,j} \cdot \mu^{z,\mathrm{nom}}_{\xi,t,j} \right) \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ j \in \mathcal{J} \,:\, \mathrm{com}^{z}_{j} \wedge \mathrm{ext}^{z}_{j} \wedge \neg \left( \mathrm{z}^{\mathrm{mod}}_{j} > 0 \right) \wedge \mathrm{on}^{z}_{t,j} +z_{\xi,t,j} \le \overline{\mathrm{z}}_{\xi,t,j} \cdot \left( Z_{j} - \gamma^{z}_{\xi,j} \cdot \mu^{z,\mathrm{nom}}_{\xi,t,j} \right) \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ j \in \mathcal{J} \,:\, \mathrm{on}^{z,\mathrm{com,ext}}_{t,j} ``` **`Process_com_ext_p_upper_big_m`** ```math -z_{\xi,t,j} \le \mathrm{M}^{z}_{\xi,j} \cdot u^{z}_{\xi,t,j} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ j \in \mathcal{J} \,:\, \mathrm{com}^{z}_{j} \wedge \mathrm{ext}^{z}_{j} \wedge \neg \left( \mathrm{z}^{\mathrm{mod}}_{j} > 0 \right) \wedge \mathrm{on}^{z}_{t,j} +z_{\xi,t,j} \le \mathrm{M}^{z}_{\xi,j} \cdot u^{z}_{\xi,t,j} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ j \in \mathcal{J} \,:\, \mathrm{on}^{z,\mathrm{com,ext}}_{t,j} ``` **`Process_com_ext_p_lower`** ```math -z_{\xi,t,j} \ge \underline{\mathrm{z}}_{\xi,t,j} \cdot \left( Z_{j} - \gamma^{z}_{\xi,j} \cdot \mu^{z,\mathrm{nom}}_{\xi,t,j} \right) + \mathrm{M}^{z}_{\xi,j} \cdot u^{z}_{\xi,t,j} - \mathrm{M}^{z}_{\xi,j} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ j \in \mathcal{J} \,:\, \mathrm{com}^{z}_{j} \wedge \mathrm{ext}^{z}_{j} \wedge \neg \left( \mathrm{z}^{\mathrm{mod}}_{j} > 0 \right) \wedge \mathrm{on}^{z}_{t,j} +z_{\xi,t,j} \ge \underline{\mathrm{z}}_{\xi,t,j} \cdot \left( Z_{j} - \gamma^{z}_{\xi,j} \cdot \mu^{z,\mathrm{nom}}_{\xi,t,j} \right) + \mathrm{M}^{z}_{\xi,j} \cdot u^{z}_{\xi,t,j} - \mathrm{M}^{z}_{\xi,j} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ j \in \mathcal{J} \,:\, \mathrm{on}^{z,\mathrm{com,ext}}_{t,j} ``` **`Process_com_ext_p_lower_nonneg`** ```math -z_{\xi,t,j} \ge 0 \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ j \in \mathcal{J} \,:\, \mathrm{com}^{z}_{j} \wedge \mathrm{ext}^{z}_{j} \wedge \mathrm{nonneg}^{z}_{j} \wedge \neg \left( \mathrm{z}^{\mathrm{mod}}_{j} > 0 \right) \wedge \mathrm{on}^{z}_{t,j} +z_{\xi,t,j} \ge 0 \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ j \in \mathcal{J} \,:\, \mathrm{on}^{z,\mathrm{com,ext}}_{t,j} \wedge \mathrm{nonneg}^{z}_{j} ``` **`Process_com_mod_p_lower`** ```math -z_{\xi,t,j} \ge \underline{\mathrm{z}}_{\xi,t,j} \cdot \mathrm{z}^{\mathrm{mod}}_{j} \cdot \left( u^{z}_{\xi,t,j} - \gamma^{z}_{\xi,j} \cdot \mu^{z,u}_{\xi,t,j} \right) \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ j \in \mathcal{J} \,:\, \mathrm{com}^{z}_{j} \wedge \mathrm{z}^{\mathrm{mod}}_{j} > 0 \wedge \mathrm{on}^{z}_{t,j} +z_{\xi,t,j} \ge \underline{\mathrm{z}}_{\xi,t,j} \cdot \mathrm{z}^{\mathrm{mod}}_{j} \cdot \left( u^{z}_{\xi,t,j} - \gamma^{z}_{\xi,j} \cdot \mu^{z,u}_{\xi,t,j} \right) \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ j \in \mathcal{J} \,:\, \mathrm{on}^{z,\mathrm{com}}_{t,j} \wedge \mathrm{z}^{\mathrm{mod}}_{j} > 0 ``` **`Process_com_mod_p_upper`** ```math -z_{\xi,t,j} \le \overline{\mathrm{z}}_{\xi,t,j} \cdot \mathrm{z}^{\mathrm{mod}}_{j} \cdot \left( u^{z}_{\xi,t,j} - \gamma^{z}_{\xi,j} \cdot \mu^{z,u}_{\xi,t,j} \right) \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ j \in \mathcal{J} \,:\, \mathrm{com}^{z}_{j} \wedge \mathrm{z}^{\mathrm{mod}}_{j} > 0 \wedge \mathrm{on}^{z}_{t,j} +z_{\xi,t,j} \le \overline{\mathrm{z}}_{\xi,t,j} \cdot \mathrm{z}^{\mathrm{mod}}_{j} \cdot \left( u^{z}_{\xi,t,j} - \gamma^{z}_{\xi,j} \cdot \mu^{z,u}_{\xi,t,j} \right) \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ j \in \mathcal{J} \,:\, \mathrm{on}^{z,\mathrm{com}}_{t,j} \wedge \mathrm{z}^{\mathrm{mod}}_{j} > 0 ``` **`Process_status_p_fixed_upper`** ```math -u^{z}_{\xi,t,j} \le \mathrm{N}^{z,\mathrm{fix}}_{\xi,j} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ j \in \mathcal{J} \,:\, \mathrm{com}^{z}_{j} \wedge \neg \left( \mathrm{ext}^{z}_{j} \wedge \mathrm{z}^{\mathrm{mod}}_{j} > 0 \right) \wedge \mathrm{on}^{z}_{t,j} +u^{z}_{\xi,t,j} \le \mathrm{N}^{z,\mathrm{fix}}_{\xi,j} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ j \in \mathcal{J} \,:\, \mathrm{on}^{z,\mathrm{com}}_{t,j} \wedge \neg \left( \mathrm{ext}^{z}_{j} \wedge \mathrm{z}^{\mathrm{mod}}_{j} > 0 \right) ``` **`Process_start_up_p_fixed_upper`** ```math -\mathit{up}^{z}_{\xi,t,j} \le \mathrm{N}^{z,\mathrm{fix}}_{\xi,j} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ j \in \mathcal{J} \,:\, \mathrm{com}^{z}_{j} \wedge \neg \left( \mathrm{ext}^{z}_{j} \wedge \mathrm{z}^{\mathrm{mod}}_{j} > 0 \right) \wedge \mathrm{on}^{z}_{t,j} +\mathit{up}^{z}_{\xi,t,j} \le \mathrm{N}^{z,\mathrm{fix}}_{\xi,j} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ j \in \mathcal{J} \,:\, \mathrm{on}^{z,\mathrm{com}}_{t,j} \wedge \neg \left( \mathrm{ext}^{z}_{j} \wedge \mathrm{z}^{\mathrm{mod}}_{j} > 0 \right) ``` **`Process_shut_down_p_fixed_upper`** ```math -\mathit{dn}^{z}_{\xi,t,j} \le \mathrm{N}^{z,\mathrm{fix}}_{\xi,j} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ j \in \mathcal{J} \,:\, \mathrm{com}^{z}_{j} \wedge \neg \left( \mathrm{ext}^{z}_{j} \wedge \mathrm{z}^{\mathrm{mod}}_{j} > 0 \right) \wedge \mathrm{on}^{z}_{t,j} +\mathit{dn}^{z}_{\xi,t,j} \le \mathrm{N}^{z,\mathrm{fix}}_{\xi,j} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ j \in \mathcal{J} \,:\, \mathrm{on}^{z,\mathrm{com}}_{t,j} \wedge \neg \left( \mathrm{ext}^{z}_{j} \wedge \mathrm{z}^{\mathrm{mod}}_{j} > 0 \right) ``` **`Process_status_p_nom_variable_upper`** ```math -u^{z}_{\xi,t,j} \le N^{z}_{j} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ j \in \mathcal{J} \,:\, \mathrm{com}^{z}_{j} \wedge \mathrm{ext}^{z}_{j} \wedge \mathrm{z}^{\mathrm{mod}}_{j} > 0 \wedge \mathrm{on}^{z}_{t,j} +u^{z}_{\xi,t,j} \le N^{z}_{j} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ j \in \mathcal{J} \,:\, \mathrm{on}^{z,\mathrm{com}}_{t,j} \wedge \mathrm{ext}^{z}_{j} \wedge \mathrm{z}^{\mathrm{mod}}_{j} > 0 ``` **`Process_start_up_p_nom_variable_upper`** ```math -\mathit{up}^{z}_{\xi,t,j} \le N^{z}_{j} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ j \in \mathcal{J} \,:\, \mathrm{com}^{z}_{j} \wedge \mathrm{ext}^{z}_{j} \wedge \mathrm{z}^{\mathrm{mod}}_{j} > 0 \wedge \mathrm{on}^{z}_{t,j} +\mathit{up}^{z}_{\xi,t,j} \le N^{z}_{j} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ j \in \mathcal{J} \,:\, \mathrm{on}^{z,\mathrm{com}}_{t,j} \wedge \mathrm{ext}^{z}_{j} \wedge \mathrm{z}^{\mathrm{mod}}_{j} > 0 ``` **`Process_shut_down_p_nom_variable_upper`** ```math -\mathit{dn}^{z}_{\xi,t,j} \le N^{z}_{j} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ j \in \mathcal{J} \,:\, \mathrm{com}^{z}_{j} \wedge \mathrm{ext}^{z}_{j} \wedge \mathrm{z}^{\mathrm{mod}}_{j} > 0 \wedge \mathrm{on}^{z}_{t,j} +\mathit{dn}^{z}_{\xi,t,j} \le N^{z}_{j} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ j \in \mathcal{J} \,:\, \mathrm{on}^{z,\mathrm{com}}_{t,j} \wedge \mathrm{ext}^{z}_{j} \wedge \mathrm{z}^{\mathrm{mod}}_{j} > 0 ``` #### Definitions @@ -470,23 +489,31 @@ u^{z}_{\xi,t,j} \le N^{z}_{j} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ \mathit{Process\_commitment\_opex}_{\xi} = \sum_{t \in \mathcal{T}} \sum_{j \in \mathcal{J}} u^{z}_{\xi,t,j} \cdot \mathrm{c}^{z,\mathrm{on}}_{\xi,t,j} \cdot \mathrm{w}_{t} \cdot \mathrm{w}^{y}_{\mathrm{snapshot\_period}(t)} + \sum_{t \in \mathcal{T}} \sum_{j \in \mathcal{J}} \mathit{up}^{z}_{\xi,t,j} \cdot \mathrm{c}^{z,\mathrm{up}}_{\xi,j} + \sum_{t \in \mathcal{T}} \sum_{j \in \mathcal{J}} \mathit{dn}^{z}_{\xi,t,j} \cdot \mathrm{c}^{z,\mathrm{dn}}_{\xi,j} \qquad \forall\, \xi \in \Xi ``` +#### Masks + +**`Process_com_ext`** + +```math +\mathrm{on}^{z,\mathrm{com,ext}}_{t,j} \iff \mathrm{com}^{z}_{j} \wedge \mathrm{ext}^{z}_{j} \wedge \neg \left( \mathrm{z}^{\mathrm{mod}}_{j} > 0 \right) \wedge \mathrm{on}^{z}_{t,j} \qquad \forall\, t \in \mathcal{T},\ j \in \mathcal{J} +``` + #### Variable domains **`Process_status`** ```math -u^{z}_{\xi,t,j} \ge 0, u^{z}_{\xi,t,j} \in \mathbb{Z} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ j \in \mathcal{J} \,:\, \mathrm{com}^{z}_{j} \wedge \mathrm{on}^{z}_{t,j} +u^{z}_{\xi,t,j} \ge 0, u^{z}_{\xi,t,j} \in \mathbb{Z} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ j \in \mathcal{J} \,:\, \mathrm{on}^{z,\mathrm{com}}_{t,j} ``` **`Process_start_up`** ```math -\mathit{up}^{z}_{\xi,t,j} \ge 0, \mathit{up}^{z}_{\xi,t,j} \in \mathbb{Z} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ j \in \mathcal{J} \,:\, \mathrm{com}^{z}_{j} \wedge \mathrm{on}^{z}_{t,j} +\mathit{up}^{z}_{\xi,t,j} \ge 0, \mathit{up}^{z}_{\xi,t,j} \in \mathbb{Z} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ j \in \mathcal{J} \,:\, \mathrm{on}^{z,\mathrm{com}}_{t,j} ``` **`Process_shut_down`** ```math -\mathit{dn}^{z}_{\xi,t,j} \ge 0, \mathit{dn}^{z}_{\xi,t,j} \in \mathbb{Z} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ j \in \mathcal{J} \,:\, \mathrm{com}^{z}_{j} \wedge \mathrm{on}^{z}_{t,j} +\mathit{dn}^{z}_{\xi,t,j} \ge 0, \mathit{dn}^{z}_{\xi,t,j} \in \mathbb{Z} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ j \in \mathcal{J} \,:\, \mathrm{on}^{z,\mathrm{com}}_{t,j} ``` diff --git a/docs/examples/pypsa/process_maintenance.md b/docs/examples/pypsa/process_maintenance.md index 0c223e1b2..eff8bd65e 100644 --- a/docs/examples/pypsa/process_maintenance.md +++ b/docs/examples/pypsa/process_maintenance.md @@ -81,9 +81,7 @@ variables: `Process-maintenance_capacity` — the chosen build while in maintenance, zero otherwise: the product the `maintcap` rows linearize dims: [scenario, snapshot, process] - where: >- - Process_maintainable AND Process_p_nom_extendable - AND NOT (Process_committable AND Process_p_nom_mod > 0) AND Process_active + where: Process_maint_ext absence: zero bounds: lower: 0 @@ -94,8 +92,9 @@ variables: maintenance may also be off dims: [scenario, snapshot, process] where: >- - Process_maintainable AND Process_committable - AND NOT (Process_p_nom_extendable AND NOT (Process_p_nom_mod > 0)) AND Process_active + Process_maintainable + AND Process_committed + AND NOT (Process_p_nom_extendable AND NOT (Process_p_nom_mod > 0)) absence: zero bounds: lower: 0 @@ -112,6 +111,20 @@ given: variables: Process_status: { dims: [scenario, snapshot, process], domain: integer } Process_p_nom_ext: { dims: [process] } + masks: + Process_committed: { dims: [snapshot, process] } + +masks: + Process_maint_ext: + description: >- + a maintainable process with an extendable build, unless it is + committable and modular, that stands in the snapshot's period — the + maintenance rows against the chosen build + where: >- + Process_maintainable + AND Process_p_nom_extendable + AND NOT (Process_committable AND Process_p_nom_mod > 0) + AND Process_active constraints: Process_maint_event_count: @@ -137,54 +150,54 @@ constraints: `Process-maintcap_upper` — the build taken off is at most the chosen build in maintenance, and at most the build less its floor out of it dims: [scenario, snapshot, process] - where: Process_maintainable AND Process_p_nom_extendable AND NOT (Process_committable AND Process_p_nom_mod > 0) AND Process_active + where: Process_maint_ext expression: Process_maintenance_capacity <= Process_p_nom_ext - Process_p_nom_min * (1 - Process_maintenance) Process_maintcap_upper_nommax: description: "`Process-maintcap_upper_nommax` — out of maintenance, no build is taken off" dims: [scenario, snapshot, process] - where: Process_maintainable AND Process_p_nom_extendable AND NOT (Process_committable AND Process_p_nom_mod > 0) AND Process_active + where: Process_maint_ext expression: Process_maintenance_capacity <= Process_p_nom_max * Process_maintenance Process_maintcap_lower_nommax: description: "`Process-maintcap_lower_nommax` — in maintenance, the whole chosen build is taken off" dims: [scenario, snapshot, process] - where: Process_maintainable AND Process_p_nom_extendable AND NOT (Process_committable AND Process_p_nom_mod > 0) AND Process_active + where: Process_maint_ext expression: Process_maintenance_capacity >= Process_p_nom_ext - Process_p_nom_max * (1 - Process_maintenance) Process_maintcap_lower_nommin: description: "`Process-maintcap_lower_nommin` — in maintenance, at least the floor of the build is taken off" dims: [scenario, snapshot, process] - where: Process_maintainable AND Process_p_nom_extendable AND NOT (Process_committable AND Process_p_nom_mod > 0) AND Process_active AND Process_p_nom_min > 0 + where: Process_maint_ext AND Process_p_nom_min > 0 expression: Process_maintenance_capacity >= Process_p_nom_min * Process_maintenance Process_maint_status_le_status: description: "`Process-maint-status-le-status` — the status in maintenance is at most the status" dims: [scenario, snapshot, process] - where: Process_maintainable AND Process_committable AND NOT Process_p_nom_extendable AND Process_active + where: Process_maintainable AND Process_committed AND NOT Process_p_nom_extendable expression: Process_maintenance_status <= Process_status Process_maint_status_le_maint: description: "`Process-maint-status-le-maint` — out of maintenance, the status in maintenance is zero" dims: [scenario, snapshot, process] - where: Process_maintainable AND Process_committable AND NOT Process_p_nom_extendable AND Process_active + where: Process_maintainable AND Process_committed AND NOT Process_p_nom_extendable expression: Process_maintenance_status <= Process_maintenance Process_maint_status_lb: description: "`Process-maint-status-lb` — on and in maintenance, the status in maintenance is one" dims: [scenario, snapshot, process] - where: Process_maintainable AND Process_committable AND NOT Process_p_nom_extendable AND Process_active + where: Process_maintainable AND Process_committed AND NOT Process_p_nom_extendable expression: Process_maintenance_status >= Process_status + Process_maintenance - 1 Process_maint_modstatus_le_status: description: "`Process-maint-modstatus-le-status` — the modules on in maintenance are at most the modules on" dims: [scenario, snapshot, process] - where: Process_maintainable AND Process_committable AND Process_p_nom_mod > 0 AND Process_active + where: Process_maintainable AND Process_committed AND Process_p_nom_mod > 0 expression: Process_maintenance_status <= Process_status Process_maint_modstatus_le_maint: description: >- `Process-maint-modstatus-le-maint` — out of maintenance, no module is on in maintenance; in it, at most the modules the build cap holds dims: [scenario, snapshot, process] - where: Process_maintainable AND Process_committable AND Process_p_nom_mod > 0 AND Process_active + where: Process_maintainable AND Process_committed AND Process_p_nom_mod > 0 expression: Process_maintenance_status <= Process_p_nom_max / Process_p_nom_mod * Process_maintenance Process_maint_modstatus_lb: description: "`Process-maint-modstatus-lb` — in maintenance, every module on is on in maintenance" dims: [scenario, snapshot, process] - where: Process_maintainable AND Process_committable AND Process_p_nom_mod > 0 AND Process_active + where: Process_maintainable AND Process_committed AND Process_p_nom_mod > 0 expression: Process_maintenance_status >= Process_status - Process_p_nom_max / Process_p_nom_mod * (1 - Process_maintenance) assumptions: @@ -271,6 +284,13 @@ assumptions: | $`\mathrm{w}^{\mathrm{gen}}`$ | `snapshot_weightings_generators` over $`\mathcal{T}`$, data another file declares | | $`u^{z}`$ | `Process_status` over $`\Xi \times \mathcal{T} \times \mathcal{J}`$ | | $`Z`$ | `Process_p_nom_ext` over $`\mathcal{J}`$ | +| $`\mathrm{on}^{z,\mathrm{com}}`$ | `Process_committed` over $`\mathcal{T} \times \mathcal{J}`$, a mask another file defines | + +#### Masks + +| Symbol | Meaning | +|---|---| +| $`\mathrm{on}^{z,\mathrm{mnt,ext}}`$ | `Process_maint_ext` over $`\mathcal{T} \times \mathcal{J}`$ — a maintainable process with an extendable build, unless it is committable and modular, that stands in the snapshot's period — the maintenance rows against the chosen build | #### Subject to @@ -295,61 +315,69 @@ assumptions: **`Process_maintcap_upper`** ```math -\mu^{z,\mathrm{nom}}_{\xi,t,j} \le Z_{j} - \underline{\mathrm{z}}^{\mathrm{nom}}_{\xi,j} \cdot \left( 1 - \mu^{z}_{\xi,t,j} \right) \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ j \in \mathcal{J} \,:\, \mathrm{mnt}^{z}_{j} \wedge \mathrm{ext}^{z}_{j} \wedge \neg \left( \mathrm{com}^{z}_{j} \wedge \mathrm{z}^{\mathrm{mod}}_{j} > 0 \right) \wedge \mathrm{on}^{z}_{t,j} +\mu^{z,\mathrm{nom}}_{\xi,t,j} \le Z_{j} - \underline{\mathrm{z}}^{\mathrm{nom}}_{\xi,j} \cdot \left( 1 - \mu^{z}_{\xi,t,j} \right) \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ j \in \mathcal{J} \,:\, \mathrm{on}^{z,\mathrm{mnt,ext}}_{t,j} ``` **`Process_maintcap_upper_nommax`** ```math -\mu^{z,\mathrm{nom}}_{\xi,t,j} \le \overline{\mathrm{z}}^{\mathrm{nom}}_{\xi,j} \cdot \mu^{z}_{\xi,t,j} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ j \in \mathcal{J} \,:\, \mathrm{mnt}^{z}_{j} \wedge \mathrm{ext}^{z}_{j} \wedge \neg \left( \mathrm{com}^{z}_{j} \wedge \mathrm{z}^{\mathrm{mod}}_{j} > 0 \right) \wedge \mathrm{on}^{z}_{t,j} +\mu^{z,\mathrm{nom}}_{\xi,t,j} \le \overline{\mathrm{z}}^{\mathrm{nom}}_{\xi,j} \cdot \mu^{z}_{\xi,t,j} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ j \in \mathcal{J} \,:\, \mathrm{on}^{z,\mathrm{mnt,ext}}_{t,j} ``` **`Process_maintcap_lower_nommax`** ```math -\mu^{z,\mathrm{nom}}_{\xi,t,j} \ge Z_{j} - \overline{\mathrm{z}}^{\mathrm{nom}}_{\xi,j} \cdot \left( 1 - \mu^{z}_{\xi,t,j} \right) \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ j \in \mathcal{J} \,:\, \mathrm{mnt}^{z}_{j} \wedge \mathrm{ext}^{z}_{j} \wedge \neg \left( \mathrm{com}^{z}_{j} \wedge \mathrm{z}^{\mathrm{mod}}_{j} > 0 \right) \wedge \mathrm{on}^{z}_{t,j} +\mu^{z,\mathrm{nom}}_{\xi,t,j} \ge Z_{j} - \overline{\mathrm{z}}^{\mathrm{nom}}_{\xi,j} \cdot \left( 1 - \mu^{z}_{\xi,t,j} \right) \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ j \in \mathcal{J} \,:\, \mathrm{on}^{z,\mathrm{mnt,ext}}_{t,j} ``` **`Process_maintcap_lower_nommin`** ```math -\mu^{z,\mathrm{nom}}_{\xi,t,j} \ge \underline{\mathrm{z}}^{\mathrm{nom}}_{\xi,j} \cdot \mu^{z}_{\xi,t,j} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ j \in \mathcal{J} \,:\, \mathrm{mnt}^{z}_{j} \wedge \mathrm{ext}^{z}_{j} \wedge \neg \left( \mathrm{com}^{z}_{j} \wedge \mathrm{z}^{\mathrm{mod}}_{j} > 0 \right) \wedge \mathrm{on}^{z}_{t,j} \wedge \underline{\mathrm{z}}^{\mathrm{nom}}_{\xi,j} > 0 +\mu^{z,\mathrm{nom}}_{\xi,t,j} \ge \underline{\mathrm{z}}^{\mathrm{nom}}_{\xi,j} \cdot \mu^{z}_{\xi,t,j} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ j \in \mathcal{J} \,:\, \mathrm{on}^{z,\mathrm{mnt,ext}}_{t,j} \wedge \underline{\mathrm{z}}^{\mathrm{nom}}_{\xi,j} > 0 ``` **`Process_maint_status_le_status`** ```math -\mu^{z,u}_{\xi,t,j} \le u^{z}_{\xi,t,j} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ j \in \mathcal{J} \,:\, \mathrm{mnt}^{z}_{j} \wedge \mathrm{com}^{z}_{j} \wedge \neg \mathrm{ext}^{z}_{j} \wedge \mathrm{on}^{z}_{t,j} +\mu^{z,u}_{\xi,t,j} \le u^{z}_{\xi,t,j} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ j \in \mathcal{J} \,:\, \mathrm{mnt}^{z}_{j} \wedge \mathrm{on}^{z,\mathrm{com}}_{t,j} \wedge \neg \mathrm{ext}^{z}_{j} ``` **`Process_maint_status_le_maint`** ```math -\mu^{z,u}_{\xi,t,j} \le \mu^{z}_{\xi,t,j} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ j \in \mathcal{J} \,:\, \mathrm{mnt}^{z}_{j} \wedge \mathrm{com}^{z}_{j} \wedge \neg \mathrm{ext}^{z}_{j} \wedge \mathrm{on}^{z}_{t,j} +\mu^{z,u}_{\xi,t,j} \le \mu^{z}_{\xi,t,j} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ j \in \mathcal{J} \,:\, \mathrm{mnt}^{z}_{j} \wedge \mathrm{on}^{z,\mathrm{com}}_{t,j} \wedge \neg \mathrm{ext}^{z}_{j} ``` **`Process_maint_status_lb`** ```math -\mu^{z,u}_{\xi,t,j} \ge u^{z}_{\xi,t,j} + \mu^{z}_{\xi,t,j} - 1 \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ j \in \mathcal{J} \,:\, \mathrm{mnt}^{z}_{j} \wedge \mathrm{com}^{z}_{j} \wedge \neg \mathrm{ext}^{z}_{j} \wedge \mathrm{on}^{z}_{t,j} +\mu^{z,u}_{\xi,t,j} \ge u^{z}_{\xi,t,j} + \mu^{z}_{\xi,t,j} - 1 \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ j \in \mathcal{J} \,:\, \mathrm{mnt}^{z}_{j} \wedge \mathrm{on}^{z,\mathrm{com}}_{t,j} \wedge \neg \mathrm{ext}^{z}_{j} ``` **`Process_maint_modstatus_le_status`** ```math -\mu^{z,u}_{\xi,t,j} \le u^{z}_{\xi,t,j} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ j \in \mathcal{J} \,:\, \mathrm{mnt}^{z}_{j} \wedge \mathrm{com}^{z}_{j} \wedge \mathrm{z}^{\mathrm{mod}}_{j} > 0 \wedge \mathrm{on}^{z}_{t,j} +\mu^{z,u}_{\xi,t,j} \le u^{z}_{\xi,t,j} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ j \in \mathcal{J} \,:\, \mathrm{mnt}^{z}_{j} \wedge \mathrm{on}^{z,\mathrm{com}}_{t,j} \wedge \mathrm{z}^{\mathrm{mod}}_{j} > 0 ``` **`Process_maint_modstatus_le_maint`** ```math -\mu^{z,u}_{\xi,t,j} \le \frac{\overline{\mathrm{z}}^{\mathrm{nom}}_{\xi,j}}{\mathrm{z}^{\mathrm{mod}}_{j}} \cdot \mu^{z}_{\xi,t,j} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ j \in \mathcal{J} \,:\, \mathrm{mnt}^{z}_{j} \wedge \mathrm{com}^{z}_{j} \wedge \mathrm{z}^{\mathrm{mod}}_{j} > 0 \wedge \mathrm{on}^{z}_{t,j} +\mu^{z,u}_{\xi,t,j} \le \frac{\overline{\mathrm{z}}^{\mathrm{nom}}_{\xi,j}}{\mathrm{z}^{\mathrm{mod}}_{j}} \cdot \mu^{z}_{\xi,t,j} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ j \in \mathcal{J} \,:\, \mathrm{mnt}^{z}_{j} \wedge \mathrm{on}^{z,\mathrm{com}}_{t,j} \wedge \mathrm{z}^{\mathrm{mod}}_{j} > 0 ``` **`Process_maint_modstatus_lb`** ```math -\mu^{z,u}_{\xi,t,j} \ge u^{z}_{\xi,t,j} - \frac{\overline{\mathrm{z}}^{\mathrm{nom}}_{\xi,j}}{\mathrm{z}^{\mathrm{mod}}_{j}} \cdot \left( 1 - \mu^{z}_{\xi,t,j} \right) \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ j \in \mathcal{J} \,:\, \mathrm{mnt}^{z}_{j} \wedge \mathrm{com}^{z}_{j} \wedge \mathrm{z}^{\mathrm{mod}}_{j} > 0 \wedge \mathrm{on}^{z}_{t,j} +\mu^{z,u}_{\xi,t,j} \ge u^{z}_{\xi,t,j} - \frac{\overline{\mathrm{z}}^{\mathrm{nom}}_{\xi,j}}{\mathrm{z}^{\mathrm{mod}}_{j}} \cdot \left( 1 - \mu^{z}_{\xi,t,j} \right) \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ j \in \mathcal{J} \,:\, \mathrm{mnt}^{z}_{j} \wedge \mathrm{on}^{z,\mathrm{com}}_{t,j} \wedge \mathrm{z}^{\mathrm{mod}}_{j} > 0 +``` + +#### Masks + +**`Process_maint_ext`** + +```math +\mathrm{on}^{z,\mathrm{mnt,ext}}_{t,j} \iff \mathrm{mnt}^{z}_{j} \wedge \mathrm{ext}^{z}_{j} \wedge \neg \left( \mathrm{com}^{z}_{j} \wedge \mathrm{z}^{\mathrm{mod}}_{j} > 0 \right) \wedge \mathrm{on}^{z}_{t,j} \qquad \forall\, t \in \mathcal{T},\ j \in \mathcal{J} ``` #### Variable domains @@ -369,13 +397,13 @@ assumptions: **`Process_maintenance_capacity`** ```math -\mu^{z,\mathrm{nom}}_{\xi,t,j} \ge 0 \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ j \in \mathcal{J} \,:\, \mathrm{mnt}^{z}_{j} \wedge \mathrm{ext}^{z}_{j} \wedge \neg \left( \mathrm{com}^{z}_{j} \wedge \mathrm{z}^{\mathrm{mod}}_{j} > 0 \right) \wedge \mathrm{on}^{z}_{t,j} +\mu^{z,\mathrm{nom}}_{\xi,t,j} \ge 0 \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ j \in \mathcal{J} \,:\, \mathrm{on}^{z,\mathrm{mnt,ext}}_{t,j} ``` **`Process_maintenance_status`** ```math -\mu^{z,u}_{\xi,t,j} \ge 0 \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ j \in \mathcal{J} \,:\, \mathrm{mnt}^{z}_{j} \wedge \mathrm{com}^{z}_{j} \wedge \neg \left( \mathrm{ext}^{z}_{j} \wedge \neg \left( \mathrm{z}^{\mathrm{mod}}_{j} > 0 \right) \right) \wedge \mathrm{on}^{z}_{t,j} +\mu^{z,u}_{\xi,t,j} \ge 0 \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ j \in \mathcal{J} \,:\, \mathrm{mnt}^{z}_{j} \wedge \mathrm{on}^{z,\mathrm{com}}_{t,j} \wedge \neg \left( \mathrm{ext}^{z}_{j} \wedge \neg \left( \mathrm{z}^{\mathrm{mod}}_{j} > 0 \right) \right) ``` #### Assumptions diff --git a/docs/examples/pypsa/process_ramping.md b/docs/examples/pypsa/process_ramping.md index ab830860c..21fc5685e 100644 --- a/docs/examples/pypsa/process_ramping.md +++ b/docs/examples/pypsa/process_ramping.md @@ -65,6 +65,8 @@ given: Process_p_nom_effective: { dims: [scenario, process] } Process_previous_status: { dims: [scenario, snapshot, process] } Process_p_nom_committed: { dims: [scenario, process] } + masks: + Process_com_ext: { dims: [snapshot, process] } expressions: Process_previous_p: @@ -137,6 +139,16 @@ expressions: * (Process_previous_status - Process_status) otherwise: Process_ramp_down_rate * Process_p_nom_effective +masks: + Process_ramps_from_previous: + description: >- + a snapshot whose ramp reads a previous output — any snapshot but its + period's first, and the horizon's first where the process comes in off + or carries an initial output + where: >- + position(snapshot, by=snapshot_period, within=period) > 0 OR (position(snapshot) == 0 AND + (Process_status_initial == 0 OR Process_p_init)) + constraints: Process_p_ramp_limit_up_run_big_m: description: >- @@ -144,11 +156,7 @@ constraints: raises internal power no faster than its limit of the chosen build; the big M releases the row in the snapshot it turns on dims: [scenario, snapshot, process] - where: >- - Process_committable AND Process_p_nom_extendable AND NOT (Process_p_nom_mod > 0) - AND (Process_ramp_limit_up OR Process_ramp_limit_start_up) - AND (position(snapshot, by=snapshot_period, within=period) > 0 OR (position(snapshot) == 0 AND (Process_status_initial == 0 OR Process_p_init))) - AND Process_active + where: Process_com_ext AND (Process_ramp_limit_up OR Process_ramp_limit_start_up) AND Process_ramps_from_previous expression: >- Process_p - Process_previous_p <= Process_ramp_up_rate * Process_p_nom_ext @@ -159,11 +167,7 @@ constraints: committed extendable process ramps no further than its start-up ramp of the chosen build; the big M releases the row everywhere else dims: [scenario, snapshot, process] - where: >- - Process_committable AND Process_p_nom_extendable AND NOT (Process_p_nom_mod > 0) - AND (Process_ramp_limit_up OR Process_ramp_limit_start_up) - AND (position(snapshot, by=snapshot_period, within=period) > 0 OR (position(snapshot) == 0 AND (Process_status_initial == 0 OR Process_p_init))) - AND Process_active + where: Process_com_ext AND (Process_ramp_limit_up OR Process_ramp_limit_start_up) AND Process_ramps_from_previous expression: >- Process_p - Process_previous_p <= Process_start_up_rate * Process_p_nom_ext @@ -175,10 +179,9 @@ constraints: releases the row in the snapshot it turns off dims: [scenario, snapshot, process] where: >- - Process_committable AND Process_p_nom_extendable AND NOT (Process_p_nom_mod > 0) + Process_com_ext AND (Process_ramp_limit_down OR Process_ramp_limit_shut_down) - AND (position(snapshot, by=snapshot_period, within=period) > 0 OR (position(snapshot) == 0 AND (Process_status_initial == 0 OR Process_p_init))) - AND Process_active + AND Process_ramps_from_previous expression: >- Process_previous_p - Process_p <= Process_ramp_down_rate * Process_p_nom_ext @@ -190,10 +193,9 @@ constraints: the chosen build; the big M releases the row everywhere else dims: [scenario, snapshot, process] where: >- - Process_committable AND Process_p_nom_extendable AND NOT (Process_p_nom_mod > 0) + Process_com_ext AND (Process_ramp_limit_down OR Process_ramp_limit_shut_down) - AND (position(snapshot, by=snapshot_period, within=period) > 0 OR (position(snapshot) == 0 AND (Process_status_initial == 0 OR Process_p_init))) - AND Process_active + AND Process_ramps_from_previous expression: >- Process_previous_p - Process_p <= Process_shut_down_rate * Process_p_nom_ext @@ -210,7 +212,7 @@ constraints: where: >- (Process_ramp_limit_up OR Process_ramp_limit_start_up) AND NOT (Process_committable AND Process_p_nom_extendable AND NOT (Process_p_nom_mod > 0)) - AND (position(snapshot, by=snapshot_period, within=period) > 0 OR (position(snapshot) == 0 AND (Process_status_initial == 0 OR Process_p_init))) + AND Process_ramps_from_previous AND Process_active expression: Process_p - Process_previous_p <= Process_ramp_up_allowance Process_p_ramp_limit_down: @@ -225,7 +227,7 @@ constraints: where: >- (Process_ramp_limit_down OR Process_ramp_limit_shut_down) AND NOT (Process_committable AND Process_p_nom_extendable AND NOT (Process_p_nom_mod > 0)) - AND (position(snapshot, by=snapshot_period, within=period) > 0 OR (position(snapshot) == 0 AND (Process_status_initial == 0 OR Process_p_init))) + AND Process_ramps_from_previous AND Process_active expression: Process_previous_p - Process_p <= Process_ramp_down_allowance @@ -281,6 +283,7 @@ assumptions: | $`\widetilde{\mathrm{z}}^{\mathrm{nom}}`$ | `Process_p_nom_effective` over $`\Xi \times \mathcal{J}`$, an expression another file defines | | $`\overleftarrow{u}^{z}`$ | `Process_previous_status` over $`\Xi \times \mathcal{T} \times \mathcal{J}`$, an expression another file defines | | $`\widehat{\mathrm{z}}^{\mathrm{nom}}`$ | `Process_p_nom_committed` over $`\Xi \times \mathcal{J}`$, an expression another file defines | +| $`\mathrm{on}^{z,\mathrm{com,ext}}`$ | `Process_com_ext` over $`\mathcal{T} \times \mathcal{J}`$, a mask another file defines | #### Definitions @@ -294,6 +297,12 @@ assumptions: | $`\Delta^{z,+}`$ | `Process_ramp_up_allowance` over $`\Xi \times \mathcal{T} \times \mathcal{J}`$ — how far a process may raise internal power between two snapshots — its ramp limit of the build while it stays on, plus its start-up ramp in the snapshot it turns on | | $`\Delta^{z,-}`$ | `Process_ramp_down_allowance` over $`\Xi \times \mathcal{T} \times \mathcal{J}`$ — how far a process may lower internal power between two snapshots — its ramp limit of the build while it stays on, plus its shut-down ramp in the snapshot it turns off | +#### Masks + +| Symbol | Meaning | +|---|---| +| $`\mathrm{prev}^{z}`$ | `Process_ramps_from_previous` over $`\Xi \times \mathcal{T} \times \mathcal{J}`$ — a snapshot whose ramp reads a previous output — any snapshot but its period's first, and the horizon's first where the process comes in off or carries an initial output | + $`\mathrm{pos}(t)`$ denotes where index $`t`$ sits along its dimension's own order — the order `shift` steps along, not the order labels sort in — counted from $`0`$. The index itself stays the coordinate, so $`t`$ compares against labels and $`\mathrm{pos}(t)`$ against positions. $`\mathrm{pos}_{\mathrm{relation}(t)}(t)`$ counts within the group a relation puts $`t`$ in: the subscript names the map, $`\mathcal{T}_{\mathrm{relation}(t)}`$ is the group it lands in, and that group has a first position of its own. @@ -303,37 +312,37 @@ $`\mathrm{pos}_{\mathrm{relation}(t)}(t)`$ counts within the group a relation pu **`Process_p_ramp_limit_up_run_big_m`** ```math -z_{\xi,t,j} - \overleftarrow{z}_{\xi,t,j} \le \widetilde{\mathrm{ru}}^{z}_{\xi,t,j} \cdot Z_{j} + \mathrm{M}^{z}_{\xi,j} - \mathrm{M}^{z}_{\xi,j} \cdot \overleftarrow{u}^{z}_{\xi,t,j} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ j \in \mathcal{J} \,:\, \mathrm{com}^{z}_{j} \wedge \mathrm{ext}^{z}_{j} \wedge \neg \left( \mathrm{z}^{\mathrm{mod}}_{j} > 0 \right) \wedge \left( \mathrm{ru}^{z}_{\xi,t,j} \text{ is defined} \vee \mathrm{ru}^{z,\mathrm{up}}_{\xi,j} \text{ is defined} \right) \wedge \left( \mathrm{pos}_{\mathrm{snapshot\_period}(t)}(t) > 0 \vee \mathrm{pos}(t) = 0 \wedge \left( \mathrm{u}^{z,0}_{\xi,j} = 0 \vee \mathrm{z}^{0}_{\xi,j} \text{ is defined} \right) \right) \wedge \mathrm{on}^{z}_{t,j} +z_{\xi,t,j} - \overleftarrow{z}_{\xi,t,j} \le \widetilde{\mathrm{ru}}^{z}_{\xi,t,j} \cdot Z_{j} + \mathrm{M}^{z}_{\xi,j} - \mathrm{M}^{z}_{\xi,j} \cdot \overleftarrow{u}^{z}_{\xi,t,j} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ j \in \mathcal{J} \,:\, \mathrm{on}^{z,\mathrm{com,ext}}_{t,j} \wedge \left( \mathrm{ru}^{z}_{\xi,t,j} \text{ is defined} \vee \mathrm{ru}^{z,\mathrm{up}}_{\xi,j} \text{ is defined} \right) \wedge \mathrm{prev}^{z}_{\xi,t,j} ``` **`Process_p_ramp_limit_up_start_big_m`** ```math -z_{\xi,t,j} - \overleftarrow{z}_{\xi,t,j} \le \widetilde{\mathrm{ru}}^{z,\mathrm{up}}_{\xi,j} \cdot Z_{j} + \mathrm{M}^{z}_{\xi,j} - \mathrm{M}^{z}_{\xi,j} \cdot \mathit{up}^{z}_{\xi,t,j} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ j \in \mathcal{J} \,:\, \mathrm{com}^{z}_{j} \wedge \mathrm{ext}^{z}_{j} \wedge \neg \left( \mathrm{z}^{\mathrm{mod}}_{j} > 0 \right) \wedge \left( \mathrm{ru}^{z}_{\xi,t,j} \text{ is defined} \vee \mathrm{ru}^{z,\mathrm{up}}_{\xi,j} \text{ is defined} \right) \wedge \left( \mathrm{pos}_{\mathrm{snapshot\_period}(t)}(t) > 0 \vee \mathrm{pos}(t) = 0 \wedge \left( \mathrm{u}^{z,0}_{\xi,j} = 0 \vee \mathrm{z}^{0}_{\xi,j} \text{ is defined} \right) \right) \wedge \mathrm{on}^{z}_{t,j} +z_{\xi,t,j} - \overleftarrow{z}_{\xi,t,j} \le \widetilde{\mathrm{ru}}^{z,\mathrm{up}}_{\xi,j} \cdot Z_{j} + \mathrm{M}^{z}_{\xi,j} - \mathrm{M}^{z}_{\xi,j} \cdot \mathit{up}^{z}_{\xi,t,j} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ j \in \mathcal{J} \,:\, \mathrm{on}^{z,\mathrm{com,ext}}_{t,j} \wedge \left( \mathrm{ru}^{z}_{\xi,t,j} \text{ is defined} \vee \mathrm{ru}^{z,\mathrm{up}}_{\xi,j} \text{ is defined} \right) \wedge \mathrm{prev}^{z}_{\xi,t,j} ``` **`Process_p_ramp_limit_down_run_big_m`** ```math -\overleftarrow{z}_{\xi,t,j} - z_{\xi,t,j} \le \widetilde{\mathrm{rd}}^{z}_{\xi,t,j} \cdot Z_{j} + \mathrm{M}^{z}_{\xi,j} - \mathrm{M}^{z}_{\xi,j} \cdot u^{z}_{\xi,t,j} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ j \in \mathcal{J} \,:\, \mathrm{com}^{z}_{j} \wedge \mathrm{ext}^{z}_{j} \wedge \neg \left( \mathrm{z}^{\mathrm{mod}}_{j} > 0 \right) \wedge \left( \mathrm{rd}^{z}_{\xi,t,j} \text{ is defined} \vee \mathrm{rd}^{z,\mathrm{dn}}_{\xi,j} \text{ is defined} \right) \wedge \left( \mathrm{pos}_{\mathrm{snapshot\_period}(t)}(t) > 0 \vee \mathrm{pos}(t) = 0 \wedge \left( \mathrm{u}^{z,0}_{\xi,j} = 0 \vee \mathrm{z}^{0}_{\xi,j} \text{ is defined} \right) \right) \wedge \mathrm{on}^{z}_{t,j} +\overleftarrow{z}_{\xi,t,j} - z_{\xi,t,j} \le \widetilde{\mathrm{rd}}^{z}_{\xi,t,j} \cdot Z_{j} + \mathrm{M}^{z}_{\xi,j} - \mathrm{M}^{z}_{\xi,j} \cdot u^{z}_{\xi,t,j} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ j \in \mathcal{J} \,:\, \mathrm{on}^{z,\mathrm{com,ext}}_{t,j} \wedge \left( \mathrm{rd}^{z}_{\xi,t,j} \text{ is defined} \vee \mathrm{rd}^{z,\mathrm{dn}}_{\xi,j} \text{ is defined} \right) \wedge \mathrm{prev}^{z}_{\xi,t,j} ``` **`Process_p_ramp_limit_down_shut_big_m`** ```math -\overleftarrow{z}_{\xi,t,j} - z_{\xi,t,j} \le \widetilde{\mathrm{rd}}^{z,\mathrm{dn}}_{\xi,j} \cdot Z_{j} + \mathrm{M}^{z}_{\xi,j} - \mathrm{M}^{z}_{\xi,j} \cdot \mathit{dn}^{z}_{\xi,t,j} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ j \in \mathcal{J} \,:\, \mathrm{com}^{z}_{j} \wedge \mathrm{ext}^{z}_{j} \wedge \neg \left( \mathrm{z}^{\mathrm{mod}}_{j} > 0 \right) \wedge \left( \mathrm{rd}^{z}_{\xi,t,j} \text{ is defined} \vee \mathrm{rd}^{z,\mathrm{dn}}_{\xi,j} \text{ is defined} \right) \wedge \left( \mathrm{pos}_{\mathrm{snapshot\_period}(t)}(t) > 0 \vee \mathrm{pos}(t) = 0 \wedge \left( \mathrm{u}^{z,0}_{\xi,j} = 0 \vee \mathrm{z}^{0}_{\xi,j} \text{ is defined} \right) \right) \wedge \mathrm{on}^{z}_{t,j} +\overleftarrow{z}_{\xi,t,j} - z_{\xi,t,j} \le \widetilde{\mathrm{rd}}^{z,\mathrm{dn}}_{\xi,j} \cdot Z_{j} + \mathrm{M}^{z}_{\xi,j} - \mathrm{M}^{z}_{\xi,j} \cdot \mathit{dn}^{z}_{\xi,t,j} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ j \in \mathcal{J} \,:\, \mathrm{on}^{z,\mathrm{com,ext}}_{t,j} \wedge \left( \mathrm{rd}^{z}_{\xi,t,j} \text{ is defined} \vee \mathrm{rd}^{z,\mathrm{dn}}_{\xi,j} \text{ is defined} \right) \wedge \mathrm{prev}^{z}_{\xi,t,j} ``` **`Process_p_ramp_limit_up`** ```math -z_{\xi,t,j} - \overleftarrow{z}_{\xi,t,j} \le \Delta^{z,+}_{\xi,t,j} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ j \in \mathcal{J} \,:\, \left( \mathrm{ru}^{z}_{\xi,t,j} \text{ is defined} \vee \mathrm{ru}^{z,\mathrm{up}}_{\xi,j} \text{ is defined} \right) \wedge \neg \left( \mathrm{com}^{z}_{j} \wedge \mathrm{ext}^{z}_{j} \wedge \neg \left( \mathrm{z}^{\mathrm{mod}}_{j} > 0 \right) \right) \wedge \left( \mathrm{pos}_{\mathrm{snapshot\_period}(t)}(t) > 0 \vee \mathrm{pos}(t) = 0 \wedge \left( \mathrm{u}^{z,0}_{\xi,j} = 0 \vee \mathrm{z}^{0}_{\xi,j} \text{ is defined} \right) \right) \wedge \mathrm{on}^{z}_{t,j} +z_{\xi,t,j} - \overleftarrow{z}_{\xi,t,j} \le \Delta^{z,+}_{\xi,t,j} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ j \in \mathcal{J} \,:\, \left( \mathrm{ru}^{z}_{\xi,t,j} \text{ is defined} \vee \mathrm{ru}^{z,\mathrm{up}}_{\xi,j} \text{ is defined} \right) \wedge \neg \left( \mathrm{com}^{z}_{j} \wedge \mathrm{ext}^{z}_{j} \wedge \neg \left( \mathrm{z}^{\mathrm{mod}}_{j} > 0 \right) \right) \wedge \mathrm{prev}^{z}_{\xi,t,j} \wedge \mathrm{on}^{z}_{t,j} ``` **`Process_p_ramp_limit_down`** ```math -\overleftarrow{z}_{\xi,t,j} - z_{\xi,t,j} \le \Delta^{z,-}_{\xi,t,j} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ j \in \mathcal{J} \,:\, \left( \mathrm{rd}^{z}_{\xi,t,j} \text{ is defined} \vee \mathrm{rd}^{z,\mathrm{dn}}_{\xi,j} \text{ is defined} \right) \wedge \neg \left( \mathrm{com}^{z}_{j} \wedge \mathrm{ext}^{z}_{j} \wedge \neg \left( \mathrm{z}^{\mathrm{mod}}_{j} > 0 \right) \right) \wedge \left( \mathrm{pos}_{\mathrm{snapshot\_period}(t)}(t) > 0 \vee \mathrm{pos}(t) = 0 \wedge \left( \mathrm{u}^{z,0}_{\xi,j} = 0 \vee \mathrm{z}^{0}_{\xi,j} \text{ is defined} \right) \right) \wedge \mathrm{on}^{z}_{t,j} +\overleftarrow{z}_{\xi,t,j} - z_{\xi,t,j} \le \Delta^{z,-}_{\xi,t,j} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ j \in \mathcal{J} \,:\, \left( \mathrm{rd}^{z}_{\xi,t,j} \text{ is defined} \vee \mathrm{rd}^{z,\mathrm{dn}}_{\xi,j} \text{ is defined} \right) \wedge \neg \left( \mathrm{com}^{z}_{j} \wedge \mathrm{ext}^{z}_{j} \wedge \neg \left( \mathrm{z}^{\mathrm{mod}}_{j} > 0 \right) \right) \wedge \mathrm{prev}^{z}_{\xi,t,j} \wedge \mathrm{on}^{z}_{t,j} ``` #### Definitions @@ -380,6 +389,14 @@ z_{\xi,t,j} - \overleftarrow{z}_{\xi,t,j} \le \Delta^{z,+}_{\xi,t,j} \qquad \for \Delta^{z,-}_{\xi,t,j} = \begin{cases} \widetilde{\mathrm{rd}}^{z}_{\xi,t,j} \cdot \widehat{\mathrm{z}}^{\mathrm{nom}}_{\xi,j} \cdot u^{z}_{\xi,t,j} + \widetilde{\mathrm{rd}}^{z,\mathrm{dn}}_{\xi,j} \cdot \widehat{\mathrm{z}}^{\mathrm{nom}}_{\xi,j} \cdot \left( \overleftarrow{u}^{z}_{\xi,t,j} - u^{z}_{\xi,t,j} \right) & \text{if } \mathrm{com}^{z}_{j} \\ \widetilde{\mathrm{rd}}^{z}_{\xi,t,j} \cdot \widetilde{\mathrm{z}}^{\mathrm{nom}}_{\xi,j} & \text{otherwise} \end{cases} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ j \in \mathcal{J} ``` +#### Masks + +**`Process_ramps_from_previous`** + +```math +\mathrm{prev}^{z}_{\xi,t,j} \iff \mathrm{pos}_{\mathrm{snapshot\_period}(t)}(t) > 0 \vee \mathrm{pos}(t) = 0 \wedge \left( \mathrm{u}^{z,0}_{\xi,j} = 0 \vee \mathrm{z}^{0}_{\xi,j} \text{ is defined} \right) \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ j \in \mathcal{J} +``` + #### Assumptions **`Process_came_in_running_unless_committable`** diff --git a/docs/examples/pypsa/storage_unit.md b/docs/examples/pypsa/storage_unit.md index f02ac6e1b..16663ed0b 100644 --- a/docs/examples/pypsa/storage_unit.md +++ b/docs/examples/pypsa/storage_unit.md @@ -308,70 +308,82 @@ expressions: sum(StorageUnit_sign * (StorageUnit_p_dispatch - StorageUnit_p_store), by=StorageUnit_bus, over=storage_unit, into=bus) adds_to: Bus_injection +masks: + StorageUnit_fix: + description: >- + a storage unit with a fixed build that stands in the snapshot's period — + PyPSA's `fix` rows + where: NOT StorageUnit_p_nom_extendable AND StorageUnit_active + StorageUnit_ext: + description: >- + a storage unit with an extendable build that stands in the snapshot's + period — PyPSA's `ext` rows + where: StorageUnit_p_nom_extendable AND StorageUnit_active + constraints: StorageUnit_fix_p_dispatch_lower: description: "`StorageUnit-fix-p_dispatch-lower` — dispatch is non-negative" dims: [scenario, snapshot, storage_unit] - where: not StorageUnit_p_nom_extendable AND StorageUnit_active + where: StorageUnit_fix expression: StorageUnit_p_dispatch >= 0 StorageUnit_fix_p_dispatch_upper: description: "`StorageUnit-fix-p_dispatch-upper` — a fixed unit dispatches at most its nominal power" dims: [scenario, snapshot, storage_unit] - where: not StorageUnit_p_nom_extendable AND StorageUnit_active + where: StorageUnit_fix expression: StorageUnit_p_dispatch <= StorageUnit_p_max_pu * StorageUnit_p_nom StorageUnit_fix_p_store_lower: description: "`StorageUnit-fix-p_store-lower` — storing is non-negative" dims: [scenario, snapshot, storage_unit] - where: not StorageUnit_p_nom_extendable AND StorageUnit_active + where: StorageUnit_fix expression: StorageUnit_p_store >= 0 StorageUnit_fix_p_store_upper: description: >- `StorageUnit-fix-p_store-upper` — a fixed unit stores at most its nominal power, the minimum-per-unit column carrying that cap negated dims: [scenario, snapshot, storage_unit] - where: not StorageUnit_p_nom_extendable AND StorageUnit_active + where: StorageUnit_fix expression: StorageUnit_p_store <= -StorageUnit_p_min_pu * StorageUnit_p_nom StorageUnit_fix_state_of_charge_lower: description: "`StorageUnit-fix-state_of_charge-lower` — charge is non-negative" dims: [scenario, snapshot, storage_unit] - where: not StorageUnit_p_nom_extendable AND StorageUnit_active + where: StorageUnit_fix expression: StorageUnit_state_of_charge >= 0 StorageUnit_fix_state_of_charge_upper: description: "`StorageUnit-fix-state_of_charge-upper` — a fixed unit holds at most its hours at nominal power" dims: [scenario, snapshot, storage_unit] - where: not StorageUnit_p_nom_extendable AND StorageUnit_active + where: StorageUnit_fix expression: StorageUnit_state_of_charge <= StorageUnit_max_hours * StorageUnit_p_nom StorageUnit_ext_p_dispatch_lower: description: "`StorageUnit-ext-p_dispatch-lower` — dispatch is non-negative" dims: [scenario, snapshot, storage_unit] - where: StorageUnit_p_nom_extendable AND StorageUnit_active + where: StorageUnit_ext expression: StorageUnit_p_dispatch >= 0 StorageUnit_ext_p_dispatch_upper: description: "`StorageUnit-ext-p_dispatch-upper` — an extendable unit dispatches at most the chosen build" dims: [scenario, snapshot, storage_unit] - where: StorageUnit_p_nom_extendable AND StorageUnit_active + where: StorageUnit_ext expression: StorageUnit_p_dispatch <= StorageUnit_p_max_pu * StorageUnit_p_nom_ext StorageUnit_ext_p_store_lower: description: "`StorageUnit-ext-p_store-lower` — storing is non-negative" dims: [scenario, snapshot, storage_unit] - where: StorageUnit_p_nom_extendable AND StorageUnit_active + where: StorageUnit_ext expression: StorageUnit_p_store >= 0 StorageUnit_ext_p_store_upper: description: >- `StorageUnit-ext-p_store-upper` — an extendable unit stores at most the chosen build, the minimum-per-unit column carrying that cap negated dims: [scenario, snapshot, storage_unit] - where: StorageUnit_p_nom_extendable AND StorageUnit_active + where: StorageUnit_ext expression: StorageUnit_p_store <= -StorageUnit_p_min_pu * StorageUnit_p_nom_ext StorageUnit_ext_state_of_charge_lower: description: "`StorageUnit-ext-state_of_charge-lower` — charge is non-negative" dims: [scenario, snapshot, storage_unit] - where: StorageUnit_p_nom_extendable AND StorageUnit_active + where: StorageUnit_ext expression: StorageUnit_state_of_charge >= 0 StorageUnit_ext_state_of_charge_upper: description: "`StorageUnit-ext-state_of_charge-upper` — an extendable unit holds at most its hours at the chosen build" dims: [scenario, snapshot, storage_unit] - where: StorageUnit_p_nom_extendable AND StorageUnit_active + where: StorageUnit_ext expression: StorageUnit_state_of_charge <= StorageUnit_max_hours * StorageUnit_p_nom_ext StorageUnit_ext_p_nom_lower: description: "`StorageUnit-ext-p_nom-lower` — the chosen build is at least its floor in every scenario" @@ -569,6 +581,13 @@ assumptions: | $`\mathit{StorageUnit\_additions}`$ | `StorageUnit_additions` over $`\mathcal{Y} \times \mathcal{I}`$ | | $`\mathit{StorageUnit\_injection}`$ | `StorageUnit_injection` over $`\Xi \times \mathcal{T} \times \mathcal{N}`$ | +#### Masks + +| Symbol | Meaning | +|---|---| +| $`\mathrm{on}^{h,\mathrm{fix}}`$ | `StorageUnit_fix` over $`\mathcal{T} \times \mathcal{S}`$ — a storage unit with a fixed build that stands in the snapshot's period — PyPSA's `fix` rows | +| $`\mathrm{on}^{h,\mathrm{ext}}`$ | `StorageUnit_ext` over $`\mathcal{T} \times \mathcal{S}`$ — a storage unit with an extendable build that stands in the snapshot's period — PyPSA's `ext` rows | + $`t \ominus k`$ denotes cyclic translation: index $`t-k`$ taken modulo the size of the dimension (`roll`). Plain $`t-k`$ (`shift`) has no wraparound — terms translated past the edge are simply absent. $`t \ominus^{\mathrm{relation}(t)} k`$ denotes a translation counted inside the group a relation puts $`t`$ in (`shift(by=relation)`), so a term never crosses out of its own group. @@ -584,73 +603,73 @@ $`\lvert \mathcal{T} \rvert`$ denotes the size of the set being counted along, a **`StorageUnit_fix_p_dispatch_lower`** ```math -h^{+}_{\xi,t,s} \ge 0 \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ s \in \mathcal{S} \,:\, \neg \mathrm{ext}^{h}_{s} \wedge \mathrm{on}^{h}_{t,s} +h^{+}_{\xi,t,s} \ge 0 \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ s \in \mathcal{S} \,:\, \mathrm{on}^{h,\mathrm{fix}}_{t,s} ``` **`StorageUnit_fix_p_dispatch_upper`** ```math -h^{+}_{\xi,t,s} \le \overline{\mathrm{h}}_{\xi,t,s} \cdot \mathrm{h}^{\mathrm{nom}}_{\xi,s} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ s \in \mathcal{S} \,:\, \neg \mathrm{ext}^{h}_{s} \wedge \mathrm{on}^{h}_{t,s} +h^{+}_{\xi,t,s} \le \overline{\mathrm{h}}_{\xi,t,s} \cdot \mathrm{h}^{\mathrm{nom}}_{\xi,s} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ s \in \mathcal{S} \,:\, \mathrm{on}^{h,\mathrm{fix}}_{t,s} ``` **`StorageUnit_fix_p_store_lower`** ```math -h^{-}_{\xi,t,s} \ge 0 \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ s \in \mathcal{S} \,:\, \neg \mathrm{ext}^{h}_{s} \wedge \mathrm{on}^{h}_{t,s} +h^{-}_{\xi,t,s} \ge 0 \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ s \in \mathcal{S} \,:\, \mathrm{on}^{h,\mathrm{fix}}_{t,s} ``` **`StorageUnit_fix_p_store_upper`** ```math -h^{-}_{\xi,t,s} \le -\underline{\mathrm{h}}_{\xi,t,s} \cdot \mathrm{h}^{\mathrm{nom}}_{\xi,s} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ s \in \mathcal{S} \,:\, \neg \mathrm{ext}^{h}_{s} \wedge \mathrm{on}^{h}_{t,s} +h^{-}_{\xi,t,s} \le -\underline{\mathrm{h}}_{\xi,t,s} \cdot \mathrm{h}^{\mathrm{nom}}_{\xi,s} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ s \in \mathcal{S} \,:\, \mathrm{on}^{h,\mathrm{fix}}_{t,s} ``` **`StorageUnit_fix_state_of_charge_lower`** ```math -\mathit{soc}_{\xi,t,s} \ge 0 \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ s \in \mathcal{S} \,:\, \neg \mathrm{ext}^{h}_{s} \wedge \mathrm{on}^{h}_{t,s} +\mathit{soc}_{\xi,t,s} \ge 0 \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ s \in \mathcal{S} \,:\, \mathrm{on}^{h,\mathrm{fix}}_{t,s} ``` **`StorageUnit_fix_state_of_charge_upper`** ```math -\mathit{soc}_{\xi,t,s} \le \mathrm{T}^{h}_{\xi,s} \cdot \mathrm{h}^{\mathrm{nom}}_{\xi,s} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ s \in \mathcal{S} \,:\, \neg \mathrm{ext}^{h}_{s} \wedge \mathrm{on}^{h}_{t,s} +\mathit{soc}_{\xi,t,s} \le \mathrm{T}^{h}_{\xi,s} \cdot \mathrm{h}^{\mathrm{nom}}_{\xi,s} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ s \in \mathcal{S} \,:\, \mathrm{on}^{h,\mathrm{fix}}_{t,s} ``` **`StorageUnit_ext_p_dispatch_lower`** ```math -h^{+}_{\xi,t,s} \ge 0 \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ s \in \mathcal{S} \,:\, \mathrm{ext}^{h}_{s} \wedge \mathrm{on}^{h}_{t,s} +h^{+}_{\xi,t,s} \ge 0 \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ s \in \mathcal{S} \,:\, \mathrm{on}^{h,\mathrm{ext}}_{t,s} ``` **`StorageUnit_ext_p_dispatch_upper`** ```math -h^{+}_{\xi,t,s} \le \overline{\mathrm{h}}_{\xi,t,s} \cdot H_{s} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ s \in \mathcal{S} \,:\, \mathrm{ext}^{h}_{s} \wedge \mathrm{on}^{h}_{t,s} +h^{+}_{\xi,t,s} \le \overline{\mathrm{h}}_{\xi,t,s} \cdot H_{s} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ s \in \mathcal{S} \,:\, \mathrm{on}^{h,\mathrm{ext}}_{t,s} ``` **`StorageUnit_ext_p_store_lower`** ```math -h^{-}_{\xi,t,s} \ge 0 \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ s \in \mathcal{S} \,:\, \mathrm{ext}^{h}_{s} \wedge \mathrm{on}^{h}_{t,s} +h^{-}_{\xi,t,s} \ge 0 \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ s \in \mathcal{S} \,:\, \mathrm{on}^{h,\mathrm{ext}}_{t,s} ``` **`StorageUnit_ext_p_store_upper`** ```math -h^{-}_{\xi,t,s} \le -\underline{\mathrm{h}}_{\xi,t,s} \cdot H_{s} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ s \in \mathcal{S} \,:\, \mathrm{ext}^{h}_{s} \wedge \mathrm{on}^{h}_{t,s} +h^{-}_{\xi,t,s} \le -\underline{\mathrm{h}}_{\xi,t,s} \cdot H_{s} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ s \in \mathcal{S} \,:\, \mathrm{on}^{h,\mathrm{ext}}_{t,s} ``` **`StorageUnit_ext_state_of_charge_lower`** ```math -\mathit{soc}_{\xi,t,s} \ge 0 \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ s \in \mathcal{S} \,:\, \mathrm{ext}^{h}_{s} \wedge \mathrm{on}^{h}_{t,s} +\mathit{soc}_{\xi,t,s} \ge 0 \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ s \in \mathcal{S} \,:\, \mathrm{on}^{h,\mathrm{ext}}_{t,s} ``` **`StorageUnit_ext_state_of_charge_upper`** ```math -\mathit{soc}_{\xi,t,s} \le \mathrm{T}^{h}_{\xi,s} \cdot H_{s} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ s \in \mathcal{S} \,:\, \mathrm{ext}^{h}_{s} \wedge \mathrm{on}^{h}_{t,s} +\mathit{soc}_{\xi,t,s} \le \mathrm{T}^{h}_{\xi,s} \cdot H_{s} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ s \in \mathcal{S} \,:\, \mathrm{on}^{h,\mathrm{ext}}_{t,s} ``` **`StorageUnit_ext_p_nom_lower`** @@ -757,6 +776,20 @@ h^{-}_{\xi,t,s} = \mathrm{h}^{-,\mathrm{set}}_{\xi,t,s} \qquad \forall\, \xi \in \mathit{StorageUnit\_injection}_{\xi,t,n} = \sum_{s \in \mathcal{S} \,:\, \mathrm{StorageUnit\_bus}(s) = n} \mathrm{sgn}^{h}_{s} \cdot \left( h^{+}_{\xi,t,s} - h^{-}_{\xi,t,s} \right) \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ n \in \mathcal{N} ``` +#### Masks + +**`StorageUnit_fix`** + +```math +\mathrm{on}^{h,\mathrm{fix}}_{t,s} \iff \neg \mathrm{ext}^{h}_{s} \wedge \mathrm{on}^{h}_{t,s} \qquad \forall\, t \in \mathcal{T},\ s \in \mathcal{S} +``` + +**`StorageUnit_ext`** + +```math +\mathrm{on}^{h,\mathrm{ext}}_{t,s} \iff \mathrm{ext}^{h}_{s} \wedge \mathrm{on}^{h}_{t,s} \qquad \forall\, t \in \mathcal{T},\ s \in \mathcal{S} +``` + #### Variable domains **`StorageUnit_p_dispatch`** diff --git a/docs/examples/pypsa/transformer.md b/docs/examples/pypsa/transformer.md index c8c87e20f..c28299af5 100644 --- a/docs/examples/pypsa/transformer.md +++ b/docs/examples/pypsa/transformer.md @@ -144,7 +144,7 @@ variables: a line does; absent, and zero in the balance, where the network is lossless dims: [scenario, snapshot, transformer] - where: transmission_losses AND Transformer_active + where: Transformer_lossy absence: zero bounds: lower: 0 @@ -200,6 +200,13 @@ expressions: + sum(Transformer_phase_shift * Transformer_phase_shift_cycle_weight, over=transformer) adds_to: Cycle_angle_sum +masks: + Transformer_lossy: + description: >- + a transformer that stands in the snapshot's period, where the run models + transmission losses + where: transmission_losses AND Transformer_active + constraints: Transformer_fix_s_lower: description: "`Transformer-fix-s-lower` — a fixed transformer carries at least the negative of its rating, the loss counted against it" @@ -244,7 +251,7 @@ constraints: Transformer_loss_upper: description: "`Transformer-loss_upper` — a transformer dissipates at most the loss at its rating" dims: [scenario, snapshot, transformer] - where: transmission_losses AND Transformer_active + where: Transformer_lossy expression: Transformer_loss <= Transformer_loss_max Transformer_loss_tangents_forward: description: >- @@ -252,14 +259,14 @@ constraints: loss sits above every cut to its curve for flow one way, as a line's does, over the segment dimension dims: [scenario, snapshot, transformer, segment] - where: transmission_losses AND Transformer_active + where: Transformer_lossy expression: Transformer_loss + Transformer_loss_slope * Transformer_s >= Transformer_loss_offset Transformer_loss_tangents_reverse: description: >- `Transformer-loss_tangents-{k}--1`, `Transformer-loss_secants-neg` — the same fan mirrored, the loss depending on the flow's magnitude dims: [scenario, snapshot, transformer, segment] - where: transmission_losses AND Transformer_active + where: Transformer_lossy expression: Transformer_loss - Transformer_loss_slope * Transformer_s >= Transformer_loss_offset ``` @@ -326,6 +333,12 @@ constraints: | $`\mathit{Transformer\_injection}`$ | `Transformer_injection` over $`\Xi \times \mathcal{T} \times \mathcal{N}`$ | | $`\mathit{Transformer\_angle\_sum}`$ | `Transformer_angle_sum` over $`\Xi \times \mathcal{T} \times \mathcal{C}`$ | +#### Masks + +| Symbol | Meaning | +|---|---| +| $`\mathrm{on}^{\sigma,\mathrm{lossy}}`$ | `Transformer_lossy` over $`\mathcal{T} \times \mathcal{M}`$ — a transformer that stands in the snapshot's period, where the run models transmission losses | + Upright is what the data supplies — a parameter such as $`\mathrm{Transformer\_phase\_shift\_varying}`$, a coordinate map, a label — and italic is what the solver chooses, such as $`\mathit{Transformer\_phase\_shift}`$. An index is italic too, being what a quantifier chooses, and a set is script. #### Subject to @@ -381,19 +394,19 @@ Upright is what the data supplies — a parameter such as $`\mathrm{Transformer\ **`Transformer_loss_upper`** ```math -\ell^{\sigma}_{\xi,t,m} \le \overline{\ell}^{\sigma}_{\xi,t,m} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ m \in \mathcal{M} \,:\, \mathrm{lossy} \wedge \mathrm{on}^{\sigma}_{t,m} +\ell^{\sigma}_{\xi,t,m} \le \overline{\ell}^{\sigma}_{\xi,t,m} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ m \in \mathcal{M} \,:\, \mathrm{on}^{\sigma,\mathrm{lossy}}_{t,m} ``` **`Transformer_loss_tangents_forward`** ```math -\ell^{\sigma}_{\xi,t,m} + \mathrm{a}^{\sigma}_{\xi,t,m,s} \cdot \sigma_{\xi,t,m} \ge \mathrm{b}^{\sigma}_{\xi,t,m,s} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ m \in \mathcal{M},\ s \in \mathcal{S} \,:\, \mathrm{lossy} \wedge \mathrm{on}^{\sigma}_{t,m} +\ell^{\sigma}_{\xi,t,m} + \mathrm{a}^{\sigma}_{\xi,t,m,s} \cdot \sigma_{\xi,t,m} \ge \mathrm{b}^{\sigma}_{\xi,t,m,s} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ m \in \mathcal{M},\ s \in \mathcal{S} \,:\, \mathrm{on}^{\sigma,\mathrm{lossy}}_{t,m} ``` **`Transformer_loss_tangents_reverse`** ```math -\ell^{\sigma}_{\xi,t,m} - \mathrm{a}^{\sigma}_{\xi,t,m,s} \cdot \sigma_{\xi,t,m} \ge \mathrm{b}^{\sigma}_{\xi,t,m,s} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ m \in \mathcal{M},\ s \in \mathcal{S} \,:\, \mathrm{lossy} \wedge \mathrm{on}^{\sigma}_{t,m} +\ell^{\sigma}_{\xi,t,m} - \mathrm{a}^{\sigma}_{\xi,t,m,s} \cdot \sigma_{\xi,t,m} \ge \mathrm{b}^{\sigma}_{\xi,t,m,s} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ m \in \mathcal{M},\ s \in \mathcal{S} \,:\, \mathrm{on}^{\sigma,\mathrm{lossy}}_{t,m} ``` #### Definitions @@ -422,6 +435,14 @@ Upright is what the data supplies — a parameter such as $`\mathrm{Transformer\ \mathit{Transformer\_angle\_sum}_{\xi,t,c} = \sum_{m \in \mathcal{M}} \sigma_{\xi,t,m} \cdot \mathrm{x}^{\sigma}_{m,c} + \sum_{m \in \mathcal{M}} \vartheta_{t,m,c} + \sum_{m \in \mathcal{M}} \mathit{Transformer\_phase\_shift}_{\xi,t,m} \cdot \mathrm{Transformer\_phase\_shift\_cycle\_weight}_{m,c} \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ c \in \mathcal{C} ``` +#### Masks + +**`Transformer_lossy`** + +```math +\mathrm{on}^{\sigma,\mathrm{lossy}}_{t,m} \iff \mathrm{lossy} \wedge \mathrm{on}^{\sigma}_{t,m} \qquad \forall\, t \in \mathcal{T},\ m \in \mathcal{M} +``` + #### Variable domains **`Transformer_s`** @@ -433,7 +454,7 @@ Upright is what the data supplies — a parameter such as $`\mathrm{Transformer\ **`Transformer_loss`** ```math -\ell^{\sigma}_{\xi,t,m} \ge 0 \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ m \in \mathcal{M} \,:\, \mathrm{lossy} \wedge \mathrm{on}^{\sigma}_{t,m} +\ell^{\sigma}_{\xi,t,m} \ge 0 \qquad \forall\, \xi \in \Xi,\ t \in \mathcal{T},\ m \in \mathcal{M} \,:\, \mathrm{on}^{\sigma,\mathrm{lossy}}_{t,m} ``` **`Transformer_phase_shift`** diff --git a/examples/pypsa.yaml b/examples/pypsa.yaml index d6e7712ef..eb144fdb9 100644 --- a/examples/pypsa.yaml +++ b/examples/pypsa.yaml @@ -1351,21 +1351,21 @@ variables: the rows below cap at one, or at the module count where the build is modular dims: [scenario, snapshot, generator] - where: Generator_committable AND Generator_active + where: Generator_committed domain: integer bounds: lower: 0 Generator_start_up: description: "`Generator-start_up` — how much of a committable unit turns on this snapshot, capped as the status is" dims: [scenario, snapshot, generator] - where: Generator_committable AND Generator_active + where: Generator_committed domain: integer bounds: lower: 0 Generator_shut_down: description: "`Generator-shut_down` — how much of a committable unit turns off this snapshot, capped as the status is" dims: [scenario, snapshot, generator] - where: Generator_committable AND Generator_active + where: Generator_committed domain: integer bounds: lower: 0 @@ -1390,9 +1390,7 @@ variables: `Generator-maintenance_capacity` — the chosen build while in maintenance, zero otherwise: the product the `maintcap` rows linearize dims: [scenario, snapshot, generator] - where: >- - Generator_maintainable AND Generator_p_nom_extendable - AND NOT (Generator_committable AND Generator_p_nom_mod > 0) AND Generator_active + where: Generator_maint_ext absence: zero bounds: lower: 0 @@ -1403,8 +1401,9 @@ variables: maintenance may also be off dims: [scenario, snapshot, generator] where: >- - Generator_maintainable AND Generator_committable - AND NOT (Generator_p_nom_extendable AND NOT (Generator_p_nom_mod > 0)) AND Generator_active + Generator_maintainable + AND Generator_committed + AND NOT (Generator_p_nom_extendable AND NOT (Generator_p_nom_mod > 0)) absence: zero bounds: lower: 0 @@ -1421,21 +1420,21 @@ variables: the rows below cap at one, or at the module count where the build is modular dims: [scenario, snapshot, link] - where: Link_committable AND Link_active + where: Link_committed domain: integer bounds: lower: 0 Link_start_up: description: "`Link-start_up` — how much of a committable link turns on this snapshot, capped as the status is" dims: [scenario, snapshot, link] - where: Link_committable AND Link_active + where: Link_committed domain: integer bounds: lower: 0 Link_shut_down: description: "`Link-shut_down` — how much of a committable link turns off this snapshot, capped as the status is" dims: [scenario, snapshot, link] - where: Link_committable AND Link_active + where: Link_committed domain: integer bounds: lower: 0 @@ -1460,9 +1459,7 @@ variables: `Link-maintenance_capacity` — the chosen build while in maintenance, zero otherwise: the product the `maintcap` rows linearize dims: [scenario, snapshot, link] - where: >- - Link_maintainable AND Link_p_nom_extendable - AND NOT (Link_committable AND Link_p_nom_mod > 0) AND Link_active + where: Link_maint_ext absence: zero bounds: lower: 0 @@ -1472,9 +1469,7 @@ variables: otherwise: the product the `maint-status` rows linearize, so a unit in maintenance may also be off dims: [scenario, snapshot, link] - where: >- - Link_maintainable AND Link_committable - AND NOT (Link_p_nom_extendable AND NOT (Link_p_nom_mod > 0)) AND Link_active + where: Link_maintainable AND Link_committed AND NOT (Link_p_nom_extendable AND NOT (Link_p_nom_mod > 0)) absence: zero bounds: lower: 0 @@ -1491,21 +1486,21 @@ variables: the rows below cap at one, or at the module count where the build is modular dims: [scenario, snapshot, process] - where: Process_committable AND Process_active + where: Process_committed domain: integer bounds: lower: 0 Process_start_up: description: "`Process-start_up` — how much of a committable process turns on this snapshot, capped as the status is" dims: [scenario, snapshot, process] - where: Process_committable AND Process_active + where: Process_committed domain: integer bounds: lower: 0 Process_shut_down: description: "`Process-shut_down` — how much of a committable process turns off this snapshot, capped as the status is" dims: [scenario, snapshot, process] - where: Process_committable AND Process_active + where: Process_committed domain: integer bounds: lower: 0 @@ -1530,9 +1525,7 @@ variables: `Process-maintenance_capacity` — the chosen build while in maintenance, zero otherwise: the product the `maintcap` rows linearize dims: [scenario, snapshot, process] - where: >- - Process_maintainable AND Process_p_nom_extendable - AND NOT (Process_committable AND Process_p_nom_mod > 0) AND Process_active + where: Process_maint_ext absence: zero bounds: lower: 0 @@ -1543,8 +1536,9 @@ variables: maintenance may also be off dims: [scenario, snapshot, process] where: >- - Process_maintainable AND Process_committable - AND NOT (Process_p_nom_extendable AND NOT (Process_p_nom_mod > 0)) AND Process_active + Process_maintainable + AND Process_committed + AND NOT (Process_p_nom_extendable AND NOT (Process_p_nom_mod > 0)) absence: zero bounds: lower: 0 @@ -1560,7 +1554,7 @@ variables: cost and held up by the cuts; absent, and zero in the balance, where the network is lossless dims: [scenario, snapshot, line] - where: transmission_losses AND Line_active + where: Line_lossy absence: zero bounds: lower: 0 @@ -1577,7 +1571,7 @@ variables: a line does; absent, and zero in the balance, where the network is lossless dims: [scenario, snapshot, transformer] - where: transmission_losses AND Transformer_active + where: Transformer_lossy absence: zero bounds: lower: 0 @@ -2360,6 +2354,127 @@ expressions: the voltage angle differences around a cycle: every branch flow times its cycle weight, and every transformer phase shift +masks: + Generator_com_ext: + description: >- + a committable generator with an extendable, non-modular build that + stands in the snapshot's period — PyPSA's `com-ext` rows, whose status + is relaxed against the chosen build + where: >- + Generator_committable + AND Generator_p_nom_extendable + AND NOT (Generator_p_nom_mod > 0) + AND Generator_active + Generator_maint_ext: + description: >- + a maintainable generator with an extendable build, unless it is + committable and modular, that stands in the snapshot's period — the + maintenance rows against the chosen build + where: >- + Generator_maintainable + AND Generator_p_nom_extendable + AND NOT (Generator_committable AND Generator_p_nom_mod > 0) + AND Generator_active + Generator_committed: + description: >- + a committable generator that stands in the snapshot's period — every + unit-commitment row's set + where: Generator_committable AND Generator_active + Generator_ramps_from_previous: + description: >- + a snapshot whose ramp reads a previous output — any snapshot but its + period's first, and the horizon's first where the generator comes in off + or carries an initial output + where: >- + position(snapshot, by=snapshot_period, within=period) > 0 OR (position(snapshot) == 0 AND + (Generator_status_initial == 0 OR Generator_p_init)) + Link_com_ext: + description: >- + a committable link with an extendable, non-modular build that stands in + the snapshot's period — PyPSA's `com-ext` rows, whose status is relaxed + against the chosen build + where: >- + Link_committable + AND Link_p_nom_extendable + AND NOT (Link_p_nom_mod > 0) + AND Link_active + Link_maint_ext: + description: >- + a maintainable link with an extendable build, unless it is committable + and modular, that stands in the snapshot's period — the maintenance rows + against the chosen build + where: >- + Link_maintainable + AND Link_p_nom_extendable + AND NOT (Link_committable AND Link_p_nom_mod > 0) + AND Link_active + Link_committed: + description: >- + a committable link that stands in the snapshot's period — every + unit-commitment row's set + where: Link_committable AND Link_active + Link_ramps_from_previous: + description: >- + a snapshot whose ramp reads a previous output — any snapshot but its + period's first, and the horizon's first where the link comes in off or + carries an initial output + where: >- + position(snapshot, by=snapshot_period, within=period) > 0 OR (position(snapshot) == 0 AND + (Link_status_initial == 0 OR Link_p_init)) + Process_com_ext: + description: >- + a committable process with an extendable, non-modular build that stands + in the snapshot's period — PyPSA's `com-ext` rows, whose status is + relaxed against the chosen build + where: >- + Process_committable + AND Process_p_nom_extendable + AND NOT (Process_p_nom_mod > 0) + AND Process_active + Process_maint_ext: + description: >- + a maintainable process with an extendable build, unless it is + committable and modular, that stands in the snapshot's period — the + maintenance rows against the chosen build + where: >- + Process_maintainable + AND Process_p_nom_extendable + AND NOT (Process_committable AND Process_p_nom_mod > 0) + AND Process_active + Process_committed: + description: >- + a committable process that stands in the snapshot's period — every + unit-commitment row's set + where: Process_committable AND Process_active + Process_ramps_from_previous: + description: >- + a snapshot whose ramp reads a previous output — any snapshot but its + period's first, and the horizon's first where the process comes in off + or carries an initial output + where: >- + position(snapshot, by=snapshot_period, within=period) > 0 OR (position(snapshot) == 0 AND + (Process_status_initial == 0 OR Process_p_init)) + StorageUnit_fix: + description: >- + a storage unit with a fixed build that stands in the snapshot's period — + PyPSA's `fix` rows + where: NOT StorageUnit_p_nom_extendable AND StorageUnit_active + StorageUnit_ext: + description: >- + a storage unit with an extendable build that stands in the snapshot's + period — PyPSA's `ext` rows + where: StorageUnit_p_nom_extendable AND StorageUnit_active + Line_lossy: + description: >- + a line that stands in the snapshot's period, where the run models + transmission losses + where: transmission_losses AND Line_active + Transformer_lossy: + description: >- + a transformer that stands in the snapshot's period, where the run models + transmission losses + where: transmission_losses AND Transformer_active + constraints: Generator_fix_p_lower: description: "`Generator-fix-p-lower` — a fixed generator outputs at least its minimum" @@ -2479,54 +2594,54 @@ constraints: StorageUnit_fix_p_dispatch_lower: description: "`StorageUnit-fix-p_dispatch-lower` — dispatch is non-negative" dims: [scenario, snapshot, storage_unit] - where: not StorageUnit_p_nom_extendable AND StorageUnit_active + where: StorageUnit_fix expression: StorageUnit_p_dispatch >= 0 StorageUnit_fix_p_dispatch_upper: description: "`StorageUnit-fix-p_dispatch-upper` — a fixed unit dispatches at most its nominal power" dims: [scenario, snapshot, storage_unit] - where: not StorageUnit_p_nom_extendable AND StorageUnit_active + where: StorageUnit_fix expression: StorageUnit_p_dispatch <= StorageUnit_p_max_pu * StorageUnit_p_nom StorageUnit_fix_p_store_lower: description: "`StorageUnit-fix-p_store-lower` — storing is non-negative" dims: [scenario, snapshot, storage_unit] - where: not StorageUnit_p_nom_extendable AND StorageUnit_active + where: StorageUnit_fix expression: StorageUnit_p_store >= 0 StorageUnit_fix_p_store_upper: description: >- `StorageUnit-fix-p_store-upper` — a fixed unit stores at most its nominal power, the minimum-per-unit column carrying that cap negated dims: [scenario, snapshot, storage_unit] - where: not StorageUnit_p_nom_extendable AND StorageUnit_active + where: StorageUnit_fix expression: StorageUnit_p_store <= -StorageUnit_p_min_pu * StorageUnit_p_nom StorageUnit_fix_state_of_charge_lower: description: "`StorageUnit-fix-state_of_charge-lower` — charge is non-negative" dims: [scenario, snapshot, storage_unit] - where: not StorageUnit_p_nom_extendable AND StorageUnit_active + where: StorageUnit_fix expression: StorageUnit_state_of_charge >= 0 StorageUnit_fix_state_of_charge_upper: description: "`StorageUnit-fix-state_of_charge-upper` — a fixed unit holds at most its hours at nominal power" dims: [scenario, snapshot, storage_unit] - where: not StorageUnit_p_nom_extendable AND StorageUnit_active + where: StorageUnit_fix expression: StorageUnit_state_of_charge <= StorageUnit_max_hours * StorageUnit_p_nom Generator_com_p_lower: description: "`Generator-com-p-lower` — a committed unit outputs at least its minimum; off, at least nothing" dims: [scenario, snapshot, generator] - where: Generator_committable AND not Generator_p_nom_extendable AND Generator_active + where: Generator_committed AND NOT Generator_p_nom_extendable expression: Generator_p >= Generator_p_min_pu * Generator_p_nom * (Generator_status - Generator_maintenance_pu * Generator_maintenance_status) Generator_com_p_upper: description: "`Generator-com-p-upper` — a committed unit outputs at most what is available; off, at most nothing" dims: [scenario, snapshot, generator] - where: Generator_committable AND not Generator_p_nom_extendable AND Generator_active + where: Generator_committed AND NOT Generator_p_nom_extendable expression: Generator_p <= Generator_p_max_pu * Generator_p_nom * (Generator_status - Generator_maintenance_pu * Generator_maintenance_status) Generator_com_transition_start_up: description: "`Generator-com-transition-start-up` — turning on is a start, counted against the state the unit carried into the snapshot" dims: [scenario, snapshot, generator] - where: Generator_committable AND Generator_active + where: Generator_committed expression: Generator_start_up >= Generator_status - Generator_previous_status Generator_com_transition_shut_down: description: "`Generator-com-transition-shut-down` — turning off is a stop, counted against the state the unit carried into the snapshot" dims: [scenario, snapshot, generator] - where: Generator_committable AND Generator_active + where: Generator_committed expression: Generator_shut_down >= Generator_previous_status - Generator_status Generator_com_up_time: description: >- @@ -2534,7 +2649,7 @@ constraints: is still on. The first snapshot's share of the window is the brought-in up time's, which the must-stay-up mask carries dims: [scenario, snapshot, generator] - where: Generator_committable AND Generator_min_up_time > 0 AND position(snapshot) > 0 AND Generator_active + where: Generator_committed AND Generator_min_up_time > 0 AND position(snapshot) > 0 expression: sum_back(Generator_start_up, along=snapshot, window=Generator_min_up_time) <= Generator_status Generator_com_down_time: description: >- @@ -2542,19 +2657,19 @@ constraints: time is still off. The first snapshot's share of the window is the brought-in down time's, which the must-stay-down mask carries dims: [scenario, snapshot, generator] - where: Generator_committable AND Generator_min_down_time > 0 AND position(snapshot) > 0 AND Generator_active + where: Generator_committed AND Generator_min_down_time > 0 AND position(snapshot) > 0 expression: sum_back(Generator_shut_down, along=snapshot, window=Generator_min_down_time) <= 1 - Generator_status Generator_com_status_must_stay_up: description: "`Generator-com-status-min_up_time_must_stay_up` — a unit still serving the up time it brought in stays on" dims: [scenario, snapshot, generator] - where: Generator_committable AND Generator_must_stay_up AND Generator_active + where: Generator_committed AND Generator_must_stay_up expression: Generator_status == 1 Generator_com_status_must_stay_down: description: >- `Generator-com-status-min_down_time_must_stay_up` — a unit still serving the down time it brought in stays off; PyPSA names the row `_must_stay_up` dims: [scenario, snapshot, generator] - where: Generator_committable AND Generator_must_stay_down AND Generator_active + where: Generator_committed AND Generator_must_stay_down expression: Generator_status == 0 Generator_p_ramp_limit_up_run_big_m: description: >- @@ -2563,10 +2678,9 @@ constraints: releases the row in the snapshot it turns on dims: [scenario, snapshot, generator] where: >- - Generator_committable AND Generator_p_nom_extendable AND NOT (Generator_p_nom_mod > 0) + Generator_com_ext AND (Generator_ramp_limit_up OR Generator_ramp_limit_start_up) - AND (position(snapshot, by=snapshot_period, within=period) > 0 OR (position(snapshot) == 0 AND (Generator_status_initial == 0 OR Generator_p_init))) - AND Generator_active + AND Generator_ramps_from_previous expression: >- Generator_p - Generator_previous_p <= Generator_ramp_up_rate * Generator_p_nom_ext @@ -2578,10 +2692,9 @@ constraints: the chosen build; the big M releases the row everywhere else dims: [scenario, snapshot, generator] where: >- - Generator_committable AND Generator_p_nom_extendable AND NOT (Generator_p_nom_mod > 0) + Generator_com_ext AND (Generator_ramp_limit_up OR Generator_ramp_limit_start_up) - AND (position(snapshot, by=snapshot_period, within=period) > 0 OR (position(snapshot) == 0 AND (Generator_status_initial == 0 OR Generator_p_init))) - AND Generator_active + AND Generator_ramps_from_previous expression: >- Generator_p - Generator_previous_p <= Generator_start_up_rate * Generator_p_nom_ext @@ -2593,10 +2706,9 @@ constraints: releases the row in the snapshot it turns off dims: [scenario, snapshot, generator] where: >- - Generator_committable AND Generator_p_nom_extendable AND NOT (Generator_p_nom_mod > 0) + Generator_com_ext AND (Generator_ramp_limit_down OR Generator_ramp_limit_shut_down) - AND (position(snapshot, by=snapshot_period, within=period) > 0 OR (position(snapshot) == 0 AND (Generator_status_initial == 0 OR Generator_p_init))) - AND Generator_active + AND Generator_ramps_from_previous expression: >- Generator_previous_p - Generator_p <= Generator_ramp_down_rate * Generator_p_nom_ext @@ -2608,10 +2720,9 @@ constraints: the chosen build; the big M releases the row everywhere else dims: [scenario, snapshot, generator] where: >- - Generator_committable AND Generator_p_nom_extendable AND NOT (Generator_p_nom_mod > 0) + Generator_com_ext AND (Generator_ramp_limit_down OR Generator_ramp_limit_shut_down) - AND (position(snapshot, by=snapshot_period, within=period) > 0 OR (position(snapshot) == 0 AND (Generator_status_initial == 0 OR Generator_p_init))) - AND Generator_active + AND Generator_ramps_from_previous expression: >- Generator_previous_p - Generator_p <= Generator_shut_down_rate * Generator_p_nom_ext @@ -2626,19 +2737,19 @@ constraints: `Generator-com-ext-p-upper-cap` — a committed extendable unit outputs at most what is available of the chosen build, whatever its status dims: [scenario, snapshot, generator] - where: Generator_committable AND Generator_p_nom_extendable AND NOT (Generator_p_nom_mod > 0) AND Generator_active + where: Generator_com_ext expression: Generator_p <= Generator_p_max_pu * (Generator_p_nom_ext - Generator_maintenance_pu * Generator_maintenance_capacity) Generator_com_ext_p_upper_big_m: description: "`Generator-com-ext-p-upper-bigM` — off, a unit outputs nothing; on, the big M is no bound" dims: [scenario, snapshot, generator] - where: Generator_committable AND Generator_p_nom_extendable AND NOT (Generator_p_nom_mod > 0) AND Generator_active + where: Generator_com_ext expression: Generator_p <= Generator_big_m * Generator_status Generator_com_ext_p_lower: description: >- `Generator-com-ext-p-lower` — a committed extendable unit outputs at least its minimum of the chosen build; off, the big M releases the row dims: [scenario, snapshot, generator] - where: Generator_committable AND Generator_p_nom_extendable AND NOT (Generator_p_nom_mod > 0) AND Generator_active + where: Generator_com_ext expression: >- Generator_p >= Generator_p_min_pu * (Generator_p_nom_ext - Generator_maintenance_pu * Generator_maintenance_capacity) @@ -2649,23 +2760,21 @@ constraints: negative, output is also plainly non-negative, a row the big-M lower cannot assert while the unit is off dims: [scenario, snapshot, generator] - where: >- - Generator_committable AND Generator_p_nom_extendable - AND Generator_p_min_pu_nonneg AND NOT (Generator_p_nom_mod > 0) AND Generator_active + where: Generator_com_ext AND Generator_p_min_pu_nonneg expression: Generator_p >= 0 Generator_com_mod_p_lower: description: >- `Generator-com-mod-p-lower` — a committed modular unit outputs at least its minimum of one module, whether the build is fixed or a decision dims: [scenario, snapshot, generator] - where: Generator_committable AND Generator_p_nom_mod > 0 AND Generator_active + where: Generator_committed AND Generator_p_nom_mod > 0 expression: Generator_p >= Generator_p_min_pu * Generator_p_nom_mod * (Generator_status - Generator_maintenance_pu * Generator_maintenance_status) Generator_com_mod_p_upper: description: >- `Generator-com-mod-p-upper` — a committed modular unit outputs at most one module's share, whether the build is fixed or a decision dims: [scenario, snapshot, generator] - where: Generator_committable AND Generator_p_nom_mod > 0 AND Generator_active + where: Generator_committed AND Generator_p_nom_mod > 0 expression: Generator_p <= Generator_p_max_pu * Generator_p_nom_mod * (Generator_status - Generator_maintenance_pu * Generator_maintenance_status) Generator_status_p_fixed_upper: description: >- @@ -2673,7 +2782,7 @@ constraints: place, an explicit row as PyPSA writes it: one where the build is not modular, and the fixed build's whole count of modules where it is dims: [scenario, snapshot, generator] - where: Generator_committable AND NOT (Generator_p_nom_extendable AND Generator_p_nom_mod > 0) AND Generator_active + where: Generator_committed AND NOT (Generator_p_nom_extendable AND Generator_p_nom_mod > 0) expression: Generator_status <= Generator_modules_installed Generator_start_up_p_fixed_upper: description: >- @@ -2681,7 +2790,7 @@ constraints: place, an explicit row as PyPSA writes it: one where the build is not modular, and the fixed build's whole count of modules where it is dims: [scenario, snapshot, generator] - where: Generator_committable AND NOT (Generator_p_nom_extendable AND Generator_p_nom_mod > 0) AND Generator_active + where: Generator_committed AND NOT (Generator_p_nom_extendable AND Generator_p_nom_mod > 0) expression: Generator_start_up <= Generator_modules_installed Generator_shut_down_p_fixed_upper: description: >- @@ -2689,22 +2798,22 @@ constraints: place, an explicit row as PyPSA writes it: one where the build is not modular, and the fixed build's whole count of modules where it is dims: [scenario, snapshot, generator] - where: Generator_committable AND NOT (Generator_p_nom_extendable AND Generator_p_nom_mod > 0) AND Generator_active + where: Generator_committed AND NOT (Generator_p_nom_extendable AND Generator_p_nom_mod > 0) expression: Generator_shut_down <= Generator_modules_installed Generator_status_p_nom_variable_upper: description: "`Generator-status-p_nom-variable-upper` — a modular unit is on only where a module is built" dims: [scenario, snapshot, generator] - where: Generator_committable AND Generator_p_nom_extendable AND Generator_p_nom_mod > 0 AND Generator_active + where: Generator_committed AND Generator_p_nom_extendable AND Generator_p_nom_mod > 0 expression: Generator_status <= Generator_n_mod Generator_start_up_p_nom_variable_upper: description: "`Generator-start_up-p_nom-variable-upper` — a modular unit starts only where a module is built" dims: [scenario, snapshot, generator] - where: Generator_committable AND Generator_p_nom_extendable AND Generator_p_nom_mod > 0 AND Generator_active + where: Generator_committed AND Generator_p_nom_extendable AND Generator_p_nom_mod > 0 expression: Generator_start_up <= Generator_n_mod Generator_shut_down_p_nom_variable_upper: description: "`Generator-shut_down-p_nom-variable-upper` — a modular unit stops only where a module is built" dims: [scenario, snapshot, generator] - where: Generator_committable AND Generator_p_nom_extendable AND Generator_p_nom_mod > 0 AND Generator_active + where: Generator_committed AND Generator_p_nom_extendable AND Generator_p_nom_mod > 0 expression: Generator_shut_down <= Generator_n_mod Generator_maint_event_count: description: "`Generator-maint-event-count` — a maintainable generator holds its number of maintenance events over the horizon" @@ -2729,74 +2838,74 @@ constraints: `Generator-maintcap_upper` — the build taken off is at most the chosen build in maintenance, and at most the build less its floor out of it dims: [scenario, snapshot, generator] - where: Generator_maintainable AND Generator_p_nom_extendable AND NOT (Generator_committable AND Generator_p_nom_mod > 0) AND Generator_active + where: Generator_maint_ext expression: Generator_maintenance_capacity <= Generator_p_nom_ext - Generator_p_nom_min * (1 - Generator_maintenance) Generator_maintcap_upper_nommax: description: "`Generator-maintcap_upper_nommax` — out of maintenance, no build is taken off" dims: [scenario, snapshot, generator] - where: Generator_maintainable AND Generator_p_nom_extendable AND NOT (Generator_committable AND Generator_p_nom_mod > 0) AND Generator_active + where: Generator_maint_ext expression: Generator_maintenance_capacity <= Generator_p_nom_max * Generator_maintenance Generator_maintcap_lower_nommax: description: "`Generator-maintcap_lower_nommax` — in maintenance, the whole chosen build is taken off" dims: [scenario, snapshot, generator] - where: Generator_maintainable AND Generator_p_nom_extendable AND NOT (Generator_committable AND Generator_p_nom_mod > 0) AND Generator_active + where: Generator_maint_ext expression: Generator_maintenance_capacity >= Generator_p_nom_ext - Generator_p_nom_max * (1 - Generator_maintenance) Generator_maintcap_lower_nommin: description: "`Generator-maintcap_lower_nommin` — in maintenance, at least the floor of the build is taken off" dims: [scenario, snapshot, generator] - where: Generator_maintainable AND Generator_p_nom_extendable AND NOT (Generator_committable AND Generator_p_nom_mod > 0) AND Generator_active AND Generator_p_nom_min > 0 + where: Generator_maint_ext AND Generator_p_nom_min > 0 expression: Generator_maintenance_capacity >= Generator_p_nom_min * Generator_maintenance Generator_maint_status_le_status: description: "`Generator-maint-status-le-status` — the status in maintenance is at most the status" dims: [scenario, snapshot, generator] - where: Generator_maintainable AND Generator_committable AND NOT Generator_p_nom_extendable AND Generator_active + where: Generator_maintainable AND Generator_committed AND NOT Generator_p_nom_extendable expression: Generator_maintenance_status <= Generator_status Generator_maint_status_le_maint: description: "`Generator-maint-status-le-maint` — out of maintenance, the status in maintenance is zero" dims: [scenario, snapshot, generator] - where: Generator_maintainable AND Generator_committable AND NOT Generator_p_nom_extendable AND Generator_active + where: Generator_maintainable AND Generator_committed AND NOT Generator_p_nom_extendable expression: Generator_maintenance_status <= Generator_maintenance Generator_maint_status_lb: description: "`Generator-maint-status-lb` — on and in maintenance, the status in maintenance is one" dims: [scenario, snapshot, generator] - where: Generator_maintainable AND Generator_committable AND NOT Generator_p_nom_extendable AND Generator_active + where: Generator_maintainable AND Generator_committed AND NOT Generator_p_nom_extendable expression: Generator_maintenance_status >= Generator_status + Generator_maintenance - 1 Generator_maint_modstatus_le_status: description: "`Generator-maint-modstatus-le-status` — the modules on in maintenance are at most the modules on" dims: [scenario, snapshot, generator] - where: Generator_maintainable AND Generator_committable AND Generator_p_nom_mod > 0 AND Generator_active + where: Generator_maintainable AND Generator_committed AND Generator_p_nom_mod > 0 expression: Generator_maintenance_status <= Generator_status Generator_maint_modstatus_le_maint: description: >- `Generator-maint-modstatus-le-maint` — out of maintenance, no module is on in maintenance; in it, at most the modules the build cap holds dims: [scenario, snapshot, generator] - where: Generator_maintainable AND Generator_committable AND Generator_p_nom_mod > 0 AND Generator_active + where: Generator_maintainable AND Generator_committed AND Generator_p_nom_mod > 0 expression: Generator_maintenance_status <= Generator_p_nom_max / Generator_p_nom_mod * Generator_maintenance Generator_maint_modstatus_lb: description: "`Generator-maint-modstatus-lb` — in maintenance, every module on is on in maintenance" dims: [scenario, snapshot, generator] - where: Generator_maintainable AND Generator_committable AND Generator_p_nom_mod > 0 AND Generator_active + where: Generator_maintainable AND Generator_committed AND Generator_p_nom_mod > 0 expression: Generator_maintenance_status >= Generator_status - Generator_p_nom_max / Generator_p_nom_mod * (1 - Generator_maintenance) Link_com_p_lower: description: "`Link-com-p-lower` — a committed link flows at least its minimum; off, at least nothing" dims: [scenario, snapshot, link] - where: Link_committable AND not Link_p_nom_extendable AND Link_active + where: Link_committed AND NOT Link_p_nom_extendable expression: Link_p >= Link_p_min_pu * Link_p_nom * (Link_status - Link_maintenance_pu * Link_maintenance_status) Link_com_p_upper: description: "`Link-com-p-upper` — a committed link flows at most what is available; off, at most nothing" dims: [scenario, snapshot, link] - where: Link_committable AND not Link_p_nom_extendable AND Link_active + where: Link_committed AND NOT Link_p_nom_extendable expression: Link_p <= Link_p_max_pu * Link_p_nom * (Link_status - Link_maintenance_pu * Link_maintenance_status) Link_com_transition_start_up: description: "`Link-com-transition-start-up` — turning on is a start, counted against the state the link carried into the snapshot" dims: [scenario, snapshot, link] - where: Link_committable AND Link_active + where: Link_committed expression: Link_start_up >= Link_status - Link_previous_status Link_com_transition_shut_down: description: "`Link-com-transition-shut-down` — turning off is a stop, counted against the state the link carried into the snapshot" dims: [scenario, snapshot, link] - where: Link_committable AND Link_active + where: Link_committed expression: Link_shut_down >= Link_previous_status - Link_status Link_com_up_time: description: >- @@ -2804,7 +2913,7 @@ constraints: is still on. The first snapshot's share of the window is the brought-in up time's, which the must-stay-up mask carries dims: [scenario, snapshot, link] - where: Link_committable AND Link_min_up_time > 0 AND position(snapshot) > 0 AND Link_active + where: Link_committed AND Link_min_up_time > 0 AND position(snapshot) > 0 expression: sum_back(Link_start_up, along=snapshot, window=Link_min_up_time) <= Link_status Link_com_down_time: description: >- @@ -2812,19 +2921,19 @@ constraints: time is still off. The first snapshot's share of the window is the brought-in down time's, which the must-stay-down mask carries dims: [scenario, snapshot, link] - where: Link_committable AND Link_min_down_time > 0 AND position(snapshot) > 0 AND Link_active + where: Link_committed AND Link_min_down_time > 0 AND position(snapshot) > 0 expression: sum_back(Link_shut_down, along=snapshot, window=Link_min_down_time) <= 1 - Link_status Link_com_status_must_stay_up: description: "`Link-com-status-min_up_time_must_stay_up` — a link still serving the up time it brought in stays on" dims: [scenario, snapshot, link] - where: Link_committable AND Link_must_stay_up AND Link_active + where: Link_committed AND Link_must_stay_up expression: Link_status == 1 Link_com_status_must_stay_down: description: >- `Link-com-status-min_down_time_must_stay_up` — a link still serving the down time it brought in stays off; PyPSA names the row `_must_stay_up` dims: [scenario, snapshot, link] - where: Link_committable AND Link_must_stay_down AND Link_active + where: Link_committed AND Link_must_stay_down expression: Link_status == 0 Link_p_ramp_limit_up_run_big_m: description: >- @@ -2832,11 +2941,7 @@ constraints: raises flow no faster than its limit of the chosen build; the big M releases the row in the snapshot it turns on dims: [scenario, snapshot, link] - where: >- - Link_committable AND Link_p_nom_extendable AND NOT (Link_p_nom_mod > 0) - AND (Link_ramp_limit_up OR Link_ramp_limit_start_up) - AND (position(snapshot, by=snapshot_period, within=period) > 0 OR (position(snapshot) == 0 AND (Link_status_initial == 0 OR Link_p_init))) - AND Link_active + where: Link_com_ext AND (Link_ramp_limit_up OR Link_ramp_limit_start_up) AND Link_ramps_from_previous expression: >- Link_p - Link_previous_p <= Link_ramp_up_rate * Link_p_nom_ext @@ -2847,11 +2952,7 @@ constraints: committed extendable link ramps no further than its start-up ramp of the chosen build; the big M releases the row everywhere else dims: [scenario, snapshot, link] - where: >- - Link_committable AND Link_p_nom_extendable AND NOT (Link_p_nom_mod > 0) - AND (Link_ramp_limit_up OR Link_ramp_limit_start_up) - AND (position(snapshot, by=snapshot_period, within=period) > 0 OR (position(snapshot) == 0 AND (Link_status_initial == 0 OR Link_p_init))) - AND Link_active + where: Link_com_ext AND (Link_ramp_limit_up OR Link_ramp_limit_start_up) AND Link_ramps_from_previous expression: >- Link_p - Link_previous_p <= Link_start_up_rate * Link_p_nom_ext @@ -2862,11 +2963,7 @@ constraints: lowers flow no faster than its limit of the chosen build; the big M releases the row in the snapshot it turns off dims: [scenario, snapshot, link] - where: >- - Link_committable AND Link_p_nom_extendable AND NOT (Link_p_nom_mod > 0) - AND (Link_ramp_limit_down OR Link_ramp_limit_shut_down) - AND (position(snapshot, by=snapshot_period, within=period) > 0 OR (position(snapshot) == 0 AND (Link_status_initial == 0 OR Link_p_init))) - AND Link_active + where: Link_com_ext AND (Link_ramp_limit_down OR Link_ramp_limit_shut_down) AND Link_ramps_from_previous expression: >- Link_previous_p - Link_p <= Link_ramp_down_rate * Link_p_nom_ext @@ -2877,11 +2974,7 @@ constraints: a committed extendable link ramps no further than its shut-down ramp of the chosen build; the big M releases the row everywhere else dims: [scenario, snapshot, link] - where: >- - Link_committable AND Link_p_nom_extendable AND NOT (Link_p_nom_mod > 0) - AND (Link_ramp_limit_down OR Link_ramp_limit_shut_down) - AND (position(snapshot, by=snapshot_period, within=period) > 0 OR (position(snapshot) == 0 AND (Link_status_initial == 0 OR Link_p_init))) - AND Link_active + where: Link_com_ext AND (Link_ramp_limit_down OR Link_ramp_limit_shut_down) AND Link_ramps_from_previous expression: >- Link_previous_p - Link_p <= Link_shut_down_rate * Link_p_nom_ext @@ -2896,19 +2989,19 @@ constraints: `Link-com-ext-p-upper-cap` — a committed extendable link flows at most what is available of the chosen build, whatever its status dims: [scenario, snapshot, link] - where: Link_committable AND Link_p_nom_extendable AND NOT (Link_p_nom_mod > 0) AND Link_active + where: Link_com_ext expression: Link_p <= Link_p_max_pu * (Link_p_nom_ext - Link_maintenance_pu * Link_maintenance_capacity) Link_com_ext_p_upper_big_m: description: "`Link-com-ext-p-upper-bigM` — off, a link flows nothing; on, the big M is no bound" dims: [scenario, snapshot, link] - where: Link_committable AND Link_p_nom_extendable AND NOT (Link_p_nom_mod > 0) AND Link_active + where: Link_com_ext expression: Link_p <= Link_big_m * Link_status Link_com_ext_p_lower: description: >- `Link-com-ext-p-lower` — a committed extendable link flows at least its minimum of the chosen build; off, the big M releases the row dims: [scenario, snapshot, link] - where: Link_committable AND Link_p_nom_extendable AND NOT (Link_p_nom_mod > 0) AND Link_active + where: Link_com_ext expression: >- Link_p >= Link_p_min_pu * (Link_p_nom_ext - Link_maintenance_pu * Link_maintenance_capacity) @@ -2919,23 +3012,21 @@ constraints: negative, flow is also plainly non-negative, a row the big-M lower cannot assert while the link is off dims: [scenario, snapshot, link] - where: >- - Link_committable AND Link_p_nom_extendable - AND Link_p_min_pu_nonneg AND NOT (Link_p_nom_mod > 0) AND Link_active + where: Link_com_ext AND Link_p_min_pu_nonneg expression: Link_p >= 0 Link_com_mod_p_lower: description: >- `Link-com-mod-p-lower` — a committed modular link flows at least its minimum of one module, whether the build is fixed or a decision dims: [scenario, snapshot, link] - where: Link_committable AND Link_p_nom_mod > 0 AND Link_active + where: Link_committed AND Link_p_nom_mod > 0 expression: Link_p >= Link_p_min_pu * Link_p_nom_mod * (Link_status - Link_maintenance_pu * Link_maintenance_status) Link_com_mod_p_upper: description: >- `Link-com-mod-p-upper` — a committed modular link flows at most one module's share, whether the build is fixed or a decision dims: [scenario, snapshot, link] - where: Link_committable AND Link_p_nom_mod > 0 AND Link_active + where: Link_committed AND Link_p_nom_mod > 0 expression: Link_p <= Link_p_max_pu * Link_p_nom_mod * (Link_status - Link_maintenance_pu * Link_maintenance_status) Link_status_p_fixed_upper: description: >- @@ -2943,7 +3034,7 @@ constraints: place, an explicit row as PyPSA writes it: one where the build is not modular, and the fixed build's whole count of modules where it is dims: [scenario, snapshot, link] - where: Link_committable AND NOT (Link_p_nom_extendable AND Link_p_nom_mod > 0) AND Link_active + where: Link_committed AND NOT (Link_p_nom_extendable AND Link_p_nom_mod > 0) expression: Link_status <= Link_modules_installed Link_start_up_p_fixed_upper: description: >- @@ -2951,7 +3042,7 @@ constraints: place, an explicit row as PyPSA writes it: one where the build is not modular, and the fixed build's whole count of modules where it is dims: [scenario, snapshot, link] - where: Link_committable AND NOT (Link_p_nom_extendable AND Link_p_nom_mod > 0) AND Link_active + where: Link_committed AND NOT (Link_p_nom_extendable AND Link_p_nom_mod > 0) expression: Link_start_up <= Link_modules_installed Link_shut_down_p_fixed_upper: description: >- @@ -2959,22 +3050,22 @@ constraints: place, an explicit row as PyPSA writes it: one where the build is not modular, and the fixed build's whole count of modules where it is dims: [scenario, snapshot, link] - where: Link_committable AND NOT (Link_p_nom_extendable AND Link_p_nom_mod > 0) AND Link_active + where: Link_committed AND NOT (Link_p_nom_extendable AND Link_p_nom_mod > 0) expression: Link_shut_down <= Link_modules_installed Link_status_p_nom_variable_upper: description: "`Link-status-p_nom-variable-upper` — a modular link is on only where a module is built" dims: [scenario, snapshot, link] - where: Link_committable AND Link_p_nom_extendable AND Link_p_nom_mod > 0 AND Link_active + where: Link_committed AND Link_p_nom_extendable AND Link_p_nom_mod > 0 expression: Link_status <= Link_n_mod Link_start_up_p_nom_variable_upper: description: "`Link-start_up-p_nom-variable-upper` — a modular link starts only where a module is built" dims: [scenario, snapshot, link] - where: Link_committable AND Link_p_nom_extendable AND Link_p_nom_mod > 0 AND Link_active + where: Link_committed AND Link_p_nom_extendable AND Link_p_nom_mod > 0 expression: Link_start_up <= Link_n_mod Link_shut_down_p_nom_variable_upper: description: "`Link-shut_down-p_nom-variable-upper` — a modular link stops only where a module is built" dims: [scenario, snapshot, link] - where: Link_committable AND Link_p_nom_extendable AND Link_p_nom_mod > 0 AND Link_active + where: Link_committed AND Link_p_nom_extendable AND Link_p_nom_mod > 0 expression: Link_shut_down <= Link_n_mod Link_maint_event_count: description: "`Link-maint-event-count` — a maintainable link holds its number of maintenance events over the horizon" @@ -2999,74 +3090,74 @@ constraints: `Link-maintcap_upper` — the build taken off is at most the chosen build in maintenance, and at most the build less its floor out of it dims: [scenario, snapshot, link] - where: Link_maintainable AND Link_p_nom_extendable AND NOT (Link_committable AND Link_p_nom_mod > 0) AND Link_active + where: Link_maint_ext expression: Link_maintenance_capacity <= Link_p_nom_ext - Link_p_nom_min * (1 - Link_maintenance) Link_maintcap_upper_nommax: description: "`Link-maintcap_upper_nommax` — out of maintenance, no build is taken off" dims: [scenario, snapshot, link] - where: Link_maintainable AND Link_p_nom_extendable AND NOT (Link_committable AND Link_p_nom_mod > 0) AND Link_active + where: Link_maint_ext expression: Link_maintenance_capacity <= Link_p_nom_max * Link_maintenance Link_maintcap_lower_nommax: description: "`Link-maintcap_lower_nommax` — in maintenance, the whole chosen build is taken off" dims: [scenario, snapshot, link] - where: Link_maintainable AND Link_p_nom_extendable AND NOT (Link_committable AND Link_p_nom_mod > 0) AND Link_active + where: Link_maint_ext expression: Link_maintenance_capacity >= Link_p_nom_ext - Link_p_nom_max * (1 - Link_maintenance) Link_maintcap_lower_nommin: description: "`Link-maintcap_lower_nommin` — in maintenance, at least the floor of the build is taken off" dims: [scenario, snapshot, link] - where: Link_maintainable AND Link_p_nom_extendable AND NOT (Link_committable AND Link_p_nom_mod > 0) AND Link_active AND Link_p_nom_min > 0 + where: Link_maint_ext AND Link_p_nom_min > 0 expression: Link_maintenance_capacity >= Link_p_nom_min * Link_maintenance Link_maint_status_le_status: description: "`Link-maint-status-le-status` — the status in maintenance is at most the status" dims: [scenario, snapshot, link] - where: Link_maintainable AND Link_committable AND NOT Link_p_nom_extendable AND Link_active + where: Link_maintainable AND Link_committed AND NOT Link_p_nom_extendable expression: Link_maintenance_status <= Link_status Link_maint_status_le_maint: description: "`Link-maint-status-le-maint` — out of maintenance, the status in maintenance is zero" dims: [scenario, snapshot, link] - where: Link_maintainable AND Link_committable AND NOT Link_p_nom_extendable AND Link_active + where: Link_maintainable AND Link_committed AND NOT Link_p_nom_extendable expression: Link_maintenance_status <= Link_maintenance Link_maint_status_lb: description: "`Link-maint-status-lb` — on and in maintenance, the status in maintenance is one" dims: [scenario, snapshot, link] - where: Link_maintainable AND Link_committable AND NOT Link_p_nom_extendable AND Link_active + where: Link_maintainable AND Link_committed AND NOT Link_p_nom_extendable expression: Link_maintenance_status >= Link_status + Link_maintenance - 1 Link_maint_modstatus_le_status: description: "`Link-maint-modstatus-le-status` — the modules on in maintenance are at most the modules on" dims: [scenario, snapshot, link] - where: Link_maintainable AND Link_committable AND Link_p_nom_mod > 0 AND Link_active + where: Link_maintainable AND Link_committed AND Link_p_nom_mod > 0 expression: Link_maintenance_status <= Link_status Link_maint_modstatus_le_maint: description: >- `Link-maint-modstatus-le-maint` — out of maintenance, no module is on in maintenance; in it, at most the modules the build cap holds dims: [scenario, snapshot, link] - where: Link_maintainable AND Link_committable AND Link_p_nom_mod > 0 AND Link_active + where: Link_maintainable AND Link_committed AND Link_p_nom_mod > 0 expression: Link_maintenance_status <= Link_p_nom_max / Link_p_nom_mod * Link_maintenance Link_maint_modstatus_lb: description: "`Link-maint-modstatus-lb` — in maintenance, every module on is on in maintenance" dims: [scenario, snapshot, link] - where: Link_maintainable AND Link_committable AND Link_p_nom_mod > 0 AND Link_active + where: Link_maintainable AND Link_committed AND Link_p_nom_mod > 0 expression: Link_maintenance_status >= Link_status - Link_p_nom_max / Link_p_nom_mod * (1 - Link_maintenance) Process_com_p_lower: description: "`Process-com-p-lower` — a committed process runs at least its minimum; off, at least nothing" dims: [scenario, snapshot, process] - where: Process_committable AND not Process_p_nom_extendable AND Process_active + where: Process_committed AND NOT Process_p_nom_extendable expression: Process_p >= Process_p_min_pu * Process_p_nom * (Process_status - Process_maintenance_pu * Process_maintenance_status) Process_com_p_upper: description: "`Process-com-p-upper` — a committed process runs at most what is available; off, at most nothing" dims: [scenario, snapshot, process] - where: Process_committable AND not Process_p_nom_extendable AND Process_active + where: Process_committed AND NOT Process_p_nom_extendable expression: Process_p <= Process_p_max_pu * Process_p_nom * (Process_status - Process_maintenance_pu * Process_maintenance_status) Process_com_transition_start_up: description: "`Process-com-transition-start-up` — turning on is a start, counted against the state the process carried into the snapshot" dims: [scenario, snapshot, process] - where: Process_committable AND Process_active + where: Process_committed expression: Process_start_up >= Process_status - Process_previous_status Process_com_transition_shut_down: description: "`Process-com-transition-shut-down` — turning off is a stop, counted against the state the process carried into the snapshot" dims: [scenario, snapshot, process] - where: Process_committable AND Process_active + where: Process_committed expression: Process_shut_down >= Process_previous_status - Process_status Process_com_up_time: description: >- @@ -3074,7 +3165,7 @@ constraints: is still on. The first snapshot's share of the window is the brought-in up time's, which the must-stay-up mask carries dims: [scenario, snapshot, process] - where: Process_committable AND Process_min_up_time > 0 AND position(snapshot) > 0 AND Process_active + where: Process_committed AND Process_min_up_time > 0 AND position(snapshot) > 0 expression: sum_back(Process_start_up, along=snapshot, window=Process_min_up_time) <= Process_status Process_com_down_time: description: >- @@ -3082,19 +3173,19 @@ constraints: time is still off. The first snapshot's share of the window is the brought-in down time's, which the must-stay-down mask carries dims: [scenario, snapshot, process] - where: Process_committable AND Process_min_down_time > 0 AND position(snapshot) > 0 AND Process_active + where: Process_committed AND Process_min_down_time > 0 AND position(snapshot) > 0 expression: sum_back(Process_shut_down, along=snapshot, window=Process_min_down_time) <= 1 - Process_status Process_com_status_must_stay_up: description: "`Process-com-status-min_up_time_must_stay_up` — a process still serving the up time it brought in stays on" dims: [scenario, snapshot, process] - where: Process_committable AND Process_must_stay_up AND Process_active + where: Process_committed AND Process_must_stay_up expression: Process_status == 1 Process_com_status_must_stay_down: description: >- `Process-com-status-min_down_time_must_stay_up` — a process still serving the down time it brought in stays off; PyPSA names the row `_must_stay_up` dims: [scenario, snapshot, process] - where: Process_committable AND Process_must_stay_down AND Process_active + where: Process_committed AND Process_must_stay_down expression: Process_status == 0 Process_p_ramp_limit_up_run_big_m: description: >- @@ -3102,11 +3193,7 @@ constraints: raises internal power no faster than its limit of the chosen build; the big M releases the row in the snapshot it turns on dims: [scenario, snapshot, process] - where: >- - Process_committable AND Process_p_nom_extendable AND NOT (Process_p_nom_mod > 0) - AND (Process_ramp_limit_up OR Process_ramp_limit_start_up) - AND (position(snapshot, by=snapshot_period, within=period) > 0 OR (position(snapshot) == 0 AND (Process_status_initial == 0 OR Process_p_init))) - AND Process_active + where: Process_com_ext AND (Process_ramp_limit_up OR Process_ramp_limit_start_up) AND Process_ramps_from_previous expression: >- Process_p - Process_previous_p <= Process_ramp_up_rate * Process_p_nom_ext @@ -3117,11 +3204,7 @@ constraints: committed extendable process ramps no further than its start-up ramp of the chosen build; the big M releases the row everywhere else dims: [scenario, snapshot, process] - where: >- - Process_committable AND Process_p_nom_extendable AND NOT (Process_p_nom_mod > 0) - AND (Process_ramp_limit_up OR Process_ramp_limit_start_up) - AND (position(snapshot, by=snapshot_period, within=period) > 0 OR (position(snapshot) == 0 AND (Process_status_initial == 0 OR Process_p_init))) - AND Process_active + where: Process_com_ext AND (Process_ramp_limit_up OR Process_ramp_limit_start_up) AND Process_ramps_from_previous expression: >- Process_p - Process_previous_p <= Process_start_up_rate * Process_p_nom_ext @@ -3133,10 +3216,9 @@ constraints: releases the row in the snapshot it turns off dims: [scenario, snapshot, process] where: >- - Process_committable AND Process_p_nom_extendable AND NOT (Process_p_nom_mod > 0) + Process_com_ext AND (Process_ramp_limit_down OR Process_ramp_limit_shut_down) - AND (position(snapshot, by=snapshot_period, within=period) > 0 OR (position(snapshot) == 0 AND (Process_status_initial == 0 OR Process_p_init))) - AND Process_active + AND Process_ramps_from_previous expression: >- Process_previous_p - Process_p <= Process_ramp_down_rate * Process_p_nom_ext @@ -3148,10 +3230,9 @@ constraints: the chosen build; the big M releases the row everywhere else dims: [scenario, snapshot, process] where: >- - Process_committable AND Process_p_nom_extendable AND NOT (Process_p_nom_mod > 0) + Process_com_ext AND (Process_ramp_limit_down OR Process_ramp_limit_shut_down) - AND (position(snapshot, by=snapshot_period, within=period) > 0 OR (position(snapshot) == 0 AND (Process_status_initial == 0 OR Process_p_init))) - AND Process_active + AND Process_ramps_from_previous expression: >- Process_previous_p - Process_p <= Process_shut_down_rate * Process_p_nom_ext @@ -3166,19 +3247,19 @@ constraints: `Process-com-ext-p-upper-cap` — a committed extendable process runs at most what is available of the chosen build, whatever its status dims: [scenario, snapshot, process] - where: Process_committable AND Process_p_nom_extendable AND NOT (Process_p_nom_mod > 0) AND Process_active + where: Process_com_ext expression: Process_p <= Process_p_max_pu * (Process_p_nom_ext - Process_maintenance_pu * Process_maintenance_capacity) Process_com_ext_p_upper_big_m: description: "`Process-com-ext-p-upper-bigM` — off, a process does not run; on, the big M is no bound" dims: [scenario, snapshot, process] - where: Process_committable AND Process_p_nom_extendable AND NOT (Process_p_nom_mod > 0) AND Process_active + where: Process_com_ext expression: Process_p <= Process_big_m * Process_status Process_com_ext_p_lower: description: >- `Process-com-ext-p-lower` — a committed extendable process runs at least its minimum of the chosen build; off, the big M releases the row dims: [scenario, snapshot, process] - where: Process_committable AND Process_p_nom_extendable AND NOT (Process_p_nom_mod > 0) AND Process_active + where: Process_com_ext expression: >- Process_p >= Process_p_min_pu * (Process_p_nom_ext - Process_maintenance_pu * Process_maintenance_capacity) @@ -3189,23 +3270,21 @@ constraints: negative, internal power is also plainly non-negative, a row the big-M lower cannot assert while the process is off dims: [scenario, snapshot, process] - where: >- - Process_committable AND Process_p_nom_extendable - AND Process_p_min_pu_nonneg AND NOT (Process_p_nom_mod > 0) AND Process_active + where: Process_com_ext AND Process_p_min_pu_nonneg expression: Process_p >= 0 Process_com_mod_p_lower: description: >- `Process-com-mod-p-lower` — a committed modular process runs at least its minimum of one module, whether the build is fixed or a decision dims: [scenario, snapshot, process] - where: Process_committable AND Process_p_nom_mod > 0 AND Process_active + where: Process_committed AND Process_p_nom_mod > 0 expression: Process_p >= Process_p_min_pu * Process_p_nom_mod * (Process_status - Process_maintenance_pu * Process_maintenance_status) Process_com_mod_p_upper: description: >- `Process-com-mod-p-upper` — a committed modular process runs at most one module's share, whether the build is fixed or a decision dims: [scenario, snapshot, process] - where: Process_committable AND Process_p_nom_mod > 0 AND Process_active + where: Process_committed AND Process_p_nom_mod > 0 expression: Process_p <= Process_p_max_pu * Process_p_nom_mod * (Process_status - Process_maintenance_pu * Process_maintenance_status) Process_status_p_fixed_upper: description: >- @@ -3213,7 +3292,7 @@ constraints: place, an explicit row as PyPSA writes it: one where the build is not modular, and the fixed build's whole count of modules where it is dims: [scenario, snapshot, process] - where: Process_committable AND NOT (Process_p_nom_extendable AND Process_p_nom_mod > 0) AND Process_active + where: Process_committed AND NOT (Process_p_nom_extendable AND Process_p_nom_mod > 0) expression: Process_status <= Process_modules_installed Process_start_up_p_fixed_upper: description: >- @@ -3221,7 +3300,7 @@ constraints: place, an explicit row as PyPSA writes it: one where the build is not modular, and the fixed build's whole count of modules where it is dims: [scenario, snapshot, process] - where: Process_committable AND NOT (Process_p_nom_extendable AND Process_p_nom_mod > 0) AND Process_active + where: Process_committed AND NOT (Process_p_nom_extendable AND Process_p_nom_mod > 0) expression: Process_start_up <= Process_modules_installed Process_shut_down_p_fixed_upper: description: >- @@ -3229,22 +3308,22 @@ constraints: place, an explicit row as PyPSA writes it: one where the build is not modular, and the fixed build's whole count of modules where it is dims: [scenario, snapshot, process] - where: Process_committable AND NOT (Process_p_nom_extendable AND Process_p_nom_mod > 0) AND Process_active + where: Process_committed AND NOT (Process_p_nom_extendable AND Process_p_nom_mod > 0) expression: Process_shut_down <= Process_modules_installed Process_status_p_nom_variable_upper: description: "`Process-status-p_nom-variable-upper` — a modular process is on only where a module is built" dims: [scenario, snapshot, process] - where: Process_committable AND Process_p_nom_extendable AND Process_p_nom_mod > 0 AND Process_active + where: Process_committed AND Process_p_nom_extendable AND Process_p_nom_mod > 0 expression: Process_status <= Process_n_mod Process_start_up_p_nom_variable_upper: description: "`Process-start_up-p_nom-variable-upper` — a modular process starts only where a module is built" dims: [scenario, snapshot, process] - where: Process_committable AND Process_p_nom_extendable AND Process_p_nom_mod > 0 AND Process_active + where: Process_committed AND Process_p_nom_extendable AND Process_p_nom_mod > 0 expression: Process_start_up <= Process_n_mod Process_shut_down_p_nom_variable_upper: description: "`Process-shut_down-p_nom-variable-upper` — a modular process stops only where a module is built" dims: [scenario, snapshot, process] - where: Process_committable AND Process_p_nom_extendable AND Process_p_nom_mod > 0 AND Process_active + where: Process_committed AND Process_p_nom_extendable AND Process_p_nom_mod > 0 expression: Process_shut_down <= Process_n_mod Process_maint_event_count: description: "`Process-maint-event-count` — a maintainable process holds its number of maintenance events over the horizon" @@ -3269,54 +3348,54 @@ constraints: `Process-maintcap_upper` — the build taken off is at most the chosen build in maintenance, and at most the build less its floor out of it dims: [scenario, snapshot, process] - where: Process_maintainable AND Process_p_nom_extendable AND NOT (Process_committable AND Process_p_nom_mod > 0) AND Process_active + where: Process_maint_ext expression: Process_maintenance_capacity <= Process_p_nom_ext - Process_p_nom_min * (1 - Process_maintenance) Process_maintcap_upper_nommax: description: "`Process-maintcap_upper_nommax` — out of maintenance, no build is taken off" dims: [scenario, snapshot, process] - where: Process_maintainable AND Process_p_nom_extendable AND NOT (Process_committable AND Process_p_nom_mod > 0) AND Process_active + where: Process_maint_ext expression: Process_maintenance_capacity <= Process_p_nom_max * Process_maintenance Process_maintcap_lower_nommax: description: "`Process-maintcap_lower_nommax` — in maintenance, the whole chosen build is taken off" dims: [scenario, snapshot, process] - where: Process_maintainable AND Process_p_nom_extendable AND NOT (Process_committable AND Process_p_nom_mod > 0) AND Process_active + where: Process_maint_ext expression: Process_maintenance_capacity >= Process_p_nom_ext - Process_p_nom_max * (1 - Process_maintenance) Process_maintcap_lower_nommin: description: "`Process-maintcap_lower_nommin` — in maintenance, at least the floor of the build is taken off" dims: [scenario, snapshot, process] - where: Process_maintainable AND Process_p_nom_extendable AND NOT (Process_committable AND Process_p_nom_mod > 0) AND Process_active AND Process_p_nom_min > 0 + where: Process_maint_ext AND Process_p_nom_min > 0 expression: Process_maintenance_capacity >= Process_p_nom_min * Process_maintenance Process_maint_status_le_status: description: "`Process-maint-status-le-status` — the status in maintenance is at most the status" dims: [scenario, snapshot, process] - where: Process_maintainable AND Process_committable AND NOT Process_p_nom_extendable AND Process_active + where: Process_maintainable AND Process_committed AND NOT Process_p_nom_extendable expression: Process_maintenance_status <= Process_status Process_maint_status_le_maint: description: "`Process-maint-status-le-maint` — out of maintenance, the status in maintenance is zero" dims: [scenario, snapshot, process] - where: Process_maintainable AND Process_committable AND NOT Process_p_nom_extendable AND Process_active + where: Process_maintainable AND Process_committed AND NOT Process_p_nom_extendable expression: Process_maintenance_status <= Process_maintenance Process_maint_status_lb: description: "`Process-maint-status-lb` — on and in maintenance, the status in maintenance is one" dims: [scenario, snapshot, process] - where: Process_maintainable AND Process_committable AND NOT Process_p_nom_extendable AND Process_active + where: Process_maintainable AND Process_committed AND NOT Process_p_nom_extendable expression: Process_maintenance_status >= Process_status + Process_maintenance - 1 Process_maint_modstatus_le_status: description: "`Process-maint-modstatus-le-status` — the modules on in maintenance are at most the modules on" dims: [scenario, snapshot, process] - where: Process_maintainable AND Process_committable AND Process_p_nom_mod > 0 AND Process_active + where: Process_maintainable AND Process_committed AND Process_p_nom_mod > 0 expression: Process_maintenance_status <= Process_status Process_maint_modstatus_le_maint: description: >- `Process-maint-modstatus-le-maint` — out of maintenance, no module is on in maintenance; in it, at most the modules the build cap holds dims: [scenario, snapshot, process] - where: Process_maintainable AND Process_committable AND Process_p_nom_mod > 0 AND Process_active + where: Process_maintainable AND Process_committed AND Process_p_nom_mod > 0 expression: Process_maintenance_status <= Process_p_nom_max / Process_p_nom_mod * Process_maintenance Process_maint_modstatus_lb: description: "`Process-maint-modstatus-lb` — in maintenance, every module on is on in maintenance" dims: [scenario, snapshot, process] - where: Process_maintainable AND Process_committable AND Process_p_nom_mod > 0 AND Process_active + where: Process_maintainable AND Process_committed AND Process_p_nom_mod > 0 expression: Process_maintenance_status >= Process_status - Process_p_nom_max / Process_p_nom_mod * (1 - Process_maintenance) Line_fix_s_lower: description: "`Line-fix-s-lower` — a fixed line carries at least the negative of its rating, the loss counted against it" @@ -3361,7 +3440,7 @@ constraints: Line_loss_upper: description: "`Line-loss_upper` — a line dissipates at most the loss at its rating" dims: [scenario, snapshot, line] - where: transmission_losses AND Line_active + where: Line_lossy expression: Line_loss <= Line_loss_max Line_loss_tangents_forward: description: >- @@ -3370,14 +3449,14 @@ constraints: `k`, or one row stacked over its `secant` axis, and this block states them all over the segment dimension dims: [scenario, snapshot, line, segment] - where: transmission_losses AND Line_active + where: Line_lossy expression: Line_loss + Line_loss_slope * Line_s >= Line_loss_offset Line_loss_tangents_reverse: description: >- `Line-loss_tangents-{k}--1`, `Line-loss_secants-neg` — the same fan mirrored, the loss depending on the flow's magnitude dims: [scenario, snapshot, line, segment] - where: transmission_losses AND Line_active + where: Line_lossy expression: Line_loss - Line_loss_slope * Line_s >= Line_loss_offset Transformer_fix_s_lower: description: "`Transformer-fix-s-lower` — a fixed transformer carries at least the negative of its rating, the loss counted against it" @@ -3422,7 +3501,7 @@ constraints: Transformer_loss_upper: description: "`Transformer-loss_upper` — a transformer dissipates at most the loss at its rating" dims: [scenario, snapshot, transformer] - where: transmission_losses AND Transformer_active + where: Transformer_lossy expression: Transformer_loss <= Transformer_loss_max Transformer_loss_tangents_forward: description: >- @@ -3430,14 +3509,14 @@ constraints: loss sits above every cut to its curve for flow one way, as a line's does, over the segment dimension dims: [scenario, snapshot, transformer, segment] - where: transmission_losses AND Transformer_active + where: Transformer_lossy expression: Transformer_loss + Transformer_loss_slope * Transformer_s >= Transformer_loss_offset Transformer_loss_tangents_reverse: description: >- `Transformer-loss_tangents-{k}--1`, `Transformer-loss_secants-neg` — the same fan mirrored, the loss depending on the flow's magnitude dims: [scenario, snapshot, transformer, segment] - where: transmission_losses AND Transformer_active + where: Transformer_lossy expression: Transformer_loss - Transformer_loss_slope * Transformer_s >= Transformer_loss_offset Line_fix_s_lower_security: description: >- @@ -3547,7 +3626,7 @@ constraints: where: >- (Generator_ramp_limit_up OR Generator_ramp_limit_start_up) AND NOT (Generator_committable AND Generator_p_nom_extendable AND NOT (Generator_p_nom_mod > 0)) - AND (position(snapshot, by=snapshot_period, within=period) > 0 OR (position(snapshot) == 0 AND (Generator_status_initial == 0 OR Generator_p_init))) + AND Generator_ramps_from_previous AND Generator_active expression: Generator_p - Generator_previous_p <= Generator_ramp_up_allowance Generator_p_ramp_limit_down: @@ -3562,7 +3641,7 @@ constraints: where: >- (Generator_ramp_limit_down OR Generator_ramp_limit_shut_down) AND NOT (Generator_committable AND Generator_p_nom_extendable AND NOT (Generator_p_nom_mod > 0)) - AND (position(snapshot, by=snapshot_period, within=period) > 0 OR (position(snapshot) == 0 AND (Generator_status_initial == 0 OR Generator_p_init))) + AND Generator_ramps_from_previous AND Generator_active expression: Generator_previous_p - Generator_p <= Generator_ramp_down_allowance Link_p_ramp_limit_up: @@ -3577,7 +3656,7 @@ constraints: where: >- (Link_ramp_limit_up OR Link_ramp_limit_start_up) AND NOT (Link_committable AND Link_p_nom_extendable AND NOT (Link_p_nom_mod > 0)) - AND (position(snapshot, by=snapshot_period, within=period) > 0 OR (position(snapshot) == 0 AND (Link_status_initial == 0 OR Link_p_init))) + AND Link_ramps_from_previous AND Link_active expression: Link_p - Link_previous_p <= Link_ramp_up_allowance Link_p_ramp_limit_down: @@ -3592,7 +3671,7 @@ constraints: where: >- (Link_ramp_limit_down OR Link_ramp_limit_shut_down) AND NOT (Link_committable AND Link_p_nom_extendable AND NOT (Link_p_nom_mod > 0)) - AND (position(snapshot, by=snapshot_period, within=period) > 0 OR (position(snapshot) == 0 AND (Link_status_initial == 0 OR Link_p_init))) + AND Link_ramps_from_previous AND Link_active expression: Link_previous_p - Link_p <= Link_ramp_down_allowance Process_p_ramp_limit_up: @@ -3607,7 +3686,7 @@ constraints: where: >- (Process_ramp_limit_up OR Process_ramp_limit_start_up) AND NOT (Process_committable AND Process_p_nom_extendable AND NOT (Process_p_nom_mod > 0)) - AND (position(snapshot, by=snapshot_period, within=period) > 0 OR (position(snapshot) == 0 AND (Process_status_initial == 0 OR Process_p_init))) + AND Process_ramps_from_previous AND Process_active expression: Process_p - Process_previous_p <= Process_ramp_up_allowance Process_p_ramp_limit_down: @@ -3622,40 +3701,40 @@ constraints: where: >- (Process_ramp_limit_down OR Process_ramp_limit_shut_down) AND NOT (Process_committable AND Process_p_nom_extendable AND NOT (Process_p_nom_mod > 0)) - AND (position(snapshot, by=snapshot_period, within=period) > 0 OR (position(snapshot) == 0 AND (Process_status_initial == 0 OR Process_p_init))) + AND Process_ramps_from_previous AND Process_active expression: Process_previous_p - Process_p <= Process_ramp_down_allowance StorageUnit_ext_p_dispatch_lower: description: "`StorageUnit-ext-p_dispatch-lower` — dispatch is non-negative" dims: [scenario, snapshot, storage_unit] - where: StorageUnit_p_nom_extendable AND StorageUnit_active + where: StorageUnit_ext expression: StorageUnit_p_dispatch >= 0 StorageUnit_ext_p_dispatch_upper: description: "`StorageUnit-ext-p_dispatch-upper` — an extendable unit dispatches at most the chosen build" dims: [scenario, snapshot, storage_unit] - where: StorageUnit_p_nom_extendable AND StorageUnit_active + where: StorageUnit_ext expression: StorageUnit_p_dispatch <= StorageUnit_p_max_pu * StorageUnit_p_nom_ext StorageUnit_ext_p_store_lower: description: "`StorageUnit-ext-p_store-lower` — storing is non-negative" dims: [scenario, snapshot, storage_unit] - where: StorageUnit_p_nom_extendable AND StorageUnit_active + where: StorageUnit_ext expression: StorageUnit_p_store >= 0 StorageUnit_ext_p_store_upper: description: >- `StorageUnit-ext-p_store-upper` — an extendable unit stores at most the chosen build, the minimum-per-unit column carrying that cap negated dims: [scenario, snapshot, storage_unit] - where: StorageUnit_p_nom_extendable AND StorageUnit_active + where: StorageUnit_ext expression: StorageUnit_p_store <= -StorageUnit_p_min_pu * StorageUnit_p_nom_ext StorageUnit_ext_state_of_charge_lower: description: "`StorageUnit-ext-state_of_charge-lower` — charge is non-negative" dims: [scenario, snapshot, storage_unit] - where: StorageUnit_p_nom_extendable AND StorageUnit_active + where: StorageUnit_ext expression: StorageUnit_state_of_charge >= 0 StorageUnit_ext_state_of_charge_upper: description: "`StorageUnit-ext-state_of_charge-upper` — an extendable unit holds at most its hours at the chosen build" dims: [scenario, snapshot, storage_unit] - where: StorageUnit_p_nom_extendable AND StorageUnit_active + where: StorageUnit_ext expression: StorageUnit_state_of_charge <= StorageUnit_max_hours * StorageUnit_p_nom_ext StorageUnit_ext_p_nom_lower: description: "`StorageUnit-ext-p_nom-lower` — the chosen build is at least its floor in every scenario" diff --git a/examples/pypsa/generator.yaml b/examples/pypsa/generator.yaml index 36379bcbd..e3c95774f 100644 --- a/examples/pypsa/generator.yaml +++ b/examples/pypsa/generator.yaml @@ -210,6 +210,13 @@ expressions: expression: sum(Generator_sign * Generator_p, by=Generator_bus, over=generator, into=bus) adds_to: Bus_injection +masks: + Generator_committed: + description: >- + a committable generator that stands in the snapshot's period — every + unit-commitment row's set + where: Generator_committable AND Generator_active + constraints: Generator_fix_p_lower: description: "`Generator-fix-p-lower` — a fixed generator outputs at least its minimum" diff --git a/examples/pypsa/generator_commitment.yaml b/examples/pypsa/generator_commitment.yaml index 8551031e9..3320aa3eb 100644 --- a/examples/pypsa/generator_commitment.yaml +++ b/examples/pypsa/generator_commitment.yaml @@ -71,21 +71,21 @@ variables: the rows below cap at one, or at the module count where the build is modular dims: [scenario, snapshot, generator] - where: Generator_committable AND Generator_active + where: Generator_committed domain: integer bounds: lower: 0 Generator_start_up: description: "`Generator-start_up` — how much of a committable unit turns on this snapshot, capped as the status is" dims: [scenario, snapshot, generator] - where: Generator_committable AND Generator_active + where: Generator_committed domain: integer bounds: lower: 0 Generator_shut_down: description: "`Generator-shut_down` — how much of a committable unit turns off this snapshot, capped as the status is" dims: [scenario, snapshot, generator] - where: Generator_committable AND Generator_active + where: Generator_committed domain: integer bounds: lower: 0 @@ -111,6 +111,8 @@ given: Generator_p_nom_ext: { dims: [generator] } expressions: scenario_opex: { dims: [scenario] } + masks: + Generator_committed: { dims: [snapshot, generator] } expressions: Generator_previous_status: @@ -128,26 +130,38 @@ expressions: + sum(sum(Generator_shut_down * Generator_shut_down_cost, over=generator), over=snapshot) adds_to: scenario_opex +masks: + Generator_com_ext: + description: >- + a committable generator with an extendable, non-modular build that + stands in the snapshot's period — PyPSA's `com-ext` rows, whose status + is relaxed against the chosen build + where: >- + Generator_committable + AND Generator_p_nom_extendable + AND NOT (Generator_p_nom_mod > 0) + AND Generator_active + constraints: Generator_com_p_lower: description: "`Generator-com-p-lower` — a committed unit outputs at least its minimum; off, at least nothing" dims: [scenario, snapshot, generator] - where: Generator_committable AND not Generator_p_nom_extendable AND Generator_active + where: Generator_committed AND NOT Generator_p_nom_extendable expression: Generator_p >= Generator_p_min_pu * Generator_p_nom * (Generator_status - Generator_maintenance_pu * Generator_maintenance_status) Generator_com_p_upper: description: "`Generator-com-p-upper` — a committed unit outputs at most what is available; off, at most nothing" dims: [scenario, snapshot, generator] - where: Generator_committable AND not Generator_p_nom_extendable AND Generator_active + where: Generator_committed AND NOT Generator_p_nom_extendable expression: Generator_p <= Generator_p_max_pu * Generator_p_nom * (Generator_status - Generator_maintenance_pu * Generator_maintenance_status) Generator_com_transition_start_up: description: "`Generator-com-transition-start-up` — turning on is a start, counted against the state the unit carried into the snapshot" dims: [scenario, snapshot, generator] - where: Generator_committable AND Generator_active + where: Generator_committed expression: Generator_start_up >= Generator_status - Generator_previous_status Generator_com_transition_shut_down: description: "`Generator-com-transition-shut-down` — turning off is a stop, counted against the state the unit carried into the snapshot" dims: [scenario, snapshot, generator] - where: Generator_committable AND Generator_active + where: Generator_committed expression: Generator_shut_down >= Generator_previous_status - Generator_status Generator_com_up_time: description: >- @@ -155,7 +169,7 @@ constraints: is still on. The first snapshot's share of the window is the brought-in up time's, which the must-stay-up mask carries dims: [scenario, snapshot, generator] - where: Generator_committable AND Generator_min_up_time > 0 AND position(snapshot) > 0 AND Generator_active + where: Generator_committed AND Generator_min_up_time > 0 AND position(snapshot) > 0 expression: sum_back(Generator_start_up, along=snapshot, window=Generator_min_up_time) <= Generator_status Generator_com_down_time: description: >- @@ -163,38 +177,38 @@ constraints: time is still off. The first snapshot's share of the window is the brought-in down time's, which the must-stay-down mask carries dims: [scenario, snapshot, generator] - where: Generator_committable AND Generator_min_down_time > 0 AND position(snapshot) > 0 AND Generator_active + where: Generator_committed AND Generator_min_down_time > 0 AND position(snapshot) > 0 expression: sum_back(Generator_shut_down, along=snapshot, window=Generator_min_down_time) <= 1 - Generator_status Generator_com_status_must_stay_up: description: "`Generator-com-status-min_up_time_must_stay_up` — a unit still serving the up time it brought in stays on" dims: [scenario, snapshot, generator] - where: Generator_committable AND Generator_must_stay_up AND Generator_active + where: Generator_committed AND Generator_must_stay_up expression: Generator_status == 1 Generator_com_status_must_stay_down: description: >- `Generator-com-status-min_down_time_must_stay_up` — a unit still serving the down time it brought in stays off; PyPSA names the row `_must_stay_up` dims: [scenario, snapshot, generator] - where: Generator_committable AND Generator_must_stay_down AND Generator_active + where: Generator_committed AND Generator_must_stay_down expression: Generator_status == 0 Generator_com_ext_p_upper_cap: description: >- `Generator-com-ext-p-upper-cap` — a committed extendable unit outputs at most what is available of the chosen build, whatever its status dims: [scenario, snapshot, generator] - where: Generator_committable AND Generator_p_nom_extendable AND NOT (Generator_p_nom_mod > 0) AND Generator_active + where: Generator_com_ext expression: Generator_p <= Generator_p_max_pu * (Generator_p_nom_ext - Generator_maintenance_pu * Generator_maintenance_capacity) Generator_com_ext_p_upper_big_m: description: "`Generator-com-ext-p-upper-bigM` — off, a unit outputs nothing; on, the big M is no bound" dims: [scenario, snapshot, generator] - where: Generator_committable AND Generator_p_nom_extendable AND NOT (Generator_p_nom_mod > 0) AND Generator_active + where: Generator_com_ext expression: Generator_p <= Generator_big_m * Generator_status Generator_com_ext_p_lower: description: >- `Generator-com-ext-p-lower` — a committed extendable unit outputs at least its minimum of the chosen build; off, the big M releases the row dims: [scenario, snapshot, generator] - where: Generator_committable AND Generator_p_nom_extendable AND NOT (Generator_p_nom_mod > 0) AND Generator_active + where: Generator_com_ext expression: >- Generator_p >= Generator_p_min_pu * (Generator_p_nom_ext - Generator_maintenance_pu * Generator_maintenance_capacity) @@ -205,23 +219,21 @@ constraints: negative, output is also plainly non-negative, a row the big-M lower cannot assert while the unit is off dims: [scenario, snapshot, generator] - where: >- - Generator_committable AND Generator_p_nom_extendable - AND Generator_p_min_pu_nonneg AND NOT (Generator_p_nom_mod > 0) AND Generator_active + where: Generator_com_ext AND Generator_p_min_pu_nonneg expression: Generator_p >= 0 Generator_com_mod_p_lower: description: >- `Generator-com-mod-p-lower` — a committed modular unit outputs at least its minimum of one module, whether the build is fixed or a decision dims: [scenario, snapshot, generator] - where: Generator_committable AND Generator_p_nom_mod > 0 AND Generator_active + where: Generator_committed AND Generator_p_nom_mod > 0 expression: Generator_p >= Generator_p_min_pu * Generator_p_nom_mod * (Generator_status - Generator_maintenance_pu * Generator_maintenance_status) Generator_com_mod_p_upper: description: >- `Generator-com-mod-p-upper` — a committed modular unit outputs at most one module's share, whether the build is fixed or a decision dims: [scenario, snapshot, generator] - where: Generator_committable AND Generator_p_nom_mod > 0 AND Generator_active + where: Generator_committed AND Generator_p_nom_mod > 0 expression: Generator_p <= Generator_p_max_pu * Generator_p_nom_mod * (Generator_status - Generator_maintenance_pu * Generator_maintenance_status) Generator_status_p_fixed_upper: description: >- @@ -229,7 +241,7 @@ constraints: place, an explicit row as PyPSA writes it: one where the build is not modular, and the fixed build's whole count of modules where it is dims: [scenario, snapshot, generator] - where: Generator_committable AND NOT (Generator_p_nom_extendable AND Generator_p_nom_mod > 0) AND Generator_active + where: Generator_committed AND NOT (Generator_p_nom_extendable AND Generator_p_nom_mod > 0) expression: Generator_status <= Generator_modules_installed Generator_start_up_p_fixed_upper: description: >- @@ -237,7 +249,7 @@ constraints: place, an explicit row as PyPSA writes it: one where the build is not modular, and the fixed build's whole count of modules where it is dims: [scenario, snapshot, generator] - where: Generator_committable AND NOT (Generator_p_nom_extendable AND Generator_p_nom_mod > 0) AND Generator_active + where: Generator_committed AND NOT (Generator_p_nom_extendable AND Generator_p_nom_mod > 0) expression: Generator_start_up <= Generator_modules_installed Generator_shut_down_p_fixed_upper: description: >- @@ -245,20 +257,20 @@ constraints: place, an explicit row as PyPSA writes it: one where the build is not modular, and the fixed build's whole count of modules where it is dims: [scenario, snapshot, generator] - where: Generator_committable AND NOT (Generator_p_nom_extendable AND Generator_p_nom_mod > 0) AND Generator_active + where: Generator_committed AND NOT (Generator_p_nom_extendable AND Generator_p_nom_mod > 0) expression: Generator_shut_down <= Generator_modules_installed Generator_status_p_nom_variable_upper: description: "`Generator-status-p_nom-variable-upper` — a modular unit is on only where a module is built" dims: [scenario, snapshot, generator] - where: Generator_committable AND Generator_p_nom_extendable AND Generator_p_nom_mod > 0 AND Generator_active + where: Generator_committed AND Generator_p_nom_extendable AND Generator_p_nom_mod > 0 expression: Generator_status <= Generator_n_mod Generator_start_up_p_nom_variable_upper: description: "`Generator-start_up-p_nom-variable-upper` — a modular unit starts only where a module is built" dims: [scenario, snapshot, generator] - where: Generator_committable AND Generator_p_nom_extendable AND Generator_p_nom_mod > 0 AND Generator_active + where: Generator_committed AND Generator_p_nom_extendable AND Generator_p_nom_mod > 0 expression: Generator_start_up <= Generator_n_mod Generator_shut_down_p_nom_variable_upper: description: "`Generator-shut_down-p_nom-variable-upper` — a modular unit stops only where a module is built" dims: [scenario, snapshot, generator] - where: Generator_committable AND Generator_p_nom_extendable AND Generator_p_nom_mod > 0 AND Generator_active + where: Generator_committed AND Generator_p_nom_extendable AND Generator_p_nom_mod > 0 expression: Generator_shut_down <= Generator_n_mod diff --git a/examples/pypsa/generator_maintenance.yaml b/examples/pypsa/generator_maintenance.yaml index 1f8ca404e..339574561 100644 --- a/examples/pypsa/generator_maintenance.yaml +++ b/examples/pypsa/generator_maintenance.yaml @@ -74,9 +74,7 @@ variables: `Generator-maintenance_capacity` — the chosen build while in maintenance, zero otherwise: the product the `maintcap` rows linearize dims: [scenario, snapshot, generator] - where: >- - Generator_maintainable AND Generator_p_nom_extendable - AND NOT (Generator_committable AND Generator_p_nom_mod > 0) AND Generator_active + where: Generator_maint_ext absence: zero bounds: lower: 0 @@ -87,8 +85,9 @@ variables: maintenance may also be off dims: [scenario, snapshot, generator] where: >- - Generator_maintainable AND Generator_committable - AND NOT (Generator_p_nom_extendable AND NOT (Generator_p_nom_mod > 0)) AND Generator_active + Generator_maintainable + AND Generator_committed + AND NOT (Generator_p_nom_extendable AND NOT (Generator_p_nom_mod > 0)) absence: zero bounds: lower: 0 @@ -105,6 +104,20 @@ given: variables: Generator_status: { dims: [scenario, snapshot, generator], domain: integer } Generator_p_nom_ext: { dims: [generator] } + masks: + Generator_committed: { dims: [snapshot, generator] } + +masks: + Generator_maint_ext: + description: >- + a maintainable generator with an extendable build, unless it is + committable and modular, that stands in the snapshot's period — the + maintenance rows against the chosen build + where: >- + Generator_maintainable + AND Generator_p_nom_extendable + AND NOT (Generator_committable AND Generator_p_nom_mod > 0) + AND Generator_active constraints: Generator_maint_event_count: @@ -130,54 +143,54 @@ constraints: `Generator-maintcap_upper` — the build taken off is at most the chosen build in maintenance, and at most the build less its floor out of it dims: [scenario, snapshot, generator] - where: Generator_maintainable AND Generator_p_nom_extendable AND NOT (Generator_committable AND Generator_p_nom_mod > 0) AND Generator_active + where: Generator_maint_ext expression: Generator_maintenance_capacity <= Generator_p_nom_ext - Generator_p_nom_min * (1 - Generator_maintenance) Generator_maintcap_upper_nommax: description: "`Generator-maintcap_upper_nommax` — out of maintenance, no build is taken off" dims: [scenario, snapshot, generator] - where: Generator_maintainable AND Generator_p_nom_extendable AND NOT (Generator_committable AND Generator_p_nom_mod > 0) AND Generator_active + where: Generator_maint_ext expression: Generator_maintenance_capacity <= Generator_p_nom_max * Generator_maintenance Generator_maintcap_lower_nommax: description: "`Generator-maintcap_lower_nommax` — in maintenance, the whole chosen build is taken off" dims: [scenario, snapshot, generator] - where: Generator_maintainable AND Generator_p_nom_extendable AND NOT (Generator_committable AND Generator_p_nom_mod > 0) AND Generator_active + where: Generator_maint_ext expression: Generator_maintenance_capacity >= Generator_p_nom_ext - Generator_p_nom_max * (1 - Generator_maintenance) Generator_maintcap_lower_nommin: description: "`Generator-maintcap_lower_nommin` — in maintenance, at least the floor of the build is taken off" dims: [scenario, snapshot, generator] - where: Generator_maintainable AND Generator_p_nom_extendable AND NOT (Generator_committable AND Generator_p_nom_mod > 0) AND Generator_active AND Generator_p_nom_min > 0 + where: Generator_maint_ext AND Generator_p_nom_min > 0 expression: Generator_maintenance_capacity >= Generator_p_nom_min * Generator_maintenance Generator_maint_status_le_status: description: "`Generator-maint-status-le-status` — the status in maintenance is at most the status" dims: [scenario, snapshot, generator] - where: Generator_maintainable AND Generator_committable AND NOT Generator_p_nom_extendable AND Generator_active + where: Generator_maintainable AND Generator_committed AND NOT Generator_p_nom_extendable expression: Generator_maintenance_status <= Generator_status Generator_maint_status_le_maint: description: "`Generator-maint-status-le-maint` — out of maintenance, the status in maintenance is zero" dims: [scenario, snapshot, generator] - where: Generator_maintainable AND Generator_committable AND NOT Generator_p_nom_extendable AND Generator_active + where: Generator_maintainable AND Generator_committed AND NOT Generator_p_nom_extendable expression: Generator_maintenance_status <= Generator_maintenance Generator_maint_status_lb: description: "`Generator-maint-status-lb` — on and in maintenance, the status in maintenance is one" dims: [scenario, snapshot, generator] - where: Generator_maintainable AND Generator_committable AND NOT Generator_p_nom_extendable AND Generator_active + where: Generator_maintainable AND Generator_committed AND NOT Generator_p_nom_extendable expression: Generator_maintenance_status >= Generator_status + Generator_maintenance - 1 Generator_maint_modstatus_le_status: description: "`Generator-maint-modstatus-le-status` — the modules on in maintenance are at most the modules on" dims: [scenario, snapshot, generator] - where: Generator_maintainable AND Generator_committable AND Generator_p_nom_mod > 0 AND Generator_active + where: Generator_maintainable AND Generator_committed AND Generator_p_nom_mod > 0 expression: Generator_maintenance_status <= Generator_status Generator_maint_modstatus_le_maint: description: >- `Generator-maint-modstatus-le-maint` — out of maintenance, no module is on in maintenance; in it, at most the modules the build cap holds dims: [scenario, snapshot, generator] - where: Generator_maintainable AND Generator_committable AND Generator_p_nom_mod > 0 AND Generator_active + where: Generator_maintainable AND Generator_committed AND Generator_p_nom_mod > 0 expression: Generator_maintenance_status <= Generator_p_nom_max / Generator_p_nom_mod * Generator_maintenance Generator_maint_modstatus_lb: description: "`Generator-maint-modstatus-lb` — in maintenance, every module on is on in maintenance" dims: [scenario, snapshot, generator] - where: Generator_maintainable AND Generator_committable AND Generator_p_nom_mod > 0 AND Generator_active + where: Generator_maintainable AND Generator_committed AND Generator_p_nom_mod > 0 expression: Generator_maintenance_status >= Generator_status - Generator_p_nom_max / Generator_p_nom_mod * (1 - Generator_maintenance) assumptions: diff --git a/examples/pypsa/generator_ramping.yaml b/examples/pypsa/generator_ramping.yaml index c128b6b68..3f701176d 100644 --- a/examples/pypsa/generator_ramping.yaml +++ b/examples/pypsa/generator_ramping.yaml @@ -58,6 +58,8 @@ given: Generator_previous_status: { dims: [scenario, snapshot, generator] } Generator_p_nom_effective: { dims: [scenario, generator] } Generator_p_nom_committed: { dims: [scenario, generator] } + masks: + Generator_com_ext: { dims: [snapshot, generator] } expressions: Generator_previous_p: @@ -130,6 +132,16 @@ expressions: * (Generator_previous_status - Generator_status) otherwise: Generator_ramp_down_rate * Generator_p_nom_effective +masks: + Generator_ramps_from_previous: + description: >- + a snapshot whose ramp reads a previous output — any snapshot but its + period's first, and the horizon's first where the generator comes in off + or carries an initial output + where: >- + position(snapshot, by=snapshot_period, within=period) > 0 OR (position(snapshot) == 0 AND + (Generator_status_initial == 0 OR Generator_p_init)) + constraints: Generator_p_ramp_limit_up_run_big_m: description: >- @@ -138,10 +150,9 @@ constraints: releases the row in the snapshot it turns on dims: [scenario, snapshot, generator] where: >- - Generator_committable AND Generator_p_nom_extendable AND NOT (Generator_p_nom_mod > 0) + Generator_com_ext AND (Generator_ramp_limit_up OR Generator_ramp_limit_start_up) - AND (position(snapshot, by=snapshot_period, within=period) > 0 OR (position(snapshot) == 0 AND (Generator_status_initial == 0 OR Generator_p_init))) - AND Generator_active + AND Generator_ramps_from_previous expression: >- Generator_p - Generator_previous_p <= Generator_ramp_up_rate * Generator_p_nom_ext @@ -153,10 +164,9 @@ constraints: the chosen build; the big M releases the row everywhere else dims: [scenario, snapshot, generator] where: >- - Generator_committable AND Generator_p_nom_extendable AND NOT (Generator_p_nom_mod > 0) + Generator_com_ext AND (Generator_ramp_limit_up OR Generator_ramp_limit_start_up) - AND (position(snapshot, by=snapshot_period, within=period) > 0 OR (position(snapshot) == 0 AND (Generator_status_initial == 0 OR Generator_p_init))) - AND Generator_active + AND Generator_ramps_from_previous expression: >- Generator_p - Generator_previous_p <= Generator_start_up_rate * Generator_p_nom_ext @@ -168,10 +178,9 @@ constraints: releases the row in the snapshot it turns off dims: [scenario, snapshot, generator] where: >- - Generator_committable AND Generator_p_nom_extendable AND NOT (Generator_p_nom_mod > 0) + Generator_com_ext AND (Generator_ramp_limit_down OR Generator_ramp_limit_shut_down) - AND (position(snapshot, by=snapshot_period, within=period) > 0 OR (position(snapshot) == 0 AND (Generator_status_initial == 0 OR Generator_p_init))) - AND Generator_active + AND Generator_ramps_from_previous expression: >- Generator_previous_p - Generator_p <= Generator_ramp_down_rate * Generator_p_nom_ext @@ -183,10 +192,9 @@ constraints: the chosen build; the big M releases the row everywhere else dims: [scenario, snapshot, generator] where: >- - Generator_committable AND Generator_p_nom_extendable AND NOT (Generator_p_nom_mod > 0) + Generator_com_ext AND (Generator_ramp_limit_down OR Generator_ramp_limit_shut_down) - AND (position(snapshot, by=snapshot_period, within=period) > 0 OR (position(snapshot) == 0 AND (Generator_status_initial == 0 OR Generator_p_init))) - AND Generator_active + AND Generator_ramps_from_previous expression: >- Generator_previous_p - Generator_p <= Generator_shut_down_rate * Generator_p_nom_ext @@ -203,7 +211,7 @@ constraints: where: >- (Generator_ramp_limit_up OR Generator_ramp_limit_start_up) AND NOT (Generator_committable AND Generator_p_nom_extendable AND NOT (Generator_p_nom_mod > 0)) - AND (position(snapshot, by=snapshot_period, within=period) > 0 OR (position(snapshot) == 0 AND (Generator_status_initial == 0 OR Generator_p_init))) + AND Generator_ramps_from_previous AND Generator_active expression: Generator_p - Generator_previous_p <= Generator_ramp_up_allowance Generator_p_ramp_limit_down: @@ -218,7 +226,7 @@ constraints: where: >- (Generator_ramp_limit_down OR Generator_ramp_limit_shut_down) AND NOT (Generator_committable AND Generator_p_nom_extendable AND NOT (Generator_p_nom_mod > 0)) - AND (position(snapshot, by=snapshot_period, within=period) > 0 OR (position(snapshot) == 0 AND (Generator_status_initial == 0 OR Generator_p_init))) + AND Generator_ramps_from_previous AND Generator_active expression: Generator_previous_p - Generator_p <= Generator_ramp_down_allowance diff --git a/examples/pypsa/line.yaml b/examples/pypsa/line.yaml index dd325ecdd..2c2cb3314 100644 --- a/examples/pypsa/line.yaml +++ b/examples/pypsa/line.yaml @@ -138,7 +138,7 @@ variables: cost and held up by the cuts; absent, and zero in the balance, where the network is lossless dims: [scenario, snapshot, line] - where: transmission_losses AND Line_active + where: Line_lossy absence: zero bounds: lower: 0 @@ -199,6 +199,13 @@ expressions: expression: sum(Line_s * Line_cycle_weight, over=line) adds_to: Cycle_angle_sum +masks: + Line_lossy: + description: >- + a line that stands in the snapshot's period, where the run models + transmission losses + where: transmission_losses AND Line_active + constraints: Line_fix_s_lower: description: "`Line-fix-s-lower` — a fixed line carries at least the negative of its rating, the loss counted against it" @@ -243,7 +250,7 @@ constraints: Line_loss_upper: description: "`Line-loss_upper` — a line dissipates at most the loss at its rating" dims: [scenario, snapshot, line] - where: transmission_losses AND Line_active + where: Line_lossy expression: Line_loss <= Line_loss_max Line_loss_tangents_forward: description: >- @@ -252,12 +259,12 @@ constraints: `k`, or one row stacked over its `secant` axis, and this block states them all over the segment dimension dims: [scenario, snapshot, line, segment] - where: transmission_losses AND Line_active + where: Line_lossy expression: Line_loss + Line_loss_slope * Line_s >= Line_loss_offset Line_loss_tangents_reverse: description: >- `Line-loss_tangents-{k}--1`, `Line-loss_secants-neg` — the same fan mirrored, the loss depending on the flow's magnitude dims: [scenario, snapshot, line, segment] - where: transmission_losses AND Line_active + where: Line_lossy expression: Line_loss - Line_loss_slope * Line_s >= Line_loss_offset diff --git a/examples/pypsa/link.yaml b/examples/pypsa/link.yaml index cc46eafe8..58fd4ab13 100644 --- a/examples/pypsa/link.yaml +++ b/examples/pypsa/link.yaml @@ -263,6 +263,13 @@ expressions: + sum(Link_output_arrival, by=Link_output_bus, over=link_output, into=bus) adds_to: Bus_injection +masks: + Link_committed: + description: >- + a committable link that stands in the snapshot's period — every + unit-commitment row's set + where: Link_committable AND Link_active + constraints: Link_fix_p_lower: description: "`Link-fix-p-lower` — a fixed link carries at least its minimum, negative for the other way" diff --git a/examples/pypsa/link_commitment.yaml b/examples/pypsa/link_commitment.yaml index 9c5cea685..9b99467d5 100644 --- a/examples/pypsa/link_commitment.yaml +++ b/examples/pypsa/link_commitment.yaml @@ -71,21 +71,21 @@ variables: the rows below cap at one, or at the module count where the build is modular dims: [scenario, snapshot, link] - where: Link_committable AND Link_active + where: Link_committed domain: integer bounds: lower: 0 Link_start_up: description: "`Link-start_up` — how much of a committable link turns on this snapshot, capped as the status is" dims: [scenario, snapshot, link] - where: Link_committable AND Link_active + where: Link_committed domain: integer bounds: lower: 0 Link_shut_down: description: "`Link-shut_down` — how much of a committable link turns off this snapshot, capped as the status is" dims: [scenario, snapshot, link] - where: Link_committable AND Link_active + where: Link_committed domain: integer bounds: lower: 0 @@ -111,6 +111,8 @@ given: Link_p_nom_ext: { dims: [link] } expressions: scenario_opex: { dims: [scenario] } + masks: + Link_committed: { dims: [snapshot, link] } expressions: Link_previous_status: @@ -128,26 +130,38 @@ expressions: + sum(sum(Link_shut_down * Link_shut_down_cost, over=link), over=snapshot) adds_to: scenario_opex +masks: + Link_com_ext: + description: >- + a committable link with an extendable, non-modular build that stands in + the snapshot's period — PyPSA's `com-ext` rows, whose status is relaxed + against the chosen build + where: >- + Link_committable + AND Link_p_nom_extendable + AND NOT (Link_p_nom_mod > 0) + AND Link_active + constraints: Link_com_p_lower: description: "`Link-com-p-lower` — a committed link flows at least its minimum; off, at least nothing" dims: [scenario, snapshot, link] - where: Link_committable AND not Link_p_nom_extendable AND Link_active + where: Link_committed AND NOT Link_p_nom_extendable expression: Link_p >= Link_p_min_pu * Link_p_nom * (Link_status - Link_maintenance_pu * Link_maintenance_status) Link_com_p_upper: description: "`Link-com-p-upper` — a committed link flows at most what is available; off, at most nothing" dims: [scenario, snapshot, link] - where: Link_committable AND not Link_p_nom_extendable AND Link_active + where: Link_committed AND NOT Link_p_nom_extendable expression: Link_p <= Link_p_max_pu * Link_p_nom * (Link_status - Link_maintenance_pu * Link_maintenance_status) Link_com_transition_start_up: description: "`Link-com-transition-start-up` — turning on is a start, counted against the state the link carried into the snapshot" dims: [scenario, snapshot, link] - where: Link_committable AND Link_active + where: Link_committed expression: Link_start_up >= Link_status - Link_previous_status Link_com_transition_shut_down: description: "`Link-com-transition-shut-down` — turning off is a stop, counted against the state the link carried into the snapshot" dims: [scenario, snapshot, link] - where: Link_committable AND Link_active + where: Link_committed expression: Link_shut_down >= Link_previous_status - Link_status Link_com_up_time: description: >- @@ -155,7 +169,7 @@ constraints: is still on. The first snapshot's share of the window is the brought-in up time's, which the must-stay-up mask carries dims: [scenario, snapshot, link] - where: Link_committable AND Link_min_up_time > 0 AND position(snapshot) > 0 AND Link_active + where: Link_committed AND Link_min_up_time > 0 AND position(snapshot) > 0 expression: sum_back(Link_start_up, along=snapshot, window=Link_min_up_time) <= Link_status Link_com_down_time: description: >- @@ -163,38 +177,38 @@ constraints: time is still off. The first snapshot's share of the window is the brought-in down time's, which the must-stay-down mask carries dims: [scenario, snapshot, link] - where: Link_committable AND Link_min_down_time > 0 AND position(snapshot) > 0 AND Link_active + where: Link_committed AND Link_min_down_time > 0 AND position(snapshot) > 0 expression: sum_back(Link_shut_down, along=snapshot, window=Link_min_down_time) <= 1 - Link_status Link_com_status_must_stay_up: description: "`Link-com-status-min_up_time_must_stay_up` — a link still serving the up time it brought in stays on" dims: [scenario, snapshot, link] - where: Link_committable AND Link_must_stay_up AND Link_active + where: Link_committed AND Link_must_stay_up expression: Link_status == 1 Link_com_status_must_stay_down: description: >- `Link-com-status-min_down_time_must_stay_up` — a link still serving the down time it brought in stays off; PyPSA names the row `_must_stay_up` dims: [scenario, snapshot, link] - where: Link_committable AND Link_must_stay_down AND Link_active + where: Link_committed AND Link_must_stay_down expression: Link_status == 0 Link_com_ext_p_upper_cap: description: >- `Link-com-ext-p-upper-cap` — a committed extendable link flows at most what is available of the chosen build, whatever its status dims: [scenario, snapshot, link] - where: Link_committable AND Link_p_nom_extendable AND NOT (Link_p_nom_mod > 0) AND Link_active + where: Link_com_ext expression: Link_p <= Link_p_max_pu * (Link_p_nom_ext - Link_maintenance_pu * Link_maintenance_capacity) Link_com_ext_p_upper_big_m: description: "`Link-com-ext-p-upper-bigM` — off, a link flows nothing; on, the big M is no bound" dims: [scenario, snapshot, link] - where: Link_committable AND Link_p_nom_extendable AND NOT (Link_p_nom_mod > 0) AND Link_active + where: Link_com_ext expression: Link_p <= Link_big_m * Link_status Link_com_ext_p_lower: description: >- `Link-com-ext-p-lower` — a committed extendable link flows at least its minimum of the chosen build; off, the big M releases the row dims: [scenario, snapshot, link] - where: Link_committable AND Link_p_nom_extendable AND NOT (Link_p_nom_mod > 0) AND Link_active + where: Link_com_ext expression: >- Link_p >= Link_p_min_pu * (Link_p_nom_ext - Link_maintenance_pu * Link_maintenance_capacity) @@ -205,23 +219,21 @@ constraints: negative, flow is also plainly non-negative, a row the big-M lower cannot assert while the link is off dims: [scenario, snapshot, link] - where: >- - Link_committable AND Link_p_nom_extendable - AND Link_p_min_pu_nonneg AND NOT (Link_p_nom_mod > 0) AND Link_active + where: Link_com_ext AND Link_p_min_pu_nonneg expression: Link_p >= 0 Link_com_mod_p_lower: description: >- `Link-com-mod-p-lower` — a committed modular link flows at least its minimum of one module, whether the build is fixed or a decision dims: [scenario, snapshot, link] - where: Link_committable AND Link_p_nom_mod > 0 AND Link_active + where: Link_committed AND Link_p_nom_mod > 0 expression: Link_p >= Link_p_min_pu * Link_p_nom_mod * (Link_status - Link_maintenance_pu * Link_maintenance_status) Link_com_mod_p_upper: description: >- `Link-com-mod-p-upper` — a committed modular link flows at most one module's share, whether the build is fixed or a decision dims: [scenario, snapshot, link] - where: Link_committable AND Link_p_nom_mod > 0 AND Link_active + where: Link_committed AND Link_p_nom_mod > 0 expression: Link_p <= Link_p_max_pu * Link_p_nom_mod * (Link_status - Link_maintenance_pu * Link_maintenance_status) Link_status_p_fixed_upper: description: >- @@ -229,7 +241,7 @@ constraints: place, an explicit row as PyPSA writes it: one where the build is not modular, and the fixed build's whole count of modules where it is dims: [scenario, snapshot, link] - where: Link_committable AND NOT (Link_p_nom_extendable AND Link_p_nom_mod > 0) AND Link_active + where: Link_committed AND NOT (Link_p_nom_extendable AND Link_p_nom_mod > 0) expression: Link_status <= Link_modules_installed Link_start_up_p_fixed_upper: description: >- @@ -237,7 +249,7 @@ constraints: place, an explicit row as PyPSA writes it: one where the build is not modular, and the fixed build's whole count of modules where it is dims: [scenario, snapshot, link] - where: Link_committable AND NOT (Link_p_nom_extendable AND Link_p_nom_mod > 0) AND Link_active + where: Link_committed AND NOT (Link_p_nom_extendable AND Link_p_nom_mod > 0) expression: Link_start_up <= Link_modules_installed Link_shut_down_p_fixed_upper: description: >- @@ -245,20 +257,20 @@ constraints: place, an explicit row as PyPSA writes it: one where the build is not modular, and the fixed build's whole count of modules where it is dims: [scenario, snapshot, link] - where: Link_committable AND NOT (Link_p_nom_extendable AND Link_p_nom_mod > 0) AND Link_active + where: Link_committed AND NOT (Link_p_nom_extendable AND Link_p_nom_mod > 0) expression: Link_shut_down <= Link_modules_installed Link_status_p_nom_variable_upper: description: "`Link-status-p_nom-variable-upper` — a modular link is on only where a module is built" dims: [scenario, snapshot, link] - where: Link_committable AND Link_p_nom_extendable AND Link_p_nom_mod > 0 AND Link_active + where: Link_committed AND Link_p_nom_extendable AND Link_p_nom_mod > 0 expression: Link_status <= Link_n_mod Link_start_up_p_nom_variable_upper: description: "`Link-start_up-p_nom-variable-upper` — a modular link starts only where a module is built" dims: [scenario, snapshot, link] - where: Link_committable AND Link_p_nom_extendable AND Link_p_nom_mod > 0 AND Link_active + where: Link_committed AND Link_p_nom_extendable AND Link_p_nom_mod > 0 expression: Link_start_up <= Link_n_mod Link_shut_down_p_nom_variable_upper: description: "`Link-shut_down-p_nom-variable-upper` — a modular link stops only where a module is built" dims: [scenario, snapshot, link] - where: Link_committable AND Link_p_nom_extendable AND Link_p_nom_mod > 0 AND Link_active + where: Link_committed AND Link_p_nom_extendable AND Link_p_nom_mod > 0 expression: Link_shut_down <= Link_n_mod diff --git a/examples/pypsa/link_maintenance.yaml b/examples/pypsa/link_maintenance.yaml index e81eefbf0..7c5a13277 100644 --- a/examples/pypsa/link_maintenance.yaml +++ b/examples/pypsa/link_maintenance.yaml @@ -74,9 +74,7 @@ variables: `Link-maintenance_capacity` — the chosen build while in maintenance, zero otherwise: the product the `maintcap` rows linearize dims: [scenario, snapshot, link] - where: >- - Link_maintainable AND Link_p_nom_extendable - AND NOT (Link_committable AND Link_p_nom_mod > 0) AND Link_active + where: Link_maint_ext absence: zero bounds: lower: 0 @@ -86,9 +84,7 @@ variables: otherwise: the product the `maint-status` rows linearize, so a unit in maintenance may also be off dims: [scenario, snapshot, link] - where: >- - Link_maintainable AND Link_committable - AND NOT (Link_p_nom_extendable AND NOT (Link_p_nom_mod > 0)) AND Link_active + where: Link_maintainable AND Link_committed AND NOT (Link_p_nom_extendable AND NOT (Link_p_nom_mod > 0)) absence: zero bounds: lower: 0 @@ -105,6 +101,20 @@ given: variables: Link_status: { dims: [scenario, snapshot, link], domain: integer } Link_p_nom_ext: { dims: [link] } + masks: + Link_committed: { dims: [snapshot, link] } + +masks: + Link_maint_ext: + description: >- + a maintainable link with an extendable build, unless it is committable + and modular, that stands in the snapshot's period — the maintenance rows + against the chosen build + where: >- + Link_maintainable + AND Link_p_nom_extendable + AND NOT (Link_committable AND Link_p_nom_mod > 0) + AND Link_active constraints: Link_maint_event_count: @@ -130,54 +140,54 @@ constraints: `Link-maintcap_upper` — the build taken off is at most the chosen build in maintenance, and at most the build less its floor out of it dims: [scenario, snapshot, link] - where: Link_maintainable AND Link_p_nom_extendable AND NOT (Link_committable AND Link_p_nom_mod > 0) AND Link_active + where: Link_maint_ext expression: Link_maintenance_capacity <= Link_p_nom_ext - Link_p_nom_min * (1 - Link_maintenance) Link_maintcap_upper_nommax: description: "`Link-maintcap_upper_nommax` — out of maintenance, no build is taken off" dims: [scenario, snapshot, link] - where: Link_maintainable AND Link_p_nom_extendable AND NOT (Link_committable AND Link_p_nom_mod > 0) AND Link_active + where: Link_maint_ext expression: Link_maintenance_capacity <= Link_p_nom_max * Link_maintenance Link_maintcap_lower_nommax: description: "`Link-maintcap_lower_nommax` — in maintenance, the whole chosen build is taken off" dims: [scenario, snapshot, link] - where: Link_maintainable AND Link_p_nom_extendable AND NOT (Link_committable AND Link_p_nom_mod > 0) AND Link_active + where: Link_maint_ext expression: Link_maintenance_capacity >= Link_p_nom_ext - Link_p_nom_max * (1 - Link_maintenance) Link_maintcap_lower_nommin: description: "`Link-maintcap_lower_nommin` — in maintenance, at least the floor of the build is taken off" dims: [scenario, snapshot, link] - where: Link_maintainable AND Link_p_nom_extendable AND NOT (Link_committable AND Link_p_nom_mod > 0) AND Link_active AND Link_p_nom_min > 0 + where: Link_maint_ext AND Link_p_nom_min > 0 expression: Link_maintenance_capacity >= Link_p_nom_min * Link_maintenance Link_maint_status_le_status: description: "`Link-maint-status-le-status` — the status in maintenance is at most the status" dims: [scenario, snapshot, link] - where: Link_maintainable AND Link_committable AND NOT Link_p_nom_extendable AND Link_active + where: Link_maintainable AND Link_committed AND NOT Link_p_nom_extendable expression: Link_maintenance_status <= Link_status Link_maint_status_le_maint: description: "`Link-maint-status-le-maint` — out of maintenance, the status in maintenance is zero" dims: [scenario, snapshot, link] - where: Link_maintainable AND Link_committable AND NOT Link_p_nom_extendable AND Link_active + where: Link_maintainable AND Link_committed AND NOT Link_p_nom_extendable expression: Link_maintenance_status <= Link_maintenance Link_maint_status_lb: description: "`Link-maint-status-lb` — on and in maintenance, the status in maintenance is one" dims: [scenario, snapshot, link] - where: Link_maintainable AND Link_committable AND NOT Link_p_nom_extendable AND Link_active + where: Link_maintainable AND Link_committed AND NOT Link_p_nom_extendable expression: Link_maintenance_status >= Link_status + Link_maintenance - 1 Link_maint_modstatus_le_status: description: "`Link-maint-modstatus-le-status` — the modules on in maintenance are at most the modules on" dims: [scenario, snapshot, link] - where: Link_maintainable AND Link_committable AND Link_p_nom_mod > 0 AND Link_active + where: Link_maintainable AND Link_committed AND Link_p_nom_mod > 0 expression: Link_maintenance_status <= Link_status Link_maint_modstatus_le_maint: description: >- `Link-maint-modstatus-le-maint` — out of maintenance, no module is on in maintenance; in it, at most the modules the build cap holds dims: [scenario, snapshot, link] - where: Link_maintainable AND Link_committable AND Link_p_nom_mod > 0 AND Link_active + where: Link_maintainable AND Link_committed AND Link_p_nom_mod > 0 expression: Link_maintenance_status <= Link_p_nom_max / Link_p_nom_mod * Link_maintenance Link_maint_modstatus_lb: description: "`Link-maint-modstatus-lb` — in maintenance, every module on is on in maintenance" dims: [scenario, snapshot, link] - where: Link_maintainable AND Link_committable AND Link_p_nom_mod > 0 AND Link_active + where: Link_maintainable AND Link_committed AND Link_p_nom_mod > 0 expression: Link_maintenance_status >= Link_status - Link_p_nom_max / Link_p_nom_mod * (1 - Link_maintenance) assumptions: diff --git a/examples/pypsa/link_ramping.yaml b/examples/pypsa/link_ramping.yaml index 4b643a02a..945a0fb6a 100644 --- a/examples/pypsa/link_ramping.yaml +++ b/examples/pypsa/link_ramping.yaml @@ -58,6 +58,8 @@ given: Link_p_nom_effective: { dims: [scenario, link] } Link_previous_status: { dims: [scenario, snapshot, link] } Link_p_nom_committed: { dims: [scenario, link] } + masks: + Link_com_ext: { dims: [snapshot, link] } expressions: Link_previous_p: @@ -130,6 +132,16 @@ expressions: * (Link_previous_status - Link_status) otherwise: Link_ramp_down_rate * Link_p_nom_effective +masks: + Link_ramps_from_previous: + description: >- + a snapshot whose ramp reads a previous output — any snapshot but its + period's first, and the horizon's first where the link comes in off or + carries an initial output + where: >- + position(snapshot, by=snapshot_period, within=period) > 0 OR (position(snapshot) == 0 AND + (Link_status_initial == 0 OR Link_p_init)) + constraints: Link_p_ramp_limit_up_run_big_m: description: >- @@ -137,11 +149,7 @@ constraints: raises flow no faster than its limit of the chosen build; the big M releases the row in the snapshot it turns on dims: [scenario, snapshot, link] - where: >- - Link_committable AND Link_p_nom_extendable AND NOT (Link_p_nom_mod > 0) - AND (Link_ramp_limit_up OR Link_ramp_limit_start_up) - AND (position(snapshot, by=snapshot_period, within=period) > 0 OR (position(snapshot) == 0 AND (Link_status_initial == 0 OR Link_p_init))) - AND Link_active + where: Link_com_ext AND (Link_ramp_limit_up OR Link_ramp_limit_start_up) AND Link_ramps_from_previous expression: >- Link_p - Link_previous_p <= Link_ramp_up_rate * Link_p_nom_ext @@ -152,11 +160,7 @@ constraints: committed extendable link ramps no further than its start-up ramp of the chosen build; the big M releases the row everywhere else dims: [scenario, snapshot, link] - where: >- - Link_committable AND Link_p_nom_extendable AND NOT (Link_p_nom_mod > 0) - AND (Link_ramp_limit_up OR Link_ramp_limit_start_up) - AND (position(snapshot, by=snapshot_period, within=period) > 0 OR (position(snapshot) == 0 AND (Link_status_initial == 0 OR Link_p_init))) - AND Link_active + where: Link_com_ext AND (Link_ramp_limit_up OR Link_ramp_limit_start_up) AND Link_ramps_from_previous expression: >- Link_p - Link_previous_p <= Link_start_up_rate * Link_p_nom_ext @@ -167,11 +171,7 @@ constraints: lowers flow no faster than its limit of the chosen build; the big M releases the row in the snapshot it turns off dims: [scenario, snapshot, link] - where: >- - Link_committable AND Link_p_nom_extendable AND NOT (Link_p_nom_mod > 0) - AND (Link_ramp_limit_down OR Link_ramp_limit_shut_down) - AND (position(snapshot, by=snapshot_period, within=period) > 0 OR (position(snapshot) == 0 AND (Link_status_initial == 0 OR Link_p_init))) - AND Link_active + where: Link_com_ext AND (Link_ramp_limit_down OR Link_ramp_limit_shut_down) AND Link_ramps_from_previous expression: >- Link_previous_p - Link_p <= Link_ramp_down_rate * Link_p_nom_ext @@ -182,11 +182,7 @@ constraints: a committed extendable link ramps no further than its shut-down ramp of the chosen build; the big M releases the row everywhere else dims: [scenario, snapshot, link] - where: >- - Link_committable AND Link_p_nom_extendable AND NOT (Link_p_nom_mod > 0) - AND (Link_ramp_limit_down OR Link_ramp_limit_shut_down) - AND (position(snapshot, by=snapshot_period, within=period) > 0 OR (position(snapshot) == 0 AND (Link_status_initial == 0 OR Link_p_init))) - AND Link_active + where: Link_com_ext AND (Link_ramp_limit_down OR Link_ramp_limit_shut_down) AND Link_ramps_from_previous expression: >- Link_previous_p - Link_p <= Link_shut_down_rate * Link_p_nom_ext @@ -203,7 +199,7 @@ constraints: where: >- (Link_ramp_limit_up OR Link_ramp_limit_start_up) AND NOT (Link_committable AND Link_p_nom_extendable AND NOT (Link_p_nom_mod > 0)) - AND (position(snapshot, by=snapshot_period, within=period) > 0 OR (position(snapshot) == 0 AND (Link_status_initial == 0 OR Link_p_init))) + AND Link_ramps_from_previous AND Link_active expression: Link_p - Link_previous_p <= Link_ramp_up_allowance Link_p_ramp_limit_down: @@ -218,7 +214,7 @@ constraints: where: >- (Link_ramp_limit_down OR Link_ramp_limit_shut_down) AND NOT (Link_committable AND Link_p_nom_extendable AND NOT (Link_p_nom_mod > 0)) - AND (position(snapshot, by=snapshot_period, within=period) > 0 OR (position(snapshot) == 0 AND (Link_status_initial == 0 OR Link_p_init))) + AND Link_ramps_from_previous AND Link_active expression: Link_previous_p - Link_p <= Link_ramp_down_allowance diff --git a/examples/pypsa/process.yaml b/examples/pypsa/process.yaml index 8c16c8a98..7c47886d9 100644 --- a/examples/pypsa/process.yaml +++ b/examples/pypsa/process.yaml @@ -233,6 +233,13 @@ expressions: sum(Process_output_arrival, by=Process_output_bus, over=process_output, into=bus) adds_to: Bus_injection +masks: + Process_committed: + description: >- + a committable process that stands in the snapshot's period — every + unit-commitment row's set + where: Process_committable AND Process_active + constraints: Process_fix_p_lower: description: "`Process-fix-p-lower` — a fixed process runs at least its minimum, negative for the other way" diff --git a/examples/pypsa/process_commitment.yaml b/examples/pypsa/process_commitment.yaml index 79c1a12dd..e748c65be 100644 --- a/examples/pypsa/process_commitment.yaml +++ b/examples/pypsa/process_commitment.yaml @@ -71,21 +71,21 @@ variables: the rows below cap at one, or at the module count where the build is modular dims: [scenario, snapshot, process] - where: Process_committable AND Process_active + where: Process_committed domain: integer bounds: lower: 0 Process_start_up: description: "`Process-start_up` — how much of a committable process turns on this snapshot, capped as the status is" dims: [scenario, snapshot, process] - where: Process_committable AND Process_active + where: Process_committed domain: integer bounds: lower: 0 Process_shut_down: description: "`Process-shut_down` — how much of a committable process turns off this snapshot, capped as the status is" dims: [scenario, snapshot, process] - where: Process_committable AND Process_active + where: Process_committed domain: integer bounds: lower: 0 @@ -111,6 +111,8 @@ given: Process_p_nom_ext: { dims: [process] } expressions: scenario_opex: { dims: [scenario] } + masks: + Process_committed: { dims: [snapshot, process] } expressions: Process_previous_status: @@ -128,26 +130,38 @@ expressions: + sum(sum(Process_shut_down * Process_shut_down_cost, over=process), over=snapshot) adds_to: scenario_opex +masks: + Process_com_ext: + description: >- + a committable process with an extendable, non-modular build that stands + in the snapshot's period — PyPSA's `com-ext` rows, whose status is + relaxed against the chosen build + where: >- + Process_committable + AND Process_p_nom_extendable + AND NOT (Process_p_nom_mod > 0) + AND Process_active + constraints: Process_com_p_lower: description: "`Process-com-p-lower` — a committed process runs at least its minimum; off, at least nothing" dims: [scenario, snapshot, process] - where: Process_committable AND not Process_p_nom_extendable AND Process_active + where: Process_committed AND NOT Process_p_nom_extendable expression: Process_p >= Process_p_min_pu * Process_p_nom * (Process_status - Process_maintenance_pu * Process_maintenance_status) Process_com_p_upper: description: "`Process-com-p-upper` — a committed process runs at most what is available; off, at most nothing" dims: [scenario, snapshot, process] - where: Process_committable AND not Process_p_nom_extendable AND Process_active + where: Process_committed AND NOT Process_p_nom_extendable expression: Process_p <= Process_p_max_pu * Process_p_nom * (Process_status - Process_maintenance_pu * Process_maintenance_status) Process_com_transition_start_up: description: "`Process-com-transition-start-up` — turning on is a start, counted against the state the process carried into the snapshot" dims: [scenario, snapshot, process] - where: Process_committable AND Process_active + where: Process_committed expression: Process_start_up >= Process_status - Process_previous_status Process_com_transition_shut_down: description: "`Process-com-transition-shut-down` — turning off is a stop, counted against the state the process carried into the snapshot" dims: [scenario, snapshot, process] - where: Process_committable AND Process_active + where: Process_committed expression: Process_shut_down >= Process_previous_status - Process_status Process_com_up_time: description: >- @@ -155,7 +169,7 @@ constraints: is still on. The first snapshot's share of the window is the brought-in up time's, which the must-stay-up mask carries dims: [scenario, snapshot, process] - where: Process_committable AND Process_min_up_time > 0 AND position(snapshot) > 0 AND Process_active + where: Process_committed AND Process_min_up_time > 0 AND position(snapshot) > 0 expression: sum_back(Process_start_up, along=snapshot, window=Process_min_up_time) <= Process_status Process_com_down_time: description: >- @@ -163,38 +177,38 @@ constraints: time is still off. The first snapshot's share of the window is the brought-in down time's, which the must-stay-down mask carries dims: [scenario, snapshot, process] - where: Process_committable AND Process_min_down_time > 0 AND position(snapshot) > 0 AND Process_active + where: Process_committed AND Process_min_down_time > 0 AND position(snapshot) > 0 expression: sum_back(Process_shut_down, along=snapshot, window=Process_min_down_time) <= 1 - Process_status Process_com_status_must_stay_up: description: "`Process-com-status-min_up_time_must_stay_up` — a process still serving the up time it brought in stays on" dims: [scenario, snapshot, process] - where: Process_committable AND Process_must_stay_up AND Process_active + where: Process_committed AND Process_must_stay_up expression: Process_status == 1 Process_com_status_must_stay_down: description: >- `Process-com-status-min_down_time_must_stay_up` — a process still serving the down time it brought in stays off; PyPSA names the row `_must_stay_up` dims: [scenario, snapshot, process] - where: Process_committable AND Process_must_stay_down AND Process_active + where: Process_committed AND Process_must_stay_down expression: Process_status == 0 Process_com_ext_p_upper_cap: description: >- `Process-com-ext-p-upper-cap` — a committed extendable process runs at most what is available of the chosen build, whatever its status dims: [scenario, snapshot, process] - where: Process_committable AND Process_p_nom_extendable AND NOT (Process_p_nom_mod > 0) AND Process_active + where: Process_com_ext expression: Process_p <= Process_p_max_pu * (Process_p_nom_ext - Process_maintenance_pu * Process_maintenance_capacity) Process_com_ext_p_upper_big_m: description: "`Process-com-ext-p-upper-bigM` — off, a process does not run; on, the big M is no bound" dims: [scenario, snapshot, process] - where: Process_committable AND Process_p_nom_extendable AND NOT (Process_p_nom_mod > 0) AND Process_active + where: Process_com_ext expression: Process_p <= Process_big_m * Process_status Process_com_ext_p_lower: description: >- `Process-com-ext-p-lower` — a committed extendable process runs at least its minimum of the chosen build; off, the big M releases the row dims: [scenario, snapshot, process] - where: Process_committable AND Process_p_nom_extendable AND NOT (Process_p_nom_mod > 0) AND Process_active + where: Process_com_ext expression: >- Process_p >= Process_p_min_pu * (Process_p_nom_ext - Process_maintenance_pu * Process_maintenance_capacity) @@ -205,23 +219,21 @@ constraints: negative, internal power is also plainly non-negative, a row the big-M lower cannot assert while the process is off dims: [scenario, snapshot, process] - where: >- - Process_committable AND Process_p_nom_extendable - AND Process_p_min_pu_nonneg AND NOT (Process_p_nom_mod > 0) AND Process_active + where: Process_com_ext AND Process_p_min_pu_nonneg expression: Process_p >= 0 Process_com_mod_p_lower: description: >- `Process-com-mod-p-lower` — a committed modular process runs at least its minimum of one module, whether the build is fixed or a decision dims: [scenario, snapshot, process] - where: Process_committable AND Process_p_nom_mod > 0 AND Process_active + where: Process_committed AND Process_p_nom_mod > 0 expression: Process_p >= Process_p_min_pu * Process_p_nom_mod * (Process_status - Process_maintenance_pu * Process_maintenance_status) Process_com_mod_p_upper: description: >- `Process-com-mod-p-upper` — a committed modular process runs at most one module's share, whether the build is fixed or a decision dims: [scenario, snapshot, process] - where: Process_committable AND Process_p_nom_mod > 0 AND Process_active + where: Process_committed AND Process_p_nom_mod > 0 expression: Process_p <= Process_p_max_pu * Process_p_nom_mod * (Process_status - Process_maintenance_pu * Process_maintenance_status) Process_status_p_fixed_upper: description: >- @@ -229,7 +241,7 @@ constraints: place, an explicit row as PyPSA writes it: one where the build is not modular, and the fixed build's whole count of modules where it is dims: [scenario, snapshot, process] - where: Process_committable AND NOT (Process_p_nom_extendable AND Process_p_nom_mod > 0) AND Process_active + where: Process_committed AND NOT (Process_p_nom_extendable AND Process_p_nom_mod > 0) expression: Process_status <= Process_modules_installed Process_start_up_p_fixed_upper: description: >- @@ -237,7 +249,7 @@ constraints: place, an explicit row as PyPSA writes it: one where the build is not modular, and the fixed build's whole count of modules where it is dims: [scenario, snapshot, process] - where: Process_committable AND NOT (Process_p_nom_extendable AND Process_p_nom_mod > 0) AND Process_active + where: Process_committed AND NOT (Process_p_nom_extendable AND Process_p_nom_mod > 0) expression: Process_start_up <= Process_modules_installed Process_shut_down_p_fixed_upper: description: >- @@ -245,20 +257,20 @@ constraints: place, an explicit row as PyPSA writes it: one where the build is not modular, and the fixed build's whole count of modules where it is dims: [scenario, snapshot, process] - where: Process_committable AND NOT (Process_p_nom_extendable AND Process_p_nom_mod > 0) AND Process_active + where: Process_committed AND NOT (Process_p_nom_extendable AND Process_p_nom_mod > 0) expression: Process_shut_down <= Process_modules_installed Process_status_p_nom_variable_upper: description: "`Process-status-p_nom-variable-upper` — a modular process is on only where a module is built" dims: [scenario, snapshot, process] - where: Process_committable AND Process_p_nom_extendable AND Process_p_nom_mod > 0 AND Process_active + where: Process_committed AND Process_p_nom_extendable AND Process_p_nom_mod > 0 expression: Process_status <= Process_n_mod Process_start_up_p_nom_variable_upper: description: "`Process-start_up-p_nom-variable-upper` — a modular process starts only where a module is built" dims: [scenario, snapshot, process] - where: Process_committable AND Process_p_nom_extendable AND Process_p_nom_mod > 0 AND Process_active + where: Process_committed AND Process_p_nom_extendable AND Process_p_nom_mod > 0 expression: Process_start_up <= Process_n_mod Process_shut_down_p_nom_variable_upper: description: "`Process-shut_down-p_nom-variable-upper` — a modular process stops only where a module is built" dims: [scenario, snapshot, process] - where: Process_committable AND Process_p_nom_extendable AND Process_p_nom_mod > 0 AND Process_active + where: Process_committed AND Process_p_nom_extendable AND Process_p_nom_mod > 0 expression: Process_shut_down <= Process_n_mod diff --git a/examples/pypsa/process_maintenance.yaml b/examples/pypsa/process_maintenance.yaml index 2f1b9de84..cff7617ff 100644 --- a/examples/pypsa/process_maintenance.yaml +++ b/examples/pypsa/process_maintenance.yaml @@ -74,9 +74,7 @@ variables: `Process-maintenance_capacity` — the chosen build while in maintenance, zero otherwise: the product the `maintcap` rows linearize dims: [scenario, snapshot, process] - where: >- - Process_maintainable AND Process_p_nom_extendable - AND NOT (Process_committable AND Process_p_nom_mod > 0) AND Process_active + where: Process_maint_ext absence: zero bounds: lower: 0 @@ -87,8 +85,9 @@ variables: maintenance may also be off dims: [scenario, snapshot, process] where: >- - Process_maintainable AND Process_committable - AND NOT (Process_p_nom_extendable AND NOT (Process_p_nom_mod > 0)) AND Process_active + Process_maintainable + AND Process_committed + AND NOT (Process_p_nom_extendable AND NOT (Process_p_nom_mod > 0)) absence: zero bounds: lower: 0 @@ -105,6 +104,20 @@ given: variables: Process_status: { dims: [scenario, snapshot, process], domain: integer } Process_p_nom_ext: { dims: [process] } + masks: + Process_committed: { dims: [snapshot, process] } + +masks: + Process_maint_ext: + description: >- + a maintainable process with an extendable build, unless it is + committable and modular, that stands in the snapshot's period — the + maintenance rows against the chosen build + where: >- + Process_maintainable + AND Process_p_nom_extendable + AND NOT (Process_committable AND Process_p_nom_mod > 0) + AND Process_active constraints: Process_maint_event_count: @@ -130,54 +143,54 @@ constraints: `Process-maintcap_upper` — the build taken off is at most the chosen build in maintenance, and at most the build less its floor out of it dims: [scenario, snapshot, process] - where: Process_maintainable AND Process_p_nom_extendable AND NOT (Process_committable AND Process_p_nom_mod > 0) AND Process_active + where: Process_maint_ext expression: Process_maintenance_capacity <= Process_p_nom_ext - Process_p_nom_min * (1 - Process_maintenance) Process_maintcap_upper_nommax: description: "`Process-maintcap_upper_nommax` — out of maintenance, no build is taken off" dims: [scenario, snapshot, process] - where: Process_maintainable AND Process_p_nom_extendable AND NOT (Process_committable AND Process_p_nom_mod > 0) AND Process_active + where: Process_maint_ext expression: Process_maintenance_capacity <= Process_p_nom_max * Process_maintenance Process_maintcap_lower_nommax: description: "`Process-maintcap_lower_nommax` — in maintenance, the whole chosen build is taken off" dims: [scenario, snapshot, process] - where: Process_maintainable AND Process_p_nom_extendable AND NOT (Process_committable AND Process_p_nom_mod > 0) AND Process_active + where: Process_maint_ext expression: Process_maintenance_capacity >= Process_p_nom_ext - Process_p_nom_max * (1 - Process_maintenance) Process_maintcap_lower_nommin: description: "`Process-maintcap_lower_nommin` — in maintenance, at least the floor of the build is taken off" dims: [scenario, snapshot, process] - where: Process_maintainable AND Process_p_nom_extendable AND NOT (Process_committable AND Process_p_nom_mod > 0) AND Process_active AND Process_p_nom_min > 0 + where: Process_maint_ext AND Process_p_nom_min > 0 expression: Process_maintenance_capacity >= Process_p_nom_min * Process_maintenance Process_maint_status_le_status: description: "`Process-maint-status-le-status` — the status in maintenance is at most the status" dims: [scenario, snapshot, process] - where: Process_maintainable AND Process_committable AND NOT Process_p_nom_extendable AND Process_active + where: Process_maintainable AND Process_committed AND NOT Process_p_nom_extendable expression: Process_maintenance_status <= Process_status Process_maint_status_le_maint: description: "`Process-maint-status-le-maint` — out of maintenance, the status in maintenance is zero" dims: [scenario, snapshot, process] - where: Process_maintainable AND Process_committable AND NOT Process_p_nom_extendable AND Process_active + where: Process_maintainable AND Process_committed AND NOT Process_p_nom_extendable expression: Process_maintenance_status <= Process_maintenance Process_maint_status_lb: description: "`Process-maint-status-lb` — on and in maintenance, the status in maintenance is one" dims: [scenario, snapshot, process] - where: Process_maintainable AND Process_committable AND NOT Process_p_nom_extendable AND Process_active + where: Process_maintainable AND Process_committed AND NOT Process_p_nom_extendable expression: Process_maintenance_status >= Process_status + Process_maintenance - 1 Process_maint_modstatus_le_status: description: "`Process-maint-modstatus-le-status` — the modules on in maintenance are at most the modules on" dims: [scenario, snapshot, process] - where: Process_maintainable AND Process_committable AND Process_p_nom_mod > 0 AND Process_active + where: Process_maintainable AND Process_committed AND Process_p_nom_mod > 0 expression: Process_maintenance_status <= Process_status Process_maint_modstatus_le_maint: description: >- `Process-maint-modstatus-le-maint` — out of maintenance, no module is on in maintenance; in it, at most the modules the build cap holds dims: [scenario, snapshot, process] - where: Process_maintainable AND Process_committable AND Process_p_nom_mod > 0 AND Process_active + where: Process_maintainable AND Process_committed AND Process_p_nom_mod > 0 expression: Process_maintenance_status <= Process_p_nom_max / Process_p_nom_mod * Process_maintenance Process_maint_modstatus_lb: description: "`Process-maint-modstatus-lb` — in maintenance, every module on is on in maintenance" dims: [scenario, snapshot, process] - where: Process_maintainable AND Process_committable AND Process_p_nom_mod > 0 AND Process_active + where: Process_maintainable AND Process_committed AND Process_p_nom_mod > 0 expression: Process_maintenance_status >= Process_status - Process_p_nom_max / Process_p_nom_mod * (1 - Process_maintenance) assumptions: diff --git a/examples/pypsa/process_ramping.yaml b/examples/pypsa/process_ramping.yaml index 7bb61fdfb..1d9911a7b 100644 --- a/examples/pypsa/process_ramping.yaml +++ b/examples/pypsa/process_ramping.yaml @@ -58,6 +58,8 @@ given: Process_p_nom_effective: { dims: [scenario, process] } Process_previous_status: { dims: [scenario, snapshot, process] } Process_p_nom_committed: { dims: [scenario, process] } + masks: + Process_com_ext: { dims: [snapshot, process] } expressions: Process_previous_p: @@ -130,6 +132,16 @@ expressions: * (Process_previous_status - Process_status) otherwise: Process_ramp_down_rate * Process_p_nom_effective +masks: + Process_ramps_from_previous: + description: >- + a snapshot whose ramp reads a previous output — any snapshot but its + period's first, and the horizon's first where the process comes in off + or carries an initial output + where: >- + position(snapshot, by=snapshot_period, within=period) > 0 OR (position(snapshot) == 0 AND + (Process_status_initial == 0 OR Process_p_init)) + constraints: Process_p_ramp_limit_up_run_big_m: description: >- @@ -137,11 +149,7 @@ constraints: raises internal power no faster than its limit of the chosen build; the big M releases the row in the snapshot it turns on dims: [scenario, snapshot, process] - where: >- - Process_committable AND Process_p_nom_extendable AND NOT (Process_p_nom_mod > 0) - AND (Process_ramp_limit_up OR Process_ramp_limit_start_up) - AND (position(snapshot, by=snapshot_period, within=period) > 0 OR (position(snapshot) == 0 AND (Process_status_initial == 0 OR Process_p_init))) - AND Process_active + where: Process_com_ext AND (Process_ramp_limit_up OR Process_ramp_limit_start_up) AND Process_ramps_from_previous expression: >- Process_p - Process_previous_p <= Process_ramp_up_rate * Process_p_nom_ext @@ -152,11 +160,7 @@ constraints: committed extendable process ramps no further than its start-up ramp of the chosen build; the big M releases the row everywhere else dims: [scenario, snapshot, process] - where: >- - Process_committable AND Process_p_nom_extendable AND NOT (Process_p_nom_mod > 0) - AND (Process_ramp_limit_up OR Process_ramp_limit_start_up) - AND (position(snapshot, by=snapshot_period, within=period) > 0 OR (position(snapshot) == 0 AND (Process_status_initial == 0 OR Process_p_init))) - AND Process_active + where: Process_com_ext AND (Process_ramp_limit_up OR Process_ramp_limit_start_up) AND Process_ramps_from_previous expression: >- Process_p - Process_previous_p <= Process_start_up_rate * Process_p_nom_ext @@ -168,10 +172,9 @@ constraints: releases the row in the snapshot it turns off dims: [scenario, snapshot, process] where: >- - Process_committable AND Process_p_nom_extendable AND NOT (Process_p_nom_mod > 0) + Process_com_ext AND (Process_ramp_limit_down OR Process_ramp_limit_shut_down) - AND (position(snapshot, by=snapshot_period, within=period) > 0 OR (position(snapshot) == 0 AND (Process_status_initial == 0 OR Process_p_init))) - AND Process_active + AND Process_ramps_from_previous expression: >- Process_previous_p - Process_p <= Process_ramp_down_rate * Process_p_nom_ext @@ -183,10 +186,9 @@ constraints: the chosen build; the big M releases the row everywhere else dims: [scenario, snapshot, process] where: >- - Process_committable AND Process_p_nom_extendable AND NOT (Process_p_nom_mod > 0) + Process_com_ext AND (Process_ramp_limit_down OR Process_ramp_limit_shut_down) - AND (position(snapshot, by=snapshot_period, within=period) > 0 OR (position(snapshot) == 0 AND (Process_status_initial == 0 OR Process_p_init))) - AND Process_active + AND Process_ramps_from_previous expression: >- Process_previous_p - Process_p <= Process_shut_down_rate * Process_p_nom_ext @@ -203,7 +205,7 @@ constraints: where: >- (Process_ramp_limit_up OR Process_ramp_limit_start_up) AND NOT (Process_committable AND Process_p_nom_extendable AND NOT (Process_p_nom_mod > 0)) - AND (position(snapshot, by=snapshot_period, within=period) > 0 OR (position(snapshot) == 0 AND (Process_status_initial == 0 OR Process_p_init))) + AND Process_ramps_from_previous AND Process_active expression: Process_p - Process_previous_p <= Process_ramp_up_allowance Process_p_ramp_limit_down: @@ -218,7 +220,7 @@ constraints: where: >- (Process_ramp_limit_down OR Process_ramp_limit_shut_down) AND NOT (Process_committable AND Process_p_nom_extendable AND NOT (Process_p_nom_mod > 0)) - AND (position(snapshot, by=snapshot_period, within=period) > 0 OR (position(snapshot) == 0 AND (Process_status_initial == 0 OR Process_p_init))) + AND Process_ramps_from_previous AND Process_active expression: Process_previous_p - Process_p <= Process_ramp_down_allowance diff --git a/examples/pypsa/storage_unit.yaml b/examples/pypsa/storage_unit.yaml index 0bcc83d97..b640c1f9c 100644 --- a/examples/pypsa/storage_unit.yaml +++ b/examples/pypsa/storage_unit.yaml @@ -301,70 +301,82 @@ expressions: sum(StorageUnit_sign * (StorageUnit_p_dispatch - StorageUnit_p_store), by=StorageUnit_bus, over=storage_unit, into=bus) adds_to: Bus_injection +masks: + StorageUnit_fix: + description: >- + a storage unit with a fixed build that stands in the snapshot's period — + PyPSA's `fix` rows + where: NOT StorageUnit_p_nom_extendable AND StorageUnit_active + StorageUnit_ext: + description: >- + a storage unit with an extendable build that stands in the snapshot's + period — PyPSA's `ext` rows + where: StorageUnit_p_nom_extendable AND StorageUnit_active + constraints: StorageUnit_fix_p_dispatch_lower: description: "`StorageUnit-fix-p_dispatch-lower` — dispatch is non-negative" dims: [scenario, snapshot, storage_unit] - where: not StorageUnit_p_nom_extendable AND StorageUnit_active + where: StorageUnit_fix expression: StorageUnit_p_dispatch >= 0 StorageUnit_fix_p_dispatch_upper: description: "`StorageUnit-fix-p_dispatch-upper` — a fixed unit dispatches at most its nominal power" dims: [scenario, snapshot, storage_unit] - where: not StorageUnit_p_nom_extendable AND StorageUnit_active + where: StorageUnit_fix expression: StorageUnit_p_dispatch <= StorageUnit_p_max_pu * StorageUnit_p_nom StorageUnit_fix_p_store_lower: description: "`StorageUnit-fix-p_store-lower` — storing is non-negative" dims: [scenario, snapshot, storage_unit] - where: not StorageUnit_p_nom_extendable AND StorageUnit_active + where: StorageUnit_fix expression: StorageUnit_p_store >= 0 StorageUnit_fix_p_store_upper: description: >- `StorageUnit-fix-p_store-upper` — a fixed unit stores at most its nominal power, the minimum-per-unit column carrying that cap negated dims: [scenario, snapshot, storage_unit] - where: not StorageUnit_p_nom_extendable AND StorageUnit_active + where: StorageUnit_fix expression: StorageUnit_p_store <= -StorageUnit_p_min_pu * StorageUnit_p_nom StorageUnit_fix_state_of_charge_lower: description: "`StorageUnit-fix-state_of_charge-lower` — charge is non-negative" dims: [scenario, snapshot, storage_unit] - where: not StorageUnit_p_nom_extendable AND StorageUnit_active + where: StorageUnit_fix expression: StorageUnit_state_of_charge >= 0 StorageUnit_fix_state_of_charge_upper: description: "`StorageUnit-fix-state_of_charge-upper` — a fixed unit holds at most its hours at nominal power" dims: [scenario, snapshot, storage_unit] - where: not StorageUnit_p_nom_extendable AND StorageUnit_active + where: StorageUnit_fix expression: StorageUnit_state_of_charge <= StorageUnit_max_hours * StorageUnit_p_nom StorageUnit_ext_p_dispatch_lower: description: "`StorageUnit-ext-p_dispatch-lower` — dispatch is non-negative" dims: [scenario, snapshot, storage_unit] - where: StorageUnit_p_nom_extendable AND StorageUnit_active + where: StorageUnit_ext expression: StorageUnit_p_dispatch >= 0 StorageUnit_ext_p_dispatch_upper: description: "`StorageUnit-ext-p_dispatch-upper` — an extendable unit dispatches at most the chosen build" dims: [scenario, snapshot, storage_unit] - where: StorageUnit_p_nom_extendable AND StorageUnit_active + where: StorageUnit_ext expression: StorageUnit_p_dispatch <= StorageUnit_p_max_pu * StorageUnit_p_nom_ext StorageUnit_ext_p_store_lower: description: "`StorageUnit-ext-p_store-lower` — storing is non-negative" dims: [scenario, snapshot, storage_unit] - where: StorageUnit_p_nom_extendable AND StorageUnit_active + where: StorageUnit_ext expression: StorageUnit_p_store >= 0 StorageUnit_ext_p_store_upper: description: >- `StorageUnit-ext-p_store-upper` — an extendable unit stores at most the chosen build, the minimum-per-unit column carrying that cap negated dims: [scenario, snapshot, storage_unit] - where: StorageUnit_p_nom_extendable AND StorageUnit_active + where: StorageUnit_ext expression: StorageUnit_p_store <= -StorageUnit_p_min_pu * StorageUnit_p_nom_ext StorageUnit_ext_state_of_charge_lower: description: "`StorageUnit-ext-state_of_charge-lower` — charge is non-negative" dims: [scenario, snapshot, storage_unit] - where: StorageUnit_p_nom_extendable AND StorageUnit_active + where: StorageUnit_ext expression: StorageUnit_state_of_charge >= 0 StorageUnit_ext_state_of_charge_upper: description: "`StorageUnit-ext-state_of_charge-upper` — an extendable unit holds at most its hours at the chosen build" dims: [scenario, snapshot, storage_unit] - where: StorageUnit_p_nom_extendable AND StorageUnit_active + where: StorageUnit_ext expression: StorageUnit_state_of_charge <= StorageUnit_max_hours * StorageUnit_p_nom_ext StorageUnit_ext_p_nom_lower: description: "`StorageUnit-ext-p_nom-lower` — the chosen build is at least its floor in every scenario" diff --git a/examples/pypsa/transformer.yaml b/examples/pypsa/transformer.yaml index 6f2f30613..922fe9309 100644 --- a/examples/pypsa/transformer.yaml +++ b/examples/pypsa/transformer.yaml @@ -137,7 +137,7 @@ variables: a line does; absent, and zero in the balance, where the network is lossless dims: [scenario, snapshot, transformer] - where: transmission_losses AND Transformer_active + where: Transformer_lossy absence: zero bounds: lower: 0 @@ -193,6 +193,13 @@ expressions: + sum(Transformer_phase_shift * Transformer_phase_shift_cycle_weight, over=transformer) adds_to: Cycle_angle_sum +masks: + Transformer_lossy: + description: >- + a transformer that stands in the snapshot's period, where the run models + transmission losses + where: transmission_losses AND Transformer_active + constraints: Transformer_fix_s_lower: description: "`Transformer-fix-s-lower` — a fixed transformer carries at least the negative of its rating, the loss counted against it" @@ -237,7 +244,7 @@ constraints: Transformer_loss_upper: description: "`Transformer-loss_upper` — a transformer dissipates at most the loss at its rating" dims: [scenario, snapshot, transformer] - where: transmission_losses AND Transformer_active + where: Transformer_lossy expression: Transformer_loss <= Transformer_loss_max Transformer_loss_tangents_forward: description: >- @@ -245,12 +252,12 @@ constraints: loss sits above every cut to its curve for flow one way, as a line's does, over the segment dimension dims: [scenario, snapshot, transformer, segment] - where: transmission_losses AND Transformer_active + where: Transformer_lossy expression: Transformer_loss + Transformer_loss_slope * Transformer_s >= Transformer_loss_offset Transformer_loss_tangents_reverse: description: >- `Transformer-loss_tangents-{k}--1`, `Transformer-loss_secants-neg` — the same fan mirrored, the loss depending on the flow's magnitude dims: [scenario, snapshot, transformer, segment] - where: transmission_losses AND Transformer_active + where: Transformer_lossy expression: Transformer_loss - Transformer_loss_slope * Transformer_s >= Transformer_loss_offset diff --git a/examples/symbols/pypsa.yaml b/examples/symbols/pypsa.yaml index c5331425f..71212d509 100644 --- a/examples/symbols/pypsa.yaml +++ b/examples/symbols/pypsa.yaml @@ -312,6 +312,22 @@ names: Line_active: '\mathrm{on}^{s}' Process_active: '\mathrm{on}^{z}' Transformer_active: '\mathrm{on}^{\sigma}' + Generator_committed: '\mathrm{on}^{\mathrm{com}}' + Generator_com_ext: '\mathrm{on}^{\mathrm{com,ext}}' + Generator_maint_ext: '\mathrm{on}^{\mathrm{mnt,ext}}' + Generator_ramps_from_previous: '\mathrm{prev}' + Link_committed: '\mathrm{on}^{f,\mathrm{com}}' + Link_com_ext: '\mathrm{on}^{f,\mathrm{com,ext}}' + Link_maint_ext: '\mathrm{on}^{f,\mathrm{mnt,ext}}' + Link_ramps_from_previous: '\mathrm{prev}^{f}' + Process_committed: '\mathrm{on}^{z,\mathrm{com}}' + Process_com_ext: '\mathrm{on}^{z,\mathrm{com,ext}}' + Process_maint_ext: '\mathrm{on}^{z,\mathrm{mnt,ext}}' + Process_ramps_from_previous: '\mathrm{prev}^{z}' + StorageUnit_fix: '\mathrm{on}^{h,\mathrm{fix}}' + StorageUnit_ext: '\mathrm{on}^{h,\mathrm{ext}}' + Line_lossy: '\mathrm{on}^{s,\mathrm{lossy}}' + Transformer_lossy: '\mathrm{on}^{\sigma,\mathrm{lossy}}' Generator_capital_weight: '\mathrm{W}' Link_capital_weight: '\mathrm{W}^{f}' StorageUnit_capital_weight: '\mathrm{W}^{h}' diff --git a/tools/gallery.py b/tools/gallery.py index a6252f750..d6cffc1cb 100644 --- a/tools/gallery.py +++ b/tools/gallery.py @@ -104,6 +104,8 @@ def symbols_for(model: Spec, table_path: Path = LIBRARY_SYMBOLS) -> dict[str, An *given.variables, *given.expressions, *given.constraints, + *model.masks, + *given.masks, } return { 'notation': table['notation'], diff --git a/tools/pypsa_split.py b/tools/pypsa_split.py index 17639c0f5..e6b5b58ff 100644 --- a/tools/pypsa_split.py +++ b/tools/pypsa_split.py @@ -18,7 +18,9 @@ with `adds_to:`, and the fragment reads that hub under `given:`. One fragment reads each hub without adding to it, with its description, so the terms always have a reader, and a new component is one new fragment. The reader of -`total_cost` also sets the objective. +`total_cost` also sets the objective. A mask goes to the topic its name +names, as any declaration does, and a fragment that reads another topic's +mask reads it under `given: masks:`. `merge` then writes each hub as the file does, so `check` is one comparison: the merged fragments and the one file have one canonical form. @@ -46,7 +48,7 @@ from collections.abc import Mapping SOURCE = Path('examples/pypsa.yaml') -SECTIONS = ('dimensions', 'relations', 'parameters', 'variables', 'expressions', 'constraints', 'assumptions') +SECTIONS = ('dimensions', 'relations', 'parameters', 'variables', 'expressions', 'masks', 'constraints', 'assumptions') FRAME = ('dimensions', 'relations') IDENT = re.compile(r'[A-Za-z_][A-Za-z0-9_]*') HEADER = '# SPDX-FileCopyrightText: mathspec Contributors\n#\n# SPDX-License-Identifier: MIT\n' @@ -221,8 +223,12 @@ def keys(self) -> list[Key]: return list(self.blocks) def frames(self) -> dict[str, tuple[str, ...]]: - """The frame of every named expression, read off the one file.""" - return {name: e.dims for name, e in to_spec(self.data).program.expressions.items()} + """The frame of every named expression and mask, read off the one file.""" + program = to_spec(self.data).program + return { + **{name: e.dims for name, e in program.expressions.items()}, + **{name: m.dims for name, m in program.masks.items()}, + } def home(self, name: str) -> str: """The fragment that reads the hub *name* without adding to it, and carries its description.""" @@ -255,7 +261,7 @@ def fragments(model: Model) -> dict[str, str]: given = {model.key(n) for n in read if model.key(n)[0] not in FRAME and model.key(n) not in mine} stated = { **{n: model.data[s][n]['dims'] for s, n in given if s in ('parameters', 'variables')}, - **{n: list(frames[n]) for s, n in given if s == 'expressions'}, + **{n: list(frames[n]) for s, n in given if s in ('expressions', 'masks')}, } frame_reads = read | set().union(*(model.names_in(dims) for dims in stated.values())) frame = {model.key(n) for n in frame_reads if model.key(n)[0] in FRAME} @@ -319,7 +325,7 @@ def _fragment( #: The kinds a fragment reads under `given:`, and the fields of the source #: declaration each restates beside the frame. -GIVEN_KINDS = {'parameters': ('dtype',), 'variables': ('domain',), 'expressions': ()} +GIVEN_KINDS = {'parameters': ('dtype',), 'variables': ('domain',), 'expressions': (), 'masks': ()} def _term_block(block: str, hub: str) -> str: From 48bd4dc3ad714e654d9a3ebe34fa8054f8513901 Mon Sep 17 00:00:00 2001 From: Claude Date: Thu, 1 Oct 2026 16:22:54 +0000 Subject: [PATCH 2/2] docs: the changelog line links #825 Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01PBmqeqBrqpQC6MVoSrguHK --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3329192a7..14ba12a39 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,7 +12,7 @@ it releases that version ([RELEASING.md](https://github.com/energy-models/mathsp ## Upcoming version -- docs(pypsa): the pypsa spec names its repeated row conditions as masks, and its topic files read them under `given: masks:` ([#PR](https://github.com/energy-models/mathspec/pull/PR)) +- docs(pypsa): the pypsa spec names its repeated row conditions as masks, and its topic files read them under `given: masks:` ([#825](https://github.com/energy-models/mathspec/pull/825)) - feat(language): a where predicate is named once under `masks:`, and another file reads it under `given: masks:` ([#821](https://github.com/energy-models/mathspec/pull/821)) ## 0.2.1 (2026-10-01)