Skip to content

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

maps:
  snapshot:
    period:
      description: the investment period a snapshot falls in
      refers_to: period
  outage:
    line:
      description: the line an outage takes out. An outage of a transformer has no row
      refers_to: line
      missing: absent
    transformer:
      description: the transformer an outage takes out. An outage of a line has no row
      refers_to: 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])" }
    otherwise: at(Transformer_s_monitored, by=outage[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]) AND Line_active
    expression: Line_s_monitored + at(Line_BODF, by=snapshot[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]) AND Line_active
    expression: Line_s_monitored + at(Line_BODF, by=snapshot[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]) AND Line_active
    expression: Line_s_monitored + at(Line_BODF, by=snapshot[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]) AND Line_active
    expression: Line_s_monitored + at(Line_BODF, by=snapshot[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]) AND Transformer_active
    expression: Transformer_s_monitored + at(Transformer_BODF, by=snapshot[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]) AND Transformer_active
    expression: Transformer_s_monitored + at(Transformer_BODF, by=snapshot[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]) AND Transformer_active
    expression: Transformer_s_monitored + at(Transformer_BODF, by=snapshot[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]) AND Transformer_active
    expression: Transformer_s_monitored + at(Transformer_BODF, by=snapshot[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{line}: \mathcal{K}^{\mathrm{out}} \to \mathcal{K}\), outage[line] is absent where the data gives no label — passive branches, each between two buses, their flow set by impedance
\(\mathcal{K}^{\mathrm{out}}\) index \(\kappa\) — outage with \(\mathrm{line}: \mathcal{K}^{\mathrm{out}} \to \mathcal{K},\ \mathrm{transformer}: \mathcal{K}^{\mathrm{out}} \to \mathcal{M}\), outage[line] is absent where the data gives no label, outage[transformer] is absent where the data gives no label — 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{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{period}: \mathcal{T} \to \mathcal{Y}\) — dispatch periods
\(\mathcal{M}\) index \(m\) — transformer with \(\mathrm{transformer}: \mathcal{K}^{\mathrm{out}} \to \mathcal{M}\), outage[transformer] is absent where the data gives no label — 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{line}(\kappa),\xi,t} & \text{if } \mathrm{line}(\kappa) \text{ is defined} \\ \check{\sigma}_{\xi,t,\mathrm{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{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{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{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{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{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{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{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{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{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{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{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{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{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{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{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{period}(t),m} \text{ is defined} \wedge \mathrm{on}^{\sigma}_{t,m} \]

See also