Giter Site home page Giter Site logo

carsons's Introduction

carsons

latest release on pypi versons of python supported by carsons GitHub license build passing or failing test coverage Maintainability

This is an implementation of Carson's Equations, a mathematical model for deriving the equivalent impedance of an AC transmission or distribution line.

Implementation

carsons is developed using python 3.6 support for unicode characters like π, ƒ, ρ, μ, ω etc. This feature allows us to avoid translating the problem into a more typical programming syntax, so the code is dense and can easily be compared to published formulations of the problem.

For example, we implement the kron reduction, a matrix decomposition step, using unicode notation to indicate the slightly different meaning of impedance values before and after a kron reduction:

def perform_kron_reduction(z_primitive):
     Ẑpp, Ẑpn = z_primitive[0:3, 0:3], z_primitive[0:3, 3:]
     Ẑnp, Ẑnn = z_primitive[3:,  0:3], z_primitive[3:,  3:]
     Z_abc = Ẑpp - Ẑpn @ inv(Ẑnn) @ Ẑnp
     return Z_abc

Take a look at the source code to see more cool unicode tricks!

Installation

~/$ pip install carsons

Usage

Carsons model requires a line model object that maps each phase to properties of the conductor for that phase.

from carsons import CarsonsEquations, calculate_impedance

class Line:
   geometric_mean_radius: {
       'A': geometric_mean_radius_A in meters
       ...
   }
   resistance: {
        'A': per-length resistance of conductor A in ohms/meters
        ...
   }
   wire_positions: {
        'A': (x, y) cross-sectional position of the conductor in meters
        ...
   }
   phases: {'A', ... }
     # map of phases 'A', 'B', 'C' and 'N<>' which are described in the
     # gmr, r and phase_positions attributes

line_impedance = calculate_impedance(CarsonsEquations(Line()))

The model supports any combination of ABC phasings (for example BC, BCN etc...) including systems with multiple neutral cables; any phases that are not present in the model will have zeros in the columns and rows corresponding to that phase.

Multiple neutrals are supported, as long as they have unique labels starting with N (e.g. Neutral1, Neutral2).

Intermediate results such as primitive impedance matrix are also available.

z_primitive = CarsonsEquations(Line()).build_z_primitive()

For examples of how to use the model, see the overhead wire tests.

carsons is tested against several cable configurations from the IEEE test feeders, as well as examples from EPRI's OpenDSS documentation.

Concentric Neutral Cable

carsons also supports modelling of concentric neutral cables of any phasings. Its usage is very similar to the example above, only requiring a few more parameters about the neutral conductors in the line model object.

from carsons import (ConcentricNeutralCarsonsEquations,
                     calculate_impedance)

class Cable:
   resistance: {
       'A': per-length resistance of conductor A in ohm/meters
       ...
   }
   geometric_mean_radius: {
       'A': geometric mean radius of conductor A in meters
       ...
   }
   wire_positions: {
        'A': (x, y) cross-sectional position of conductor A in meters
        ...
   }
   phases: {'A', 'NA', ... }
   neutral_strand_gmr: {
       'NA': neutral strand gmr of phase A in meters
       ...
   }
   neutral_strand_resistance: {
       'NA': neutral strand resistance of phase A in ohm/meters
       ...
   }
   neutral_strand_diameter: {
       'NA': neutral strand diameter of phase A in meters
       ...
   }
   diameter_over_neutral: {
       'NA': diameter over neutral of phase A in meters
       ...
   }
   neutral_strand_count: {
       'NA': neutral strand count of phase A
       ...
   }

cable_impedance = calculate_impedance(ConcentricNeutralCarsonsEquations(Cable()))

For examples of how to use the model, see the concentric cable tests.

Multi-Conductor Cable

carsons also supports modelling of phased duplex, triplex, quadruplex cables and triplex secondary. It only requires a few more parameters to describe cable's geometry.

from carsons import (MultiConductorCarsonsEquations,
                     calculate_impedance)

class Cable:
    resistance: {
        'A': per-length resistance of conductor A in ohm/meters
        ...
    }
    geometric_mean_radius: {
        'A': geometric mean radius of conductor A in meters
        ...
    }
    wire_positions: {
        'A': (x, y) cross-sectional position of conductor A in meters
        ...
    }
    outside_radius: {
        'A': outside radius of conductor A, including insulation and jacket thickness
        ...
    }
    insulation_thickness: {
        'A': insulation thickness of conductor A
        ...
    }
    phases: {'A', ... }

cable_impedance = calculate_impedance(MultiConductorCarsonsEquations(Cable()))

To model a triplex secondary cable, the inputs should be keyed on secondary conductors S1 and S2. The impedance result is a 2 x 2 matrix.

