diff --git a/src/egon/data/airflow/dags/pipeline.py b/src/egon/data/airflow/dags/pipeline.py index 23ba1878c..e17a7d9de 100755 --- a/src/egon/data/airflow/dags/pipeline.py +++ b/src/egon/data/airflow/dags/pipeline.py @@ -55,7 +55,7 @@ from egon.data.datasets.heat_supply.individual_heating import ( HeatPumps2035, HeatPumps2050, - HeatPumpsPypsaEurSec, + HeatPumpsPypsaEur, ) from egon.data.datasets.hydrogen_etrago import ( HydrogenBusEtrago, @@ -346,8 +346,8 @@ ] ) - # Minimum heat pump capacity for pypsa-eur-sec - heat_pumps_pypsa_eur_sec = HeatPumpsPypsaEurSec( + # Minimum heat pump capacity for pypsa-eur + heat_pumps_pypsa_eur = HeatPumpsPypsaEur( dependencies=[ cts_demand_buildings, DistrictHeatingAreas, @@ -375,7 +375,7 @@ dependencies=[prepare_pypsa_eur, tyndp_data, osmtgmod, fix_subnetworks] ) - # run pypsa-eur-sec + # run pypsa-eur run_pypsaeur = RunPypsaEur( dependencies=[ prepare_pypsa_eur, @@ -595,7 +595,7 @@ DistrictHeatingAreas, heat_supply, heat_time_series, - heat_pumps_pypsa_eur_sec, + heat_pumps_pypsa_eur, power_plants, ] ) @@ -615,7 +615,7 @@ heat_pumps_2050 = HeatPumps2050( dependencies=[ run_pypsaeur, - heat_pumps_pypsa_eur_sec, + heat_pumps_pypsa_eur, heat_supply, ] ) diff --git a/src/egon/data/datasets/heat_etrago/__init__.py b/src/egon/data/datasets/heat_etrago/__init__.py index 9b062b5eb..c1082993c 100644 --- a/src/egon/data/datasets/heat_etrago/__init__.py +++ b/src/egon/data/datasets/heat_etrago/__init__.py @@ -368,13 +368,15 @@ def insert_central_direct_heat(scenario): # Map solar thermal collectors to weather cells join = gpd.sjoin(weather_cells, solar_thermal)[["index_right"]] + weather_year = get_sector_parameters("global", scenario)["weather_year"] + feedin = db.select_dataframe( f""" SELECT w_id, feedin FROM {sources['feedin_timeseries']['schema']}. {sources['feedin_timeseries']['table']} WHERE carrier = 'solar_thermal' - AND weather_year = 2019 + AND weather_year = {weather_year} """, index_col="w_id", ) diff --git a/src/egon/data/datasets/heat_etrago/power_to_heat.py b/src/egon/data/datasets/heat_etrago/power_to_heat.py index 8d7cc3bb5..38421c3b7 100644 --- a/src/egon/data/datasets/heat_etrago/power_to_heat.py +++ b/src/egon/data/datasets/heat_etrago/power_to_heat.py @@ -548,7 +548,8 @@ def assign_electrical_bus(heat_pumps, carrier, scenario, multiple_per_mv_grid=Fa power_to_heat["share_demand"] = power_to_heat.groupby( "area_id" - ).demand.apply(lambda grp: grp / grp.sum()) + ).demand.apply(lambda grp: grp / grp.sum()).values + power_to_heat["capacity"] = power_to_heat["share_demand"].mul( heat_pumps.capacity[power_to_heat.area_id].values diff --git a/src/egon/data/datasets/heat_supply/individual_heating.py b/src/egon/data/datasets/heat_supply/individual_heating.py index 9a7e5afa4..141537454 100644 --- a/src/egon/data/datasets/heat_supply/individual_heating.py +++ b/src/egon/data/datasets/heat_supply/individual_heating.py @@ -224,6 +224,8 @@ engine = db.engine() Base = declarative_base() +scenarios = config.settings()["egon-data"]["--scenarios"] + class EgonEtragoTimeseriesIndividualHeating(Base): __tablename__ = "egon_etrago_timeseries_individual_heating" @@ -242,9 +244,9 @@ class EgonHpCapacityBuildings(Base): hp_capacity = Column(REAL) -class HeatPumpsPypsaEurSec(Dataset): +class HeatPumpsPypsaEur(Dataset): def __init__(self, dependencies): - def dyn_parallel_tasks_pypsa_eur_sec(): + def dyn_parallel_tasks_pypsa_eur(): """Dynamically generate tasks The goal is to speed up tasks by parallelising bulks of mvgds. @@ -256,7 +258,7 @@ def dyn_parallel_tasks_pypsa_eur_sec(): set of airflow.PythonOperators The tasks. Each element is of :func:`egon.data.datasets.heat_supply.individual_heating. - determine_hp_cap_peak_load_mvgd_ts_pypsa_eur_sec` + determine_hp_cap_peak_load_mvgd_ts_pypsa_eur` """ parallel_tasks = config.datasets()["demand_timeseries_mvgd"].get( "parallel_tasks", 1 @@ -268,29 +270,45 @@ def dyn_parallel_tasks_pypsa_eur_sec(): PythonOperator( task_id=( f"individual_heating." - f"determine-hp-capacity-pypsa-eur-sec-" + f"determine-hp-capacity-pypsa-eur-" f"mvgd-bulk{i}" ), python_callable=split_mvgds_into_bulks, op_kwargs={ "n": i, "max_n": parallel_tasks, - "func": determine_hp_cap_peak_load_mvgd_ts_pypsa_eur_sec, # noqa: E501 + "func": determine_hp_cap_peak_load_mvgd_ts_pypsa_eur, # noqa: E501 }, ) ) return tasks - super().__init__( - name="HeatPumpsPypsaEurSec", - version="0.0.2", - dependencies=dependencies, - tasks=( + tasks_HeatPumpsPypsaEur = set() + + if "eGon100RE" in scenarios: + tasks_HeatPumpsPypsaEur = ( delete_pypsa_eur_sec_csv_file, delete_mvgd_ts_100RE, delete_heat_peak_loads_100RE, - {*dyn_parallel_tasks_pypsa_eur_sec()}, - ), + {*dyn_parallel_tasks_pypsa_eur()}, + ) + else: + tasks_HeatPumpsPypsaEur = ( + PythonOperator( + task_id="HeatPumpsPypsaEur_skipped", + python_callable=skip_task, + op_kwargs={ + "scn": "eGon100RE", + "task": "HeatPumpsPypsaEur", + }, + ), + ) + + super().__init__( + name="HeatPumpsPypsaEurSec", + version="0.0.3", + dependencies=dependencies, + tasks=tasks_HeatPumpsPypsaEur, ) @@ -333,16 +351,29 @@ def dyn_parallel_tasks_2019(): ) return tasks - super().__init__( - name="HeatPumps2019", - version="0.0.2", - dependencies=dependencies, - tasks=( + tasks_HeatPumps2019 = set() + + if "status2019" in scenarios: + tasks_HeatPumps2019 = ( delete_heat_peak_loads_2019, delete_hp_capacity_2019, delete_mvgd_ts_2019, {*dyn_parallel_tasks_2019()}, - ), + ) + else: + tasks_HeatPumps2019 = ( + PythonOperator( + task_id="HeatPumps2019_skipped", + python_callable=skip_task, + op_kwargs={"scn": "status2019", "task": "HeatPumps2019"}, + ), + ) + + super().__init__( + name="HeatPumps2019", + version="0.0.3", + dependencies=dependencies, + tasks=tasks_HeatPumps2019, ) @@ -385,29 +416,55 @@ def dyn_parallel_tasks_2035(): ) return tasks - super().__init__( - name="HeatPumps2035", - version="0.0.2", - dependencies=dependencies, - tasks=( + tasks_HeatPumps2035 = set() + + if "eGon2035" in scenarios: + tasks_HeatPumps2035 = ( delete_heat_peak_loads_2035, delete_hp_capacity_2035, delete_mvgd_ts_2035, {*dyn_parallel_tasks_2035()}, - ), + ) + else: + tasks_HeatPumps2035 = ( + PythonOperator( + task_id="HeatPumps2035_skipped", + python_callable=skip_task, + op_kwargs={"scn": "eGon2035", "task": "HeatPumps2035"}, + ), + ) + + super().__init__( + name="HeatPumps2035", + version="0.0.3", + dependencies=dependencies, + tasks=tasks_HeatPumps2035, ) class HeatPumps2050(Dataset): def __init__(self, dependencies): + tasks_HeatPumps2050 = set() + + if "eGon100RE" in scenarios: + tasks_HeatPumps2050 = ( + delete_hp_capacity_100RE, + determine_hp_cap_buildings_eGon100RE, + ) + else: + tasks_HeatPumps2050 = ( + PythonOperator( + task_id="HeatPumps2050_skipped", + python_callable=skip_task, + op_kwargs={"scn": "eGon100RE", "task": "HeatPumps2050"}, + ), + ) + super().__init__( name="HeatPumps2050", - version="0.0.2", + version="0.0.3", dependencies=dependencies, - tasks=( - delete_hp_capacity_100RE, - determine_hp_cap_buildings_eGon100RE, - ), + tasks=tasks_HeatPumps2050, ) @@ -421,6 +478,15 @@ class BuildingHeatPeakLoads(Base): peak_load_in_w = Column(REAL) +def skip_task(scn=str, task=str): + def not_executed(): + logger.info( + f"{scn} is not in the list of scenarios. {task} dataset is skipped." + ) + + return not_executed + + def adapt_numpy_float64(numpy_float64): return AsIs(numpy_float64) @@ -2014,7 +2080,7 @@ def determine_hp_cap_peak_load_mvgd_ts_2019(mvgd_ids): ) -def determine_hp_cap_peak_load_mvgd_ts_pypsa_eur_sec(mvgd_ids): +def determine_hp_cap_peak_load_mvgd_ts_pypsa_eur(mvgd_ids): """ Main function to determine minimum required HP capacity in MV for pypsa-eur-sec. Further, creates heat demand time series for all buildings diff --git a/src/egon/data/datasets/scenario_parameters/parameters.py b/src/egon/data/datasets/scenario_parameters/parameters.py index 91e7b6bc0..8f99cbc6e 100755 --- a/src/egon/data/datasets/scenario_parameters/parameters.py +++ b/src/egon/data/datasets/scenario_parameters/parameters.py @@ -116,6 +116,7 @@ def global_settings(scenario): "coal": 0.335, # [t_CO2/MW_th] "other_non_renewable": 0.268, # [t_CO2/MW_th] }, + "interest_rate": 0.05, # [p.u.] } elif scenario == "eGon2021": @@ -1109,12 +1110,83 @@ def heat(scenario): } elif scenario == "eGon100RE": + costs = read_csv(2050) + parameters = { "DE_demand_reduction_residential": 0.640720648501849, "DE_demand_reduction_service": 0.390895195300713, "DE_district_heating_share": 0.19, } + parameters["marginal_cost"] = { + "central_heat_pump": read_costs( + costs, "central air-sourced heat pump", "VOM" + ), + "central_gas_chp": read_costs(costs, "central gas CHP", "VOM"), + "central_gas_boiler": read_costs( + costs, "central gas boiler", "VOM" + ), + "central_resistive_heater": read_costs( + costs, "central resistive heater", "VOM" + ), + "geo_thermal": 2.9, # Danish Energy Agency + "water_tank_charger": 0, # Danish Energy Agency + "water_tank_discharger": 0, # Danish Energy Agency + "rural_heat_pump": 0, # Danish Energy Agency, Technology Data for Individual Heating Plants + } + + # Insert efficiency in p.u. + parameters["efficiency"] = { + "water_tank_charger": read_costs( + costs, "water tank charger", "efficiency" + ), + "water_tank_discharger": read_costs( + costs, "water tank discharger", "efficiency" + ), + "central_resistive_heater": read_costs( + costs, "central resistive heater", "efficiency" + ), + "central_gas_boiler": read_costs( + costs, "central gas boiler", "efficiency" + ), + "rural_resistive_heater": read_costs( + costs, "decentral resistive heater", "efficiency" + ), + "rural_gas_boiler": read_costs( + costs, "decentral gas boiler", "efficiency" + ), + } + + # Insert overnight investment costs, in EUR/MWh + parameters["overnight_cost"] = { + "central_water_tank": read_costs( + costs, "central water tank storage", "investment" + ), + "rural_water_tank": read_costs( + costs, "decentral water tank storage", "investment" + ), + } + + # Insert lifetime + parameters["lifetime"] = { + "central_water_tank": read_costs( + costs, "central water tank storage", "lifetime" + ), + "rural_water_tank": read_costs( + costs, "decentral water tank storage", "lifetime" + ), + } + + # Insert annualized capital costs + parameters["capital_cost"] = {} + + for comp in parameters["overnight_cost"].keys(): + parameters["capital_cost"][comp] = annualize_capital_costs( + parameters["overnight_cost"][comp], + parameters["lifetime"][comp], + global_settings("eGon100RE")["interest_rate"], + ) + elif scenario == "eGon2021": parameters = {}