From 193d972a32c597717a69e78508ae3d7a590075d5 Mon Sep 17 00:00:00 2001 From: LukasFrankenQ Date: Fri, 10 Nov 2023 23:18:45 +0000 Subject: [PATCH] added simple version of hot water tank flex --- config/config.yaml | 4 +++- scripts/prepare_network.py | 34 +++++++++++++++++++++++++++++++--- 2 files changed, 34 insertions(+), 4 deletions(-) diff --git a/config/config.yaml b/config/config.yaml index c53c40fc..b2cfe00f 100644 --- a/config/config.yaml +++ b/config/config.yaml @@ -39,7 +39,7 @@ scenario: # int: # intelligent EV charging; centrally optimal charging of EV fleet # v2g: # switches on vehicle to grid # cosy: # heat flex cosy-like: Allows shifting of morning and afternoon peaks by 3 hours - # store:# simulates the presence of a watertank for increased heat flexibility + # tank: # simulates the presence of a watertank for increased heat flexibility opts: # only relevant for PyPSA-Eur - 'morocco' # adds Xlinks project; interconnection to Morocco with renewable generation @@ -82,6 +82,8 @@ flexibility: end: 19 hourly_heat_loss: 0. # as share between 0 and 1 battery_ignore_threshold: 1 # GW (ignore battery with less than this GB capacity) + water_tank_standing_loss: 0.02 # see Small scale hot water tank https://ens.dk/en/our-services/projections-and-models/technology-data/technology-data-energy-storage + water_tank_max_hours: 12 # Decision based on Lizana et al. 2023 Fig 12 b1 # EV flexibility parameters go_tariff_share: false # share of people on go tariff (if false taken from FES data) diff --git a/scripts/prepare_network.py b/scripts/prepare_network.py index 150711c3..7e7abddc 100755 --- a/scripts/prepare_network.py +++ b/scripts/prepare_network.py @@ -591,6 +591,7 @@ def add_heat_pump_load( intraday_profile_file, scenario, year, + flexopts, ): year = int(year) @@ -700,13 +701,13 @@ def add_heat_pump_load( [0., 1.] ) - heatflex = "heat" in snakemake.wildcards["flexopts"].split("-") + heatflex = list(set(flexopts).intersection({"cosy", "tank"}))[0] or False # add infrastructure for flexibility # grid -> house -> link to thermal inertia -> thermal inertia store -> link to house - if share_smart_tariff > 0. and heatflex: + if share_smart_tariff > 0. and heatflex == 'cosy': - logger.info("Adding heat flexibility") + logger.info("Adding heat flexibility according to cosy tariff.") mor_start = snakemake.config["flexibility"]["heat_flex_windows"]["morning"]["start"] mor_end = snakemake.config["flexibility"]["heat_flex_windows"]["morning"]["end"] @@ -794,6 +795,32 @@ def add_heat_pump_load( p_max_pu=p_max_pu, p_min_pu=p_min_pu, ) + + elif share_smart_tariff > 0. and heatflex == 'tank': + + logger.info("Adding heat flexibility adding a hot water tank.") + + standing_loss = snakemake.config["flexibility"]["water_tank_standing_loss"] + max_hours = snakemake.config["flexibility"]["water_tank_max_hours"] + + p_nom = ( + future_heat_demand + .rolling(max_hours) + .mean() + .max() + .set_axis(nodes + ' hot water tanks') + ) + + n.madd( + "StorageUnit", + nodes + " hot water tanks", + bus=heat_demand_spatial.nodes, + carrier="hot water tank", + p_nom=p_nom, + max_hours=max_hours, + e_cyclic=True, + standing_loss=standing_loss, + ) def add_bev(n, transport_config, flex_config, flexopts): @@ -1816,6 +1843,7 @@ def add_hydrogen_demand(n, scenario, year, costs): snakemake.input["heat_profile"], snakemake.wildcards.fes, snakemake.wildcards.year, + flexopts, ) logger.info("Adding BEV load.")