pypsa-eur/scripts/add_transmission_projects_and_dlr.py

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

107 lines
3.2 KiB
Python
Raw Permalink Normal View History

# -*- coding: utf-8 -*-
# SPDX-FileCopyrightText: : 2017-2024 The PyPSA-Eur Authors
#
# SPDX-License-Identifier: MIT
"""
Add transmission projects and DLR to the network.
"""
import logging
from pathlib import Path
import numpy as np
import pandas as pd
import pypsa
import xarray as xr
from _helpers import configure_logging, set_scenario_config
logger = logging.getLogger(__name__)
def attach_transmission_projects(
n: pypsa.Network, transmission_projects: list[str]
) -> None:
logger.info("Adding transmission projects to network.")
for path in transmission_projects:
path = Path(path)
df = pd.read_csv(path, index_col=0, dtype={"bus0": str, "bus1": str})
if df.empty:
continue
if "new_buses" in path.name:
n.madd("Bus", df.index, **df)
elif "new_lines" in path.name:
n.madd("Line", df.index, **df)
elif "new_links" in path.name:
n.madd("Link", df.index, **df)
elif "adjust_lines" in path.name:
n.lines.update(df)
elif "adjust_links" in path.name:
n.links.update(df)
def attach_line_rating(
n: pypsa.Network,
rating: pd.DataFrame,
s_max_pu: float,
correction_factor: float,
max_voltage_difference: float | bool,
max_line_rating: float | bool,
) -> None:
logger.info("Attaching dynamic line rating to network.")
# TODO: Only considers overhead lines
n.lines_t.s_max_pu = (rating / n.lines.s_nom[rating.columns]) * correction_factor
if max_voltage_difference:
x_pu = (
n.lines.type.map(n.line_types["x_per_length"])
* n.lines.length
/ (n.lines.v_nom**2)
)
# need to clip here as cap values might be below 1
# -> would mean the line cannot be operated at actual given pessimistic ampacity
s_max_pu_cap = (
np.deg2rad(max_voltage_difference) / (x_pu * n.lines.s_nom)
).clip(lower=1)
n.lines_t.s_max_pu = n.lines_t.s_max_pu.clip(
lower=1, upper=s_max_pu_cap, axis=1
)
if max_line_rating:
n.lines_t.s_max_pu = n.lines_t.s_max_pu.clip(upper=max_line_rating)
n.lines_t.s_max_pu *= s_max_pu
if __name__ == "__main__":
if "snakemake" not in globals():
from _helpers import mock_snakemake
snakemake = mock_snakemake("add_transmission_projects_and_dlr")
configure_logging(snakemake)
set_scenario_config(snakemake)
params = snakemake.params
n = pypsa.Network(snakemake.input.network)
if params["transmission_projects"]["enable"]:
attach_transmission_projects(n, snakemake.input.transmission_projects)
if params["dlr"]["activate"]:
rating = xr.open_dataarray(snakemake.input.dlr).to_pandas().transpose()
s_max_pu = params["s_max_pu"]
correction_factor = params["dlr"]["correction_factor"]
max_voltage_difference = params["dlr"]["max_voltage_difference"]
max_line_rating = params["dlr"]["max_line_rating"]
attach_line_rating(
n,
rating,
s_max_pu,
correction_factor,
max_voltage_difference,
max_line_rating,
)
n.export_to_netcdf(snakemake.output[0])