PyPSA in 24 files#
You can read the PyPSA spec here one topic at a time.
PyPSA in one file states it as examples/pypsa.yaml, one spec
of about four thousand lines. The same spec is split into 24 fragments, one file
per topic under examples/pypsa/. merge joins the 24 files back into the one
file, and the two have the same canonical form.
Each fragment loads and prints on its own, and
advice runs on each fragment alone. A
fragment lists each name that it reads but does not declare under
given. Some sums take a
share from every component, such as the bus balance or the operating cost. A
component names its share of such a sum as an expression of its own, a
term, whose adds_to: key
names the sum. For each sum, one fragment reads it and adds nothing to it, so
the terms always have a reader. To add a component, you add one file, and the
network file does not change.
tools/pypsa_split.py writes the 24 files from the one file, and a check
compares them to it, so the two always agree. The split is a proof of concept,
and which of the two is the source is not decided yet.
What each file says#
The fragments are of three kinds:
- A component file owns the PyPSA class of that name: its dimension, its
data, its variables, its rows and its share of each sum. The committable
classes are
Generator,LinkandProcess. Each of them is cut by feature into four files: the class, its commitment, its ramping and its maintenance. The three sets of four files read alike, because PyPSA builds the same rows for each class. - An owner file reads a sum with its description, and holds the row that
reads it. The network reads
Bus_injection, and power flow readsCycle_angle_sum. - The settings file holds the weightings and the flags that every topic
reads. It also reads the totals whose own readers a spec may leave out: the
cost, the carriers and the global constraints. It sets the objective, which
reads
total_cost. Each component adds its capital cost tototal_cost, and the cost file adds the operating cost at risk.
The sums#
The fragments#
| Fragment | Parameters | Variables | Constraints | Reads | Adds to |
|---|---|---|---|---|---|
| carrier | 2 | 0 | 1 | 1 | |
| cost | 1 | 3 | 2 | 4 | total_cost |
| generator | 24 | 3 | 11 | 17 | primary_energy, operational_limit, tech_capacity_expansion, scenario_opex, total_cost, Carrier_additions, Bus_injection |
| generator_commitment | 10 | 3 | 20 | 17 | scenario_opex |
| generator_maintenance | 5 | 4 | 13 | 9 | |
| generator_ramping | 5 | 0 | 6 | 14 | |
| global_constraints | 3 | 0 | 15 | 6 | |
| line | 22 | 4 | 14 | 9 | transmission_volume_expansion, transmission_expansion_cost, tech_capacity_expansion, total_cost, Carrier_additions, Bus_injection, Cycle_angle_sum |
| link | 24 | 3 | 9 | 16 | transmission_volume_expansion, transmission_expansion_cost, tech_capacity_expansion, scenario_opex, total_cost, Carrier_additions, Bus_injection |
| link_commitment | 10 | 3 | 20 | 17 | scenario_opex |
| link_maintenance | 5 | 4 | 13 | 9 | |
| link_ramping | 5 | 0 | 6 | 14 | |
| load | 3 | 0 | 0 | 1 | Bus_injection |
| network | 0 | 0 | 1 | 1 | |
| power_flow | 0 | 0 | 1 | 1 | |
| process | 22 | 3 | 9 | 14 | tech_capacity_expansion, scenario_opex, total_cost, Carrier_additions, Bus_injection |
| process_commitment | 10 | 3 | 20 | 17 | scenario_opex |
| process_maintenance | 5 | 4 | 13 | 9 | |
| process_ramping | 5 | 0 | 6 | 14 | |
| security | 2 | 0 | 8 | 10 | |
| settings | 9 | 0 | 0 | 8 | |
| storage_unit | 36 | 6 | 21 | 14 | primary_energy, operational_limit, tech_capacity_expansion, scenario_opex, total_cost, Carrier_additions, Bus_injection |
| store | 29 | 4 | 11 | 14 | primary_energy, operational_limit, tech_capacity_expansion, scenario_opex, total_cost, Carrier_additions, Bus_injection |
| transformer | 24 | 5 | 16 | 5 | total_cost, Bus_injection, Cycle_angle_sum |
Leaving a file out#
You may leave out a component family, the cost, the carriers, the global
constraints or security. What is left is a whole spec, with nothing left under
given:. You may not leave out the network or power flow while a component is
in, because the terms of the component would then add to a sum that no fragment
reads, and merge refuses the files.