#------------------------------------------------------------------------------
# Copyright (C) 2008 Richard W. Lincoln
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; version 2 dated June, 1991.
#
# This software is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANDABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software Foundation,
# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#------------------------------------------------------------------------------

""" Defines the LineCode object """

#------------------------------------------------------------------------------
#  Imports:
#------------------------------------------------------------------------------

from enthought.traits.api import HasTraits, List, Int, Float, Enum, Array, Bool

#------------------------------------------------------------------------------
#  "LineCode" class:
#------------------------------------------------------------------------------

class LineCode(HasTraits):
    """ The Linecode object is a general DSS object used by all circuits
    as a reference for obtaining line impedances.

    Linecodes are objects that contain impedance characteristics for lines and
    cables.  The term "line code" is an old term that simply refers to a code
    that was made up by programmers to describe a line construction.  In most
    distribution analysis programs, one can describe a line by its linecode
    and its length.  Linecodes were defined in a separate file.  This
    collection of objects emulates the old linecode files, except that the
    concept is slightly more powerful.

    Ultimately, the impedance of a line is described by its series impedance
    matrix and nodal capacitive admittance matrix.  These matrices may be
    specified directly or they can be generated by specifying the symmetrical
    component data.  Note that the impedances of lines may be specified
    directly and one does not need to use a line code, although the linecode
    will be more convenient most of the time.  There may be hundreds of lines,
    but only a few different kinds of line constructions.

    LineCode also performs a Kron reduction, reducing out the last conductor
    in the impedance matrices, which is assumed to be a neutral conductor.
    This applies only if the impedance is specified as a matrix. If the
    impedance is defined as symmetrical components, this function does not
    apply because symmetrical component values already assume the reduction.

    By specifying the values of Rg, Xg, and rho, the DSS will take the base
    frequency impedance matrix values and adjust the earth return component
    for frequency. Skin effect in the conductors is not modified. To represent
    skin effect, you have to define the geometry.

    This assumes the impedance matrix is constructed as follows:

                 Z_{11} + Z_{g} Z_{12} + Z_{g} Z_{13} + Z_{g}

    Z = R + jX = Z_{21} + Z_{g} Z_{22} + Z_{g} Z_{23} + Z_{g}

                 Z_{31} + Z_{g} Z_{32} + Z_{g} Z_{33} + Z_{g}

    """

    # Number of phases in the line this line code data represents.  Setting
    # this property reinitializes the line code.  Impedance matrix is reset
    # for default symmetrical component.
    n_phases = Int(3)

    # Positive-sequence Resistance, ohms per unit length.  See also r_matrix.
    r1 = Float(
        0.058, desc="Positive-sequence resistance, ohms per unit length"
    )

    # Positive-sequence Reactance, ohms per unit length.  See also x_matrix.
    x1 = Float(
        0.1206, desc="Positive-sequence reactance, ohms per unit length"
    )

    # Zero-sequence Resistance, ohms per unit length.
    r0 = Float(0.1784, desc="Zero-sequence resistance, ohms per unit length")

    # Zero-sequence Reactance, ohms per unit length.
    x0 = Float(0.4047, desc="Zero-sequence reactance, ohms per unit length")

    # Positive-sequence capacitance, nF per unit length. See also c_matrix.
    c1 = Float(3.4, desc="Positive-sequence capacitance, nF per unit length")

    # Zero-sequence capacitance, nF per unit length.
    c0 = Float(1.6, desc="Zero-sequence capacitance, nF per unit length")

    # One of (ohms per ...) {none|mi|km|kft|m|me|ft|in|cm}.  Default is none;
    # assumes units agree with length units given in Line object.
    units = Enum("None", "mi", "km", "kft", "m", "me", "ft", "in", "cm")


    # Resistance matrix, lower triangle, ohms per unit length. Order of the
    # matrix is the number of phases.  May be used to specify the impedance of
    # any line configuration.  For balanced line models, you may use the
    # standard symmetrical component data definition instead.
    r_matrix = Array

    # Reactance matrix, lower triangle, ohms per unit length. Order of the
    # matrix is the number of phases.  May be used to specify the impedance of
    # any line configuration.  For balanced line models, you may use the
    # standard symmetrical component data definition instead.
    x_matrix = Array

    # Nodal Capacitance matrix, lower triangle, nf per unit length.Order of the
    # matrix is the number of phases.  May be used to specify the shunt
    # capacitance of any line configuration.  For balanced line models, you may
    # use the standard symmetrical component data definition instead.
    c_matrix = Array

    # Frequency (Hz) at which impedances are specified.
    base_freq = Float(60.0, desc="Frequency at which impedances are specified")

    # Normal ampere limit on line.  This is the so-called Planning Limit. It
    # may also be the value above which load will have to be dropped in a
    # contingency.  Usually about 75% - 80% of the emergency (one-hour) rating.
    norm_amps = Float(400.0, desc="Normal ampere limit on line")

    # Emergency ampere limit on line (usually one-hour rating).
    emerg_amps = Float(600.0, desc="Emergency ampere limit on line")

    # Number of faults per unit length per year.
    fault_rate = Float(0.1, desc="Number of faults per unit length per year")

    # Percentage of the faults that become permanent (requiring a line crew to
    # repair and a sustained interruption).
    pct_perm = Float(20.0, desc="Percentage of faults that become permanent")

    # Hours to repair.
    repair = Int(3, desc="Hours to repair")

    # Kron = Y/N. Default=N.  Perform Kron reduction on the impedance matrix
    # after it is formed, reducing order by 1.  Do this only on initial
    # definition after matrices are defined. Ignored for symmetrical
    # components.
    kron = Bool(False)

    # Carson earth return resistance per unit length used to compute impedance
    # values at base frequency.  For making better frequency adjustments.
    rg = Float(0.0, desc="Carson earth return resistance per unit length")

    # Carson earth return reactance per unit length used to compute impedance
    # values at base frequency.  For making better frequency adjustments.
    xg = Float(0.0, desc="Carson earth return reactance per unit length")

    # Earth resitivity (meter ohms used to compute earth correction factor.
    rho = Float(100.0, desc="Earth resitivity")

# EOF -------------------------------------------------------------------------
