Problem 5.3#
Integrated Energy Grids
Problem 5.3
Note: This is equivalent to Problem 2.2 which we solved using linopy, but here we will use PyPSA.
Consider the following economic dispatch problem:
• we have three generators: solar, wind and gas
• solar and wind have no marginal costs, and gas has fuel costs of 60 EUR/MWh.
• we need to cover a electricity demand of 13.2 MWh
• the installed capacities are 15 MW, 20 MW and 20 MW for wind, solar, and gas, respectively
• assume the capacity factor for solar is 0.17 and for wind 0.33.
Use PYPSA to find the optimal solution as well and obtain the electricity price (Lagrange multiplier for the energy balance constraint)
Note
If you have not yet set up Python on your computer, you can execute this tutorial in your browser via Google Colab. Click on the rocket in the top right corner and launch “Colab”. If that doesn’t work download the .ipynb
file and import it in Google Colab.
Then install the following packages by executing the following command in a Jupyter cell at the top of the notebook.
!pip install numpy pypsa
import numpy as np
import pypsa
We start by creating the network object and adding the bus.
network = pypsa.Network()
network.add("Bus", "my bus")
network.buses
v_nom | type | x | y | carrier | unit | location | v_mag_pu_set | v_mag_pu_min | v_mag_pu_max | control | generator | sub_network | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Bus | |||||||||||||
my bus | 1.0 | 0.0 | 0.0 | AC | 1.0 | 0.0 | inf | PQ |
We add the generators
network.add("Generator",
"solar",
bus="my bus",
p_nom=15,
p_max_pu=0.17, #capacity factor
marginal_cost=0)
network.add("Generator",
"wind",
bus="my bus",
p_nom=20,
p_max_pu=0.33, #capacity factor
marginal_cost=0)
network.add("Generator",
"gas",
bus="my bus",
p_nom=20,
marginal_cost=60) #EUR/MWh_elec
network.generators
bus | control | type | p_nom | p_nom_mod | p_nom_extendable | p_nom_min | p_nom_max | p_min_pu | p_max_pu | ... | min_up_time | min_down_time | up_time_before | down_time_before | ramp_limit_up | ramp_limit_down | ramp_limit_start_up | ramp_limit_shut_down | weight | p_nom_opt | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Generator | |||||||||||||||||||||
solar | my bus | PQ | 15.0 | 0.0 | False | 0.0 | inf | 0.0 | 0.17 | ... | 0 | 0 | 1 | 0 | NaN | NaN | 1.0 | 1.0 | 1.0 | 0.0 | |
wind | my bus | PQ | 20.0 | 0.0 | False | 0.0 | inf | 0.0 | 0.33 | ... | 0 | 0 | 1 | 0 | NaN | NaN | 1.0 | 1.0 | 1.0 | 0.0 | |
gas | my bus | PQ | 20.0 | 0.0 | False | 0.0 | inf | 0.0 | 1.00 | ... | 0 | 0 | 1 | 0 | NaN | NaN | 1.0 | 1.0 | 1.0 | 0.0 |
3 rows × 37 columns
We add the load
network.add("Load",
"electricity demand",
bus="my bus",
p_set=13.2)
network.loads
bus | carrier | type | p_set | q_set | sign | active | |
---|---|---|---|---|---|---|---|
Load | |||||||
electricity demand | my bus | 13.2 | 0.0 | -1.0 | True |
Calculate the optimal economic dispatch
network.optimize()
WARNING:pypsa.consistency:The following buses have carriers which are not defined:
Index(['my bus'], dtype='object', name='Bus')
INFO:linopy.model: Solve problem using Highs solver
INFO:linopy.io: Writing time: 0.01s
INFO:linopy.constants: Optimization successful:
Status: ok
Termination condition: optimal
Solution: 3 primals, 7 duals
Objective: 2.43e+02
Solver model: available
Solver message: Optimal
INFO:pypsa.optimization.optimize:The shadow-prices of the constraints Generator-fix-p-lower, Generator-fix-p-upper were not assigned to the network.
Running HiGHS 1.10.0 (git hash: fd86653): Copyright (c) 2025 HiGHS under MIT licence terms
LP linopy-problem-flthrja8 has 7 rows; 3 cols; 9 nonzeros
Coefficient ranges:
Matrix [1e+00, 1e+00]
Cost [6e+01, 6e+01]
Bound [0e+00, 0e+00]
RHS [3e+00, 2e+01]
Presolving model
0 rows, 0 cols, 0 nonzeros 0s
0 rows, 0 cols, 0 nonzeros 0s
Presolve : Reductions: rows 0(-7); columns 0(-3); elements 0(-9) - Reduced to empty
Solving the original LP from the solution after postsolve
Model name : linopy-problem-flthrja8
Model status : Optimal
Objective value : 2.4300000000e+02
Relative P-D gap : 0.0000000000e+00
HiGHS run time : 0.00
Writing the solution to /tmp/linopy-solve-985oe5uf.sol
('ok', 'optimal')
Now we can show the optimal dispatch and the electricity price (marginal cost at the bus)
network.generators_t.p
Generator | solar | wind | gas |
---|---|---|---|
snapshot | |||
now | 2.55 | 6.6 | 4.05 |
network.buses_t.marginal_price
Bus | my bus |
---|---|
snapshot | |
now | 60.0 |