update myopic mode to heat system declarations

This commit is contained in:
AmosSchledorn 2024-08-05 11:27:52 +02:00
parent 10e0b30a40
commit 5362c37696
4 changed files with 118 additions and 113 deletions

View File

@ -69,6 +69,7 @@ rule add_brownfield:
snapshots=config_provider("snapshots"), snapshots=config_provider("snapshots"),
drop_leap_day=config_provider("enable", "drop_leap_day"), drop_leap_day=config_provider("enable", "drop_leap_day"),
carriers=config_provider("electricity", "renewable_carriers"), carriers=config_provider("electricity", "renewable_carriers"),
heat_pump_sources=config_provider("sector", "heat_pump_sources"),
input: input:
unpack(input_profile_tech_brownfield), unpack(input_profile_tech_brownfield),
simplify_busmap=resources("busmap_elec_s{simpl}.csv"), simplify_busmap=resources("busmap_elec_s{simpl}.csv"),
@ -77,18 +78,7 @@ rule add_brownfield:
+ "prenetworks/elec_s{simpl}_{clusters}_l{ll}_{opts}_{sector_opts}_{planning_horizons}.nc", + "prenetworks/elec_s{simpl}_{clusters}_l{ll}_{opts}_{sector_opts}_{planning_horizons}.nc",
network_p=solved_previous_horizon, #solved network at previous time step network_p=solved_previous_horizon, #solved network at previous time step
costs=resources("costs_{planning_horizons}.csv"), costs=resources("costs_{planning_horizons}.csv"),
cop_soil_decentral_heating=resources( cop_profiles=resources("cop_profiles_elec_s{simpl}_{clusters}.nc"),
"cop_soil_decentral_heating_elec_s{simpl}_{clusters}.nc"
),
cop_air_decentral_heating=resources(
"cop_air_decentral_heating_elec_s{simpl}_{clusters}.nc"
),
cop_air_central_heating=resources(
"cop_air_central_heating_elec_s{simpl}_{clusters}.nc"
),
cop_soil_central_heating=resources(
"cop_soil_central_heating_elec_s{simpl}_{clusters}.nc"
),
output: output:
RESULTS RESULTS
+ "prenetworks-brownfield/elec_s{simpl}_{clusters}_l{ll}_{opts}_{sector_opts}_{planning_horizons}.nc", + "prenetworks-brownfield/elec_s{simpl}_{clusters}_l{ll}_{opts}_{sector_opts}_{planning_horizons}.nc",

View File

