Source code for prereise.gather.griddata.transmission.tests.test_geometry

from math import pi, sqrt

import pytest

from prereise.gather.griddata.transmission.const import kilometers_per_mile as km_per_mi
from prereise.gather.griddata.transmission.geometry import (
    Conductor,
    ConductorBundle,
    Line,
    PhaseLocations,
    Tower,
)

# Conversion factor for tower spacing in feet to tower spacing in meters
m_in_ft = 304.8e-3


[docs]def test_conductor_by_parameter_values(): # 'Cardinal' conductor outer_diameter = 0.03038 strand_radius = 1.688e-3 rated_dc_resistance_per_1000_ft = 0.0179 rated_dc_resistance_per_km = rated_dc_resistance_per_1000_ft * 3.2808 # Calculate for solid-aluminum (resistance should be lower than rated) conductor = Conductor(radius=(outer_diameter / 2), material="aluminum") assert conductor.resistance_per_km < rated_dc_resistance_per_km # Count 54 aluminum strands only for conductance purposes, ignore 7 steel strands # (resistance should be approximately equal to rated) area = 54 * pi * strand_radius**2 conductor = Conductor( radius=(outer_diameter / 2), area=area, material="aluminum", current_limit=1015, ) assert conductor.resistance_per_km == pytest.approx(rated_dc_resistance_per_km, 0.1)
[docs]def test_conductor_by_name(): conductor = Conductor("cardinal") assert conductor.resistance_per_km == 0.0709 assert conductor.radius == pytest.approx(0.01519) assert conductor.name == "Cardinal"
[docs]def test_conductor_name_and_parameters(): with pytest.raises(TypeError): Conductor("Cardinal", resistance_per_km=0.1)
[docs]def test_conductor_bundle(): spacing = 0.4572 conductor = Conductor("Cardinal") # standard ACSR conductor for n in (2, 3): bundle = ConductorBundle(n=n, spacing=spacing, conductor=conductor) assert bundle.resistance_per_km == conductor.resistance_per_km / n assert bundle.spacing_L == (conductor.gmr * spacing ** (n - 1)) ** (1 / n) assert bundle.spacing_C == (conductor.radius * spacing ** (n - 1)) ** (1 / n)
[docs]def test_tower_single_circuit(): # Tower has two-conductor bundles (1.5 ft spacing), 24 ft b/w phases, 90 ft height spacing = 1.5 * m_in_ft locations = PhaseLocations( a=(-24 * m_in_ft, 90 * m_in_ft), b=(0, 90 * m_in_ft), c=(24 * m_in_ft, 90 * m_in_ft), ) # Instantiate objects conductor = Conductor("Cardinal") # standard ACSR conductor bundle = ConductorBundle(n=2, spacing=spacing, conductor=conductor) tower = Tower(locations=locations, bundle=bundle) # Calculate for 50-mile distances (test case) resistance_per_50_mi = tower.resistance * 50 * km_per_mi series_reactance_per_50_mi = 2 * pi * 60 * tower.inductance * 50 * km_per_mi shunt_admittance_per_50_mi = 2 * pi * 60 * tower.capacitance * 50 * km_per_mi # Expected values expected_resistance = 2.82 # Ohms expected_series_reactance = 29.2 # Ohms expected_shunt_admittance = 3.59e-4 # Siemens # Check # relative tolerance of 5% to account for unknown temperature for resistivity assert resistance_per_50_mi == pytest.approx(expected_resistance, rel=0.05) # Reactance & admittance values match within 1%, since they're purely gemetric assert series_reactance_per_50_mi == pytest.approx( expected_series_reactance, rel=0.01 ) assert shunt_admittance_per_50_mi == pytest.approx( expected_shunt_admittance, rel=0.01 ) line = Line(tower=tower, length=(50 * km_per_mi), voltage=345) assert line.power_rating == pytest.approx(1207, rel=0.01)
[docs]def test_tower_double_circuit(): locations = PhaseLocations( circuits=2, a=((-9 * m_in_ft, 120 * m_in_ft), (9 * m_in_ft, 100 * m_in_ft)), b=((-10.5 * m_in_ft, 110 * m_in_ft), (10.5 * m_in_ft, 110 * m_in_ft)), c=((-9 * m_in_ft, 100 * m_in_ft), (9 * m_in_ft, 120 * m_in_ft)), ) # Instantiate objects conductor = Conductor("Ostrich") # standard ACSR conductor bundle = ConductorBundle(n=1, conductor=conductor) tower = Tower(locations=locations, bundle=bundle) # Calculate per-mile values (test case) series_reactance_per_mi = 2 * pi * 60 * tower.inductance * km_per_mi shunt_admittance_per_mi = 2 * pi * 60 * tower.capacitance * km_per_mi # Expected values expected_series_reactance = 0.372 # Ohms expected_shunt_admittance = 11.41e-6 # Siemens # Check assert series_reactance_per_mi == pytest.approx(expected_series_reactance, rel=0.01) assert shunt_admittance_per_mi == pytest.approx(expected_shunt_admittance, rel=0.01)
[docs]def test_line_long(): conductor = Conductor("Rook") # standard ACSR conductor conductor.resistance_per_km = 0.09963 # rated value at 50 C locations = PhaseLocations(a=(-7.25, 50), b=(0, 50), c=(7.25, 50)) bundle = ConductorBundle(n=1, conductor=conductor) tower = Tower(locations=locations, bundle=bundle) line = Line(tower=tower, length=370, voltage=215) # The following values are appreciably different than what we would see using a # short-line model that just multiplies per-length by total length assert line.series_impedance.imag == pytest.approx(183.6619, rel=0.005) assert line.series_impedance.real == pytest.approx(34.20553, rel=0.005) assert line.shunt_admittance == pytest.approx(0.001198j, rel=0.005) assert line.surge_impedance_loading == pytest.approx(215**2 / 406.4, rel=0.005) assert line.thermal_rating == pytest.approx(215 * 795 * sqrt(3) / 1e3) assert line.power_rating == pytest.approx(1.14534 * 113.742, rel=0.005)
[docs]def test_line_short(): short_line_length = 10 # km omega = 60 * 2 * pi conductor = Conductor("Rook") locations = PhaseLocations(a=(-7.25, 50), b=(0, 50), c=(7.25, 50)) bundle = ConductorBundle(n=1, conductor=conductor) tower = Tower(locations=locations, bundle=bundle) line = Line(tower=tower, length=10, voltage=215) assert line.power_rating == line.thermal_rating assert line.series_impedance.imag == pytest.approx( line.tower.inductance * omega * short_line_length, rel=1e-4, ) assert line.series_impedance.real == pytest.approx( line.tower.resistance * short_line_length, rel=1e-4, ) assert line.shunt_admittance.imag == pytest.approx( short_line_length * line.tower.capacitance * omega, rel=1e-4 )