Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Transition from stores to storage units for LTES, introducing energy-to-power ratio #1444

Open
wants to merge 12 commits into
base: master
Choose a base branch
from
Open
2 changes: 2 additions & 0 deletions config/config.default.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -1215,6 +1215,8 @@ plotting:
residential urban decentral water tanks discharger: '#baac9e'
services rural water tanks discharger: '#bbc2b8'
services urban decentral water tanks discharger: '#bdd8d3'
water pits: '#cc826a'
cpschau marked this conversation as resolved.
Show resolved Hide resolved
urban central hot water pits: '#d96f4c'
# heat demand
Heat load: '#cc1f1f'
heat: '#cc1f1f'
Expand Down
2 changes: 2 additions & 0 deletions doc/release_notes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ Release Notes
Upcoming Release
================

* Added PTES and transitioned LTES stores to storage units to implement an energy-to-power ratio in ``prepare_sector_network``.

* Feature: Introduce geothermal district heating (direct utilisation and heat pumps). Potentials are based on `Manz et al. 2024: Spatial analysis of renewable and excess heat potentials for climate-neutral district heating in Europe <https://www.sciencedirect.com/science/article/pii/S0960148124001769>`.

* Feature: Allow CHPs to use different fuel sources such as gas, oil, coal, and methanol. Note that the cost assumptions are based on a gas CHP (except for solid biomass-fired CHP).
Expand Down
79 changes: 46 additions & 33 deletions scripts/prepare_sector_network.py
Original file line number Diff line number Diff line change
Expand Up @@ -2261,54 +2261,67 @@ def add_heat(
if options["tes"]:
n.add("Carrier", f"{heat_system} water tanks")

n.add(
"Bus",
nodes + f" {heat_system} water tanks",
location=nodes,
carrier=f"{heat_system} water tanks",
unit="MWh_th",
)

n.add(
"Link",
nodes + f" {heat_system} water tanks charger",
bus0=nodes + f" {heat_system} heat",
bus1=nodes + f" {heat_system} water tanks",
efficiency=costs.at["water tank charger", "efficiency"],
carrier=f"{heat_system} water tanks charger",
p_nom_extendable=True,
)

n.add(
"Link",
nodes + f" {heat_system} water tanks discharger",
bus0=nodes + f" {heat_system} water tanks",
bus1=nodes + f" {heat_system} heat",
carrier=f"{heat_system} water tanks discharger",
efficiency=costs.at["water tank discharger", "efficiency"],
p_nom_extendable=True,
)

tes_time_constant_days = options["tes_tau"][
heat_system.central_or_decentral
]

n.add(
"Store",
"StorageUnit",
nodes + f" {heat_system} water tanks",
bus=nodes + f" {heat_system} water tanks",
e_cyclic=True,
e_nom_extendable=True,
bus=nodes + f" {heat_system} heat",
carrier=f"{heat_system} water tanks",
efficiency_store=costs.at[
heat_system.central_or_decentral + " water tank charger",
"efficiency",
],
max_hours=costs.at[
amos-schledorn marked this conversation as resolved.
Show resolved Hide resolved
heat_system.central_or_decentral + " water tank storage",
"energy to power ratio",
],
efficiency_dispatch=costs.at[
heat_system.central_or_decentral + " water tank discharger",
"efficiency",
],
p_nom_extendable=True,
standing_loss=1 - np.exp(-1 / 24 / tes_time_constant_days),
capital_cost=costs.at[
amos-schledorn marked this conversation as resolved.
Show resolved Hide resolved
heat_system.central_or_decentral + " water tank storage", "fixed"
]
* costs.at[
heat_system.central_or_decentral + " water tank storage",
"energy to power ratio",
],
lifetime=costs.at[
heat_system.central_or_decentral + " water tank storage", "lifetime"
],
cyclic_state_of_charge=True,
)

if heat_system == HeatSystem.URBAN_CENTRAL:
n.add("Carrier", f"{heat_system} water pits")

n.add(
"StorageUnit",
nodes + f" {heat_system} water pits",
bus=nodes + f" {heat_system} heat",
carrier=f"{heat_system} water pits",
efficiency_store=costs.at[
"central water pit charger", "efficiency"
],
max_hours=costs.at[
"central water pit storage", "energy to power ratio"
],
efficiency_dispatch=costs.at[
"central water pit discharger", "efficiency"
],
p_nom_extendable=True,
standing_loss=1 - np.exp(-1 / 24 / tes_time_constant_days),
capital_cost=costs.at["central water pit storage", "fixed"]
* costs.at["central water pit storage", "energy to power ratio"],
lifetime=costs.at["central water pit storage", "lifetime"],
cyclic_state_of_charge=True,
)

if options["resistive_heaters"]:
key = f"{heat_system.central_or_decentral} resistive heater"

Expand Down Expand Up @@ -4250,7 +4263,7 @@ def define_clustering(attributes, aggregate_dict):
return agg

logger.info("Cluster residential and service heat buses.")
components = ["Bus", "Carrier", "Generator", "Link", "Load", "Store"]
components = ["Bus", "Carrier", "Generator", "Link", "Load", "Store", "StorageUnit"]

for c in n.iterate_components(components):
df = c.df
Expand Down
Loading