Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor: update values and logic for representative transformer designs #286

Merged
merged 4 commits into from
May 5, 2022
Merged
Show file tree
Hide file tree
Changes from all 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
27 changes: 0 additions & 27 deletions prereise/gather/griddata/hifld/const.py
Original file line number Diff line number Diff line change
Expand Up @@ -127,33 +127,6 @@
"500": 500,
}

transformer_reactance = { # per-unit
(69, 115): 0.14242,
(69, 138): 0.10895,
(69, 161): 0.14943,
(69, 230): 0.09538,
(69, 345): 0.08896,
(115, 161): 0.04516,
(115, 230): 0.04299,
(115, 345): 0.04020,
(115, 500): 0.06182,
(138, 161): 0.02818,
(138, 230): 0.03679,
(138, 345): 0.03889,
(138, 500): 0.03279,
(138, 765): 0.02284,
(161, 230): 0.06539,
(161, 345): 0.03293,
(161, 500): 0.06978,
(230, 345): 0.02085,
(230, 500): 0.01846,
(230, 765): 0.01616,
(345, 500): 0.01974,
(345, 765): 0.01625,
(500, 765): 0.00436,
}
transformer_rating = 800 # MVA

eia_storage_gen_types = {
"Batteries",
"Flywheels",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
high_kV,x_to_r_ratio
69,20
115,25
138,27
161,28
230,30
345,60
500,70
765,80
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
sub_id,low_kV,high_kV,number
300060,69,138,4
300940,69,138,2
304621,69,138,3
308608,69,138,3
24 changes: 24 additions & 0 deletions prereise/gather/griddata/hifld/data/transformer_params.csv
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
low_kV,high_kV,x,MVA
69,115,0.19,60
69,138,0.14,100
69,161,0.12,85
69,230,0.11,190
69,345,0.07,250
115,161,0.048,180
115,230,0.044,290
115,345,0.046,400
115,500,0.047,300
138,161,0.028,220
138,230,0.041,330
138,345,0.033,480
138,500,0.045,470
138,765,0.024,850
161,230,0.042,330
161,345,0.028,500
161,500,0.016,1100
230,345,0.018,580
230,500,0.013,1100
230,765,0.0165,1250
345,500,0.0105,1100
345,765,0.0085,2100
500,765,0.0045,2100
52 changes: 52 additions & 0 deletions prereise/gather/griddata/hifld/data_access/load.py
Original file line number Diff line number Diff line change
Expand Up @@ -336,6 +336,58 @@ def get_hifld_electric_power_transmission_lines(path):
return properties.query("STATUS == 'IN SERVICE' or STATUS == 'NOT AVAILABLE'")


def get_transformer_number_overrides(path):
"""Load overrides for the number of transformers between buses.

:param str path: path to a CSV file containing columns: 'sub_id', 'low_kV',
'high_kV', and 'number'.
:return: (*pandas.Series*) -- index is a MultiIndex of
('sub_id', 'low_kV', 'high_kV'), values are 'number' integers.
"""
return pd.read_csv(path).set_index(["sub_id", "low_kV", "high_kV"]).squeeze()


def get_transformer_parameters(
data_dir=None, transformer_designs_path=None, impedance_ratios_path=None
):
"""Load transformer designs (by voltage pairs) and transformer impedance ratios
(by higher voltage) and combine into a single dataframe.

:param str data_dir: if this is not None, two files in this directory will be
loaded: 'transformer_params.csv' and 'transformer_impedance_ratios.csv'.
Required columns for each file are listed in the descriptions of
the ``transformer_designs_path`` and ``impedance_ratios_path`` parameters.
:param str transformer_designs_path: if ``data_dir`` is None, this file will be
loaded. Required columns are 'low_kV', 'high_kV', 'x', and 'MVA'.
:param str impedance_ratios_path: if ``data_dir`` is None, this file will be loaded.
Required columns are 'high_kV' and 'x_to_r_ratio'.
:raises TypeError: if ``data_dir`` is None and either of
``transformer_designs_path`` or ``impedance_ratios_path`` is None.
:return: (*pandas.DataFrame*) -- index is (low_kV, high_kV), columns are 'x', 'r',
and 'MVA'. 'x' and 'r' values are per-unit, 'MVA' is in megawatts.
"""
if data_dir is None and (
transformer_designs_path is None or impedance_ratios_path is None
):
raise TypeError(
"Either data_dir or transformer_designs_path and impedance_ratios_path "
"must be specified."
)
if data_dir is not None:
transformer_designs_path = os.path.join(data_dir, "transformer_params.csv")
impedance_ratios_path = os.path.join(
data_dir, "transformer_impedance_ratios.csv"
)
transformer_designs = pd.read_csv(transformer_designs_path)
transformer_impedance_ratios = pd.read_csv(
impedance_ratios_path, index_col="high_kV"
)
transformer_designs["r"] = transformer_designs["x"] / transformer_designs[
"high_kV"
].map(transformer_impedance_ratios["x_to_r_ratio"])
return transformer_designs.set_index(["low_kV", "high_kV"])[["x", "r", "MVA"]]


def get_zone(path):
"""Read zone CSV file.

Expand Down
109 changes: 41 additions & 68 deletions prereise/gather/griddata/hifld/data_process/tests/test_transmission.py
Original file line number Diff line number Diff line change
@@ -1,20 +1,15 @@
from unittest.mock import Mock

import pandas as pd
import pytest
from pandas.testing import assert_frame_equal, assert_series_equal

from prereise.gather.griddata.hifld import const
from prereise.gather.griddata.hifld.data_process.transmission import (
add_b2bs_to_dc_lines,
add_impedance_and_rating,
add_lines_impedances_ratings,
add_substation_info_to_buses,
assign_buses_to_lines,
augment_line_voltages,
create_buses,
create_transformers,
estimate_branch_impedance,
estimate_branch_rating,
filter_islands_and_connect_with_mst,
map_lines_to_substations_using_coords,
split_lines_to_ac_and_dc,
Expand All @@ -37,7 +32,7 @@ def test_add_b2bs_to_dc_lines():
assert_frame_equal(dc_lines.iloc[2:], expected_new_rows)


def test_add_impedance_and_rating():
def test_add_lines_impedances_ratings():
branch = pd.DataFrame(
{
"VOLTAGE": [69, 75, 75, 138],
Expand All @@ -52,7 +47,7 @@ def test_add_impedance_and_rating():
}
)
expected_modified_branch = pd.concat([branch, expected_new_columns], axis=1)
add_impedance_and_rating(branch, bus_voltages=None)
add_lines_impedances_ratings(branch)
assert_frame_equal(branch, expected_modified_branch)


Expand Down Expand Up @@ -185,71 +180,49 @@ def test_create_transformers():
},
dtype="float",
)
expected_transformers = pd.DataFrame(
{"from_bus_id": [0, 2, 4, 5], "to_bus_id": [1, 3, 5, 6]}
)
transformers = create_transformers(bus)
assert_frame_equal(transformers, expected_transformers)


def test_estimate_branch_impedance_lines():
resistance = 0.01
reactance = 0.1
fake_lines = [Mock(series_impedance=(resistance + 1j * reactance))] * 3
branch = pd.DataFrame(
{"VOLTAGE": [69, 70, 345], "type": ["Line"] * 3, "line_object": fake_lines}
transformer_designs = pd.DataFrame(
{
"x": [0.19, 0.07, 0.044, 0.018],
"r": [0.01, 0.001, 0.001, 5e-4],
"MVA": [60, 250, 280, 580],
},
index=pd.MultiIndex.from_tuples([(69, 115), (69, 345), (115, 230), (230, 345)]),
)
x = estimate_branch_impedance(branch.iloc[0], pd.Series())
assert x == reactance / (69**2 / const.s_base)
x = estimate_branch_impedance(branch.iloc[1], pd.Series())
assert x == reactance / (70**2 / const.s_base)
x = estimate_branch_impedance(branch.iloc[2], pd.Series())
assert x == reactance / (345**2 / const.s_base)


def test_estimate_branch_impedance_transformers():
transformers = pd.DataFrame(
{"from_bus_id": [0, 1, 2], "to_bus_id": [1, 2, 3], "type": ["Transformer"] * 3}
lines = pd.DataFrame(
[
# One branch to low-voltage side of buses (0, 1) transformer
{"from_bus_id": 100, "to_bus_id": 0, "rateA": 75},
# Two branches to high-voltage side of buses (0, 1) transformer
{"from_bus_id": 1, "to_bus_id": 101, "rateA": 100},
{"from_bus_id": 1, "to_bus_id": 102, "rateA": 300},
# Two branches to low-voltage side of buses (2, 3) transformer
{"from_bus_id": 103, "to_bus_id": 2, "rateA": 50},
{"from_bus_id": 104, "to_bus_id": 2, "rateA": 100},
# One branch to high-voltage side of buses (2, 3) transformer
{"from_bus_id": 3, "to_bus_id": 105, "rateA": 300},
# One branch to each side of buses (5, 6) transformer
# The second of these is also on the high-voltage side of buses (4, 5) xfmr
{"from_bus_id": 6, "to_bus_id": 106, "rateA": 500},
{"from_bus_id": 5, "to_bus_id": 107, "rateA": 250},
# One branch connected to no transformers
{"from_bus_id": 998, "to_bus_id": 999, "rateA": 100e3},
]
)
bus_voltages = pd.Series([69, 230, 350, 500])
x = estimate_branch_impedance(transformers.iloc[0], bus_voltages)
assert x == const.transformer_reactance[(69, 230)]
x = estimate_branch_impedance(transformers.iloc[1], bus_voltages)
assert x == const.transformer_reactance[(230, 345)]
x = estimate_branch_impedance(transformers.iloc[2], bus_voltages)
assert x == const.transformer_reactance[(345, 500)]


def test_estimate_branch_rating_lines():
fake_ratings = pd.Series([10, 20, 30, 40])
fake_thermal_ratings = pd.Series([100, 200, 300, 400])
fake_lines = [Mock(power_rating=i) for i in fake_ratings]
branch = pd.DataFrame(
# One transformer to (0, 1) (only needs to support the low-voltage power)
# Three transformer to (2, 3) (low-voltage side requires 3x transformers in total)
# One transformer to (4, 5) (only needs to support the low-voltage power)
# One transformer to (5, 6) (only needs to support the low-voltage power)
expected_transformers = pd.DataFrame(
{
"VOLTAGE": [69, 140, 345, 499],
"type": ["Line"] * 4,
"line_object": fake_lines,
"from_bus_id": [0, 2, 2, 2, 4, 5],
"to_bus_id": [1, 3, 3, 3, 5, 6],
"x": [0.07, 0.19, 0.19, 0.19, 0.044, 0.018],
"r": [0.001, 0.01, 0.01, 0.01, 0.001, 5e-4],
"rateA": [250.0, 60.0, 60.0, 60.0, 280.0, 580.0],
}
)
assert_series_equal(
fake_ratings,
branch.apply(estimate_branch_rating, args=[None, fake_thermal_ratings], axis=1),
)


def test_estimate_branch_rating_transformers():
thermal_ratings = pd.Series([100, 550, 1655, 2585], index=[69, 230, 345, 500])
transformers = pd.DataFrame(
{"from_bus_id": [0, 1, 2], "to_bus_id": [1, 2, 3], "type": ["Transformer"] * 3}
)
bus_voltages = pd.Series([69, 230, 350, 500])

rating = estimate_branch_rating(transformers.iloc[0], bus_voltages, thermal_ratings)
assert rating == const.transformer_rating
rating = estimate_branch_rating(transformers.iloc[1], bus_voltages, thermal_ratings)
assert rating == const.transformer_rating * 3
rating = estimate_branch_rating(transformers.iloc[2], bus_voltages, thermal_ratings)
assert rating == const.transformer_rating * 4
transformers = create_transformers(bus, lines, transformer_designs)
assert_frame_equal(transformers, expected_transformers)


def test_filter_islands_and_connect_with_mst():
Expand Down
Loading