Security#
This file states the security-constrained flows over the outages. It is one of the 25 whole specs of one topic each (fragments) that merge composes into the spec of examples/pypsa.yaml. Outage_s is the flow an outage takes off its branch. Each security row adds a share of it through the outage factors Line_BODF and Transformer_BODF.
given:
parameters:
Line_active: { dims: [snapshot, line], dtype: bool }
Transformer_active: { dims: [snapshot, transformer], dtype: bool }
Line_s_nom: { dims: [scenario, line] }
Line_s_nom_extendable: { dims: [line], dtype: bool }
Line_s_max_pu: { dims: [scenario, snapshot, line] }
Transformer_s_nom: { dims: [scenario, transformer] }
Transformer_s_nom_extendable: { dims: [transformer], dtype: bool }
Transformer_s_max_pu: { dims: [scenario, snapshot, transformer] }
variables:
Line_s_nom_ext: { dims: [line] }
Transformer_s_nom_ext: { dims: [transformer] }
expressions:
Line_s_monitored: { dims: [line, scenario, snapshot] }
Transformer_s_monitored: { dims: [scenario, snapshot, transformer] }
dimensions:
scenario:
description: the futures dispatch is chosen in, each with a weight
snapshot:
description: dispatch periods
dtype: datetime
ordered: true
line:
description: passive branches, each between two buses, their flow set by impedance
transformer:
description: passive branches between two buses, their flow set by impedance and tap ratio, with a phase shift fixed or optimised
outage:
description: >-
the passive branches a security-constrained run takes out one at a time
(PyPSA's `branch_outages`), each a line or a transformer. A plain run
has none
period:
description: investment periods. It is PyPSA's `investment_periods`
dtype: int
ordered: true
relations:
snapshot_period:
description: the investment period a snapshot falls in
key: snapshot
values: period
Outage_line:
description: the line an outage takes out. An outage of a transformer has no row
key: outage
values: line
missing: absent
Outage_transformer:
description: the transformer an outage takes out. An outage of a line has no row
key: outage
values: transformer
missing: absent
parameters:
Line_BODF:
description: >-
the share of an outaged branch's flow a line takes on when that branch
goes out (PyPSA's `BODF`), data prep. It comes from the PTDF of the
sub-network the period's active branches form. A row exists only where
the line and the outage are active in the period and share a
sub-network. It is -1 at the outaged line itself. PyPSA takes the factors
of the first scenario (`abstract.py:652`), and refuses impedances that
differ by scenario (`constants.py:33-35`). So the factors are the same in
every scenario
dims: [period, line, outage]
missing: absent
Transformer_BODF:
description: >-
the share of an outaged branch's flow a transformer takes on when that
branch goes out, as a line's. A row only where the transformer and the
outage are active in the period and share a sub-network. It is the same
in every scenario, as a line's
dims: [period, transformer, outage]
missing: absent
expressions:
Outage_s:
description: >-
the flow an outage takes off its branch: the outaged line's or
transformer's flow before it goes out
dims: [scenario, snapshot, outage]
cases:
line: { when: Outage_line, expression: "at(Line_s_monitored, by=Outage_line[line])" }
otherwise: at(Transformer_s_monitored, by=Outage_transformer[transformer])
constraints:
Line_fix_s_lower_security:
description: >-
`Line-fix-s-lower-security-for-{c}-outage-in-sub-network-{n}` — after
any one outage, a fixed line carries at least the negative of its
rating. Its flow takes on its share of the outaged branch's flow. PyPSA
names one row per outaged component `c` and sub-network `n`. Under
`multi_investment_periods` it appends `-period-{p}` for each period `p`.
This entry states them all over the outage dimension. A line inactive in
the snapshot's period has no row
dims: [scenario, snapshot, line, outage]
where: not Line_s_nom_extendable AND at(Line_BODF, by=snapshot_period[period]) AND Line_active
expression: Line_s_monitored + at(Line_BODF, by=snapshot_period[period]) * Outage_s >= -Line_s_max_pu * Line_s_nom
Line_fix_s_upper_security:
description: >-
`Line-fix-s-upper-security-for-{c}-outage-in-sub-network-{n}` — after
any one outage, a fixed line carries at most its rating. Its flow takes
on its share of the outaged branch's flow. PyPSA names one row per
outaged component `c` and sub-network `n`. Under
`multi_investment_periods` it appends `-period-{p}` for each period `p`.
This entry states them all over the outage dimension. A line inactive in
the snapshot's period has no row
dims: [scenario, snapshot, line, outage]
where: not Line_s_nom_extendable AND at(Line_BODF, by=snapshot_period[period]) AND Line_active
expression: Line_s_monitored + at(Line_BODF, by=snapshot_period[period]) * Outage_s <= Line_s_max_pu * Line_s_nom
Line_ext_s_lower_security:
description: >-
`Line-ext-s-lower-security-for-{c}-outage-in-sub-network-{n}` — after
any one outage, an extendable line carries at least the negative of its
rating of the chosen build. Its flow takes on its share of the outaged
branch's flow. PyPSA names one row per outaged component `c` and
sub-network `n`. Under `multi_investment_periods` it appends
`-period-{p}` for each period `p`. This entry states them all over the
outage dimension. A line inactive in the snapshot's period has no row
dims: [scenario, snapshot, line, outage]
where: Line_s_nom_extendable AND at(Line_BODF, by=snapshot_period[period]) AND Line_active
expression: Line_s_monitored + at(Line_BODF, by=snapshot_period[period]) * Outage_s >= -Line_s_max_pu * Line_s_nom_ext
Line_ext_s_upper_security:
description: >-
`Line-ext-s-upper-security-for-{c}-outage-in-sub-network-{n}` — after
any one outage, an extendable line carries at most its rating of the
chosen build. Its flow takes on its share of the outaged branch's flow.
PyPSA names one row per outaged component `c` and sub-network `n`. Under
`multi_investment_periods` it appends `-period-{p}` for each period `p`.
This entry states them all over the outage dimension. A line inactive in
the snapshot's period has no row
dims: [scenario, snapshot, line, outage]
where: Line_s_nom_extendable AND at(Line_BODF, by=snapshot_period[period]) AND Line_active
expression: Line_s_monitored + at(Line_BODF, by=snapshot_period[period]) * Outage_s <= Line_s_max_pu * Line_s_nom_ext
Transformer_fix_s_lower_security:
description: >-
`Transformer-fix-s-lower-security-for-{c}-outage-in-sub-network-{n}` —
after any one outage, a fixed transformer carries at least the negative
of its rating. Its flow takes on its share of the outaged branch's flow.
PyPSA names one row per outaged component `c` and sub-network `n`. Under
`multi_investment_periods` it appends `-period-{p}` for each period `p`.
This entry states them all over the outage dimension. A transformer
inactive in the snapshot's period has no row
dims: [scenario, snapshot, transformer, outage]
where: not Transformer_s_nom_extendable AND at(Transformer_BODF, by=snapshot_period[period]) AND Transformer_active
expression: Transformer_s_monitored + at(Transformer_BODF, by=snapshot_period[period]) * Outage_s >= -Transformer_s_max_pu * Transformer_s_nom
Transformer_fix_s_upper_security:
description: >-
`Transformer-fix-s-upper-security-for-{c}-outage-in-sub-network-{n}` —
after any one outage, a fixed transformer carries at most its rating.
Its flow takes on its share of the outaged branch's flow. PyPSA names
one row per outaged component `c` and sub-network `n`. Under
`multi_investment_periods` it appends `-period-{p}` for each period `p`.
This entry states them all over the outage dimension. A transformer
inactive in the snapshot's period has no row
dims: [scenario, snapshot, transformer, outage]
where: not Transformer_s_nom_extendable AND at(Transformer_BODF, by=snapshot_period[period]) AND Transformer_active
expression: Transformer_s_monitored + at(Transformer_BODF, by=snapshot_period[period]) * Outage_s <= Transformer_s_max_pu * Transformer_s_nom
Transformer_ext_s_lower_security:
description: >-
`Transformer-ext-s-lower-security-for-{c}-outage-in-sub-network-{n}` —
after any one outage, an extendable transformer carries at least the
negative of its rating of the chosen build. Its flow takes on its share
of the outaged branch's flow. PyPSA names one row per outaged component
`c` and sub-network `n`. Under `multi_investment_periods` it appends
`-period-{p}` for each period `p`. This entry states them all over the
outage dimension. A transformer inactive in the snapshot's period has no
row
dims: [scenario, snapshot, transformer, outage]
where: Transformer_s_nom_extendable AND at(Transformer_BODF, by=snapshot_period[period]) AND Transformer_active
expression: Transformer_s_monitored + at(Transformer_BODF, by=snapshot_period[period]) * Outage_s >= -Transformer_s_max_pu * Transformer_s_nom_ext
Transformer_ext_s_upper_security:
description: >-
`Transformer-ext-s-upper-security-for-{c}-outage-in-sub-network-{n}` —
after any one outage, an extendable transformer carries at most its
rating of the chosen build. Its flow takes on its share of the outaged
branch's flow. PyPSA names one row per outaged component `c` and
sub-network `n`. Under `multi_investment_periods` it appends
`-period-{p}` for each period `p`. This entry states them all over the
outage dimension. A transformer inactive in the snapshot's period has no
row
dims: [scenario, snapshot, transformer, outage]
where: Transformer_s_nom_extendable AND at(Transformer_BODF, by=snapshot_period[period]) AND Transformer_active
expression: Transformer_s_monitored + at(Transformer_BODF, by=snapshot_period[period]) * Outage_s <= Transformer_s_max_pu * Transformer_s_nom_ext
Given#
| Symbol | Meaning |
|---|---|
| \(\mathrm{on}^{s}\) | Line_active over \(\mathcal{K} \times \mathcal{T}\), data another file declares |
| \(\overline{\mathrm{s}}\) | Line_s_max_pu over \(\mathcal{K} \times \Xi \times \mathcal{T}\), data another file declares |
| \(\mathrm{s}^{\mathrm{nom}}\) | Line_s_nom over \(\mathcal{K} \times \Xi\), data another file declares |
| \(\mathrm{ext}^{s}\) | Line_s_nom_extendable over \(\mathcal{K}\), data another file declares |
| \(\mathrm{on}^{\sigma}\) | Transformer_active over \(\mathcal{T} \times \mathcal{M}\), data another file declares |
| \(\overline{\sigma}\) | Transformer_s_max_pu over \(\Xi \times \mathcal{T} \times \mathcal{M}\), data another file declares |
| \(\sigma^{\mathrm{nom}}\) | Transformer_s_nom over \(\Xi \times \mathcal{M}\), data another file declares |
| \(\mathrm{ext}^{\sigma}\) | Transformer_s_nom_extendable over \(\mathcal{M}\), data another file declares |
| \(S\) | Line_s_nom_ext over \(\mathcal{K}\) |
| \(\Sigma\) | Transformer_s_nom_ext over \(\mathcal{M}\) |
| \(\check{s}\) | Line_s_monitored over \(\mathcal{K} \times \Xi \times \mathcal{T}\), an expression another file defines |
| \(\check{\sigma}\) | Transformer_s_monitored over \(\Xi \times \mathcal{T} \times \mathcal{M}\), an expression another file defines |
Sets#
| Symbol | Meaning |
|---|---|
| \(\mathcal{K}\) | index \(k\) — line with \(\mathrm{Outage\_line}: \mathcal{K}^{\mathrm{out}} \to \mathcal{K}\), Outage_line is absent where the data has no row — passive branches, each between two buses, their flow set by impedance |
| \(\mathcal{K}^{\mathrm{out}}\) | index \(\kappa\) — outage with \(\mathrm{Outage\_line}: \mathcal{K}^{\mathrm{out}} \to \mathcal{K},\ \mathrm{Outage\_transformer}: \mathcal{K}^{\mathrm{out}} \to \mathcal{M}\), Outage_line is absent where the data has no row, Outage_transformer is absent where the data has no row — the passive branches a security-constrained run takes out one at a time (PyPSA's branch_outages), each a line or a transformer. A plain run has none |
| \(\mathcal{Y}\) | index \(y\) — period with \(\mathrm{snapshot\_period}: \mathcal{T} \to \mathcal{Y}\) — investment periods. It is PyPSA's investment_periods |
| \(\Xi\) | index \(\xi\) — scenario — the futures dispatch is chosen in, each with a weight |
| \(\mathcal{T}\) | index \(t\) — snapshot with \(\mathrm{snapshot\_period}: \mathcal{T} \to \mathcal{Y}\) — dispatch periods |
| \(\mathcal{M}\) | index \(m\) — transformer with \(\mathrm{Outage\_transformer}: \mathcal{K}^{\mathrm{out}} \to \mathcal{M}\), Outage_transformer is absent where the data has no row — passive branches between two buses, their flow set by impedance and tap ratio, with a phase shift fixed or optimised |
Parameters#
| Symbol | Meaning |
|---|---|
| \(\beta\) | Line_BODF over \(\mathcal{K} \times \mathcal{K}^{\mathrm{out}} \times \mathcal{Y}\), absent where the data has no row — the share of an outaged branch's flow a line takes on when that branch goes out (PyPSA's BODF), data prep. It comes from the PTDF of the sub-network the period's active branches form. A row exists only where the line and the outage are active in the period and share a sub-network. It is -1 at the outaged line itself. PyPSA takes the factors of the first scenario (abstract.py:652), and refuses impedances that differ by scenario (constants.py:33-35). So the factors are the same in every scenario |
| \(\beta^{\sigma}\) | Transformer_BODF over \(\mathcal{K}^{\mathrm{out}} \times \mathcal{Y} \times \mathcal{M}\), absent where the data has no row — the share of an outaged branch's flow a transformer takes on when that branch goes out, as a line's. A row only where the transformer and the outage are active in the period and share a sub-network. It is the same in every scenario, as a line's |
Definitions#
| Symbol | Meaning |
|---|---|
| \(\hat{s}\) | Outage_s over \(\mathcal{K}^{\mathrm{out}} \times \Xi \times \mathcal{T}\) — the flow an outage takes off its branch: the outaged line's or transformer's flow before it goes out |
Definitions#
Outage_s
\[
\hat{s}_{\kappa,\xi,t} = \begin{cases} \check{s}_{\mathrm{Outage\_line}(\kappa),\xi,t} & \text{if } \mathrm{Outage\_line}(\kappa) \text{ is defined} \\ \check{\sigma}_{\xi,t,\mathrm{Outage\_transformer}(\kappa)} & \text{otherwise} \end{cases} \qquad \forall\, \kappa \in \mathcal{K}^{\mathrm{out}},\ \xi \in \Xi,\ t \in \mathcal{T}
\]
Subject to#
Line_ext_s_lower_security
\[
\check{s}_{k,\xi,t} + \beta_{k,\kappa,\mathrm{snapshot\_period}(t)} \cdot \hat{s}_{\kappa,\xi,t} \ge -\overline{\mathrm{s}}_{k,\xi,t} \cdot S_{k} \qquad \forall\, k \in \mathcal{K},\ \kappa \in \mathcal{K}^{\mathrm{out}},\ \xi \in \Xi,\ t \in \mathcal{T} \,:\, \mathrm{ext}^{s}_{k} \wedge \beta_{k,\kappa,\mathrm{snapshot\_period}(t)} \text{ is defined} \wedge \mathrm{on}^{s}_{k,t}
\]
Line_ext_s_upper_security
\[
\check{s}_{k,\xi,t} + \beta_{k,\kappa,\mathrm{snapshot\_period}(t)} \cdot \hat{s}_{\kappa,\xi,t} \le \overline{\mathrm{s}}_{k,\xi,t} \cdot S_{k} \qquad \forall\, k \in \mathcal{K},\ \kappa \in \mathcal{K}^{\mathrm{out}},\ \xi \in \Xi,\ t \in \mathcal{T} \,:\, \mathrm{ext}^{s}_{k} \wedge \beta_{k,\kappa,\mathrm{snapshot\_period}(t)} \text{ is defined} \wedge \mathrm{on}^{s}_{k,t}
\]
Line_fix_s_lower_security
\[
\check{s}_{k,\xi,t} + \beta_{k,\kappa,\mathrm{snapshot\_period}(t)} \cdot \hat{s}_{\kappa,\xi,t} \ge -\overline{\mathrm{s}}_{k,\xi,t} \cdot \mathrm{s}^{\mathrm{nom}}_{k,\xi} \qquad \forall\, k \in \mathcal{K},\ \kappa \in \mathcal{K}^{\mathrm{out}},\ \xi \in \Xi,\ t \in \mathcal{T} \,:\, \neg \mathrm{ext}^{s}_{k} \wedge \beta_{k,\kappa,\mathrm{snapshot\_period}(t)} \text{ is defined} \wedge \mathrm{on}^{s}_{k,t}
\]
Line_fix_s_upper_security
\[
\check{s}_{k,\xi,t} + \beta_{k,\kappa,\mathrm{snapshot\_period}(t)} \cdot \hat{s}_{\kappa,\xi,t} \le \overline{\mathrm{s}}_{k,\xi,t} \cdot \mathrm{s}^{\mathrm{nom}}_{k,\xi} \qquad \forall\, k \in \mathcal{K},\ \kappa \in \mathcal{K}^{\mathrm{out}},\ \xi \in \Xi,\ t \in \mathcal{T} \,:\, \neg \mathrm{ext}^{s}_{k} \wedge \beta_{k,\kappa,\mathrm{snapshot\_period}(t)} \text{ is defined} \wedge \mathrm{on}^{s}_{k,t}
\]
Transformer_ext_s_lower_security
\[
\check{\sigma}_{\xi,t,m} + \beta^{\sigma}_{\kappa,\mathrm{snapshot\_period}(t),m} \cdot \hat{s}_{\kappa,\xi,t} \ge -\overline{\sigma}_{\xi,t,m} \cdot \Sigma_{m} \qquad \forall\, \kappa \in \mathcal{K}^{\mathrm{out}},\ \xi \in \Xi,\ t \in \mathcal{T},\ m \in \mathcal{M} \,:\, \mathrm{ext}^{\sigma}_{m} \wedge \beta^{\sigma}_{\kappa,\mathrm{snapshot\_period}(t),m} \text{ is defined} \wedge \mathrm{on}^{\sigma}_{t,m}
\]
Transformer_ext_s_upper_security
\[
\check{\sigma}_{\xi,t,m} + \beta^{\sigma}_{\kappa,\mathrm{snapshot\_period}(t),m} \cdot \hat{s}_{\kappa,\xi,t} \le \overline{\sigma}_{\xi,t,m} \cdot \Sigma_{m} \qquad \forall\, \kappa \in \mathcal{K}^{\mathrm{out}},\ \xi \in \Xi,\ t \in \mathcal{T},\ m \in \mathcal{M} \,:\, \mathrm{ext}^{\sigma}_{m} \wedge \beta^{\sigma}_{\kappa,\mathrm{snapshot\_period}(t),m} \text{ is defined} \wedge \mathrm{on}^{\sigma}_{t,m}
\]
Transformer_fix_s_lower_security
\[
\check{\sigma}_{\xi,t,m} + \beta^{\sigma}_{\kappa,\mathrm{snapshot\_period}(t),m} \cdot \hat{s}_{\kappa,\xi,t} \ge -\overline{\sigma}_{\xi,t,m} \cdot \sigma^{\mathrm{nom}}_{\xi,m} \qquad \forall\, \kappa \in \mathcal{K}^{\mathrm{out}},\ \xi \in \Xi,\ t \in \mathcal{T},\ m \in \mathcal{M} \,:\, \neg \mathrm{ext}^{\sigma}_{m} \wedge \beta^{\sigma}_{\kappa,\mathrm{snapshot\_period}(t),m} \text{ is defined} \wedge \mathrm{on}^{\sigma}_{t,m}
\]
Transformer_fix_s_upper_security
\[
\check{\sigma}_{\xi,t,m} + \beta^{\sigma}_{\kappa,\mathrm{snapshot\_period}(t),m} \cdot \hat{s}_{\kappa,\xi,t} \le \overline{\sigma}_{\xi,t,m} \cdot \sigma^{\mathrm{nom}}_{\xi,m} \qquad \forall\, \kappa \in \mathcal{K}^{\mathrm{out}},\ \xi \in \Xi,\ t \in \mathcal{T},\ m \in \mathcal{M} \,:\, \neg \mathrm{ext}^{\sigma}_{m} \wedge \beta^{\sigma}_{\kappa,\mathrm{snapshot\_period}(t),m} \text{ is defined} \wedge \mathrm{on}^{\sigma}_{t,m}
\]
See also
- PyPSA in 25 files, for how the fragments compose
- PyPSA in one file, for the same spec as one file, rung by rung