Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions doc/release_notes.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@

* Extend `tyndp-archive` support to integrate three new datasets (`desnz_electricity_consumption`, `jrc_energy_atlas`, `ons_lad`) and two new versions (`nitrogen_statistics`, `synthetic_electricity_demand`) ([#758](https://github.com/open-energy-transition/open-tyndp/pull/758)).

* Restore correct assigned countries for virtual TYNDP nodes ([#794](https://github.com/open-energy-transition/open-tyndp/pull/794)).


**Documentation**

Expand Down
22 changes: 22 additions & 0 deletions scripts/base_network.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@
get_snapshots,
set_scenario_config,
)
from scripts.build_tyndp_network import AC_VIRTUAL_NODES_IT

PD_GE_2_2 = parse(pd.__version__) >= Version("2.2")

Expand Down Expand Up @@ -560,6 +561,25 @@ def prefer_voltage(x, which):
return buses


def _restore_virtual_node_countries_tyndp(
n: pypsa.Network, buses: pd.DataFrame
) -> None:
"""
Restore the declared country of TYNDP virtual nodes instead of coordinate-based country assignment
from `_set_countries_and_substations`.

Parameters
----------
n : pypsa.Network
Network whose `buses` country assignment is corrected in place.
buses : pd.DataFrame
Buses as loaded in `_load_buses`, holding the countries declared in
build_tyndp_network before the coordinate-based reassignment.
"""
nodes = n.buses.index.intersection(AC_VIRTUAL_NODES_IT)
n.buses.loc[nodes, "country"] = buses.loc[nodes, "country"]


def _replace_b2b_converter_at_country_border_by_link(n):
# Affects only the B2B converter in Lithuania at the Polish border at the moment
buscntry = n.buses.country
Expand Down Expand Up @@ -752,6 +772,8 @@ def base_network(

_set_countries_and_substations(n, config, country_shapes, offshore_shapes)

_restore_virtual_node_countries_tyndp(n, buses)

_set_links_underwater_fraction(n, offshore_shapes)

_replace_b2b_converter_at_country_border_by_link(n)
Expand Down
80 changes: 58 additions & 22 deletions scripts/build_tyndp_network.py
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,11 @@
"UK": "GB",
}

AC_VIRTUAL_NODES_IT = {
"ITCO": "FR15",
"ITVI": "ITSI",
}

IBFI_COORD = (63.0, 25.0)


Expand Down Expand Up @@ -223,6 +228,41 @@ def build_shapes(
return bidding_shapes, country_shapes


def _add_virtual_node(
target_gdf: gpd.GeoDataFrame,
new_bus: str,
ref_bus: str,
source_gdf: gpd.GeoDataFrame | None = None,
**overrides,
) -> None:
"""
Add a virtual node to target Dataframe as a copy of an existing reference bus.

The virtual node inherits every attribute of the reference bus and takes its
own name as ``station_id`` and ``tags``. Any remaining attribute is set
through ``overrides``.

Parameters
----------
target_gdf : gpd.GeoDataFrame
Bus GeoDataFrame the virtual node is appended to, modified in place.
new_bus : str
Name of the virtual node.
ref_bus : str
Name of the reference bus whose attributes are copied.
source_gdf : gpd.GeoDataFrame, optional
Bus GeoDataFrame holding the reference bus. Defaults to ``target``.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The default is None, which implies the use of target_df

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

jep, good point. I clarified it.

**overrides, optional
Attribute values overriding those inherited from the reference bus.
"""
source_gdf = target_gdf if source_gdf is None else source_gdf
target_gdf.loc[new_bus] = (
source_gdf.loc[[ref_bus]]
.assign(station_id=new_bus, tags=new_bus, **overrides)
.loc[ref_bus]
)


def build_buses(
buses_fn: str,
countries: list[str],
Expand Down Expand Up @@ -281,14 +321,10 @@ def build_buses(

# Manually add Italian virtual nodes # TODO Refine assumptions
if "IT" in countries:
buses.loc["ITCO"] = (
buses.loc[["FR15"]]
.assign(station_id="ITCO", country="IT", tags="ITCO")
.loc["FR15"]
)
buses.loc["ITVI"] = (
buses.loc[["ITSI"]].assign(station_id="ITVI", tags="ITVI").loc["ITSI"]
)
for node, location in AC_VIRTUAL_NODES_IT.items():
_add_virtual_node(
target_gdf=buses, new_bus=node, ref_bus=location, country="IT"
)

buses_h2 = (
country_shapes[["node", "x", "y"]]
Expand All @@ -309,23 +345,23 @@ def build_buses(

# Manually add IBIT and IBFI nodes # TODO Refine assumptions
if "IT" in countries:
buses_h2.loc["IBIT H2"] = (
buses.loc[["ITN1"]]
.assign(station_id="IBIT H2", voltage=None, dc="f", tags="IBIT H2")
.loc["ITN1"]
_add_virtual_node(
target_gdf=buses_h2,
new_bus="IBIT H2",
ref_bus="ITN1",
source_gdf=buses,
voltage=None,
dc="f",
)
if "FI" in countries:
ibfi_lat, ibfi_long = IBFI_COORD
buses_h2.loc["IBFI H2"] = (
buses_h2.loc[["FI H2"]]
.assign(
station_id="IBFI H2",
tags="IBFI H2",
x=ibfi_long,
y=ibfi_lat,
geometry=Point(ibfi_long, ibfi_lat),
)
.loc["FI H2"]
_add_virtual_node(
target_gdf=buses_h2,
new_bus="IBFI H2",
ref_bus="FI H2",
x=ibfi_long,
y=ibfi_lat,
geometry=Point(ibfi_long, ibfi_lat),
)

return buses, buses_h2
Expand Down
Loading