Source code for VeraGridEngine.Devices.Branches.series_reactance

# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at https://mozilla.org/MPL/2.0/.
# SPDX-License-Identifier: MPL-2.0

import numpy as np
from typing import Tuple
from VeraGridEngine.basic_structures import Logger
from VeraGridEngine.Devices.Substation.bus import Bus
from VeraGridEngine.enumerations import BuildStatus, DeviceType, PrpCat
from VeraGridEngine.Devices.Parents.branch_parent import BranchParent
from VeraGridEngine.Devices.Parents.editable_device import GCProp


[docs] class SeriesReactance(BranchParent): __slots__ = ( '_tolerance', '_r_fault', '_x_fault', '_fault_pos', '_R', '_X', '_R0', '_X0', '_R2', '_X2', ) LOCAL_PROPERTY_DECLARATIONS: Tuple[GCProp, ...] = ( GCProp( prop_name='R', units='p.u.', tpe=float, definition='Total positive sequence resistance.', cat=[PrpCat.PF], ), GCProp( prop_name='X', units='p.u.', tpe=float, definition='Total positive sequence reactance.', cat=[PrpCat.PF], ), GCProp( prop_name='R0', units='p.u.', tpe=float, definition='Total zero sequence resistance.', cat=[PrpCat.SC, PrpCat.PF3], ), GCProp( prop_name='X0', units='p.u.', tpe=float, definition='Total zero sequence reactance.', cat=[PrpCat.SC, PrpCat.PF3], ), GCProp( prop_name='R2', units='p.u.', tpe=float, definition='Total negative sequence resistance.', cat=[PrpCat.SC, PrpCat.PF3], ), GCProp( prop_name='X2', units='p.u.', tpe=float, definition='Total negative sequence reactance.', cat=[PrpCat.SC, PrpCat.PF3], ), GCProp( prop_name='tolerance', units='%', tpe=float, definition='Tolerance expected for the impedance values % is expected ' 'for transformers0% for lines.', cat=[PrpCat.PF], ), ) def __init__(self, bus_from: Bus = None, bus_to: Bus = None, name='SeriesReactance', idtag=None, code='', r=1e-20, x=1e-5, design_rate: float = 9999.0, rate=9999.0, active=True, tolerance=0, cost=100.0, mttf=0, mttr=0, r_fault=0.0, x_fault=0.0, fault_pos=0.5, temp_base=20, temp_oper=20, alpha=0.00330, contingency_factor=1.0, protection_rating_factor: float = 1.4, contingency_enabled=True, monitor_loading=True, r0=1e-20, x0=1e-20, r2=1e-20, x2=1e-20, capex=0, opex=0, build_status: BuildStatus = BuildStatus.Commissioned): """ AC current Line :param bus_from: "From" :ref:`bus<Bus>` object :param bus_to: "To" :ref:`bus<Bus>` object :param name: Name of the branch :param idtag: UUID code :param code: secondary ID :param r: Branch resistance in per unit :param x: Branch reactance in per unit :param design_rate: Design rate (MVA) :param rate: Branch rate in MVA :param active: Is the branch active? :param tolerance: Tolerance specified for the branch impedance in % :param cost: overload cost :param mttf: Mean time to failure in hours :param mttr: Mean time to recovery in hours :param r_fault: Mid-line fault resistance in per unit (SC only) :param x_fault: Mid-line fault reactance in per unit (SC only) :param fault_pos: Mid-line fault position in per unit (0.0 = `bus_from`, 0.5 = middle, 1.0 = `bus_to`) :param temp_base: Base temperature at which `r` is measured in Β°C :param temp_oper: Operating temperature in Β°C :param alpha: Thermal constant of the material in Β°C :param contingency_factor: Rating factor in case of contingency :param protection_rating_factor: Rating factor before the protections tripping :param contingency_enabled: enabled for contingencies (Legacy) :param monitor_loading: monitor the loading (used in OPF) :param r0: zero-sequence resistence (p.u.) :param x0: zero-sequence reactance (p.u.) :param r2: negative-sequence resistence (p.u.) :param x2: negative-sequence reactance (p.u.) :param capex: Cost of investment (e/MW) :param opex: Cost of operation (e/MWh) :param build_status: build status (now time) """ BranchParent.__init__(self, name=name, idtag=idtag, code=code, bus_from=bus_from, bus_to=bus_to, active=active, reducible=False, design_rate=design_rate, rate=rate, contingency_factor=contingency_factor, protection_rating_factor=protection_rating_factor, contingency_enabled=contingency_enabled, monitor_loading=monitor_loading, mttf=mttf, mttr=mttr, build_status=build_status, capex=capex, opex=opex, cost=cost, temp_base=temp_base, temp_oper=temp_oper, alpha=alpha, device_type=DeviceType.SeriesReactanceDevice) # line impedance tolerance self.tolerance = tolerance # short circuit impedance self.r_fault = r_fault self.x_fault = x_fault self.fault_pos = fault_pos # total impedance and admittance in p.u. self.R = r self.X = x self.R0 = r0 self.X0 = x0 self.R2 = r2 self.X2 = x2 @property def R_corrected(self): """ Returns a temperature corrected resistance based on a formula provided by: NFPA 70-2005, National Electrical Code, Table 8, footnote #2; and https://en.wikipedia.org/wiki/Electrical_resistivity_and_conductivity#Linear_approximation (version of 2019-01-03 at 15:20 EST). """ return self.R * (1 + self.alpha * (self.temp_oper - self.temp_base))
[docs] def change_base(self, Sbase_old, Sbase_new): """ Change the impedance base :param Sbase_old: old base (MVA) :param Sbase_new: new base (MVA) """ b = Sbase_new / Sbase_old self.R *= b self.X *= b
[docs] def get_weight(self) -> float: """ Get a weight of this line for graph purposes the weight is the impedance module (sqrt(r^2 + x^2)) :return: weight value """ return np.sqrt(self.R * self.R + self.X * self.X)
[docs] def fix_inconsistencies(self, logger: Logger): """ Fix the inconsistencies :param logger: :return: """ errors = False if self.R < 0.0: logger.add_warning("Corrected transformer R<0", self.name, self.R, -self.R) self.R = -self.R errors = True return errors
[docs] def fill_design_properties(self, r_ohm, x_ohm, length, Imax, Sbase): """ Fill R, X, B from not-in-per-unit parameters :param r_ohm: Resistance per km in OHM :param x_ohm: Reactance per km in OHM :param length: length in kn :param Imax: Maximum current in kA :param Sbase: Base power in MVA (take always 100 MVA) """ R = r_ohm * length X = x_ohm * length Vf = self.get_max_bus_nominal_voltage() Zbase = (Vf * Vf) / Sbase self.R = np.round(R / Zbase, 6) self.X = np.round(X / Zbase, 6) self.rate = np.round(Imax * Vf * 1.73205080757, 6) # nominal power in MVA = kA * kV * sqrt(3)
# Scalar property accessors coerce assignments to the declared schema types. @property def R(self) -> float: """ Get ``R``. :return: float """ return self._R @R.setter def R(self, val: float) -> None: """ Set ``R``. :param val: Value to assign. :return: None """ self._R = float(val) @property def X(self) -> float: """ Get ``X``. :return: float """ return self._X @X.setter def X(self, val: float) -> None: """ Set ``X``. :param val: Value to assign. :return: None """ self._X = float(val) @property def R0(self) -> float: """ Get ``R0``. :return: float """ return self._R0 @R0.setter def R0(self, val: float) -> None: """ Set ``R0``. :param val: Value to assign. :return: None """ self._R0 = float(val) @property def X0(self) -> float: """ Get ``X0``. :return: float """ return self._X0 @X0.setter def X0(self, val: float) -> None: """ Set ``X0``. :param val: Value to assign. :return: None """ self._X0 = float(val) @property def R2(self) -> float: """ Get ``R2``. :return: float """ return self._R2 @R2.setter def R2(self, val: float) -> None: """ Set ``R2``. :param val: Value to assign. :return: None """ self._R2 = float(val) @property def X2(self) -> float: """ Get ``X2``. :return: float """ return self._X2 @X2.setter def X2(self, val: float) -> None: """ Set ``X2``. :param val: Value to assign. :return: None """ self._X2 = float(val) @property def tolerance(self) -> float: """ Get ``tolerance``. :return: float """ return self._tolerance @tolerance.setter def tolerance(self, val: float) -> None: """ Set ``tolerance``. :param val: Value to assign. :return: None """ self._tolerance = float(val) @property def r_fault(self) -> float: """ Get ``r_fault``. :return: float """ return self._r_fault @r_fault.setter def r_fault(self, val: float) -> None: """ Set ``r_fault``. :param val: Value to assign. :return: None """ self._r_fault = float(val) @property def x_fault(self) -> float: """ Get ``x_fault``. :return: float """ return self._x_fault @x_fault.setter def x_fault(self, val: float) -> None: """ Set ``x_fault``. :param val: Value to assign. :return: None """ self._x_fault = float(val) @property def fault_pos(self) -> float: """ Get ``fault_pos``. :return: float """ return self._fault_pos @fault_pos.setter def fault_pos(self, val: float) -> None: """ Set ``fault_pos``. :param val: Value to assign. :return: None """ self._fault_pos = float(val)