Source code for egon.data.datasets.heat_etrago

"""The central module containing all code dealing with heat sector in etrago
"""
import pandas as pd
import geopandas as gpd
from egon.data import db, config
from egon.data.datasets.heat_etrago.power_to_heat import (
    insert_central_power_to_heat,
    insert_individual_power_to_heat,
)
from egon.data.datasets import Dataset
from egon.data.datasets.etrago_setup import link_geom_from_buses
from egon.data.datasets.scenario_parameters import get_sector_parameters


[docs]def insert_buses(carrier, scenario): """Insert heat buses to etrago table Heat buses are divided into central and individual heating Parameters ---------- carrier : str Name of the carrier, either 'central_heat' or 'rural_heat' scenario : str, optional Name of the scenario. """ sources = config.datasets()["etrago_heat"]["sources"] target = config.datasets()["etrago_heat"]["targets"]["heat_buses"] # Delete existing heat buses (central or rural) db.execute_sql( f""" DELETE FROM {target['schema']}.{target['table']} WHERE scn_name = '{scenario}' AND carrier = '{carrier}' AND country = 'DE' """ ) # Select unused index of buses next_bus_id = db.next_etrago_id("bus") # initalize dataframe for heat buses heat_buses = ( gpd.GeoDataFrame( columns=["scn_name", "bus_id", "carrier", "x", "y", "geom"] ) .set_geometry("geom") .set_crs(epsg=4326) ) # If central heat, create one bus per district heating area if carrier == "central_heat": areas = db.select_geodataframe( f""" SELECT area_id, geom_polygon as geom FROM {sources['district_heating_areas']['schema']}. {sources['district_heating_areas']['table']} WHERE scenario = '{scenario}' """, index_col="area_id", ) heat_buses.geom = areas.centroid.to_crs(epsg=4326) # otherwise create one heat bus per hvmv substation # which represents aggregated individual heating for etrago else: mv_grids = db.select_geodataframe( f""" SELECT ST_Centroid(geom) AS geom FROM {sources['mv_grids']['schema']}. {sources['mv_grids']['table']} WHERE bus_id IN (SELECT DISTINCT bus_id FROM boundaries.egon_map_zensus_grid_districts a JOIN demand.egon_peta_heat b ON a.zensus_population_id = b.zensus_population_id WHERE b.scenario = '{scenario}' AND b.zensus_population_id NOT IN ( SELECT zensus_population_id FROM demand.egon_map_zensus_district_heating_areas WHERE scenario = '{scenario}' ) ) """ ) heat_buses.geom = mv_grids.geom.to_crs(epsg=4326) # Insert values into dataframe heat_buses.scn_name = scenario heat_buses.carrier = carrier heat_buses.x = heat_buses.geom.x heat_buses.y = heat_buses.geom.y heat_buses.bus_id = range(next_bus_id, next_bus_id + len(heat_buses)) # Insert data into database heat_buses.to_postgis( target["table"], schema=target["schema"], if_exists="append", con=db.engine(), )
[docs]def insert_store(scenario, carrier): sources = config.datasets()["etrago_heat"]["sources"] targets = config.datasets()["etrago_heat"]["targets"] db.execute_sql( f""" DELETE FROM {targets['heat_buses']['schema']}. {targets['heat_buses']['table']} WHERE carrier = '{carrier}_store' AND scn_name = '{scenario}' AND country = 'DE' """ ) db.execute_sql( f""" DELETE FROM {targets['heat_links']['schema']}. {targets['heat_links']['table']} WHERE carrier LIKE '{carrier}_store%' AND scn_name = '{scenario}' AND bus0 IN (SELECT bus_id FROM {targets['heat_buses']['schema']}. {targets['heat_buses']['table']} WHERE scn_name = '{scenario}' AND country = 'DE') AND bus1 IN (SELECT bus_id FROM {targets['heat_buses']['schema']}. {targets['heat_buses']['table']} WHERE scn_name = '{scenario}' AND country = 'DE') """ ) db.execute_sql( f""" DELETE FROM {targets['heat_stores']['schema']}. {targets['heat_stores']['table']} WHERE carrier = '{carrier}_store' AND scn_name = '{scenario}' AND bus IN (SELECT bus_id FROM {targets['heat_buses']['schema']}. {targets['heat_buses']['table']} WHERE scn_name = '{scenario}' AND country = 'DE') """ ) dh_bus = db.select_geodataframe( f""" SELECT * FROM {targets['heat_buses']['schema']}. {targets['heat_buses']['table']} WHERE carrier = '{carrier}' AND scn_name = '{scenario}' AND country = 'DE' """, epsg=4326, ) water_tank_bus = dh_bus.copy() water_tank_bus.carrier = carrier + "_store" water_tank_bus.bus_id = range( db.next_etrago_id("bus"), db.next_etrago_id("bus") + len(water_tank_bus), ) water_tank_bus.to_postgis( targets["heat_buses"]["table"], schema=targets["heat_buses"]["schema"], con=db.engine(), if_exists="append", index=False, ) water_tank_charger = pd.DataFrame( data={ "scn_name": scenario, "bus0": dh_bus.bus_id, "bus1": water_tank_bus.bus_id, "carrier": carrier + "_store_charger", "efficiency": get_sector_parameters("heat", "eGon2035")[ "efficiency" ]["water_tank_charger"], "marginal_cost": get_sector_parameters("heat", "eGon2035")[ "marginal_cost" ]["water_tank_charger"], "p_nom_extendable": True, "link_id": range( db.next_etrago_id("link"), db.next_etrago_id("link") + len(water_tank_bus), ), } ) water_tank_charger.to_sql( targets["heat_links"]["table"], schema=targets["heat_links"]["schema"], con=db.engine(), if_exists="append", index=False, ) water_tank_discharger = pd.DataFrame( data={ "scn_name": scenario, "bus0": water_tank_bus.bus_id, "bus1": dh_bus.bus_id, "carrier": carrier + "_store_discharger", "efficiency": get_sector_parameters("heat", "eGon2035")[ "efficiency" ]["water_tank_discharger"], "marginal_cost": get_sector_parameters("heat", "eGon2035")[ "marginal_cost" ]["water_tank_discharger"], "p_nom_extendable": True, "link_id": range( db.next_etrago_id("link"), db.next_etrago_id("link") + len(water_tank_bus), ), } ) water_tank_discharger.to_sql( targets["heat_links"]["table"], schema=targets["heat_links"]["schema"], con=db.engine(), if_exists="append", index=False, ) water_tank_store = pd.DataFrame( data={ "scn_name": scenario, "bus": water_tank_bus.bus_id, "carrier": carrier + "_store", "capital_cost": get_sector_parameters("heat", "eGon2035")[ "capital_cost" ][f"{carrier.split('_')[0]}_water_tank"], "lifetime": get_sector_parameters("heat", "eGon2035")["lifetime"][ f"{carrier.split('_')[0]}_water_tank" ], "e_nom_extendable": True, "store_id": range( db.next_etrago_id("store"), db.next_etrago_id("store") + len(water_tank_bus), ), } ) water_tank_store.to_sql( targets["heat_stores"]["table"], schema=targets["heat_stores"]["schema"], con=db.engine(), if_exists="append", index=False, )
[docs]def store(): insert_store("eGon2035", "central_heat") insert_store("eGon2035", "rural_heat")
[docs]def insert_central_direct_heat(scenario="eGon2035"): """Insert renewable heating technologies (solar and geo thermal) Parameters ---------- scenario : str, optional Name of the scenario The default is 'eGon2035'. Returns ------- None. """ sources = config.datasets()["etrago_heat"]["sources"] targets = config.datasets()["etrago_heat"]["targets"] db.execute_sql( f""" DELETE FROM {targets['heat_generators']['schema']}. {targets['heat_generators']['table']} WHERE carrier IN ('solar_thermal_collector', 'geo_thermal') AND scn_name = '{scenario}' AND bus IN (SELECT bus_id FROM {targets['heat_buses']['schema']}. {targets['heat_buses']['table']} WHERE scn_name = '{scenario}' AND country = 'DE') """ ) db.execute_sql( f""" DELETE FROM {targets['heat_generator_timeseries']['schema']}. {targets['heat_generator_timeseries']['table']} WHERE scn_name = '{scenario}' AND generator_id NOT IN ( SELECT generator_id FROM {targets['heat_generators']['schema']}. {targets['heat_generators']['table']} WHERE scn_name = '{scenario}') """ ) central_thermal = db.select_geodataframe( f""" SELECT district_heating_id, capacity, geometry, carrier FROM {sources['district_heating_supply']['schema']}. {sources['district_heating_supply']['table']} WHERE scenario = '{scenario}' AND carrier IN ( 'solar_thermal_collector', 'geo_thermal') """, geom_col="geometry", index_col="district_heating_id", ) map_dh_id_bus_id = db.select_dataframe( f""" SELECT bus_id, area_id, id FROM {targets['heat_buses']['schema']}. {targets['heat_buses']['table']} JOIN {sources['district_heating_areas']['schema']}. {sources['district_heating_areas']['table']} ON ST_Transform(ST_Centroid(geom_polygon), 4326) = geom WHERE carrier = 'central_heat' AND scenario = '{scenario}' AND scn_name = '{scenario}' """, index_col="id", ) new_id = db.next_etrago_id("generator") generator = pd.DataFrame( data={ "scn_name": scenario, "carrier": central_thermal.carrier, "bus": map_dh_id_bus_id.bus_id[central_thermal.index], "p_nom": central_thermal.capacity, "generator_id": range(new_id, new_id + len(central_thermal)), } ) solar_thermal = central_thermal[ central_thermal.carrier == "solar_thermal_collector" ] weather_cells = db.select_geodataframe( f""" SELECT w_id, geom FROM {sources['weather_cells']['schema']}. {sources['weather_cells']['table']} """, index_col="w_id", ) # Map solar thermal collectors to weather cells join = gpd.sjoin(weather_cells, solar_thermal)[["index_right"]] 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 = 2011 """, index_col="w_id", ) timeseries = pd.DataFrame( data={ "scn_name": scenario, "temp_id": 1, "p_max_pu": feedin.feedin[join.index].values, "generator_id": generator.generator_id[ generator.carrier == "solar_thermal_collector" ].values, } ).set_index("generator_id") generator = generator.set_index("generator_id") generator.to_sql( targets["heat_generators"]["table"], schema=targets["heat_generators"]["schema"], if_exists="append", con=db.engine(), ) timeseries.to_sql( targets["heat_generator_timeseries"]["table"], schema=targets["heat_generator_timeseries"]["schema"], if_exists="append", con=db.engine(), )
[docs]def insert_central_gas_boilers(scenario="eGon2035"): """Inserts gas boilers for district heating to eTraGo-table Parameters ---------- scenario : str, optional Name of the scenario. The default is 'eGon2035'. Returns ------- None. """ sources = config.datasets()["etrago_heat"]["sources"] targets = config.datasets()["etrago_heat"]["targets"] db.execute_sql( f""" DELETE FROM {targets['heat_links']['schema']}. {targets['heat_links']['table']} WHERE carrier LIKE '%central_gas_boiler%' AND scn_name = '{scenario}' """ ) central_boilers = db.select_dataframe( f""" SELECT c.bus_id as bus0, b.bus_id as bus1, capacity, a.carrier, scenario as scn_name FROM {sources['district_heating_supply']['schema']}. {sources['district_heating_supply']['table']} a JOIN {targets['heat_buses']['schema']}. {targets['heat_buses']['table']} b ON ST_Transform(ST_Centroid(geometry), 4326) = geom JOIN {sources['ch4_voronoi']['schema']}. {sources['ch4_voronoi']['table']} c ON ST_Intersects(ST_Transform(a.geometry, 4326), c.geom) WHERE scenario = '{scenario}' AND b.scn_name = '{scenario}' AND a.carrier = 'gas_boiler' AND b.carrier='central_heat' AND c.carrier='CH4' AND c.scn_name = '{scenario}' """ ) # Add LineString topology central_boilers = link_geom_from_buses(central_boilers, scenario) # Add efficiency and marginal costs of gas boilers central_boilers["efficiency"] = get_sector_parameters("heat", "eGon2035")[ "efficiency" ]["central_gas_boiler"] central_boilers["marginal_cost"] = get_sector_parameters( "heat", "eGon2035" )["marginal_cost"]["central_gas_boiler"] # Transform thermal capacity to CH4 installed capacity central_boilers["p_nom"] = central_boilers.capacity.div( central_boilers.efficiency ) # Drop unused columns central_boilers.drop(["capacity"], axis=1, inplace=True) # Set index central_boilers.index += db.next_etrago_id("link") central_boilers.index.name = "link_id" # Set carrier name central_boilers.carrier = "central_gas_boiler" central_boilers.reset_index().to_postgis( targets["heat_links"]["table"], schema=targets["heat_links"]["schema"], con=db.engine(), if_exists="append", )
[docs]def insert_rural_gas_boilers(scenario="eGon2035"): """Inserts gas boilers for individual heating to eTraGo-table Parameters ---------- scenario : str, optional Name of the scenario. The default is 'eGon2035'. Returns ------- None. """ sources = config.datasets()["etrago_heat"]["sources"] targets = config.datasets()["etrago_heat"]["targets"] db.execute_sql( f""" DELETE FROM {targets['heat_links']['schema']}. {targets['heat_links']['table']} WHERE carrier = 'rural_gas_boiler' AND scn_name = '{scenario}' AND bus0 IN (SELECT bus_id FROM {targets['heat_buses']['schema']}. {targets['heat_buses']['table']} WHERE scn_name = '{scenario}' AND country = 'DE') AND bus1 IN (SELECT bus_id FROM {targets['heat_buses']['schema']}. {targets['heat_buses']['table']} WHERE scn_name = '{scenario}' AND country = 'DE') """ ) rural_boilers = db.select_dataframe( f""" SELECT c.bus_id as bus0, b.bus_id as bus1, capacity, a.carrier, scenario as scn_name FROM {sources['individual_heating_supply']['schema']}. {sources['individual_heating_supply']['table']} a JOIN {targets['heat_buses']['schema']}. {targets['heat_buses']['table']} b ON ST_Transform(ST_Centroid(a.geometry), 4326) = b.geom JOIN {sources['ch4_voronoi']['schema']}. {sources['ch4_voronoi']['table']} c ON ST_Intersects(ST_Transform(a.geometry, 4326), c.geom) WHERE scenario = '{scenario}' AND b.scn_name = '{scenario}' AND a.carrier = 'gas_boiler' AND b.carrier='rural_heat' AND c.carrier='CH4' AND c.scn_name = '{scenario}' """ ) # Add LineString topology rural_boilers = link_geom_from_buses(rural_boilers, scenario) # Add efficiency of gas boilers rural_boilers["efficiency"] = get_sector_parameters("heat", "eGon2035")[ "efficiency" ]["rural_gas_boiler"] # Transform thermal capacity to CH4 installed capacity rural_boilers["p_nom"] = rural_boilers.capacity.div( rural_boilers.efficiency ) # Drop unused columns rural_boilers.drop(["capacity"], axis=1, inplace=True) # Set index rural_boilers.index += db.next_etrago_id("link") rural_boilers.index.name = "link_id" # Set carrier name rural_boilers.carrier = "rural_gas_boiler" rural_boilers.reset_index().to_postgis( targets["heat_links"]["table"], schema=targets["heat_links"]["schema"], con=db.engine(), if_exists="append", )
[docs]def buses(): """Insert individual and district heat buses into eTraGo-tables Parameters ---------- Returns ------- None. """ insert_buses("central_heat", scenario="eGon2035") insert_buses("rural_heat", scenario="eGon2035") insert_buses("central_heat", scenario="eGon100RE") insert_buses("rural_heat", scenario="eGon100RE")
[docs]def supply(): """Insert individual and district heat supply into eTraGo-tables Parameters ---------- Returns ------- None. """ insert_central_direct_heat(scenario="eGon2035") insert_central_power_to_heat(scenario="eGon2035") insert_individual_power_to_heat(scenario="eGon2035") # insert_rural_gas_boilers(scenario="eGon2035") insert_central_gas_boilers(scenario="eGon2035")
[docs]class HeatEtrago(Dataset): def __init__(self, dependencies): super().__init__( name="HeatEtrago", version="0.0.10", dependencies=dependencies, tasks=(buses, supply, store), )