Note
You can download this example as a Jupyter notebook or start it in interactive mode.
Constraining the total capacity per bus and carrier#
In this small example, we limit the nominal capacity of generators of the same production carrier at the same bus.
Therefore, we introduce a column nom_min_{carrier} and nom_max_{carrier} in the buses dataframe. These are then used as lower and upper bounds of generators of the same carrier at the same bus.
We start with importing a small example network.
[1]:
import pandas as pd
import pypsa
[2]:
n = pypsa.examples.ac_dc_meshed(from_master=True)
n.links_t.p_set = pd.DataFrame(
index=n.snapshots
) # remove forced fixed values in optimization
WARNING:pypsa.io:Importing network from PyPSA version v0.17.1 while current version is v0.29.0. Read the release notes at https://pypsa.readthedocs.io/en/latest/release_notes.html to prepare your network for import.
INFO:pypsa.io:Imported network ac-dc-meshed.nc has buses, carriers, generators, global_constraints, lines, links, loads
Now add a second wind generator at bus ‘Frankfurt’ and limit the combined capacity.
[3]:
n.add(
"Generator",
"Frankfurt Wind 2",
bus="Frankfurt",
capital_cost=120,
carrier="wind",
p_nom_extendable=True,
)
n.buses.loc[["Frankfurt", "Manchester"], "nom_min_wind"] = 2000
n.buses.loc[["Frankfurt"], "nom_max_wind"] = 2200
We are running the lopf and check whether the constraint is fulfilled.
[4]:
n.optimize()
WARNING:pypsa.consistency:The following lines have carriers which are not defined:
Index(['0', '1', '2', '3', '4', '5', '6'], dtype='object', name='Line')
WARNING:pypsa.consistency:The following lines have zero x, which could break the linear load flow:
Index(['2', '3', '4'], dtype='object', name='Line')
WARNING:pypsa.consistency:The following lines have zero r, which could break the linear load flow:
Index(['0', '1', '5', '6'], dtype='object', name='Line')
WARNING:pypsa.consistency:The following links have carriers which are not defined:
Index(['Norwich Converter', 'Norway Converter', 'Bremen Converter', 'DC link'], dtype='object', name='Link')
WARNING:pypsa.consistency:The following buses have carriers which are not defined:
Index(['London', 'Norwich', 'Norwich DC', 'Manchester', 'Bremen', 'Bremen DC',
'Frankfurt', 'Norway', 'Norway DC'],
dtype='object', name='Bus')
WARNING:pypsa.consistency:The following lines have carriers which are not defined:
Index(['0', '1', '2', '3', '4', '5', '6'], dtype='object', name='Line')
WARNING:pypsa.consistency:The following lines have zero x, which could break the linear load flow:
Index(['2', '3', '4'], dtype='object', name='Line')
WARNING:pypsa.consistency:The following lines have zero r, which could break the linear load flow:
Index(['0', '1', '5', '6'], dtype='object', name='Line')
WARNING:pypsa.consistency:The following links have carriers which are not defined:
Index(['Norwich Converter', 'Norway Converter', 'Bremen Converter', 'DC link'], dtype='object', name='Link')
WARNING:pypsa.consistency:The following buses have carriers which are not defined:
Index(['London', 'Norwich', 'Norwich DC', 'Manchester', 'Bremen', 'Bremen DC',
'Frankfurt', 'Norway', 'Norway DC'],
dtype='object', name='Bus')
INFO:linopy.model: Solve problem using Highs solver
INFO:linopy.io: Writing time: 0.08s
INFO:linopy.solvers:Log file at /tmp/highs.log
INFO:linopy.constants: Optimization successful:
Status: ok
Termination condition: optimal
Solution: 199 primals, 492 duals
Objective: -1.38e+07
Solver model: available
Solver message: optimal
INFO:pypsa.optimization.optimize:The shadow-prices of the constraints Generator-ext-p-lower, Generator-ext-p-upper, Line-ext-s-lower, Line-ext-s-upper, Link-ext-p-lower, Link-ext-p-upper, Kirchhoff-Voltage-Law were not assigned to the network.
Running HiGHS 1.7.2 (git hash: 184e327): Copyright (c) 2024 HiGHS under MIT licence terms
Coefficient ranges:
Matrix [1e-02, 1e+00]
Cost [9e-03, 3e+03]
Bound [2e+07, 2e+07]
RHS [9e-01, 2e+03]
Presolving model
403 rows, 198 cols, 964 nonzeros 0s
320 rows, 115 cols, 1055 nonzeros 0s
318 rows, 114 cols, 1061 nonzeros 0s
Presolve : Reductions: rows 318(-174); columns 114(-85); elements 1061(+8)
Solving the presolved LP
Using EKK dual simplex solver - serial
Iteration Objective Infeasibilities num(sum)
0 -1.5896394920e+07 Pr: 101(185533); Du: 0(3.84552e-11) 0s
121 -1.3793078250e+07 Pr: 0(0) 0s
Solving the original LP from the solution after postsolve
Model status : Optimal
Simplex iterations: 121
Objective value : -1.3793078250e+07
HiGHS run time : 0.00
Writing the solution to /tmp/linopy-solve-ea9pqcav.sol
[4]:
('ok', 'optimal')
[5]:
n.generators[["p_nom_opt"]]
[5]:
| p_nom_opt | |
|---|---|
| Generator | |
| Manchester Wind | 2000.000000 |
| Manchester Gas | -0.000000 |
| Norway Wind | 895.372552 |
| Norway Gas | 91.001539 |
| Frankfurt Wind | 100.000000 |
| Frankfurt Gas | 884.092697 |
| Frankfurt Wind 2 | 2100.000000 |
Looks good! The generators of carrier ‘wind’ at bus ‘Frankfurt’ are just the limit of 2200 MW.