""" Builds clustered natural gas network based on data from: [1] the SciGRID Gas project (https://www.gas.scigrid.de/) [2] ENTSOG capacity map (https://www.entsog.eu/sites/default/files/2019-10/Capacities%20for%20Transmission%20Capacity%20Map%20RTS008_NS%20-%20DWH_final.xlsx) """ import logging logger = logging.getLogger(__name__) import re import json import pandas as pd import geopandas as gpd import numpy as np from shapely.geometry import Point def concat_gdf(gdf_list, crs='EPSG:4326'): """Convert to gepandas dataframe with given Coordinate Reference System (crs).""" return gpd.GeoDataFrame(pd.concat(gdf_list),crs=crs) def string2list(string, with_None=True): """Convert string format to a list.""" p = re.compile('(? MW clean_pipes.loc[:, 'capacity_recalculated'] *= 1e3 # rename columns to_rename = { 'capacity_recalculated': 'pipe_capacity_MW', 'buses_start': 'bus0', 'buses_destination': 'bus1' } clean_pipes.rename(columns=to_rename, inplace=True) return clean_pipes def diameter2capacity(pipe_diameter_mm): """Calculate pipe capacity based on diameter. 20 inch (500 mm) 50 bar -> 1.5 GW CH4 pipe capacity (LHV) 24 inch (600 mm) 50 bar -> 5 GW CH4 pipe capacity (LHV) 36 inch (900 mm) 50 bar -> 11.25 GW CH4 pipe capacity (LHV) 48 inch (1200 mm) 80 bar -> 21.7 GW CH4 pipe capacity (LHV) Based on p.15 of https://gasforclimate2050.eu/wp-content/uploads/2020/07/2020_European-Hydrogen-Backbone_Report.pdf """ # slopes definitions m0 = (5 - 1.5) / (600 - 500) m1 = (11.25 - 5) / (900 - 600) m2 = (21.7 - 11.25) / (1200 - 900) # intercept a0 = -16 a1 = -7.5 a2 = -20.1 if pipe_diameter_mm < 500: return np.nan elif pipe_diameter_mm < 600: return a0 + m0 * pipe_diameter_mm elif pipe_diameter_mm < 900: return a1 + m1 * pipe_diameter_mm else: return a2 + m2 * pipe_diameter_mm def determine_pipe_capacity(gas_network): """Check pipe capacity depending on diameter and pressure.""" gas_network["capacity_recalculated"] = gas_network.diameter_mm.apply(diameter2capacity) # if pipe capacity smaller than 1.5 GW take original pipe capacity low_cap = gas_network.Capacity_GWh_h < 1.5 gas_network.loc[low_cap, "capacity_recalculated"] = gas_network.loc[low_cap, "capacity_recalculated"].fillna(gas_network.loc[low_cap, "Capacity_GWh_h"]) # for pipes without diameter assume 500 mm diameter gas_network["capacity_recalculated"].fillna(1.5, inplace=True) # for nord stream take orginal data nord_stream = gas_network[gas_network.max_pressure_bar==220].index gas_network.loc[nord_stream, "capacity_recalculated"] = gas_network.loc[nord_stream, "Capacity_GWh_h"] if __name__ == "__main__": if 'snakemake' not in globals(): from helper import mock_snakemake snakemake = mock_snakemake('build_gas_network', network='elec', simpl='', clusters='37', lv='1.0', opts='', planning_horizons='2020', sector_opts='168H-T-H-B-I') logging.basicConfig(level=snakemake.config['logging_level']) # import gas network data gas_network, points = load_gas_network(snakemake.input.gas_network) # get clustered bus regions bus_regions = load_bus_regions( snakemake.input.regions_onshore, snakemake.input.regions_offshore ) nodes = pd.Index(bus_regions.name.unique()) # map gas network points to network buses points2buses_map = points2buses(points, bus_regions) # create gas network between pypsa nodes gas_connections = build_gas_network_topology(gas_network, points2buses_map) gas_connections = clean_dataset(nodes, gas_connections) gas_connections.to_csv(snakemake.output.clustered_gas_network)