Skip to content

Commit

Permalink
Length based pipeline efficiency
Browse files Browse the repository at this point in the history
Major changes:
- change the efficiency of H2 pipelines from a static value (that is somewhat faulty see BR pypsa-meets-earth#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.
  • Loading branch information
Eric-Nitschke committed Nov 29, 2024
1 parent e386102 commit 00b41f7
Show file tree
Hide file tree
Showing 3 changed files with 53 additions and 8 deletions.
8 changes: 8 additions & 0 deletions config.default.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down
46 changes: 43 additions & 3 deletions scripts/add_extra_components.py
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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():
Expand All @@ -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

Expand Down
7 changes: 2 additions & 5 deletions scripts/solve_network.py
Original file line number Diff line number Diff line change
Expand Up @@ -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"] = (
Expand Down

0 comments on commit 00b41f7

Please sign in to comment.