@ -438,8 +438,8 @@ def add_heating_capacities_installed_before_baseyear(
currently assumed heating capacities split between residential and currently assumed heating capacities split between residential and
services proportional to heating load in both 50% capacities services proportional to heating load in both 50% capacities
in rural buses 50% in urban buses in rural buses 50% in urban buses
cop: dict cop: xr.DataArray
Dictionary with time-dependent coefficients of performance (COPs) for air and ground heat pumps as values and keys "air decentral", "ground decentral", "air central", "ground central" DataArray with time-dependent coefficients of performance (COPs) heat pumps. Coordinates are heat sources (see config), heat system types (see :file:`scripts/enums/HeatSystemType.py`), nodes and snapshots.
time_dep_hp_cop: bool time_dep_hp_cop: bool
If True, time-dependent (dynamic) COPs are used for heat pumps If True, time-dependent (dynamic) COPs are used for heat pumps
""" """
@ -452,23 +452,11 @@ def add_heating_capacities_installed_before_baseyear(
n.buses.location[n.buses.index.str.contains(f"{heat_system} heat")] n.buses.location[n.buses.index.str.contains(f"{heat_system} heat")]
) )
if (not heat_system.is_central) and options["electricity_distribution_grid"]: if (not heat_system == HeatSystem.URBAN_CENTRAL) and options["electricity_distribution_grid"]:
nodes_elec = nodes + " low voltage" nodes_elec = nodes + " low voltage"
else: else:
nodes_elec = nodes nodes_elec = nodes
# Add heat pumps
heat_source = snakemake.params.heat_pump_sources[heat_system.system_type.value]
costs_name = f"{heat_system.system_type} {heat_source}-sourced heat pump"
efficiency = (
cop.sel(heat_system=heat_system.system_type.value, heat_source=heat_source, name=nodes)
.to_pandas()
.reindex(index=n.snapshots)
if options["time_dep_hp_cop"]
else costs.at[costs_name, "efficiency"]
)
too_large_grouping_years = [gy for gy in grouping_years if gy >= int(baseyear)] too_large_grouping_years = [gy for gy in grouping_years if gy >= int(baseyear)]
if too_large_grouping_years: if too_large_grouping_years:
logger.warning( logger.warning(
@ -493,6 +481,17 @@ def add_heating_capacities_installed_before_baseyear(
ratios = _years / _years.sum() ratios = _years / _years.sum()
for ratio, grouping_year in zip(ratios, valid_grouping_years): for ratio, grouping_year in zip(ratios, valid_grouping_years):
# Add heat pumps
for heat_source in snakemake.params.heat_pump_sources[heat_system.system_type.value]:
costs_name = heat_system.heat_pump_costs_name(heat_source)
efficiency = (
cop.sel(heat_system=heat_system.system_type.value, heat_source=heat_source, name=nodes)
.to_pandas()
.reindex(index=n.snapshots)
if options["time_dep_hp_cop"]
else costs.at[costs_name, "efficiency"]
)
n.madd( n.madd(
"Link", "Link",
@ -520,42 +519,42 @@ def add_heating_capacities_installed_before_baseyear(
suffix=f" {heat_system} resistive heater-{grouping_year}", suffix=f" {heat_system} resistive heater-{grouping_year}",
bus0=nodes_elec, bus0=nodes_elec,
bus1=nodes + " " + heat_system.value + " heat", bus1=nodes + " " + heat_system.value + " heat",
carrier=heat_system + " resistive heater", carrier=heat_system.value + " resistive heater",
efficiency=costs.at[f"{heat_system.system_type} resistive heater", "efficiency"], efficiency=costs.at[heat_system.resistive_heater_costs_name, "efficiency"],
capital_cost=( capital_cost=(
costs.at[f"{heat_system.system_type} resistive heater", "efficiency"] costs.at[heat_system.resistive_heater_costs_name, "efficiency"]
* costs.at[f"{heat_system.system_type} resistive heater", "fixed"] * costs.at[heat_system.resistive_heater_costs_name, "fixed"]
), ),
p_nom=( p_nom=(
existing_heating.loc[nodes, (heat_system.value, "resistive heater")] existing_heating.loc[nodes, (heat_system.value, "resistive heater")]
* ratio * ratio
/ costs.at[f"{heat_system.system_type} resistive heater", "efficiency"] / costs.at[heat_system.resistive_heater_costs_name, "efficiency"]
), ),
build_year=int(grouping_year), build_year=int(grouping_year),
lifetime=costs.at[f"{heat_system.system_type} resistive heater", "lifetime"], lifetime=costs.at[heat_system.resistive_heater_costs_name, "lifetime"],
) )
n.madd( n.madd(
"Link", "Link",
nodes, nodes,
suffix=f" {heat_system} gas boiler-{grouping_year}", suffix=f"{heat_system} gas boiler-{grouping_year}",
bus0="EU gas" if "EU gas" in spatial.gas.nodes else nodes + " gas", bus0="EU gas" if "EU gas" in spatial.gas.nodes else nodes + " gas",
bus1=nodes + " " + heat_system + " heat", bus1=f"{nodes} {heat_system} heat",
bus2="co2 atmosphere", bus2="co2 atmosphere",
carrier=heat_system + " gas boiler", carrier=heat_system.value + " gas boiler",
efficiency=costs.at[f"{heat_system.system_type} gas boiler", "efficiency"], efficiency=costs.at[heat_system.gas_boiler_costs_name, "efficiency"],
efficiency2=costs.at["gas", "CO2 intensity"], efficiency2=costs.at["gas", "CO2 intensity"],
capital_cost=( capital_cost=(
costs.at[f"{heat_system.system_type} gas boiler", "efficiency"] costs.at[heat_system.gas_boiler_costs_name, "efficiency"]
* costs.at[f"{heat_system.system_type} gas boiler", "fixed"] * costs.at[heat_system.gas_boiler_costs_name, "fixed"]
), ),
p_nom=( p_nom=(
existing_heating.loc[nodes, (heat_system, "gas boiler")] existing_heating.loc[nodes, (heat_system.value, "gas boiler")]
* ratio * ratio
/ costs.at[f"{heat_system.system_type} gas boiler", "efficiency"] / costs.at[heat_system.gas_boiler_costs_name, "efficiency"]
), ),
build_year=int(grouping_year), build_year=int(grouping_year),
lifetime=costs.at[f"{heat_system.system_type} gas boiler", "lifetime"], lifetime=costs.at[heat_system.gas_boiler_costs_name, "lifetime"],
) )
n.madd( n.madd(
@ -563,20 +562,20 @@ def add_heating_capacities_installed_before_baseyear(
nodes, nodes,
suffix=f" {heat_system} oil boiler-{grouping_year}", suffix=f" {heat_system} oil boiler-{grouping_year}",
bus0=spatial.oil.nodes, bus0=spatial.oil.nodes,
bus1=nodes + " " + heat_system + " heat", bus1=f"{nodes} {heat_system} heat",
bus2="co2 atmosphere", bus2="co2 atmosphere",
carrier=heat_system + " oil boiler", carrier=heat_system.value + " oil boiler",
efficiency=costs.at["decentral oil boiler", "efficiency"], efficiency=costs.at[heat_system.oil_boiler_costs_name, "efficiency"],
efficiency2=costs.at["oil", "CO2 intensity"], efficiency2=costs.at["oil", "CO2 intensity"],
capital_cost=costs.at["decentral oil boiler", "efficiency"] capital_cost=costs.at[heat_system.oil_boiler_costs_name, "efficiency"]
* costs.at["decentral oil boiler", "fixed"], * costs.at[heat_system.oil_boiler_costs_name, "fixed"],
p_nom=( p_nom=(
existing_heating.loc[nodes, (heat_system, "oil boiler")] existing_heating.loc[nodes, (heat_system.value, "oil boiler")]
* ratio * ratio
/ costs.at["decentral oil boiler", "efficiency"] / costs.at[heat_system.oil_boiler_costs_name, "efficiency"]
), ),
build_year=int(grouping_year), build_year=int(grouping_year),
lifetime=costs.at[f"{heat_system.system_type} gas boiler", "lifetime"], lifetime=costs.at[f"{heat_system.central_or_decentral} gas boiler", "lifetime"],
) )
# delete links with p_nom=nan corresponding to extra nodes in country # delete links with p_nom=nan corresponding to extra nodes in country
@ -651,28 +650,7 @@ if __name__ == "__main__":
n=n, n=n,
baseyear=baseyear, baseyear=baseyear,
grouping_years=grouping_years_heat, grouping_years=grouping_years_heat,
cop={ cop=xr.open_dataarray(snakemake.input.cop_profiles),
"air decentral": xr.open_dataarray(
snakemake.input.cop_air_decentral_heating
)
.to_pandas()
.reindex(index=n.snapshots),
"ground decentral": xr.open_dataarray(
snakemake.input.cop_soil_decentral_heating
)
.to_pandas()
.reindex(index=n.snapshots),
"air central": xr.open_dataarray(
snakemake.input.cop_air_central_heating
)
.to_pandas()
.reindex(index=n.snapshots),
"ground central": xr.open_dataarray(
snakemake.input.cop_soil_central_heating
)
.to_pandas()
.reindex(index=n.snapshots),
},
time_dep_hp_cop=options["time_dep_hp_cop"], time_dep_hp_cop=options["time_dep_hp_cop"],
costs=costs, costs=costs,
default_lifetime=snakemake.params.existing_capacities[ default_lifetime=snakemake.params.existing_capacities[

View File

@ -210,7 +210,7 @@ class HeatSystem(Enum):
def heat_pump_costs_name(self, heat_source: str) -> str: def heat_pump_costs_name(self, heat_source: str) -> str:
""" """
Generates the name for the heat pump costs based on the heat source. Generates the name for the heat pump costs based on the heat source and system.
Parameters Parameters
---------- ----------
@ -223,3 +223,41 @@ class HeatSystem(Enum):
The name for the heat pump costs. The name for the heat pump costs.
""" """
return f"{self.central_or_decentral} {heat_source}-sourced heat pump" return f"{self.central_or_decentral} {heat_source}-sourced heat pump"
@property
def resistive_heater_costs_name(self) -> str:
"""
Generates the name for the resistive heater costs based on the heat system.
Returns
-------
str
The name for the heater costs.
"""
return f"{self.central_or_decentral} resistive heater"
@property
def gas_boiler_costs_name(self) -> str:
"""
Generates the name for the gas boiler costs based on the heat system.
Returns
-------
str
The name for the gas boiler costs.
"""
return f"{self.central_or_decentral} gas boiler"
@property
def oil_boiler_costs_name(self) -> str:
"""
Generates the name for the oil boiler costs based on the heat system.
Returns
-------
str
The name for the oil boiler costs.
"""
return "decentral oil boiler"

View File

@ -1802,7 +1802,7 @@ def build_heat_demand(n):
return heat_demand return heat_demand
def add_heat(n, costs): def add_heat(n, costs, cop):
logger.info("Add heat sector") logger.info("Add heat sector")
sectors = ["residential", "services"] sectors = ["residential", "services"]
@ -1833,7 +1833,6 @@ def add_heat(n, costs):
# 1e3 converts from W/m^2 to MW/(1000m^2) = kW/m^2 # 1e3 converts from W/m^2 to MW/(1000m^2) = kW/m^2
solar_thermal = options["solar_cf_correction"] * solar_thermal / 1e3 solar_thermal = options["solar_cf_correction"] * solar_thermal / 1e3
cop = xr.open_dataarray(snakemake.input.cop_profiles)
for ( for (
heat_system heat_system
) in ( ) in (
@ -4098,7 +4097,7 @@ if __name__ == "__main__":
add_land_transport(n, costs) add_land_transport(n, costs)
if options["heating"]: if options["heating"]:
add_heat(n, costs) add_heat(n=n, costs=costs, cop=xr.open_dataarray(snakemake.input.cop_profiles))
if options["biomass"]: if options["biomass"]:
add_biomass(n, costs) add_biomass(n, costs)