Wind Turbine combined with Heat Pump and Water Tank

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_4705/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-ienkqyxj.lp --output /tmp/linopy-solve-43t9nti8.sol
Reading problem data from '/tmp/linopy-problem-ienkqyxj.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-43t9nti8.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