class Cable:
    resistance: {
        'S1': per-length resistance of conductor S1 in ohm/meters
        ...
    }
    geometric_mean_radius: {
        'S1': geometric mean radius of conductor S1 in meters
        ...
    }
    wire_positions: {
        'S1': (x, y) cross-sectional position of conductor S1 in meters
        ...
    }
    outside_radius: {
        'S1': outside radius of conductor S1, including insulation and jacket thickness
        ...
    }
    insulation_thickness: {
        'S1': insulation thickness of conductor S1
        ...
    }
    phases: {'S1', ... }

For examples of how to use the model, see the multi-conductor cable tests.

Tape Shield Cable

carsons also supports modelling of tape shield cables of any phasings. Its usage is very similar to the example above, only requiring a few more parameters about the tape shield conductors in the line model object.

from carsons import (TapeShieldedCableCarsonsEquations,
                     calculate_impedance)

class Cable:
   resistance: {
       'A': per-length resistance of conductor A in ohm/meters
       ...
   }
   geometric_mean_radius: {
       'A': geometric mean radius of conductor A in meters
       ...
   }
   wire_positions: {
        'A': (x, y) cross-sectional position of conductor A in meters
        ...
   }
   phases: {'A', ... }
   tape_shield_thickness: {
       'A': thickness of tape shield conductor on phase A cable in meters
       ...
   }
   tape_shield_outer_diameter: {
       'A': outer diameter of tape shield conductor on phase A cable in meters
       ...
   }
   

cable_impedance = calculate_impedance(TapeShieldedCableCarsonsEquations(Cable()))

For examples of how to use the model, see the tape shielded cable tests.

Problem Description


Carsons equations model an AC transmission or distribution line into an equivalent set of phase-phase impedances, which can be used to model the line in a power flow analysis.

For example, say we have a 4-wire system on a utility pole, with A, B, C phase conductors as well as a neutral cable N. We know that when conductors carry electrical current, they exhibit a magnetic field --- so its pretty easy to imagine that, e.g., the magnetic field produced by A would interact with the B, C, and N conductors.

                        B
                          O
                          |
                          |
              A        N  |       C
                O        O|         O
                ----------|-----------
                          |
                          |
                          |
                          |
                          |
                          |
                          |
                          |
                          |
                          |
                          |
                          |
                          |
    ==============[Ground]============================
    /     /     /     /     /     /     /     /     /
         /     /     /     /     /     /     /
              /     /     /     /     /
 
 
 
 
 
 
 
 
 
 
                 A*       N*          C*
                   0        0           0
 
                           B*
                             0

Figure: Cross-section of a 4-wire distribution line, with
        ground return.

However, each conductor also has a ground return path (or 'image') --- shown as A*, B*, C*, and N* in the figure above --- which is a magnetically induced current path in the ground. When A produces a magnetic field, that field also interacts with B*, C*, N*, and A*. Carsons equations model all these interactions and reduce them to an equivalent impedance matrix that makes it much easier to model this system.

In addition carsons implements the kron reduction, a conversion that approximates the impedances caused by neutral cables by incorporating them into the impedances for phase A, B, and C. Since most AC and DC powerflow formulations don't model the neutral cable, this is a valuable simplification.

References

The following works were used to produce this formulation:

carsons's People

Contributors

andace avatar anjoman avatar bluejuniper avatar emilyylma avatar etimberg avatar greatestape avatar kdheepak avatar veronicaguo avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

carsons's Issues

Command "python setup.py egg_info" failed with error code 1

I am attempting to load this package into:
Windows 10
Python 3.6
Anaconda 5.1

I receive the following error

(base) C:\Users\XXXXXXXXX>pip install carsons
Collecting carsons
  Downloading https://files.pythonhosted.org/packages/72/83/b0e2954f67741643b1fd2be62d3f1f6a5b96f99ad1c16fa4a0faabcff2eb/carsons-0.2.1.tar.gz
    Complete output from command python setup.py egg_info:
    Traceback (most recent call last):
      File "<string>", line 1, in <module>
      File "C:\Users\XXXXXXXXX\AppData\Local\Temp\pip-build-el644y7h\carsons\setup.py", line 31, in <module>
        long_description=readme(),
      File "C:\Users\XXXXXXXXX\AppData\Local\Temp\pip-build-el644y7h\carsons\setup.py", line 10, in readme
        return f.read()
      File "C:\Users\XXXXXXXXX\AppData\Local\Continuum\anaconda3\lib\encodings\cp1252.py", line 23, in decode
        return codecs.charmap_decode(input,self.errors,decoding_table)[0]
    UnicodeDecodeError: 'charmap' codec can't decode byte 0x81 in position 1163: character maps to <undefined>

    ----------------------------------------
Command "python setup.py egg_info" failed with error code 1 in C:\Users\XXXXXXXXX\AppData\Local\Temp\pip-build-el644y7h\carsons\

What do I need to do to solve this?

Fix test model phases attribute

The way we abstract a line right now, it has to have a .phases attribute which is a mapping of

{
    'A': 'A',
    'B': 'B',
    ...
}

... for each phase a wire has. This is a clumsy modelling and it also prevents us from modelling configurations that have multiple neutral wires that have different resistance / gmr / wire position properties.

