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
[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.2,0.7,0.4],
capital_cost=500)
network.add("Load",
"heat demand",
bus="0 heat",
p_set=20.)
#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.,3.2,3.],
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)
[3]:
network.lopf(network.snapshots)
INFO:pypsa.opf:Performed preliminary steps
INFO:pypsa.opf:Building pyomo model using `kirchhoff` formulation
INFO:pypsa.opf:Solving model using glpk
WARNING:pyomo.solvers:Could not locate the 'glpsol' executable, which is required for solver 'glpk'
---------------------------------------------------------------------------
ApplicationError Traceback (most recent call last)
/tmp/ipykernel_677/416887474.py in <module>
----> 1 network.lopf(network.snapshots)
~/checkouts/readthedocs.org/user_builds/pypsa-docs-staging/envs/latest/lib/python3.7/site-packages/pypsa/components.py in lopf(self, snapshots, pyomo, solver_name, solver_options, solver_logfile, formulation, keep_files, extra_functionality, multi_investment_periods, **kwargs)
646
647 if pyomo:
--> 648 return network_lopf(self, **args)
649 else:
650 return network_lopf_lowmem(self, **args)
~/checkouts/readthedocs.org/user_builds/pypsa-docs-staging/envs/latest/lib/python3.7/site-packages/pypsa/opf.py in network_lopf(network, snapshots, solver_name, solver_io, skip_pre, extra_functionality, multi_investment_periods, solver_logfile, solver_options, keep_files, formulation, ptdf_tolerance, free_memory, extra_postprocessing)
1663 solver_logfile=solver_logfile, solver_options=solver_options,
1664 keep_files=keep_files, free_memory=free_memory,
-> 1665 extra_postprocessing=extra_postprocessing)
~/checkouts/readthedocs.org/user_builds/pypsa-docs-staging/envs/latest/lib/python3.7/site-packages/pypsa/opf.py in network_lopf_solve(network, snapshots, formulation, solver_options, solver_logfile, keep_files, free_memory, extra_postprocessing)
1563 network.results = network.opt.solve(*args, suffixes=["dual"], keepfiles=keep_files, logfile=solver_logfile, options=solver_options)
1564 else:
-> 1565 network.results = network.opt.solve(*args, suffixes=["dual"], keepfiles=keep_files, logfile=solver_logfile, options=solver_options)
1566
1567 if logger.isEnabledFor(logging.INFO):
~/checkouts/readthedocs.org/user_builds/pypsa-docs-staging/envs/latest/lib/python3.7/site-packages/pyomo/opt/base/solvers.py in solve(self, *args, **kwds)
510 """ Solve the problem """
511
--> 512 self.available(exception_flag=True)
513 #
514 # If the inputs are models, then validate that they have been
~/checkouts/readthedocs.org/user_builds/pypsa-docs-staging/envs/latest/lib/python3.7/site-packages/pyomo/opt/solver/shellcmd.py in available(self, exception_flag)
123 if exception_flag:
124 msg = "No executable found for solver '%s'"
--> 125 raise ApplicationError(msg % self.name)
126 return False
127 return True
ApplicationError: No executable found for solver 'glpk'
[4]:
pd.DataFrame({attr: network.stores_t[attr]["water tank"] for attr in ["p","e"]})
---------------------------------------------------------------------------
KeyError Traceback (most recent call last)
~/checkouts/readthedocs.org/user_builds/pypsa-docs-staging/envs/latest/lib/python3.7/site-packages/pandas/core/indexes/base.py in get_loc(self, key, method, tolerance)
3360 try:
-> 3361 return self._engine.get_loc(casted_key)
3362 except KeyError as err:
~/checkouts/readthedocs.org/user_builds/pypsa-docs-staging/envs/latest/lib/python3.7/site-packages/pandas/_libs/index.pyx in pandas._libs.index.IndexEngine.get_loc()
~/checkouts/readthedocs.org/user_builds/pypsa-docs-staging/envs/latest/lib/python3.7/site-packages/pandas/_libs/index.pyx in pandas._libs.index.IndexEngine.get_loc()
pandas/_libs/hashtable_class_helper.pxi in pandas._libs.hashtable.PyObjectHashTable.get_item()
pandas/_libs/hashtable_class_helper.pxi in pandas._libs.hashtable.PyObjectHashTable.get_item()
KeyError: 'water tank'
The above exception was the direct cause of the following exception:
KeyError Traceback (most recent call last)
/tmp/ipykernel_677/1237326891.py in <module>
----> 1 pd.DataFrame({attr: network.stores_t[attr]["water tank"] for attr in ["p","e"]})
/tmp/ipykernel_677/1237326891.py in <dictcomp>(.0)
----> 1 pd.DataFrame({attr: network.stores_t[attr]["water tank"] for attr in ["p","e"]})
~/checkouts/readthedocs.org/user_builds/pypsa-docs-staging/envs/latest/lib/python3.7/site-packages/pandas/core/frame.py in __getitem__(self, key)
3456 if self.columns.nlevels > 1:
3457 return self._getitem_multilevel(key)
-> 3458 indexer = self.columns.get_loc(key)
3459 if is_integer(indexer):
3460 indexer = [indexer]
~/checkouts/readthedocs.org/user_builds/pypsa-docs-staging/envs/latest/lib/python3.7/site-packages/pandas/core/indexes/base.py in get_loc(self, key, method, tolerance)
3361 return self._engine.get_loc(casted_key)
3362 except KeyError as err:
-> 3363 raise KeyError(key) from err
3364
3365 if is_scalar(key) and isna(key) and not self.hasnans:
KeyError: 'water tank'
[5]:
pd.DataFrame({attr: network.links_t[attr]["heat pump"] for attr in ["p0","p1"]})
---------------------------------------------------------------------------
KeyError Traceback (most recent call last)
~/checkouts/readthedocs.org/user_builds/pypsa-docs-staging/envs/latest/lib/python3.7/site-packages/pandas/core/indexes/base.py in get_loc(self, key, method, tolerance)
3360 try:
-> 3361 return self._engine.get_loc(casted_key)
3362 except KeyError as err:
~/checkouts/readthedocs.org/user_builds/pypsa-docs-staging/envs/latest/lib/python3.7/site-packages/pandas/_libs/index.pyx in pandas._libs.index.IndexEngine.get_loc()
~/checkouts/readthedocs.org/user_builds/pypsa-docs-staging/envs/latest/lib/python3.7/site-packages/pandas/_libs/index.pyx in pandas._libs.index.IndexEngine.get_loc()
pandas/_libs/hashtable_class_helper.pxi in pandas._libs.hashtable.PyObjectHashTable.get_item()
pandas/_libs/hashtable_class_helper.pxi in pandas._libs.hashtable.PyObjectHashTable.get_item()
KeyError: 'heat pump'
The above exception was the direct cause of the following exception:
KeyError Traceback (most recent call last)
/tmp/ipykernel_677/4244564901.py in <module>
----> 1 pd.DataFrame({attr: network.links_t[attr]["heat pump"] for attr in ["p0","p1"]})
/tmp/ipykernel_677/4244564901.py in <dictcomp>(.0)
----> 1 pd.DataFrame({attr: network.links_t[attr]["heat pump"] for attr in ["p0","p1"]})
~/checkouts/readthedocs.org/user_builds/pypsa-docs-staging/envs/latest/lib/python3.7/site-packages/pandas/core/frame.py in __getitem__(self, key)
3456 if self.columns.nlevels > 1:
3457 return self._getitem_multilevel(key)
-> 3458 indexer = self.columns.get_loc(key)
3459 if is_integer(indexer):
3460 indexer = [indexer]
~/checkouts/readthedocs.org/user_builds/pypsa-docs-staging/envs/latest/lib/python3.7/site-packages/pandas/core/indexes/base.py in get_loc(self, key, method, tolerance)
3361 return self._engine.get_loc(casted_key)
3362 except KeyError as err:
-> 3363 raise KeyError(key) from err
3364
3365 if is_scalar(key) and isna(key) and not self.hasnans:
KeyError: 'heat pump'
[6]:
network.stores.loc[["water tank"]].T
[6]:
| water tank | |
|---|---|
| attribute | |
| bus | 0 heat |
| type | |
| carrier | heat |
| e_nom | 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 |
| capital_cost | 0.0 |
| standing_loss | 0.01 |
| build_year | 0 |
| lifetime | inf |
| e_nom_opt | 0.0 |
[7]:
network.generators.loc[["wind turbine"]].T
[7]:
| wind turbine | |
|---|---|
| attribute | |
| bus | 0 |
| control | Slack |
| type | |
| p_nom | 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 |
| build_year | 0 |
| lifetime | inf |
| capital_cost | 500.0 |
| efficiency | 1.0 |
| committable | False |
| start_up_cost | 0.0 |
| shut_down_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 |
| p_nom_opt | 0.0 |