Skip to content

Commit

Permalink
Merge pull request #675 from PyPSA/fneum/line-rating
Browse files Browse the repository at this point in the history
Dynamic line rating
  • Loading branch information
FabianHofmann authored Jul 26, 2023
2 parents 799f4f3 + 1d5c8c7 commit e91dfdc
Show file tree
Hide file tree
Showing 10 changed files with 252 additions and 197 deletions.
6 changes: 6 additions & 0 deletions config/config.default.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -227,6 +227,12 @@ lines:
max_extension: .inf
length_factor: 1.25
under_construction: 'zero' # 'zero': set capacity to zero, 'remove': remove, 'keep': with full capacity
dynamic_line_rating:
activate: false
cutout: europe-2013-era5
correction_factor: 0.95
max_voltage_difference: false
max_line_rating: false

# docs in https://pypsa-eur.readthedocs.io/en/latest/configuration.html#links
links:
Expand Down
6 changes: 6 additions & 0 deletions config/test/config.electricity.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,12 @@ renewable:
clustering:
exclude_carriers: ["OCGT", "offwind-ac", "coal"]

lines:
dynamic_line_rating:
activate: true
cutout: be-03-2013-era5
max_line_rating: 1.3


solving:
solver:
Expand Down
5 changes: 5 additions & 0 deletions config/test/config.myopic.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,11 @@ renewable:
solar:
cutout: be-03-2013-era5

lines:
dynamic_line_rating:
activate: true
max_line_rating: 1.3

industry:
St_primary_fraction:
2030: 0.6
Expand Down
5 changes: 5 additions & 0 deletions config/test/config.overnight.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,11 @@ renewable:
solar:
cutout: be-03-2013-era5

lines:
dynamic_line_rating:
activate: true
max_line_rating: 1.3

sector:
gas_network: true
H2_retrofit: true
Expand Down
195 changes: 0 additions & 195 deletions data/costs.csv

This file was deleted.

6 changes: 6 additions & 0 deletions doc/configtables/lines.csv
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,9 @@ s_nom_max,MW,"float","Global upper limit for the maximum capacity of each extend
max_extension,MW,"float","Upper limit for the extended capacity of each extendable line."
length_factor,--,float,"Correction factor to account for the fact that buses are *not* connected by lines through air-line distance."
under_construction,--,"One of {'zero': set capacity to zero, 'remove': remove completely, 'keep': keep with full capacity}","Specifies how to handle lines which are currently under construction."
dynamic_line_rating,,,
-- activate,bool,"true or false","Whether to take dynamic line rating into account"
-- cutout,--,"Should be a folder listed in the configuration ``atlite: cutouts:`` (e.g. 'europe-2013-era5') or reference an existing folder in the directory ``cutouts``. Source module must be ERA5.","Specifies the directory where the relevant weather data ist stored."
-- correction_factor,--,"float","Factor to compensate for overestimation of wind speeds in hourly averaged wind data"
-- max_voltage_difference,deg,"float","Maximum voltage angle difference in degrees or 'false' to disable"
-- max_line_rating,--,"float","Maximum line rating relative to nominal capacity without DLR, e.g. 1.3 or 'false' to disable"
1 change: 1 addition & 0 deletions envs/environment.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ dependencies:
- descartes
- rasterio!=1.2.10


- pip:
- tsam>=1.1.0
- git+https://github.com/PyPSA/PyPSA.git@master
27 changes: 27 additions & 0 deletions rules/build_electricity.smk
Original file line number Diff line number Diff line change
Expand Up @@ -274,6 +274,30 @@ rule build_hydro_profile:
"../scripts/build_hydro_profile.py"


if config["lines"]["dynamic_line_rating"]["activate"]:

rule build_line_rating:
input:
base_network=RESOURCES + "networks/base.nc",
cutout="cutouts/"
+ CDIR
+ config["lines"]["dynamic_line_rating"]["cutout"]
+ ".nc",
output:
output=RESOURCES + "networks/line_rating.nc",
log:
LOGS + "build_line_rating.log",
benchmark:
BENCHMARKS + "build_line_rating"
threads: ATLITE_NPROCESSES
resources:
mem_mb=ATLITE_NPROCESSES * 1000,
conda:
"../envs/environment.yaml"
script:
"../scripts/build_line_rating.py"


rule add_electricity:
params:
length_factor=config["lines"]["length_factor"],
Expand All @@ -295,6 +319,9 @@ rule add_electricity:
if str(fn).startswith("data/")
},
base_network=RESOURCES + "networks/base.nc",
line_rating=RESOURCES + "networks/line_rating.nc"
if config["lines"]["dynamic_line_rating"]["activate"]
else RESOURCES + "networks/base.nc",
tech_costs=COSTS,
regions=RESOURCES + "regions_onshore.geojson",
powerplants=RESOURCES + "powerplants.csv",
Expand Down
43 changes: 41 additions & 2 deletions scripts/add_electricity.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@
# SPDX-FileCopyrightText: : 2017-2023 The PyPSA-Eur Authors
#
# SPDX-License-Identifier: MIT

# coding: utf-8
"""
Adds electrical generators and existing hydro storage units to a base network.
Expand Down Expand Up @@ -752,6 +750,30 @@ def estimate_renewable_capacities(n, year, tech_map, expansion_limit, countries)
)


def attach_line_rating(
n, rating, s_max_pu, correction_factor, max_voltage_difference, max_line_rating
):
# 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
Expand Down Expand Up @@ -834,6 +856,23 @@ def estimate_renewable_capacities(n, year, tech_map, expansion_limit, countries)

update_p_nom_max(n)

line_rating_config = snakemake.config["lines"]["dynamic_line_rating"]
if line_rating_config["activate"]:
rating = xr.open_dataarray(snakemake.input.line_rating).to_pandas().transpose()
s_max_pu = snakemake.config["lines"]["s_max_pu"]
correction_factor = line_rating_config["correction_factor"]
max_voltage_difference = line_rating_config["max_voltage_difference"]
max_line_rating = line_rating_config["max_line_rating"]

attach_line_rating(
n,
rating,
s_max_pu,
correction_factor,
max_voltage_difference,
max_line_rating,
)

sanitize_carriers(n, snakemake.config)

n.meta = snakemake.config
Expand Down
Loading

0 comments on commit e91dfdc

Please sign in to comment.