An ideal solution would:

  • simplify the return value of .phases
  • support multiple wires with a phase of 'N'
  • provide an abstract interface that third parties can implement to get their data into the Carsons Equations model

Support user-defined frequency

currently, Carsons has the assumed operating frequency hard-coded to 60 hz. This is suitable for north-american markets but not for other ones. We should add the frequency as a parameter to all impedance calculations, with the default being 60hz for backwards compatibility.

Test Carsons with the full P/Q expansion

Currently, the Carsons model always uses a truncated expansion for computing the P/Q terms at each i/j combination:

def compute_Q(self, i, j, number_of_terms=2):

Ideally we would expose the number of terms so a user can configure them, and we would have a reliable example calculation to use as a test case where, if you don't use the full P/Q series, the test would fail because the impedance is not calculated precisely enough.

One possible approach would be to expose a FullCarsons and ModifiedCarsons, which is how the Kersting source describes the simplification of taking only the first 1--2 terms of P/Q. The ModifiedCarsons model is needed for all cable calculations, since it can be formulated to not rely on having a y position. An overhead line can be supported by both the Full and Modified carsons equations

Support Parallel Overhead Distribution Lines/Underground cables

Overhead lines and underground cables from two different feeders commonly run in parallel. For example:

  • Two different feeders leaving the same substation can share the same pole before branching out.
  • Overhead lines of two feeders can also merge together, run in parallel for a while, and then branch out again.
  • Underground cables from two feeders can also share the same common trench.

The work is to update calculations so the mutual impedances between the two lines are known. This will enable more accurate power-flow calculations.

Test multiple neutrals case

Carsons supports models with multiple neutrals. We need to validate that the results are correct. Most of the work involved would be in finding a test case in an existing IEEE model where someone has turned a geometric model into equivalent impedances -- given this, we could easily write a test to ensure that the z_ABC we produce for that cable is correct.

Refactor Carsons models to avoid double class creation

The CarsonsEquations model class is instantiated from another object that contains the necessary attributes. This poses a problem when you want to run Carson's equations on some values as you need to create a shim class to pass those values to the model.

Some ideas for improving this

  • add property names in __init__ instead of a plain model
  • keep the model and replace with a dictionary

Issue in test suite data

Great job on the implementation of carsons equations, it's a very useful reference.

I believe this matrix in the tests is incorrectly ordered.

return array([
[1.74792626e-04+0.00085989j,
5.92176264e-05+0.00052913j,
5.92176264e-05+0.00048481j,
5.92176264e-05+0.00048873j],
[5.92176264e-05+0.00052913j,
1.74792626e-04+0.00085989j,
5.92176264e-05+0.0004515j,
5.92176264e-05+0.00046756j],
[5.92176264e-05+0.00048481j,
5.92176264e-05+0.0004515j,
1.74792626e-04+0.00085989j,
5.92176264e-05+0.00047687j],
[5.92176264e-05+0.00048873j,
5.92176264e-05+0.00046756j,
5.92176264e-05+0.00047687j,
4.27069626e-04+0.00096095j]])

If I use the carsons.py file to generate the z_primitive_matrix for ABCN_geometry_line I get the following:

0.00017479262640653616 + j 0.000859886093793189    5.9217626406536145e-05 + j 0.0004848090114987014    5.9217626406536145e-05 + j 0.0005291270819387303    5.9217626406536145e-05 + j 0.000488729331339374
5.9217626406536145e-05 + j 0.0004848090114987014    0.00017479262640653616 + j 0.000859886093793189    5.9217626406536145e-05 + j 0.0004514956068104968    5.9217626406536145e-05 + j 0.000476865015771444
5.9217626406536145e-05 + j 0.0005291270819387303    5.9217626406536145e-05 + j 0.0004514956068104968    0.00017479262640653616 + j 0.000859886093793189    5.9217626406536145e-05 + j 0.0004675586100839125   
5.9217626406536145e-05 + j 0.000488729331339374    5.9217626406536145e-05 + j 0.000476865015771444    5.9217626406536145e-05 + j 0.0004675586100839125    0.00042706962640653615 + j 0.0009609520589591509

If you make this change, you will be able to get rid of the decimal=4 keyword argument in the assertion in your tests.

assert_array_almost_equal(
z_primitive_expected,
z_primitive_computed,
decimal=4)

Support tape shield cables

Carsons supports overhead wires as well as underground cables where each phase conductor has a concentric neutral. However, there is another somewhat common cable typology, the tape-shield. This is where the cable has a thin conductive shield around the insulation, and then there is a separate neutral cable pulled underground alongside the phase conductors.

Since we already support Concentric Neutrals using the modified carsons equations, it shouldn't be too hard to build a TapeShieldCarsonsEquations that implements the particular geometric equivalents for a tape shield cable.

Part of the work would involve exploring IEEE, OpenDSS or other resources for sample calculations that can be used as tests for this calculation. IEEE4/13 has a AN example, but we'd want to also have example calculations for 2- and 3-phase cables.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.