Global constraints#
This file states the five system totals that PyPSA caps. Each total is a sum that the components add to. It is one of the 25 whole specs of one topic each (fragments) that merge composes into the spec of examples/pypsa.yaml. Each total has an upper-bound, a lower-bound and an equality row, such as GlobalConstraint_primary_energy_ub.
given:
parameters:
scenario_weight: { dims: [scenario] }
expressions:
primary_energy: { dims: [global_constraint, scenario] }
operational_limit: { dims: [global_constraint, scenario] }
transmission_volume_expansion: { dims: [global_constraint, scenario] }
transmission_expansion_cost: { dims: [global_constraint, scenario] }
tech_capacity_expansion: { dims: [global_constraint] }
dimensions:
scenario:
description: the futures dispatch is chosen in, each with a weight
global_constraint:
description: PyPSA's `GlobalConstraint` rows, one label per declared limit
parameters:
GlobalConstraint_type:
description: >-
which formula the row takes: `primary_energy`, `operational_limit`,
`transmission_volume_expansion_limit`,
`transmission_expansion_cost_limit`, `tech_capacity_expansion_limit` or
`flow_based`
dims: [global_constraint]
dtype: str
GlobalConstraint_sense:
description: >-
the row's sense in each scenario: `<=`, `>=` or `==`. PyPSA reads a
row's sense per scenario (`global_constraints.py:576`, `:779`, `:859-864`)
dims: [scenario, global_constraint]
dtype: str
GlobalConstraint_constant:
description: >-
the constant the total is held against. What a variable cannot represent
is folded in here in data prep. That is an initial charge, times its
period's years for each counted period where the storage reopens per
period, or a non-extendable build. PyPSA reads it per scenario
(`global_constraints.py:577`, `:780`, `:859-864`)
dims: [scenario, global_constraint]
constraints:
GlobalConstraint_primary_energy_ub:
description: "`primary_energy` — its total, at most its constant"
dims: [scenario, global_constraint]
where: GlobalConstraint_type == 'primary_energy' AND GlobalConstraint_sense == '<='
expression: primary_energy <= GlobalConstraint_constant
GlobalConstraint_primary_energy_lb:
description: "`primary_energy` — its total, at least its constant"
dims: [scenario, global_constraint]
where: GlobalConstraint_type == 'primary_energy' AND GlobalConstraint_sense == '>='
expression: primary_energy >= GlobalConstraint_constant
GlobalConstraint_primary_energy_eq:
description: "`primary_energy` — its total, at its constant"
dims: [scenario, global_constraint]
where: GlobalConstraint_type == 'primary_energy' AND GlobalConstraint_sense == '=='
expression: primary_energy == GlobalConstraint_constant
GlobalConstraint_operational_limit_ub:
description: "`operational_limit` — its total, at most its constant"
dims: [scenario, global_constraint]
where: GlobalConstraint_type == 'operational_limit' AND GlobalConstraint_sense == '<='
expression: operational_limit <= GlobalConstraint_constant
GlobalConstraint_operational_limit_lb:
description: "`operational_limit` — its total, at least its constant"
dims: [scenario, global_constraint]
where: GlobalConstraint_type == 'operational_limit' AND GlobalConstraint_sense == '>='
expression: operational_limit >= GlobalConstraint_constant
GlobalConstraint_operational_limit_eq:
description: "`operational_limit` — its total, at its constant"
dims: [scenario, global_constraint]
where: GlobalConstraint_type == 'operational_limit' AND GlobalConstraint_sense == '=='
expression: operational_limit == GlobalConstraint_constant
GlobalConstraint_transmission_volume_expansion_limit_ub:
description: "`transmission_volume_expansion_limit` — its total, at most its constant"
dims: [scenario, global_constraint]
where: GlobalConstraint_type == 'transmission_volume_expansion_limit' AND GlobalConstraint_sense == '<='
expression: transmission_volume_expansion <= GlobalConstraint_constant
GlobalConstraint_transmission_volume_expansion_limit_lb:
description: "`transmission_volume_expansion_limit` — its total, at least its constant"
dims: [scenario, global_constraint]
where: GlobalConstraint_type == 'transmission_volume_expansion_limit' AND GlobalConstraint_sense == '>='
expression: transmission_volume_expansion >= GlobalConstraint_constant
GlobalConstraint_transmission_volume_expansion_limit_eq:
description: "`transmission_volume_expansion_limit` — its total, at its constant"
dims: [scenario, global_constraint]
where: GlobalConstraint_type == 'transmission_volume_expansion_limit' AND GlobalConstraint_sense == '=='
expression: transmission_volume_expansion == GlobalConstraint_constant
GlobalConstraint_transmission_expansion_cost_limit_ub:
description: "`transmission_expansion_cost_limit` — its total, at most its constant"
dims: [scenario, global_constraint]
where: GlobalConstraint_type == 'transmission_expansion_cost_limit' AND GlobalConstraint_sense == '<='
expression: transmission_expansion_cost <= GlobalConstraint_constant
GlobalConstraint_transmission_expansion_cost_limit_lb:
description: "`transmission_expansion_cost_limit` — its total, at least its constant"
dims: [scenario, global_constraint]
where: GlobalConstraint_type == 'transmission_expansion_cost_limit' AND GlobalConstraint_sense == '>='
expression: transmission_expansion_cost >= GlobalConstraint_constant
GlobalConstraint_transmission_expansion_cost_limit_eq:
description: "`transmission_expansion_cost_limit` — its total, at its constant"
dims: [scenario, global_constraint]
where: GlobalConstraint_type == 'transmission_expansion_cost_limit' AND GlobalConstraint_sense == '=='
expression: transmission_expansion_cost == GlobalConstraint_constant
GlobalConstraint_tech_capacity_expansion_limit_ub:
description: "`tech_capacity_expansion_limit` — its total, at most its constant"
dims: [scenario, global_constraint]
where: GlobalConstraint_type == 'tech_capacity_expansion_limit' AND GlobalConstraint_sense == '<='
expression: tech_capacity_expansion <= GlobalConstraint_constant
GlobalConstraint_tech_capacity_expansion_limit_lb:
description: "`tech_capacity_expansion_limit` — its total, at least its constant"
dims: [scenario, global_constraint]
where: GlobalConstraint_type == 'tech_capacity_expansion_limit' AND GlobalConstraint_sense == '>='
expression: tech_capacity_expansion >= GlobalConstraint_constant
GlobalConstraint_tech_capacity_expansion_limit_eq:
description: "`tech_capacity_expansion_limit` — its total, at its constant"
dims: [scenario, global_constraint]
where: GlobalConstraint_type == 'tech_capacity_expansion_limit' AND GlobalConstraint_sense == '=='
expression: tech_capacity_expansion == GlobalConstraint_constant
assumptions:
GlobalConstraint_tech_capacity_expansion_limit_without_scenarios:
holds: "GlobalConstraint_type != 'tech_capacity_expansion_limit'"
where: "count(scenario_weight, over=scenario) > 1"
description: >-
PyPSA does not build a `tech_capacity_expansion_limit` row on a network
with scenarios and refuses it (`global_constraints.py:68-70`). The spec
cannot tell a network with one scenario from one with none. A tool thus
refuses the row only where there is more than one scenario
Given#
| Symbol | Meaning |
|---|---|
| \(\pi\) | scenario_weight over \(\Xi\), data another file declares |
| \(\mathit{operational\_limit}\) | operational_limit over \(\mathcal{G} \times \Xi\), an expression another file defines |
| \(\mathit{primary\_energy}\) | primary_energy over \(\mathcal{G} \times \Xi\), an expression another file defines |
| \(\mathit{tech\_capacity\_expansion}\) | tech_capacity_expansion over \(\mathcal{G}\), an expression another file defines |
| \(\mathit{transmission\_expansion\_cost}\) | transmission_expansion_cost over \(\mathcal{G} \times \Xi\), an expression another file defines |
| \(\mathit{transmission\_volume\_expansion}\) | transmission_volume_expansion over \(\mathcal{G} \times \Xi\), an expression another file defines |
Sets#
| Symbol | Meaning |
|---|---|
| \(\mathcal{G}\) | index \(g\) — global_constraint — PyPSA's GlobalConstraint rows, one label per declared limit |
| \(\Xi\) | index \(\xi\) — scenario — the futures dispatch is chosen in, each with a weight |
Parameters#
| Symbol | Meaning |
|---|---|
| \(\mathrm{K}\) | GlobalConstraint_constant over \(\mathcal{G} \times \Xi\) — the constant the total is held against. What a variable cannot represent is folded in here in data prep. That is an initial charge, times its period's years for each counted period where the storage reopens per period, or a non-extendable build. PyPSA reads it per scenario (global_constraints.py:577, :780, :859-864) |
| \(\mathrm{sense}\) | GlobalConstraint_sense over \(\mathcal{G} \times \Xi\) — the row's sense in each scenario: <=, >= or ==. PyPSA reads a row's sense per scenario (global_constraints.py:576, :779, :859-864) |
| \(\mathrm{type}\) | GlobalConstraint_type over \(\mathcal{G}\) — which formula the row takes: primary_energy, operational_limit, transmission_volume_expansion_limit, transmission_expansion_cost_limit, tech_capacity_expansion_limit or flow_based |
Subject to#
GlobalConstraint_operational_limit_eq
GlobalConstraint_operational_limit_lb
GlobalConstraint_operational_limit_ub
GlobalConstraint_primary_energy_eq
GlobalConstraint_primary_energy_lb
GlobalConstraint_primary_energy_ub
GlobalConstraint_tech_capacity_expansion_limit_eq
GlobalConstraint_tech_capacity_expansion_limit_lb
GlobalConstraint_tech_capacity_expansion_limit_ub
GlobalConstraint_transmission_expansion_cost_limit_eq
GlobalConstraint_transmission_expansion_cost_limit_lb
GlobalConstraint_transmission_expansion_cost_limit_ub
GlobalConstraint_transmission_volume_expansion_limit_eq
GlobalConstraint_transmission_volume_expansion_limit_lb
GlobalConstraint_transmission_volume_expansion_limit_ub
Assumptions#
GlobalConstraint_tech_capacity_expansion_limit_without_scenarios
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