From 0ed9434fbb9a1b3df4d8a7d9b295be0ebe265823 Mon Sep 17 00:00:00 2001 From: Francesco Witte Date: Wed, 1 Jun 2022 16:51:30 +0200 Subject: [PATCH 1/4] Add p_nom for H2 feed-in links --- CHANGELOG.rst | 2 + .../data/datasets/hydrogen_etrago/__init__.py | 2 +- .../datasets/hydrogen_etrago/h2_to_ch4.py | 44 +++++++++++++++++-- 3 files changed, 43 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index e60d49fe4f..44fd0520e3 100755 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -357,6 +357,8 @@ Changed `#581 `_ * Update deposit id to access v0.7 of the zenodo repository `#736 `_ +* Include simplified restrictions for H2 feed-in into CH4 grid + `#790 `_ Bug Fixes diff --git a/src/egon/data/datasets/hydrogen_etrago/__init__.py b/src/egon/data/datasets/hydrogen_etrago/__init__.py index 83244775d5..bb118caa2d 100644 --- a/src/egon/data/datasets/hydrogen_etrago/__init__.py +++ b/src/egon/data/datasets/hydrogen_etrago/__init__.py @@ -67,7 +67,7 @@ class HydrogenMethaneLinkEtrago(Dataset): def __init__(self, dependencies): super().__init__( name="HydrogenMethaneLinkEtrago", - version="0.0.4", + version="0.0.5", dependencies=dependencies, tasks=(insert_h2_to_ch4_to_h2, insert_h2_to_ch4_eGon100RE), ) diff --git a/src/egon/data/datasets/hydrogen_etrago/h2_to_ch4.py b/src/egon/data/datasets/hydrogen_etrago/h2_to_ch4.py index 3560a3ce81..07045736d8 100644 --- a/src/egon/data/datasets/hydrogen_etrago/h2_to_ch4.py +++ b/src/egon/data/datasets/hydrogen_etrago/h2_to_ch4.py @@ -53,6 +53,45 @@ def insert_h2_to_ch4_to_h2(): scn_params = get_sector_parameters("gas", scn_name) + pipeline_capacities = db.select_dataframe( + f""" + SELECT bus0, bus1, p_nom FROM grid.egon_etrago_link + WHERE scn_name = '{scn_name}' AND carrier = 'CH4' + AND ( + bus0 IN ( + SELECT bus_id FROM grid.egon_etrago_bus + WHERE scn_name = '{scn_name}' AND country = 'DE' + ) OR bus1 IN ( + SELECT bus_id FROM grid.egon_etrago_bus + WHERE scn_name = '{scn_name}' AND country = 'DE' + ) + ); + """ + ) + + feed_in["p_nom"] = 0 + feed_in["p_nom_extendable"] = False + # calculation of H2 energy share via volumetric share outsourced + # in a mixture of H2 and CH4 with 15 %vol share at 50 bar and 25 °C, the + # energy share of H2 roughly corresponds to 5 % of total energy + # therefore, that fraction is multiplied to the pipeline capacity at each + # CH4 node for maximum H2 feedin + # -> Will upload lookup table to zenodo in future + H2_energy_share = 0.05 + + for bus in feed_in["bus1"].values: + # calculate the total pipeline capacity connected to a specific bus + nodal_capacity = pipeline_capacities.loc[ + (pipeline_capacities["bus0"] == bus) + | (pipeline_capacities["bus1"] == bus) + , "p_nom" + ].sum() + # multiply total pipeline capacity with H2 energy share corresponding + # to volumetric share + feed_in.loc[feed_in["bus1"] == bus, "p_nom"] = ( + nodal_capacity * H2_energy_share + ) + # Write new entries for table, carrier in zip( [methanation, SMR, feed_in], ["H2_to_CH4", "CH4_to_H2", "H2_feedin"] @@ -61,10 +100,7 @@ def insert_h2_to_ch4_to_h2(): # set parameters according to carrier name table["carrier"] = carrier table["efficiency"] = scn_params["efficiency"][carrier] - if carrier == "H2_feedin": - table["p_nom_extendable"] = False - table["p_nom"] = 1e9 - else: + if carrier != "H2_feedin": table["p_nom_extendable"] = True table["capital_cost"] = scn_params["capital_cost"][carrier] table["lifetime"] = scn_params["lifetime"][carrier] From 5435ccf5d465cf91ed0c70cc444409d6a658919f Mon Sep 17 00:00:00 2001 From: Francesco Witte Date: Fri, 3 Jun 2022 12:54:44 +0200 Subject: [PATCH 2/4] Add H2 energy share calculation for feedin --- .../datasets/hydrogen_etrago/h2_to_ch4.py | 76 +++++++++++++++++-- 1 file changed, 70 insertions(+), 6 deletions(-) diff --git a/src/egon/data/datasets/hydrogen_etrago/h2_to_ch4.py b/src/egon/data/datasets/hydrogen_etrago/h2_to_ch4.py index 07045736d8..ad3cc50b0f 100644 --- a/src/egon/data/datasets/hydrogen_etrago/h2_to_ch4.py +++ b/src/egon/data/datasets/hydrogen_etrago/h2_to_ch4.py @@ -72,12 +72,8 @@ def insert_h2_to_ch4_to_h2(): feed_in["p_nom"] = 0 feed_in["p_nom_extendable"] = False # calculation of H2 energy share via volumetric share outsourced - # in a mixture of H2 and CH4 with 15 %vol share at 50 bar and 25 °C, the - # energy share of H2 roughly corresponds to 5 % of total energy - # therefore, that fraction is multiplied to the pipeline capacity at each - # CH4 node for maximum H2 feedin - # -> Will upload lookup table to zenodo in future - H2_energy_share = 0.05 + # in a mixture of H2 and CH4 with 15 %vol share at 50 bar and 25 °C + H2_energy_share = H2_CH4_mix_energy_fractions(0.15, T=25, p=50) for bus in feed_in["bus1"].values: # calculate the total pipeline capacity connected to a specific bus @@ -124,3 +120,71 @@ def insert_h2_to_ch4_eGon100RE(): copy_and_modify_links( "eGon2035", "eGon100RE", ["H2_to_CH4", "CH4_to_H2"], "gas" ) + + +def H2_CH4_mix_energy_fractions(x, T=25, p=50): + """ + Calculate the fraction of H2 with respect to energy in a H2 CH4 mixture. + + Given the volumetric fraction of H2 in a H2 and CH4 mixture, the fraction + of H2 with respect to energy is calculated with the ideal gas mixture law. + Beware, that changing the fraction of H2 changes the overall energy within + a specific volume of the mixture. If H2 is fed into CH4, the pipeline + capacity (based on energy) therefore decreases if the volumetric flow + does not change. This effect is neglected in eGon. At 15 vol% H2 the + decrease in capacity equals about 10 % if volumetric flow does not change. + + Parameters + ---------- + x : float + Volumetric percentage of H2 in the mixture + T : int, optional + Temperature of the mixture, by default 25 + p : int, optional + Pressure of the mixture, by default 50 + + Returns + ------- + float + Fraction of H2 in mixture with respect to energy (LHV) + """ + + # molar masses + M_H2 = 0.00201588 + M_CH4 = 0.0160428 + + # universal gas constant (fluid independent!) + R_u = 8.31446261815324 + # individual gas constants + R_H2 = R_u / M_H2 + R_CH4 = R_u / M_CH4 + + # volume is fixed: 1m^3, use ideal gas law at 25 °C, 50 bar + V = 1 + T += 273.15 + p *= 1e5 + # volumetric shares of gases (specify share of H2) + V_H2 = x + V_CH4 = 1 - x + + # calculate data of mixture + M_mix = V_H2 * M_H2 + V_CH4 * M_CH4 + R_mix = R_u / M_mix + m_mix = p * V / (R_mix * T) + + # calulate masses with volumetric shares at mixture pressure + m_H2 = p * V_H2 / (R_H2 * T) + m_CH4 = p * V_CH4 / (R_CH4 * T) + + msg = ( + "Consistency check faild, individual masses are not equal to sum of " + "masses. Residual is: " + str(m_mix - m_H2 - m_CH4) + ) + assert round(m_mix - m_H2 - m_CH4, 6) == 0.0, msg + + LHV = { + "CH4": 50e6, + "H2": 120e6 + } + + return m_H2 * LHV["H2"] / (m_H2 * LHV["H2"] + m_CH4 * LHV["CH4"]) From b8f69d326bc0f67949c604379bfd8af794907d3f Mon Sep 17 00:00:00 2001 From: Francesco Witte Date: Fri, 3 Jun 2022 17:08:18 +0200 Subject: [PATCH 3/4] Move volumetric H2 share to scn_params --- src/egon/data/datasets/hydrogen_etrago/h2_to_ch4.py | 5 +++-- src/egon/data/datasets/scenario_parameters/parameters.py | 5 ++++- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/src/egon/data/datasets/hydrogen_etrago/h2_to_ch4.py b/src/egon/data/datasets/hydrogen_etrago/h2_to_ch4.py index ad3cc50b0f..79b4088091 100644 --- a/src/egon/data/datasets/hydrogen_etrago/h2_to_ch4.py +++ b/src/egon/data/datasets/hydrogen_etrago/h2_to_ch4.py @@ -72,8 +72,9 @@ def insert_h2_to_ch4_to_h2(): feed_in["p_nom"] = 0 feed_in["p_nom_extendable"] = False # calculation of H2 energy share via volumetric share outsourced - # in a mixture of H2 and CH4 with 15 %vol share at 50 bar and 25 °C - H2_energy_share = H2_CH4_mix_energy_fractions(0.15, T=25, p=50) + # in a mixture of H2 and CH4 with 15 %vol share + H2_share = scn_params["H2_feedin_volumetric_fraction"] + H2_energy_share = H2_CH4_mix_energy_fractions(H2_share) for bus in feed_in["bus1"].values: # calculate the total pipeline capacity connected to a specific bus diff --git a/src/egon/data/datasets/scenario_parameters/parameters.py b/src/egon/data/datasets/scenario_parameters/parameters.py index 20a71e4d40..ed9044e096 100644 --- a/src/egon/data/datasets/scenario_parameters/parameters.py +++ b/src/egon/data/datasets/scenario_parameters/parameters.py @@ -476,7 +476,10 @@ def gas(scenario): costs = read_csv(2035) - parameters = {"main_gas_carrier": "CH4"} + parameters = { + "main_gas_carrier": "CH4", + "H2_feedin_volumetric_fraction": 0.15, + } # Insert effciencies in p.u. parameters["efficiency"] = { "power_to_H2": read_costs(costs, "electrolysis", "efficiency"), From c74d52a5d92a489cd8d20d6a678079af6ff6baf9 Mon Sep 17 00:00:00 2001 From: Francesco Witte Date: Mon, 27 Jun 2022 14:06:14 +0200 Subject: [PATCH 4/4] Run black and isort --- src/egon/data/datasets/hydrogen_etrago/h2_to_ch4.py | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/src/egon/data/datasets/hydrogen_etrago/h2_to_ch4.py b/src/egon/data/datasets/hydrogen_etrago/h2_to_ch4.py index 79b4088091..6a1e7b99c1 100644 --- a/src/egon/data/datasets/hydrogen_etrago/h2_to_ch4.py +++ b/src/egon/data/datasets/hydrogen_etrago/h2_to_ch4.py @@ -80,8 +80,8 @@ def insert_h2_to_ch4_to_h2(): # calculate the total pipeline capacity connected to a specific bus nodal_capacity = pipeline_capacities.loc[ (pipeline_capacities["bus0"] == bus) - | (pipeline_capacities["bus1"] == bus) - , "p_nom" + | (pipeline_capacities["bus1"] == bus), + "p_nom", ].sum() # multiply total pipeline capacity with H2 energy share corresponding # to volumetric share @@ -183,9 +183,6 @@ def H2_CH4_mix_energy_fractions(x, T=25, p=50): ) assert round(m_mix - m_H2 - m_CH4, 6) == 0.0, msg - LHV = { - "CH4": 50e6, - "H2": 120e6 - } + LHV = {"CH4": 50e6, "H2": 120e6} return m_H2 * LHV["H2"] / (m_H2 * LHV["H2"] + m_CH4 * LHV["CH4"])