From 00b41f7910f2b076314447bb179d5fa6da3fa560 Mon Sep 17 00:00:00 2001 From: Eric Nitschke Date: Fri, 29 Nov 2024 16:54:01 +0100 Subject: [PATCH 1/4] Length based pipeline efficiency Major changes: - change the efficiency of H2 pipelines from a static value (that is somewhat faulty see BR #1213) to a length based calculation similar to PyPSA-Eur in scripts/add_extra_components.py. Minor changes: - override the networks component attributes in scripts/add_extra_components.py and scripts/solve_network.py to accomodate the length based efficiencies. - add the transmission efficiencies of H2 pipelines to the config. --- config.default.yaml | 8 ++++++ scripts/add_extra_components.py | 46 ++++++++++++++++++++++++++++++--- scripts/solve_network.py | 7 ++--- 3 files changed, 53 insertions(+), 8 deletions(-) diff --git a/config.default.yaml b/config.default.yaml index 19f26d96c..fa710675d 100644 --- a/config.default.yaml +++ b/config.default.yaml @@ -522,6 +522,14 @@ sector: lignite: spatial_lignite: false + # TODO: move this section to a different file + # efficiencies for length based link efficiencies. Copied from PyPSA-Eur. + transmission_efficiency: + H2 pipeline: + efficiency_static: 1 + efficiency_per_1000km: 1 # 0.982 + compression_per_1000km: 0.018 + international_bunkers: false #Whether or not to count the emissions of international aviation and navigation oil: diff --git a/scripts/add_extra_components.py b/scripts/add_extra_components.py index 2c317c305..3f7f334bd 100644 --- a/scripts/add_extra_components.py +++ b/scripts/add_extra_components.py @@ -57,7 +57,7 @@ import numpy as np import pandas as pd import pypsa -from _helpers import configure_logging, create_logger +from _helpers import configure_logging, create_logger, override_component_attrs from add_electricity import ( _add_missing_carriers_from_costs, add_nice_carrier_names, @@ -261,10 +261,49 @@ def attach_hydrogen_pipelines(n, costs, config): p_nom_extendable=True, length=h2_links.length.values, capital_cost=costs.at["H2 pipeline", "capital_cost"] * h2_links.length, - efficiency=costs.at["H2 pipeline", "efficiency"], carrier="H2 pipeline", ) + # TODO: when using the lossy_bidirectional_links fix, move this line AFTER lossy_bidirectional_links() + # set the pipelines's efficiency + set_length_based_efficiency(n, "H2 pipeline", " H2",config) + + +def set_length_based_efficiency(n: pypsa.components.Network, carrier: str, bus_suffix: str, config: dict) -> None: + + ''' + Set the efficiency of all links of type carrier in network n based on their length and the values specified in the config. + Additionally add the length based electricity demand, required for compression (if applicable). + ''' + + # get the links length based efficiency and required compression + efficiencies = config["sector"]["transmission_efficiency"][carrier] + efficiency_static = efficiencies.get("efficiency_static", 1) + efficiency_per_1000km = efficiencies.get("efficiency_per_1000km", 1) + compression_per_1000km = efficiencies.get("compression_per_1000km", 0) + + # indetify all links of type carrier + carrier_i = n.links.loc[n.links.carrier == carrier].index + + # set the links' length based efficiency + n.links.loc[carrier_i, "efficiency"] = ( + efficiency_static + * efficiency_per_1000km ** (n.links.loc[carrier_i, "length"] / 1e3) + ) + + # set the links's electricity demand for compression + if compression_per_1000km > 0: + n.links.loc[carrier_i, "bus2"] = n.links.loc[carrier_i, "bus0"].str.removesuffix(bus_suffix) + # TODO: use these lines to set bus 2 instead, once n.buses.location is functional and remove bus_suffix. + ''' + n.links.loc[carrier_i, "bus2"] = n.links.loc[carrier_i, "bus0"].map( + n.buses.location + ) # electricity + ''' + n.links.loc[carrier_i, "efficiency2"] = ( + -compression_per_1000km * n.links.loc[carrier_i, "length"] / 1e3 # TODO: change to length_original when using the lossy_bidirectional_links fix + ) + if __name__ == "__main__": if "snakemake" not in globals(): @@ -274,7 +313,8 @@ def attach_hydrogen_pipelines(n, costs, config): configure_logging(snakemake) - n = pypsa.Network(snakemake.input.network) + overrides = override_component_attrs(snakemake.input.overrides) + n = pypsa.Network(snakemake.input.network, override_component_attrs=overrides) Nyears = n.snapshot_weightings.objective.sum() / 8760.0 config = snakemake.config diff --git a/scripts/solve_network.py b/scripts/solve_network.py index a9bbfbaa1..10d8a4751 100755 --- a/scripts/solve_network.py +++ b/scripts/solve_network.py @@ -986,11 +986,8 @@ def solve_network(n, config, solving={}, opts="", **kwargs): is_sector_coupled = "sopts" in snakemake.wildcards.keys() - if is_sector_coupled: - overrides = override_component_attrs(snakemake.input.overrides) - n = pypsa.Network(snakemake.input.network, override_component_attrs=overrides) - else: - n = pypsa.Network(snakemake.input.network) + overrides = override_component_attrs(snakemake.input.overrides) + n = pypsa.Network(snakemake.input.network, override_component_attrs=overrides) if snakemake.params.augmented_line_connection.get("add_to_snakefile"): n.lines.loc[n.lines.index.str.contains("new"), "s_nom_min"] = ( From e0928be5f707a1ee618ff292f47bdc00ac9da5d4 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Fri, 29 Nov 2024 16:09:59 +0000 Subject: [PATCH 2/4] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- scripts/add_extra_components.py | 27 ++++++++++++++++----------- 1 file changed, 16 insertions(+), 11 deletions(-) diff --git a/scripts/add_extra_components.py b/scripts/add_extra_components.py index 3f7f334bd..9a72482e6 100644 --- a/scripts/add_extra_components.py +++ b/scripts/add_extra_components.py @@ -264,24 +264,25 @@ def attach_hydrogen_pipelines(n, costs, config): carrier="H2 pipeline", ) - # TODO: when using the lossy_bidirectional_links fix, move this line AFTER lossy_bidirectional_links() + # TODO: when using the lossy_bidirectional_links fix, move this line AFTER lossy_bidirectional_links() # set the pipelines's efficiency - set_length_based_efficiency(n, "H2 pipeline", " H2",config) + set_length_based_efficiency(n, "H2 pipeline", " H2", config) -def set_length_based_efficiency(n: pypsa.components.Network, carrier: str, bus_suffix: str, config: dict) -> None: - - ''' +def set_length_based_efficiency( + n: pypsa.components.Network, carrier: str, bus_suffix: str, config: dict +) -> None: + """ Set the efficiency of all links of type carrier in network n based on their length and the values specified in the config. Additionally add the length based electricity demand, required for compression (if applicable). - ''' + """ # get the links length based efficiency and required compression efficiencies = config["sector"]["transmission_efficiency"][carrier] efficiency_static = efficiencies.get("efficiency_static", 1) efficiency_per_1000km = efficiencies.get("efficiency_per_1000km", 1) compression_per_1000km = efficiencies.get("compression_per_1000km", 0) - + # indetify all links of type carrier carrier_i = n.links.loc[n.links.carrier == carrier].index @@ -293,15 +294,19 @@ def set_length_based_efficiency(n: pypsa.components.Network, carrier: str, bus_s # set the links's electricity demand for compression if compression_per_1000km > 0: - n.links.loc[carrier_i, "bus2"] = n.links.loc[carrier_i, "bus0"].str.removesuffix(bus_suffix) + n.links.loc[carrier_i, "bus2"] = n.links.loc[ + carrier_i, "bus0" + ].str.removesuffix(bus_suffix) # TODO: use these lines to set bus 2 instead, once n.buses.location is functional and remove bus_suffix. - ''' + """ n.links.loc[carrier_i, "bus2"] = n.links.loc[carrier_i, "bus0"].map( n.buses.location ) # electricity - ''' + """ n.links.loc[carrier_i, "efficiency2"] = ( - -compression_per_1000km * n.links.loc[carrier_i, "length"] / 1e3 # TODO: change to length_original when using the lossy_bidirectional_links fix + -compression_per_1000km + * n.links.loc[carrier_i, "length"] + / 1e3 # TODO: change to length_original when using the lossy_bidirectional_links fix ) From f1c2f4dc4f0ad31b605004154c29ad07a7094892 Mon Sep 17 00:00:00 2001 From: Eric Nitschke Date: Thu, 19 Dec 2024 10:32:58 +0100 Subject: [PATCH 3/4] Revert "[pre-commit.ci] auto fixes from pre-commit.com hooks" This reverts commit e0928be5f707a1ee618ff292f47bdc00ac9da5d4. --- scripts/add_extra_components.py | 27 +++++++++++---------------- 1 file changed, 11 insertions(+), 16 deletions(-) diff --git a/scripts/add_extra_components.py b/scripts/add_extra_components.py index 9a72482e6..3f7f334bd 100644 --- a/scripts/add_extra_components.py +++ b/scripts/add_extra_components.py @@ -264,25 +264,24 @@ def attach_hydrogen_pipelines(n, costs, config): carrier="H2 pipeline", ) - # TODO: when using the lossy_bidirectional_links fix, move this line AFTER lossy_bidirectional_links() + # TODO: when using the lossy_bidirectional_links fix, move this line AFTER lossy_bidirectional_links() # set the pipelines's efficiency - set_length_based_efficiency(n, "H2 pipeline", " H2", config) + set_length_based_efficiency(n, "H2 pipeline", " H2",config) -def set_length_based_efficiency( - n: pypsa.components.Network, carrier: str, bus_suffix: str, config: dict -) -> None: - """ +def set_length_based_efficiency(n: pypsa.components.Network, carrier: str, bus_suffix: str, config: dict) -> None: + + ''' Set the efficiency of all links of type carrier in network n based on their length and the values specified in the config. Additionally add the length based electricity demand, required for compression (if applicable). - """ + ''' # get the links length based efficiency and required compression efficiencies = config["sector"]["transmission_efficiency"][carrier] efficiency_static = efficiencies.get("efficiency_static", 1) efficiency_per_1000km = efficiencies.get("efficiency_per_1000km", 1) compression_per_1000km = efficiencies.get("compression_per_1000km", 0) - + # indetify all links of type carrier carrier_i = n.links.loc[n.links.carrier == carrier].index @@ -294,19 +293,15 @@ def set_length_based_efficiency( # set the links's electricity demand for compression if compression_per_1000km > 0: - n.links.loc[carrier_i, "bus2"] = n.links.loc[ - carrier_i, "bus0" - ].str.removesuffix(bus_suffix) + n.links.loc[carrier_i, "bus2"] = n.links.loc[carrier_i, "bus0"].str.removesuffix(bus_suffix) # TODO: use these lines to set bus 2 instead, once n.buses.location is functional and remove bus_suffix. - """ + ''' n.links.loc[carrier_i, "bus2"] = n.links.loc[carrier_i, "bus0"].map( n.buses.location ) # electricity - """ + ''' n.links.loc[carrier_i, "efficiency2"] = ( - -compression_per_1000km - * n.links.loc[carrier_i, "length"] - / 1e3 # TODO: change to length_original when using the lossy_bidirectional_links fix + -compression_per_1000km * n.links.loc[carrier_i, "length"] / 1e3 # TODO: change to length_original when using the lossy_bidirectional_links fix ) From a8e57318d2f755c48caa3a2f82d97a14b1bdf4d5 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Thu, 19 Dec 2024 09:34:05 +0000 Subject: [PATCH 4/4] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- scripts/add_extra_components.py | 27 ++++++++++++++++----------- 1 file changed, 16 insertions(+), 11 deletions(-) diff --git a/scripts/add_extra_components.py b/scripts/add_extra_components.py index 3f7f334bd..9a72482e6 100644 --- a/scripts/add_extra_components.py +++ b/scripts/add_extra_components.py @@ -264,24 +264,25 @@ def attach_hydrogen_pipelines(n, costs, config): carrier="H2 pipeline", ) - # TODO: when using the lossy_bidirectional_links fix, move this line AFTER lossy_bidirectional_links() + # TODO: when using the lossy_bidirectional_links fix, move this line AFTER lossy_bidirectional_links() # set the pipelines's efficiency - set_length_based_efficiency(n, "H2 pipeline", " H2",config) + set_length_based_efficiency(n, "H2 pipeline", " H2", config) -def set_length_based_efficiency(n: pypsa.components.Network, carrier: str, bus_suffix: str, config: dict) -> None: - - ''' +def set_length_based_efficiency( + n: pypsa.components.Network, carrier: str, bus_suffix: str, config: dict +) -> None: + """ Set the efficiency of all links of type carrier in network n based on their length and the values specified in the config. Additionally add the length based electricity demand, required for compression (if applicable). - ''' + """ # get the links length based efficiency and required compression efficiencies = config["sector"]["transmission_efficiency"][carrier] efficiency_static = efficiencies.get("efficiency_static", 1) efficiency_per_1000km = efficiencies.get("efficiency_per_1000km", 1) compression_per_1000km = efficiencies.get("compression_per_1000km", 0) - + # indetify all links of type carrier carrier_i = n.links.loc[n.links.carrier == carrier].index @@ -293,15 +294,19 @@ def set_length_based_efficiency(n: pypsa.components.Network, carrier: str, bus_s # set the links's electricity demand for compression if compression_per_1000km > 0: - n.links.loc[carrier_i, "bus2"] = n.links.loc[carrier_i, "bus0"].str.removesuffix(bus_suffix) + n.links.loc[carrier_i, "bus2"] = n.links.loc[ + carrier_i, "bus0" + ].str.removesuffix(bus_suffix) # TODO: use these lines to set bus 2 instead, once n.buses.location is functional and remove bus_suffix. - ''' + """ n.links.loc[carrier_i, "bus2"] = n.links.loc[carrier_i, "bus0"].map( n.buses.location ) # electricity - ''' + """ n.links.loc[carrier_i, "efficiency2"] = ( - -compression_per_1000km * n.links.loc[carrier_i, "length"] / 1e3 # TODO: change to length_original when using the lossy_bidirectional_links fix + -compression_per_1000km + * n.links.loc[carrier_i, "length"] + / 1e3 # TODO: change to length_original when using the lossy_bidirectional_links fix )