Skip to content

Commit

Permalink
Final adjustments for bidirectional lossy links
Browse files Browse the repository at this point in the history
Minor changes:
- add a transmission efficiency parameter to the Snakefile for add_extra_components and change the bidirectional lossy link implementation in _helpers.py to use the parameter rather than the full config as input
- add the adjustment to the override component input for Windows in the Snakefile to all rules calling solve_network.py
- revert the identification of backward links in solve_network.py to again accommodate the myopic naming scheme
  • Loading branch information
Eric-Nitschke committed Jan 14, 2025
1 parent b1ef404 commit 090eeb9
Show file tree
Hide file tree
Showing 4 changed files with 40 additions and 10 deletions.
23 changes: 20 additions & 3 deletions Snakefile
Original file line number Diff line number Diff line change
Expand Up @@ -732,6 +732,8 @@ if config["augmented_line_connection"].get("add_to_snakefile", False) == False:


rule add_extra_components:
params:
transmission_efficiency=config["sector"]["transmission_efficiency"],
input:
overrides="data/override_component_attrs",
network="networks/" + RDIR + "elec_s{simpl}_{clusters}.nc",
Expand Down Expand Up @@ -879,7 +881,12 @@ if config["monte_carlo"]["options"].get("add_to_snakefile", False) == True:
solving=config["solving"],
augmented_line_connection=config["augmented_line_connection"],
input:
overrides="data/override_component_attrs",
overrides=(
os.getcwd() + "/data/override_component_attrs"
if os.name == "nt"
else "data/override_component_attrs"
),
# on Windows os.getcwd() is required because of the "copy-minimal" shadow directory
network="networks/"
+ RDIR
+ "elec_s{simpl}_{clusters}_ec_l{ll}_{opts}_{unc}.nc",
Expand Down Expand Up @@ -1623,7 +1630,12 @@ if config["foresight"] == "overnight":
solving=config["solving"],
augmented_line_connection=config["augmented_line_connection"],
input:
overrides="data/override_component_attrs",
overrides=(
os.getcwd() + "/data/override_component_attrs"
if os.name == "nt"
else "data/override_component_attrs"
),
# on Windows os.getcwd() is required because of the "copy-minimal" shadow directory
# network=RESDIR
# + "prenetworks/elec_s{simpl}_{clusters}_ec_l{ll}_{opts}_{sopts}_{planning_horizons}_{discountrate}.nc",
network=RESDIR
Expand Down Expand Up @@ -2089,7 +2101,12 @@ if config["foresight"] == "myopic":
"co2_sequestration_potential", 200
),
input:
overrides="data/override_component_attrs",
overrides=(
os.getcwd() + "/data/override_component_attrs"
if os.name == "nt"
else "data/override_component_attrs"
),
# on Windows os.getcwd() is required because of the "copy-minimal" shadow directory
network=RESDIR
+ "prenetworks-brownfield/elec_s{simpl}_{clusters}_l{ll}_{opts}_{sopts}_{planning_horizons}_{discountrate}_{demand}_{h2export}export.nc",
costs=CDIR + "costs_{planning_horizons}.csv",
Expand Down
6 changes: 3 additions & 3 deletions scripts/_helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -1520,7 +1520,7 @@ def lossy_bidirectional_links(n, carrier):
n.links["length_original"] = n.links["length_original"].fillna(n.links.length)


def set_length_based_efficiency(n, carrier, bus_suffix, config):
def set_length_based_efficiency(n, carrier, bus_suffix, transmission_efficiency):
"""
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).
Expand All @@ -1532,12 +1532,12 @@ def set_length_based_efficiency(n, carrier, bus_suffix, config):
"""

# get the links length based efficiency and required compression
if carrier not in config["sector"]["transmission_efficiency"]:
if carrier not in transmission_efficiency:
raise KeyError(
f"An error occurred when setting the length based efficiency for the Links of type {carrier}."
f"The Link type {carrier} was not found in the config under config['sector']['transmission_efficiency']."
)
efficiencies = config["sector"]["transmission_efficiency"][carrier]
efficiencies = 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)
Expand Down
7 changes: 4 additions & 3 deletions scripts/add_extra_components.py
Original file line number Diff line number Diff line change
Expand Up @@ -231,7 +231,7 @@ def attach_stores(n, costs, config):
)


def attach_hydrogen_pipelines(n, costs, config):
def attach_hydrogen_pipelines(n, costs, config, transmission_efficiency):
elec_opts = config["electricity"]
ext_carriers = elec_opts["extendable_carriers"]
as_stores = ext_carriers.get("Store", [])
Expand Down Expand Up @@ -274,7 +274,7 @@ def attach_hydrogen_pipelines(n, costs, config):
lossy_bidirectional_links(n, "H2 pipeline")

# set the pipelines efficiency and the electricity required by the pipeline for compression
set_length_based_efficiency(n, "H2 pipeline", " H2", config)
set_length_based_efficiency(n, "H2 pipeline", " H2", transmission_efficiency)


if __name__ == "__main__":
Expand All @@ -288,6 +288,7 @@ def attach_hydrogen_pipelines(n, costs, config):
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
transmission_efficiency = snakemake.params.transmission_efficiency
config = snakemake.config

costs = load_costs(
Expand All @@ -299,7 +300,7 @@ def attach_hydrogen_pipelines(n, costs, config):

attach_storageunits(n, costs, config)
attach_stores(n, costs, config)
attach_hydrogen_pipelines(n, costs, config)
attach_hydrogen_pipelines(n, costs, config, transmission_efficiency)

add_nice_carrier_names(n, config=snakemake.config)

Expand Down
14 changes: 13 additions & 1 deletion scripts/solve_network.py
Original file line number Diff line number Diff line change
Expand Up @@ -871,8 +871,20 @@ def add_lossy_bidirectional_link_constraints(n: pypsa.components.Network) -> Non
n.links.carrier.isin(carriers) & ~n.links.reversed & n.links.p_nom_extendable
].index

# function to get backward (reversed) indices corresponding to forward links
# this function is required to properly interact with the myopic naming scheme
def get_backward_i(forward_i):
return pd.Index(
[
re.sub(r"-(\d{4})$", r"-reversed-\1", s)
if re.search(r"-\d{4}$", s)
else s + "-reversed"
for s in forward_i
]
)

# get the indices of all backward links (reversed)
backward_i = forward_i + "-reversed"
backward_i = get_backward_i(forward_i)

# get the p_nom optimization variables for the links using the get_var function
links_p_nom = get_var(n, "Link", "p_nom")
Expand Down

0 comments on commit 090eeb9

Please sign in to comment.