Solving¶
Scripts for solving the network optimization problem.
solve_network
¶
Solves linear optimal power flow for a network iteratively while updating reactances.
Relevant Settings¶
.. code:: yaml
solving:
tmpdir:
options:
formulation:
clip_p_max_pu:
load_shedding:
noisy_costs:
nhours:
min_iterations:
max_iterations:
skip_iterations:
track_iterations:
solver:
name:
.. seealso::
Documentation of the configuration file config.yaml at
:ref:electricity_cf, :ref:solving_cf, :ref:plotting_cf
Inputs¶
networks/elec_s{simpl}_{clusters}_ec_l{ll}_{opts}.nc: confer :ref:prepare
Outputs¶
-
results/networks/elec_s{simpl}_{clusters}_ec_l{ll}_{opts}.nc: Solved PyPSA network including optimisation results.. image:: /img/results.png :width: 40 %
Description¶
Total annual system costs are minimised with PyPSA. The full formulation of the
linear optimal power flow (plus investment planning)
is provided in the
documentation of PyPSA <https://pypsa.readthedocs.io/en/latest/optimal_power_flow.html#linear-optimal-power-flow>_.
The optimization is based on the :func:network.optimize function.
Additionally, some extra constraints specified in :mod:prepare_network and :mod:solve_network are added.
Solving the network in multiple iterations is motivated through the dependence of transmission line capacities and impedances on values of corresponding flows. As lines are expanded their electrical parameters change, which renders the optimisation bilinear even if the power flow equations are linearized. To retain the computational advantage of continuous linear programming, a sequential linear programming technique is used, where in between iterations the line impedances are updated. Details (and errors introduced through this heuristic) are discussed in the paper
- Fabian Neumann and Tom Brown.
Heuristics for Transmission Expansion Planning in Low-Carbon Energy System Models <https://arxiv.org/abs/1907.10548>), 16th International Conference on the European Energy Market, 2019.arXiv:1907.10548 <https://arxiv.org/abs/1907.10548>.
.. warning:: Capital costs of existing network components are not included in the objective function, since for the optimisation problem they are just a constant term (no influence on optimal result).
Therefore, these capital costs are not included in ``network.objective``!
If you want to calculate the full total annual system costs add these to the objective value.
.. tip::
The rule :mod:solve_all_networks runs
for all scenario s in the configuration file
the rule :mod:solve_network.
get_load_shedding_capacity(n, safety_margin=1.2)
¶
add_CCL_constraints(n, config)
¶
Add CCL (country & carrier limit) constraint to the network.
Add minimum and maximum levels of generator nominal capacity per carrier for individual countries. Opts and path for agg_p_nom_minmax.csv must be defined in config.yaml. Default file is available at data/agg_p_nom_minmax.csv. Parameter include_existing in config.yaml decides whether existing capacities are considered in the CCL constraints. Default is false.
Parameters¶
n : pypsa.Network config : dict
Example¶
scenario: opts: [CCL-Co2L-24H] electricity: agg_p_nom_limits: file: data/agg_p_nom_minmax.csv include_existing: false
add_EQ_constraints(n, o, scaling=0.1)
¶
Add equity constraints to the network.
Currently this is only implemented for the electricity sector only.
Opts must be specified in the config.yaml.
Parameters¶
n : pypsa.Network o : str
Example¶
scenario: opts: [Co2L-EQ0.7-24h]
Require each country or node to on average produce a minimal share of its total electricity consumption itself. Example: EQ0.7c demands each country to produce on average at least 70% of its consumption; EQ0.7 demands each node to produce on average at least 70% of its consumption.
add_BAU_constraints(n, config)
¶
Add a per-carrier minimal overall capacity.
BAU_mincapacities and opts must be adjusted in the config.yaml.
Parameters¶
n : pypsa.Network config : dict
Example¶
scenario: opts: [Co2L-BAU-24h] electricity: BAU_mincapacities: solar: 0 onwind: 0 OCGT: 100000 offwind-ac: 0 offwind-dc: 0 Which sets minimum expansion across all nodes e.g. in Europe to 100GW. OCGT bus 1 + OCGT bus 2 + ... > 100000
add_SAFE_constraints(n, config)
¶
Add a capacity reserve margin of a certain fraction above the peak demand. Renewable generators and storage do not contribute. Ignores network.
Parameters¶
n : pypsa.Network
config : dict
Example¶
config.yaml requires to specify opts:
scenario: opts: [Co2L-SAFE-24h] electricity: SAFE_reservemargin: 0.1 Which sets a reserve margin of 10% above the peak demand.
add_operational_reserve_margin_constraint(n, sns, config)
¶
Build reserve margin constraints based on the formulation as suggested in GenX https://energy.mit.edu/wp-content/uploads/2017/10/Enhanced-Decision-Support-for-a-Changing-Electricity-Landscape.pdf It implies that the reserve margin also accounts for optimal dispatch of distributed energy resources (DERs) and demand response which is a novel feature of GenX.
add_operational_reserve_margin(n, sns, config)
¶
Parameters¶
n : pypsa.Network
sns: pd.DatetimeIndex
config : dict
Example:¶
config.yaml requires to specify operational_reserve: operational_reserve: # like https://genxproject.github.io/GenX/dev/core/#Reserves activate: true epsilon_load: 0.02 # percentage of load at each snapshot epsilon_vres: 0.02 # percentage of VRES at each snapshot contingency: 400000 # MW
add_battery_constraints(n)
¶
Add constraint ensuring that charger = discharger, i.e. 1 * charger_size - efficiency * discharger_size = 0
add_RES_constraints(n, res_share, config)
¶
The constraint ensures that a predefined share of power is generated by renewable sources
Parameters¶
n : pypsa.Network
res_share: float
config : dict
hydrogen_temporal_constraint(n, n_ref, time_period)
¶
Applies temporal constraints for hydrogen production based on renewable energy sources (RES) and electrolysis within a specified time period. The function ensures that the hydrogen production adheres to policy configurations such as temporal matching and allowed excess. Parameters:
n : pypsa.Network The PyPSA network object containing the current state of the energy system model. n_ref : pypsa.Network A reference PyPSA network object used for additionality constraints (if enabled). time_period : str The time period for grouping constraints. Can be one of "hour", "month", or "year". Returns:
None Adds constraints directly to the PyPSA network model. Raises:
KeyError
If required configuration keys are missing in snakemake.config.
ValueError
If an unsupported time_period is provided.
add_lossy_bidirectional_link_constraints(n)
¶
Ensures that the two links simulating a bidirectional_link are extended the same amount.
extra_functionality(n, snapshots)
¶
Collects supplementary constraints which will be passed to
pypsa.linopf.network_lopf.
If you want to enforce additional custom constraints, this is a good location to add them.
The arguments opts and snakemake.config are expected to be attached to the network.