From f096592b7f61ea807b650b89e3f8eca3dec8957c Mon Sep 17 00:00:00 2001 From: AmosSchledorn Date: Fri, 26 Jul 2024 19:45:45 +0200 Subject: [PATCH 01/17] add option to make central heating forward/return temperatures country-specific --- config/config.default.yaml | 14 ++++++-- scripts/_helpers.py | 4 +++ scripts/build_cop_profiles/run.py | 60 +++++++++++++++++++++++++++---- 3 files changed, 70 insertions(+), 8 deletions(-) diff --git a/config/config.default.yaml b/config/config.default.yaml index a606cd25..16825d59 100644 --- a/config/config.default.yaml +++ b/config/config.default.yaml @@ -409,8 +409,18 @@ sector: 2050: 1.0 district_heating_loss: 0.15 # check these numbers! - forward_temperature: 90 #C - return_temperature: 50 #C + forward_temperature: + generic: 90 + DK: 70 + SE: 70 + NO: 70 + FI: 70 + return_temperature: + generic: 50 + DK: 40 + SE: 40 + NO: 40 + FI: 40 heat_source_cooling: 6 #K heat_pump_cop_approximation: refrigerant: ammonia diff --git a/scripts/_helpers.py b/scripts/_helpers.py index a3b77c1c..040ba125 100644 --- a/scripts/_helpers.py +++ b/scripts/_helpers.py @@ -785,3 +785,7 @@ def get_snapshots(snapshots, drop_leap_day=False, freq="h", **kwargs): time = time[~((time.month == 2) & (time.day == 29))] return time + + +def get_country_from_node_name(node_name: str) -> str: + return node_name[:2] \ No newline at end of file diff --git a/scripts/build_cop_profiles/run.py b/scripts/build_cop_profiles/run.py index 12d012bb..0c40a94d 100644 --- a/scripts/build_cop_profiles/run.py +++ b/scripts/build_cop_profiles/run.py @@ -5,10 +5,43 @@ import numpy as np import xarray as xr -from _helpers import set_scenario_config +from _helpers import set_scenario_config, get_country_from_node_name from CentralHeatingCopApproximator import CentralHeatingCopApproximator from DecentralHeatingCopApproximator import DecentralHeatingCopApproximator + +def map_temperature_dict_to_onshore_regions( + temperature_dict: dict, onshore_regions: xr.DataArray +) -> xr.DataArray: + """ + Map dictionary of temperatures to onshore regions. + + Parameters: + ---------- + temperature_dict : dictionary + Dictionary with temperatures as values and country keys as keys. One key must be named "generic" + onshore_regions : xr.DataArray + Names of onshore regions + + Returns: + ------- + xr.DataArray + The dictionary values mapped to onshore regions with onshore regions as coordinates. + """ + return xr.DataArray( + [ + ( + temperature_dict[get_country_from_node_name(node_name)] + if get_country_from_node_name(node_name) in temperature_dict.keys() + else temperature_dict["generic"] + ) + for node_name in onshore_regions["name"].values + ], + dims=["name"], + coords={"name": onshore_regions["name"]}, + ) + + if __name__ == "__main__": if "snakemake" not in globals(): from _helpers import mock_snakemake @@ -23,12 +56,12 @@ if __name__ == "__main__": for source_type in ["air", "soil"]: # source inlet temperature (air/soil) is based on weather data - source_inlet_temperature_celsius = xr.open_dataarray( + source_inlet_temperature_celsius: xr.DataArray = xr.open_dataarray( snakemake.input[f"temp_{source_type}_total"] ) # Approximate COP for decentral (individual) heating - cop_individual_heating = DecentralHeatingCopApproximator( + cop_individual_heating: xr.DataArray = DecentralHeatingCopApproximator( forward_temperature_celsius=snakemake.params.heat_pump_sink_T_decentral_heating, source_inlet_temperature_celsius=source_inlet_temperature_celsius, source_type=source_type, @@ -37,10 +70,25 @@ if __name__ == "__main__": snakemake.output[f"cop_{source_type}_decentral_heating"] ) + # map forward and return temperatures specified on country-level to onshore regions + onshore_regions: xr.DataArray = source_inlet_temperature_celsius["name"] + forward_temperature_central_heating: xr.DataArray = ( + map_temperature_dict_to_onshore_regions( + temperature_dict=snakemake.params.forward_temperature_central_heating, + onshore_regions=onshore_regions, + ) + ) + return_temperature_central_heating: xr.DataArray = ( + map_temperature_dict_to_onshore_regions( + temperature_dict=snakemake.params.return_temperature_central_heating, + onshore_regions=onshore_regions, + ) + ) + # Approximate COP for central (district) heating - cop_central_heating = CentralHeatingCopApproximator( - forward_temperature_celsius=snakemake.params.forward_temperature_central_heating, - return_temperature_celsius=snakemake.params.return_temperature_central_heating, + cop_central_heating: xr.DataArray = CentralHeatingCopApproximator( + forward_temperature_celsius=forward_temperature_central_heating, + return_temperature_celsius=return_temperature_central_heating, source_inlet_temperature_celsius=source_inlet_temperature_celsius, source_outlet_temperature_celsius=source_inlet_temperature_celsius - snakemake.params.heat_source_cooling_central_heating, From 08c30d8b2ecd2be73168a87e61fdd32f07405d24 Mon Sep 17 00:00:00 2001 From: AmosSchledorn Date: Fri, 26 Jul 2024 20:08:06 +0200 Subject: [PATCH 02/17] ensure correct dimensions in forward/return temperature arayx and change naming from "generic" to "default" --- config/config.default.yaml | 5 ++--- scripts/build_cop_profiles/run.py | 26 ++++++++++++++++---------- 2 files changed, 18 insertions(+), 13 deletions(-) diff --git a/config/config.default.yaml b/config/config.default.yaml index 16825d59..527f68c4 100644 --- a/config/config.default.yaml +++ b/config/config.default.yaml @@ -408,15 +408,14 @@ sector: 2045: 0.8 2050: 1.0 district_heating_loss: 0.15 - # check these numbers! forward_temperature: - generic: 90 + default: 90 DK: 70 SE: 70 NO: 70 FI: 70 return_temperature: - generic: 50 + default: 50 DK: 40 SE: 40 NO: 40 diff --git a/scripts/build_cop_profiles/run.py b/scripts/build_cop_profiles/run.py index 0c40a94d..d2976b6e 100644 --- a/scripts/build_cop_profiles/run.py +++ b/scripts/build_cop_profiles/run.py @@ -11,7 +11,7 @@ from DecentralHeatingCopApproximator import DecentralHeatingCopApproximator def map_temperature_dict_to_onshore_regions( - temperature_dict: dict, onshore_regions: xr.DataArray + temperature_dict: dict, onshore_regions: xr.DataArray, snapshots: xr.DataArray ) -> xr.DataArray: """ Map dictionary of temperatures to onshore regions. @@ -19,7 +19,7 @@ def map_temperature_dict_to_onshore_regions( Parameters: ---------- temperature_dict : dictionary - Dictionary with temperatures as values and country keys as keys. One key must be named "generic" + Dictionary with temperatures as values and country keys as keys. One key must be named "default" onshore_regions : xr.DataArray Names of onshore regions @@ -30,15 +30,19 @@ def map_temperature_dict_to_onshore_regions( """ return xr.DataArray( [ - ( - temperature_dict[get_country_from_node_name(node_name)] - if get_country_from_node_name(node_name) in temperature_dict.keys() - else temperature_dict["generic"] - ) - for node_name in onshore_regions["name"].values + [ + ( + temperature_dict[get_country_from_node_name(node_name)] + if get_country_from_node_name(node_name) in temperature_dict.keys() + else temperature_dict["default"] + ) + for node_name in onshore_regions["name"].values + ] + # pass both nodes and snapshots as dimensions to preserve correct data structure + for _ in snapshots["time"].values ], - dims=["name"], - coords={"name": onshore_regions["name"]}, + dims=["time", "name"], + coords={"time": snapshots["time"], "name": onshore_regions["name"]}, ) @@ -76,12 +80,14 @@ if __name__ == "__main__": map_temperature_dict_to_onshore_regions( temperature_dict=snakemake.params.forward_temperature_central_heating, onshore_regions=onshore_regions, + snapshots=source_inlet_temperature_celsius["time"] ) ) return_temperature_central_heating: xr.DataArray = ( map_temperature_dict_to_onshore_regions( temperature_dict=snakemake.params.return_temperature_central_heating, onshore_regions=onshore_regions, + snapshots=source_inlet_temperature_celsius["time"] ) ) From 9d485a2185ce4a39a27325e070573b2859c1647e Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Fri, 26 Jul 2024 18:12:18 +0000 Subject: [PATCH 03/17] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- config/config.default.yaml | 2 +- scripts/_helpers.py | 2 +- scripts/build_cop_profiles/run.py | 6 +++--- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/config/config.default.yaml b/config/config.default.yaml index 527f68c4..92a24534 100644 --- a/config/config.default.yaml +++ b/config/config.default.yaml @@ -414,7 +414,7 @@ sector: SE: 70 NO: 70 FI: 70 - return_temperature: + return_temperature: default: 50 DK: 40 SE: 40 diff --git a/scripts/_helpers.py b/scripts/_helpers.py index 040ba125..1c890ea5 100644 --- a/scripts/_helpers.py +++ b/scripts/_helpers.py @@ -788,4 +788,4 @@ def get_snapshots(snapshots, drop_leap_day=False, freq="h", **kwargs): def get_country_from_node_name(node_name: str) -> str: - return node_name[:2] \ No newline at end of file + return node_name[:2] diff --git a/scripts/build_cop_profiles/run.py b/scripts/build_cop_profiles/run.py index d2976b6e..ef6253dd 100644 --- a/scripts/build_cop_profiles/run.py +++ b/scripts/build_cop_profiles/run.py @@ -5,7 +5,7 @@ import numpy as np import xarray as xr -from _helpers import set_scenario_config, get_country_from_node_name +from _helpers import get_country_from_node_name, set_scenario_config from CentralHeatingCopApproximator import CentralHeatingCopApproximator from DecentralHeatingCopApproximator import DecentralHeatingCopApproximator @@ -80,14 +80,14 @@ if __name__ == "__main__": map_temperature_dict_to_onshore_regions( temperature_dict=snakemake.params.forward_temperature_central_heating, onshore_regions=onshore_regions, - snapshots=source_inlet_temperature_celsius["time"] + snapshots=source_inlet_temperature_celsius["time"], ) ) return_temperature_central_heating: xr.DataArray = ( map_temperature_dict_to_onshore_regions( temperature_dict=snakemake.params.return_temperature_central_heating, onshore_regions=onshore_regions, - snapshots=source_inlet_temperature_celsius["time"] + snapshots=source_inlet_temperature_celsius["time"], ) ) From 80603fda6eef226ca48de1b037150bf9faa33495 Mon Sep 17 00:00:00 2001 From: AmosSchledorn Date: Wed, 7 Aug 2024 13:33:59 +0200 Subject: [PATCH 04/17] update config and script --- config/config.default.yaml | 15 +++++---------- rules/build_sector.smk | 2 ++ scripts/build_cop_profiles/run.py | 30 +++++++++++++++++------------- 3 files changed, 24 insertions(+), 23 deletions(-) diff --git a/config/config.default.yaml b/config/config.default.yaml index f7ee6716..12610771 100644 --- a/config/config.default.yaml +++ b/config/config.default.yaml @@ -410,18 +410,13 @@ sector: 2045: 0.8 2050: 1.0 district_heating_loss: 0.15 + # check these numbers! forward_temperature: - default: 90 - DK: 70 - SE: 70 - NO: 70 - FI: 70 + DE: 90 #C + DK: 60 #C return_temperature: - default: 50 - DK: 40 - SE: 40 - NO: 40 - FI: 40 + DE: 50 #C + DK: 40 #C heat_source_cooling: 6 #K heat_pump_cop_approximation: refrigerant: ammonia diff --git a/rules/build_sector.smk b/rules/build_sector.smk index 5916aa02..c7796bab 100644 --- a/rules/build_sector.smk +++ b/rules/build_sector.smk @@ -242,9 +242,11 @@ rule build_cop_profiles: "sector", "district_heating", "heat_pump_cop_approximation" ), heat_pump_sources=config_provider("sector", "heat_pump_sources"), + snapshots=config_provider("snapshots"), input: temp_soil_total=resources("temp_soil_total_elec_s{simpl}_{clusters}.nc"), temp_air_total=resources("temp_air_total_elec_s{simpl}_{clusters}.nc"), + regions_onshore=resources("regions_onshore_elec_s{simpl}_{clusters}.geojson"), output: cop_profiles=resources("cop_profiles_elec_s{simpl}_{clusters}.nc"), resources: diff --git a/scripts/build_cop_profiles/run.py b/scripts/build_cop_profiles/run.py index 44bca6eb..69e2b519 100644 --- a/scripts/build_cop_profiles/run.py +++ b/scripts/build_cop_profiles/run.py @@ -8,6 +8,7 @@ import sys import numpy as np import pandas as pd import xarray as xr +import geopandas as gpd from _helpers import get_country_from_node_name, set_scenario_config from CentralHeatingCopApproximator import CentralHeatingCopApproximator from DecentralHeatingCopApproximator import DecentralHeatingCopApproximator @@ -17,8 +18,8 @@ from scripts.definitions.heat_system_type import HeatSystemType def map_temperature_dict_to_onshore_regions( supply_temperature_by_country: dict, - onshore_regions: xr.DataArray, - snapshots: xr.DataArray, + regions_onshore: pd.Index, + snapshots: pd.DatetimeIndex, ) -> xr.DataArray: """ Map dictionary of temperatures to onshore regions. @@ -27,8 +28,10 @@ def map_temperature_dict_to_onshore_regions( ---------- supply_temperature_by_country : dictionary Dictionary with temperatures as values and country keys as keys. One key must be named "default" - onshore_regions : xr.DataArray + regions_onshore : pd.Index Names of onshore regions + snapshots : pd.DatetimeIndex + Time stamps Returns: ------- @@ -44,13 +47,13 @@ def map_temperature_dict_to_onshore_regions( in supply_temperature_by_country.keys() else supply_temperature_by_country["default"] ) - for node_name in onshore_regions["name"].values + for node_name in regions_onshore.values ] # pass both nodes and snapshots as dimensions to preserve correct data structure - for _ in snapshots["time"].values + for _ in snapshots ], dims=["time", "name"], - coords={"time": snapshots["time"], "name": onshore_regions["name"]}, + coords={"time": snapshots, "name": regions_onshore}, ) @@ -108,19 +111,20 @@ if __name__ == "__main__": set_scenario_config(snakemake) # map forward and return temperatures specified on country-level to onshore regions - onshore_regions: xr.DataArray = source_inlet_temperature_celsius["name"] + regions_onshore = gpd.read_file(snakemake.input.regions_onshore)["name"] + snapshots = pd.date_range(freq="h", **snakemake.params.snapshots) forward_temperature_central_heating_by_node_and_time: xr.DataArray = ( map_temperature_dict_to_onshore_regions( - temperature_dict=snakemake.params.forward_temperature_central_heating, - onshore_regions=onshore_regions, - snapshots=source_inlet_temperature_celsius["time"], + supply_temperature_by_country=snakemake.params.forward_temperature_central_heating, + regions_onshore=regions_onshore, + snapshots=snapshots, ) ) return_temperature_central_heating_by_node_and_time: xr.DataArray = ( map_temperature_dict_to_onshore_regions( - temperature_dict=snakemake.params.return_temperature_central_heating, - onshore_regions=onshore_regions, - snapshots=source_inlet_temperature_celsius["time"], + supply_temperature_by_country=snakemake.params.return_temperature_central_heating, + regions_onshore=regions_onshore, + snapshots=snapshots, ) ) cop_all_system_types = [] From 7f76bf8e84a7b0a962cf1c4c8bb186d4ae0103da Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Wed, 7 Aug 2024 12:37:44 +0000 Subject: [PATCH 05/17] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- scripts/build_cop_profiles/run.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/build_cop_profiles/run.py b/scripts/build_cop_profiles/run.py index 69e2b519..d21b863d 100644 --- a/scripts/build_cop_profiles/run.py +++ b/scripts/build_cop_profiles/run.py @@ -5,10 +5,10 @@ import sys +import geopandas as gpd import numpy as np import pandas as pd import xarray as xr -import geopandas as gpd from _helpers import get_country_from_node_name, set_scenario_config from CentralHeatingCopApproximator import CentralHeatingCopApproximator from DecentralHeatingCopApproximator import DecentralHeatingCopApproximator From ab6415bdc33253796cf4c3b9831a2144bc012ffc Mon Sep 17 00:00:00 2001 From: AmosSchledorn Date: Wed, 7 Aug 2024 14:54:28 +0200 Subject: [PATCH 06/17] re-add default supply temperature --- config/config.default.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/config/config.default.yaml b/config/config.default.yaml index 12610771..aead3e3d 100644 --- a/config/config.default.yaml +++ b/config/config.default.yaml @@ -412,9 +412,11 @@ sector: district_heating_loss: 0.15 # check these numbers! forward_temperature: + Default: 90 DE: 90 #C DK: 60 #C return_temperature: + Default: 50 DE: 50 #C DK: 40 #C heat_source_cooling: 6 #K From 69c6ea0e1229a52364c04001222a39eccd3b52a0 Mon Sep 17 00:00:00 2001 From: AmosSchledorn Date: Wed, 7 Aug 2024 17:55:29 +0200 Subject: [PATCH 07/17] use relative imports of scripts.definitions where possible --- scripts/add_existing_baseyear.py | 6 +++--- scripts/prepare_sector_network.py | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/scripts/add_existing_baseyear.py b/scripts/add_existing_baseyear.py index f67c38d9..942b1398 100644 --- a/scripts/add_existing_baseyear.py +++ b/scripts/add_existing_baseyear.py @@ -24,9 +24,9 @@ from _helpers import ( from add_electricity import sanitize_carriers from prepare_sector_network import cluster_heat_buses, define_spatial, prepare_costs -from scripts.definitions.heat_sector import HeatSector -from scripts.definitions.heat_system import HeatSystem -from scripts.definitions.heat_system_type import HeatSystemType +from definitions.heat_sector import HeatSector +from definitions.heat_system import HeatSystem +from definitions.heat_system_type import HeatSystemType logger = logging.getLogger(__name__) cc = coco.CountryConverter() diff --git a/scripts/prepare_sector_network.py b/scripts/prepare_sector_network.py index 585b3f25..7c6f7c61 100644 --- a/scripts/prepare_sector_network.py +++ b/scripts/prepare_sector_network.py @@ -37,9 +37,9 @@ from pypsa.geo import haversine_pts from pypsa.io import import_components_from_dataframe from scipy.stats import beta -from scripts.definitions.heat_sector import HeatSector -from scripts.definitions.heat_system import HeatSystem -from scripts.definitions.heat_system_type import HeatSystemType +from definitions.heat_sector import HeatSector +from definitions.heat_system import HeatSystem +from definitions.heat_system_type import HeatSystemType spatial = SimpleNamespace() logger = logging.getLogger(__name__) From cfed67f794ea68f0200bde8023c9e1ae4defe9f0 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Thu, 8 Aug 2024 14:46:06 +0000 Subject: [PATCH 08/17] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- scripts/add_existing_baseyear.py | 3 +-- scripts/prepare_sector_network.py | 7 +++---- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/scripts/add_existing_baseyear.py b/scripts/add_existing_baseyear.py index 942b1398..212ae8af 100644 --- a/scripts/add_existing_baseyear.py +++ b/scripts/add_existing_baseyear.py @@ -22,11 +22,10 @@ from _helpers import ( update_config_from_wildcards, ) from add_electricity import sanitize_carriers -from prepare_sector_network import cluster_heat_buses, define_spatial, prepare_costs - from definitions.heat_sector import HeatSector from definitions.heat_system import HeatSystem from definitions.heat_system_type import HeatSystemType +from prepare_sector_network import cluster_heat_buses, define_spatial, prepare_costs logger = logging.getLogger(__name__) cc = coco.CountryConverter() diff --git a/scripts/prepare_sector_network.py b/scripts/prepare_sector_network.py index 7c6f7c61..191294b6 100644 --- a/scripts/prepare_sector_network.py +++ b/scripts/prepare_sector_network.py @@ -30,6 +30,9 @@ from build_energy_totals import ( build_eurostat_co2, ) from build_transport_demand import transport_degree_factor +from definitions.heat_sector import HeatSector +from definitions.heat_system import HeatSystem +from definitions.heat_system_type import HeatSystemType from networkx.algorithms import complement from networkx.algorithms.connectivity.edge_augmentation import k_edge_augmentation from prepare_network import maybe_adjust_costs_and_potentials @@ -37,10 +40,6 @@ from pypsa.geo import haversine_pts from pypsa.io import import_components_from_dataframe from scipy.stats import beta -from definitions.heat_sector import HeatSector -from definitions.heat_system import HeatSystem -from definitions.heat_system_type import HeatSystemType - spatial = SimpleNamespace() logger = logging.getLogger(__name__) From 130ee49dbd132c07713c165b4b43a91676fe47c5 Mon Sep 17 00:00:00 2001 From: AmosSchledorn Date: Fri, 26 Jul 2024 19:45:45 +0200 Subject: [PATCH 09/17] add option to make central heating forward/return temperatures country-specific --- scripts/build_cop_profiles/run.py | 37 +++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/scripts/build_cop_profiles/run.py b/scripts/build_cop_profiles/run.py index d21b863d..1b2c0a35 100644 --- a/scripts/build_cop_profiles/run.py +++ b/scripts/build_cop_profiles/run.py @@ -3,6 +3,43 @@ # # SPDX-License-Identifier: MIT +""" +Approximate heat pump coefficient-of-performance (COP) profiles for different heat sources and systems. + +For central heating, this is based on Jensen et al. (2018) (c.f. `CentralHeatingCopApproximator `_) and for decentral heating, the approximation is based on Staffell et al. (2012) (c.f. `DecentralHeatingCopApproximator `_). + +Relevant Settings +----------------- + +.. code:: yaml + sector: + heat_pump_sink_T_decentral_heating: + district_heating: + forward_temperature: + return_temperature: + heat_source_cooling: + heat_pump_cop_approximation: + refrigerant: + heat_exchanger_pinch_point_temperature_difference + isentropic_compressor_efficiency: + heat_loss: + heat_pump_sources: + urban central: + urban decentral: + rural: + snapshots: + +Inputs +------ +- `resources//regions_onshore.geojson`: Onshore regions +- `resources//temp_soil_total`: Ground temperature +- `resources//temp_air_total`: Air temperature + +Outputs +------- +- `resources//cop_profiles.nc`: Heat pump coefficient-of-performance (COP) profiles +""" + import sys import geopandas as gpd From a914366391b03e6c10a7056e955eccbf21d0520e Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Thu, 8 Aug 2024 15:13:31 +0000 Subject: [PATCH 10/17] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- scripts/build_cop_profiles/run.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/build_cop_profiles/run.py b/scripts/build_cop_profiles/run.py index 1b2c0a35..23229e98 100644 --- a/scripts/build_cop_profiles/run.py +++ b/scripts/build_cop_profiles/run.py @@ -2,9 +2,9 @@ # SPDX-FileCopyrightText: : 2020-2024 The PyPSA-Eur Authors # # SPDX-License-Identifier: MIT - """ -Approximate heat pump coefficient-of-performance (COP) profiles for different heat sources and systems. +Approximate heat pump coefficient-of-performance (COP) profiles for different +heat sources and systems. For central heating, this is based on Jensen et al. (2018) (c.f. `CentralHeatingCopApproximator `_) and for decentral heating, the approximation is based on Staffell et al. (2012) (c.f. `DecentralHeatingCopApproximator `_). From 023cc7529e4ff70d81c64f0027e2553d673f24ec Mon Sep 17 00:00:00 2001 From: AmosSchledorn Date: Thu, 8 Aug 2024 17:15:01 +0200 Subject: [PATCH 11/17] set lower supply temperatures for Scandinavia --- config/config.default.yaml | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/config/config.default.yaml b/config/config.default.yaml index aead3e3d..adb9ffa1 100644 --- a/config/config.default.yaml +++ b/config/config.default.yaml @@ -412,13 +412,17 @@ sector: district_heating_loss: 0.15 # check these numbers! forward_temperature: - Default: 90 - DE: 90 #C - DK: 60 #C + default: 90 + DK: 70 + SE: 70 + NO: 70 + FI: 70 return_temperature: - Default: 50 - DE: 50 #C - DK: 40 #C + default: 50 + DK: 40 + SE: 40 + NO: 40 + FI: 40 heat_source_cooling: 6 #K heat_pump_cop_approximation: refrigerant: ammonia From 5ee5a43be30dd953685f4f78c291bce3a5d92edc Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Thu, 8 Aug 2024 15:16:03 +0000 Subject: [PATCH 12/17] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- config/config.default.yaml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/config/config.default.yaml b/config/config.default.yaml index adb9ffa1..65006938 100644 --- a/config/config.default.yaml +++ b/config/config.default.yaml @@ -413,10 +413,10 @@ sector: # check these numbers! forward_temperature: default: 90 - DK: 70 - SE: 70 - NO: 70 - FI: 70 + DK: 70 + SE: 70 + NO: 70 + FI: 70 return_temperature: default: 50 DK: 40 From 9a0930419e98a010dba814d2201c4ad639e1d94f Mon Sep 17 00:00:00 2001 From: AmosSchledorn Date: Thu, 8 Aug 2024 17:17:33 +0200 Subject: [PATCH 13/17] update configtables --- doc/configtables/sector.csv | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/configtables/sector.csv b/doc/configtables/sector.csv index e0deb8ca..9b8ed932 100644 --- a/doc/configtables/sector.csv +++ b/doc/configtables/sector.csv @@ -9,8 +9,8 @@ district_heating,--,,`prepare_sector_network.py Date: Thu, 8 Aug 2024 17:18:48 +0200 Subject: [PATCH 14/17] update release notes --- doc/release_notes.rst | 2 ++ 1 file changed, 2 insertions(+) diff --git a/doc/release_notes.rst b/doc/release_notes.rst index 9ce418b2..7a815ebc 100644 --- a/doc/release_notes.rst +++ b/doc/release_notes.rst @@ -10,6 +10,8 @@ Release Notes Upcoming Release ================ +* Added option to use country-specific district heating forward and return temperatures. Defaults to lower temperatures in Scandinavia. + * Changed heat pump COP approximation for central heating to be based on `Jensen et al. (2018) `__ and a default forward temperature of 90C. This is more realistic for district heating than the previously used approximation method. * split solid biomass potentials into solid biomass and municipal solid waste. Add option to use municipal solid waste. This option is only activated in combination with the flag ``waste_to_energy`` From 7542d57820e84970f90ff2407c13238200156763 Mon Sep 17 00:00:00 2001 From: AmosSchledorn Date: Tue, 13 Aug 2024 17:07:20 +0200 Subject: [PATCH 15/17] style: move get_country_from_node_name function from _helpers tu run --- scripts/_helpers.py | 3 --- scripts/build_cop_profiles/run.py | 4 +++- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/scripts/_helpers.py b/scripts/_helpers.py index 1c890ea5..d97144ba 100644 --- a/scripts/_helpers.py +++ b/scripts/_helpers.py @@ -786,6 +786,3 @@ def get_snapshots(snapshots, drop_leap_day=False, freq="h", **kwargs): return time - -def get_country_from_node_name(node_name: str) -> str: - return node_name[:2] diff --git a/scripts/build_cop_profiles/run.py b/scripts/build_cop_profiles/run.py index 23229e98..401fdc18 100644 --- a/scripts/build_cop_profiles/run.py +++ b/scripts/build_cop_profiles/run.py @@ -46,7 +46,7 @@ import geopandas as gpd import numpy as np import pandas as pd import xarray as xr -from _helpers import get_country_from_node_name, set_scenario_config +from _helpers import set_scenario_config from CentralHeatingCopApproximator import CentralHeatingCopApproximator from DecentralHeatingCopApproximator import DecentralHeatingCopApproximator @@ -134,6 +134,8 @@ def get_cop( source_type=heat_source, ).approximate_cop() +def get_country_from_node_name(node_name: str) -> str: + return node_name[:2] if __name__ == "__main__": if "snakemake" not in globals(): From 92435678723b01482d544f0606ff5c26ced8063c Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Tue, 13 Aug 2024 15:08:47 +0000 Subject: [PATCH 16/17] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- scripts/_helpers.py | 1 - scripts/build_cop_profiles/run.py | 2 ++ 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/scripts/_helpers.py b/scripts/_helpers.py index d97144ba..a3b77c1c 100644 --- a/scripts/_helpers.py +++ b/scripts/_helpers.py @@ -785,4 +785,3 @@ def get_snapshots(snapshots, drop_leap_day=False, freq="h", **kwargs): time = time[~((time.month == 2) & (time.day == 29))] return time - diff --git a/scripts/build_cop_profiles/run.py b/scripts/build_cop_profiles/run.py index 401fdc18..b4ec3e43 100644 --- a/scripts/build_cop_profiles/run.py +++ b/scripts/build_cop_profiles/run.py @@ -134,9 +134,11 @@ def get_cop( source_type=heat_source, ).approximate_cop() + def get_country_from_node_name(node_name: str) -> str: return node_name[:2] + if __name__ == "__main__": if "snakemake" not in globals(): from _helpers import mock_snakemake From 18759053f01476f6ab2cf624d13ce3d20b3b03c0 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Fri, 16 Aug 2024 11:42:18 +0000 Subject: [PATCH 17/17] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- scripts/prepare_sector_network.py | 31 ++++++++++++++++++++----------- 1 file changed, 20 insertions(+), 11 deletions(-) diff --git a/scripts/prepare_sector_network.py b/scripts/prepare_sector_network.py index 23863067..71b50439 100644 --- a/scripts/prepare_sector_network.py +++ b/scripts/prepare_sector_network.py @@ -2830,8 +2830,11 @@ def add_biomass(n, costs): ) if options["bioH2"]: - name = (pd.Index(spatial.biomass.nodes) + " " - + pd.Index(spatial.h2.nodes.str.replace(" H2", ""))) + name = ( + pd.Index(spatial.biomass.nodes) + + " " + + pd.Index(spatial.h2.nodes.str.replace(" H2", "")) + ) n.madd( "Link", name, @@ -2841,16 +2844,22 @@ def add_biomass(n, costs): bus2=spatial.co2.nodes, bus3="co2 atmosphere", carrier="solid biomass to hydrogen", - efficiency=costs.at['solid biomass to hydrogen', 'efficiency'], - efficiency2=costs.at['solid biomass', 'CO2 intensity'] * options["cc_fraction"], - efficiency3=-costs.at['solid biomass', 'CO2 intensity'] * options["cc_fraction"], + efficiency=costs.at["solid biomass to hydrogen", "efficiency"], + efficiency2=costs.at["solid biomass", "CO2 intensity"] + * options["cc_fraction"], + efficiency3=-costs.at["solid biomass", "CO2 intensity"] + * options["cc_fraction"], p_nom_extendable=True, - capital_cost=costs.at['solid biomass to hydrogen', 'fixed'] * costs.at['solid biomass to hydrogen', 'efficiency'] - + costs.at['biomass CHP capture', 'fixed'] * costs.at['solid biomass', 'CO2 intensity'], - overnight_cost=costs.at['solid biomass to hydrogen', 'investment'] * costs.at['solid biomass to hydrogen', 'efficiency'] - + costs.at['biomass CHP capture', 'investment'] * costs.at['solid biomass', 'CO2 intensity'], - marginal_cost=0., - ) + capital_cost=costs.at["solid biomass to hydrogen", "fixed"] + * costs.at["solid biomass to hydrogen", "efficiency"] + + costs.at["biomass CHP capture", "fixed"] + * costs.at["solid biomass", "CO2 intensity"], + overnight_cost=costs.at["solid biomass to hydrogen", "investment"] + * costs.at["solid biomass to hydrogen", "efficiency"] + + costs.at["biomass CHP capture", "investment"] + * costs.at["solid biomass", "CO2 intensity"], + marginal_cost=0.0, + ) def add_industry(n, costs):