Note
You can download this example as a Jupyter notebook or start it in interactive mode.
Wind Turbine combined with Heat Pump and Water Tank#
In this example the heat demand is supplied by a wind turbine in combination with a heat pump and a water tank that stores hot water with a standing loss.
[1]:
import pypsa
import pandas as pd
from pyomo.environ import Constraint
ERROR 1: PROJ: proj_create_from_database: Open of /home/docs/checkouts/readthedocs.org/user_builds/pypsa/conda/latest/share/proj failed
[2]:
network = pypsa.Network()
network.set_snapshots(pd.date_range("2016-01-01 00:00", "2016-01-01 03:00", freq="H"))
network.add("Bus", "0", carrier="AC")
network.add("Bus", "0 heat", carrier="heat")
network.add("Carrier", "wind")
network.add("Carrier", "heat")
network.add(
"Generator",
"wind turbine",
bus="0",
carrier="wind",
p_nom_extendable=True,
p_max_pu=[0.0, 0.2, 0.7, 0.4],
capital_cost=500,
)
network.add("Load", "heat demand", bus="0 heat", p_set=20.0)
# NB: Heat pump has changing efficiency (properly the Coefficient of Performance, COP)
# due to changing ambient temperature
network.add(
"Link",
"heat pump",
bus0="0",
bus1="0 heat",
efficiency=[2.5, 3.0, 3.2, 3.0],
capital_cost=1000,
p_nom_extendable=True,
)
network.add(
"Store",
"water tank",
bus="0 heat",
e_cyclic=True,
e_nom_extendable=True,
standing_loss=0.01,
)
/tmp/ipykernel_4709/743167227.py:2: FutureWarning: 'H' is deprecated and will be removed in a future version, please use 'h' instead.
network.set_snapshots(pd.date_range("2016-01-01 00:00", "2016-01-01 03:00", freq="H"))
[3]:
network.optimize()
INFO:linopy.model: Solve problem using Glpk solver
INFO:linopy.io: Writing time: 0.06s
INFO:linopy.solvers:GLPSOL--GLPK LP/MIP Solver 5.0
Parameter(s) specified in the command line:
--lp /tmp/linopy-problem-mncuhp82.lp --output /tmp/linopy-solve-od2266vv.sol
Reading problem data from '/tmp/linopy-problem-mncuhp82.lp'...
39 rows, 19 columns, 66 non-zeros
206 lines were read
GLPK Simplex Optimizer 5.0
39 rows, 19 columns, 66 non-zeros
Preprocessing...
20 rows, 16 columns, 43 non-zeros
Scaling...
A: min|aij| = 2.000e-01 max|aij| = 3.200e+00 ratio = 1.600e+01
Problem data seem to be well scaled
Constructing initial basis...
Size of triangular part is 19
0: obj = 0.000000000e+00 inf = 1.980e+02 (4)
9: obj = 2.549967375e+04 inf = 0.000e+00 (0)
* 11: obj = 2.350058582e+04 inf = 0.000e+00 (0)
OPTIMAL LP SOLUTION FOUND
Time used: 0.0 secs
Memory used: 0.1 Mb (56692 bytes)
Writing basic solution to '/tmp/linopy-solve-od2266vv.sol'...
INFO:linopy.constants: Optimization successful:
Status: ok
Termination condition: optimal
Solution: 19 primals, 39 duals
Objective: 2.35e+04
Solver model: not available
Solver message: optimal
/home/docs/checkouts/readthedocs.org/user_builds/pypsa/conda/latest/lib/python3.11/site-packages/pypsa/optimization/optimize.py:357: FutureWarning: A value is trying to be set on a copy of a DataFrame or Series through chained assignment using an inplace method.
The behavior will change in pandas 3.0. This inplace method will never work because the intermediate object on which we are setting values always behaves as a copy.
For example, when doing 'df[col].method(value, inplace=True)', try using 'df.method({col: value}, inplace=True)' or df[col] = df[col].method(value) instead, to perform the operation inplace on the original object.
n.df(c)[attr + "_opt"].update(df)
INFO:pypsa.optimization.optimize:The shadow-prices of the constraints Generator-ext-p-lower, Generator-ext-p-upper, Link-ext-p-lower, Link-ext-p-upper, Store-ext-e-lower, Store-ext-e-upper, Store-energy_balance were not assigned to the network.
[3]:
('ok', 'optimal')
[4]:
pd.DataFrame({attr: network.stores_t[attr]["water tank"] for attr in ["p", "e"]})
[4]:
p | e | |
---|---|---|
snapshot | ||
2016-01-01 00:00:00 | 20.00000 | 4.37671 |
2016-01-01 01:00:00 | 4.33294 | 0.00000 |
2016-01-01 02:00:00 | -13.42310 | 13.42310 |
2016-01-01 03:00:00 | -11.33410 | 24.62290 |
[5]:
pd.DataFrame({attr: network.links_t[attr]["heat pump"] for attr in ["p0", "p1"]})
[5]:
p0 | p1 | |
---|---|---|
snapshot | ||
2016-01-01 00:00:00 | 0.00000 | -0.00000 |
2016-01-01 01:00:00 | 5.22235 | -15.66705 |
2016-01-01 02:00:00 | 10.44470 | -33.42304 |
2016-01-01 03:00:00 | 10.44470 | -31.33410 |
[6]:
network.stores.loc[["water tank"]].T
[6]:
Store | water tank |
---|---|
attribute | |
bus | 0 heat |
type | |
carrier | heat |
e_nom | 0.0 |
e_nom_mod | 0.0 |
e_nom_extendable | True |
e_nom_min | 0.0 |
e_nom_max | inf |
e_min_pu | 0.0 |
e_max_pu | 1.0 |
e_initial | 0.0 |
e_initial_per_period | False |
e_cyclic | True |
e_cyclic_per_period | True |
p_set | 0.0 |
q_set | 0.0 |
sign | 1.0 |
marginal_cost | 0.0 |
marginal_cost_quadratic | 0.0 |
capital_cost | 0.0 |
standing_loss | 0.01 |
build_year | 0 |
lifetime | inf |
e_nom_opt | 24.6229 |
[7]:
network.generators.loc[["wind turbine"]].T
[7]:
Generator | wind turbine |
---|---|
attribute | |
bus | 0 |
control | PQ |
type | |
p_nom | 0.0 |
p_nom_mod | 0.0 |
p_nom_extendable | True |
p_nom_min | 0.0 |
p_nom_max | inf |
p_min_pu | 0.0 |
p_max_pu | 1.0 |
p_set | 0.0 |
q_set | 0.0 |
sign | 1.0 |
carrier | wind |
marginal_cost | 0.0 |
marginal_cost_quadratic | 0.0 |
build_year | 0 |
lifetime | inf |
capital_cost | 500.0 |
efficiency | 1.0 |
committable | False |
start_up_cost | 0.0 |
shut_down_cost | 0.0 |
stand_by_cost | 0.0 |
min_up_time | 0 |
min_down_time | 0 |
up_time_before | 1 |
down_time_before | 0 |
ramp_limit_up | NaN |
ramp_limit_down | NaN |
ramp_limit_start_up | 1.0 |
ramp_limit_shut_down | 1.0 |
weight | 1.0 |
p_nom_opt | 26.1118 |