Click here to Skip to main content
15,893,722 members
Articles / Desktop Programming / Win32

Windows Development in C++, Working with Menus

Rate me:
Please Sign up or sign in to vote.
4.96/5 (60 votes)
3 Jan 2015CPOL19 min read 172.9K   4.1K   163  
Windows API, menus, C++ lambda expressions, std::enable_shared_from_this
// hpowernetsolver.h
#pragma once

/*
 * Copyright 2012,2013 - Espen Harlinn, All rights reserved
 *
 * Ongoing work ...
 *
 *
 *
 */

#ifndef __HPOWERNETSOLVER_H__
#define __HPOWERNETSOLVER_H__

#include "hpowerdef.h"
#include "hwinstring.h"
#include "hwindatetime.h"
#include "hwincomponent.h"
#include <array>

namespace harlinn
{
    namespace power
    {
        namespace network
        {
            using namespace harlinn::windows;
            typedef std::complex<double> complex;

            typedef std:: array<double,3> VectorD3;
            typedef std:: array<complex,3> VectorC3;
            typedef std:: array<std ::array<double,3>,3> MatrixD3x3;
            typedef std:: array<std ::array<complex,3>,3> MatrixC3x3;

            enum class Phase : int
            {
                None = 0,
                A = 1,
                B = 2,
                C = 4,
                ThreePhase = A | B | C,
                N = 8,
                ThreePhaseN = ThreePhase | N,

                //split phase
                S1	= 0x0010,
                S2	= 0x0020,
                SN	= 0x0040,
                S	= 0x0070,
                Ground = 0x0080,
                Delta = 0x0100
            };
            DEFINE_ENUM_FLAG_OPERATORS(Phase)

            enum class Condition : int
            {
                Normal = 0,
                Contact = 0x1000,
                PhaseAContact = static_cast<int>(Phase::A) | Contact,
                PhaseBContact = static_cast<int>(Phase::B) | Contact,
                PhaseCContact = static_cast<int>(Phase::C) | Contact,
                NeutralContact = static_cast<int>(Phase::N) | Contact,
                Split1Contact = static_cast<int>(Phase::S1) | Contact,
                Split2Contact = static_cast<int>(Phase::S2) | Contact,
                SplitNContact = static_cast<int>(Phase::SN) | Contact,
                GroundContact = static_cast<int>(Phase::Ground) | Contact,
                ContactMask = 0x10ff,
                Open =  0x2000,
                PhaseAOpen = static_cast<int>(Phase::A) | Open,
                PhaseBOpen = static_cast<int>(Phase::B) | Open,
                PhaseCOpen = static_cast<int>(Phase::C) | Open,
                NeutralOpen = static_cast<int>(Phase::N) | Open,
                Split1Open = static_cast<int>(Phase::S1) | Open,
                Split2Open = static_cast<int>(Phase::S2) | Open,
                SplitNOpen = static_cast<int>(Phase::SN) | Open,
                GroundOpen = static_cast<int>(Phase::Ground) | Open,
                OpenMask = 0x20ff,
                ConditionMask = 0x3000
            };
            DEFINE_ENUM_FLAG_OPERATORS(Condition)

            template<typename T>
            struct Range
            {
                typedef T value_type;
                value_type low;
                value_type high;

                Range()
                    : low(T()),
                      high(T())
                {}

                Range(const T& theLowValue, const T& theHighValue)
                    : low(theLowValue),
                      high(theHighValue)
                {}


            };


            // -----------------------------------------------------------------
            // PowerElement
            // -----------------------------------------------------------------
            class PowerElement : public Component
            {
                Phase phases;
                Condition conditions;
                double nominalVoltage;
                int solutionCode;
                DateTime timeStamp;
                DateTime previousTimeStamp;
            public:
                typedef Component Base;

                PowerElement()
                    : phases(Phase::None),
                    conditions(Condition::Normal),
                    nominalVoltage(0.0),
                    solutionCode(-1),
                    timeStamp(DateTime::MinValue),
                    previousTimeStamp(DateTime::MinValue)
                {}

                Phase Phases() const { return phases; }
                PowerElement& SetPhases(Phase thePhases ) { phases = thePhases; return *this; }

                Condition Conditions() const { return conditions; }
                PowerElement& SetConditions(Condition theConditions) { conditions = theConditions; return *this; }

                double NominalVoltage() const { return nominalVoltage; }
                PowerElement& SetNominalVoltage(double theNominalVoltage) { nominalVoltage = theNominalVoltage; return *this; }

                int SolutionCode() const { return solutionCode; }
                PowerElement& SetSolutionCode(int theSolutionCode) { solutionCode = theSolutionCode; return *this; }

                DateTime TimeStamp() const { return timeStamp; }
                PowerElement& SetTimeStamp( const DateTime& theValue ) { timeStamp = theValue; return *this; }

                DateTime PreviousTimeStamp() const { return previousTimeStamp; }
                PowerElement& SetPreviousTimeStamp( const DateTime& theValue ) { previousTimeStamp = theValue; return *this; }
                TimeSpan TimeStep() const { TimeSpan result = timeStamp - previousTimeStamp; return result; }


                virtual PowerElement& Evaluate(const DateTime& theTimeStamp )
                {
                    previousTimeStamp = timeStamp;
                    timeStamp = theTimeStamp;
                    return *this;
                }

            };


            enum class NodeElementType
            {
                PQ = 0, 
                PV = 1, 
                Swing = 2
            };

            enum class NodeElementFlags
            {
                None = 0,
                HasSource = 1
            };

            enum class NodeElementStatus 
            {	
                // voltage is nominal
                Nominal = 1,
                // voltage is too low
			    Undervolt,
                // voltage is too high
			    Overvolt,
	        };
	        enum class NodeElementServiceStatus
            { 
                // The node is out of service
		        OutOfService = 0,
                // The node is operational
		        InService = 1, 
	        };


            enum class NodeElementSubType
            {
                // not a child node
		        None = 0,
                // a child node
		        Child = 1,
                // a child node which has not been linked
		        ChildNoInit = 2,
                // a parent of a child
		        Parent = 3,
                // a child node with different 
                // phase-connection than the parent
		        DiffChild = 4,
                // a parent node with different 
                // phase-connection than the child
		        DiffParent = 5
		    };



            // -----------------------------------------------------------------
            // NodeElement
            // -----------------------------------------------------------------
            class EdgeElement;
            class NodeElement : public PowerElement
            {

            public:
                // voltage at last pass
	            VectorC3 previousVoltage;
                // current injection: shunt+power+current
	            VectorC3 currentInjection;
                // Previous timestep for propogating child node properties
	            DateTime previousTimestep;
                // Previous power values - for child node propogation
	            MatrixC3x3 previousChildPower;
                // Previous current value - Phase 1&2 current injections 
                // for child node propogation in triplex mode
	            complex previousChildCurrent12;
            
                // frequency if this is a reference bus
	            double frequency;
                // reference bus defining the frequency
	            NodeElement* referenceBus;

	            static unsigned int totalNodeCount;

                // number of links connecting to this node
	            unsigned short k;

                // Previous voltage value for Master/Slave functionality
	            std::vector<complex> previousVoltageValue;
                // Power value for Master/Slave functionality
	            std::vector<complex> previousPowerValue;
            
	            // Last time the node was out of service
	            DateTime previousDisconnect;
                // last total uptime
	            double previousUptime;
                // current uptime
	            double currentUptime;

	            NodeElementSubType SubNode;
                NodeElementFlags busflags;
                NodeElementStatus status;
                NodeElementServiceStatus serviceStatus;


                // flags for reconvergent input lines
                Phase busPhasesIn;
                // flags for output lines
	            Phase busPhasesOut;
                // convergence voltage limit
	            double maximumVoltageError; 

	            // bus voltage to ground
                VectorC3 voltage;
                // bus voltage delta
	            VectorC3 voltageDelta;	
                // bus current injection (>= 0 -> in)
	            VectorC3 current;
                // bus power injection (>= 0 -> in)
	            VectorC3 power;
                // bus shunt admittance 
	            VectorC3 shunt;

                // Phase 1&2 current injections 
                // in triplex mode
	            complex current12;

                // Include nominal residential 
                // currents for angle adjustments
	            VectorC3 nominalResidentialCurrents;

                // Extra current calculation information for triplex lines
	            std::vector<complex> triplexData;	
                // extra calculation data
	            std::vector<complex> extraData;

                // child node list
                std::vector<NodeElement*> children;

                NodeElement* parent;
	            std::vector<EdgeElement*> links;
	            
	            // mean repair time
                TimeSpan meanRepairTime;

                // Index of matching Node
	            int index;		

                // Index of parent Node
	            int parentIndex;

                // Phase tracking for reliability 
                Phase previousPhases;	

                inline bool isSplit() const
                {
                    return (Phases() & Phase::S) != Phase::None;
                }
            };


            // -----------------------------------------------------------------
            // GeneratorMode
            // -----------------------------------------------------------------
            enum class GeneratorMode
            {
                ConstantVoltage = 1, 
                ConstantPQ = 2, 
                ConstantPF = 4, 
                SupplyDriven = 5
            };

            // -----------------------------------------------------------------
            // GeneratorStatus
            // -----------------------------------------------------------------
            enum class GeneratorStatus
            {
                Offline = 0,
                Online = 1
            };

            // -----------------------------------------------------------------
            // GeneratorPowerType
            // -----------------------------------------------------------------
            enum class GeneratorPowerType
            {
                DC = 1,
                AC = 2
            };

            // -----------------------------------------------------------------
            // GeneratorElement
            // -----------------------------------------------------------------
            class GeneratorElement : public NodeElement
            {
            public:
                Phase phases;
	            GeneratorMode mode;
                GeneratorStatus status;
	            GeneratorPowerType powerType;

	            double rInternal;
	            double rLoad;
	            complex maxVoltage;
	            complex maxCurrent;

	            double frequency;
	            double maxFrequency;
	            double minFrequency;
	            double KV;
	            double powerAngle;
	
                // maximum real power capacity
	            double maxPower;
                // minimum real power capacity
                double minPower;
	
                // maximum reactive power capacity
	            double maxReactivePower;
                // minimum reactive power capacity
                double minReactivePower;
                // nominal rated capacity
	            double ratedkVA;
	
	            double efficiency;
	
	            complex EAInternal;
	            complex EBInternal;
	            complex ECInternal;

                // Voltage
	            complex phaseAVOut;
	            complex phaseBVOut;
	            complex phaseCVOut;
	            
	            // current
	            complex phaseAIOut;
	            complex phaseBIOut;
	            complex phaseCIOut;

                // power
	            complex powerAOut;
	            complex powerBOut;
	            complex powerCOut;

	            complex VAOut;

	            double pfOut;

                // three voltages on three lines
                MatrixC3x3 circuitVoltages;
	
                // the three current on three lines
                MatrixC3x3 lineCurrents;
            };


            // -----------------------------------------------------------------
            // LoadElement
            // -----------------------------------------------------------------
            class LoadElement : public NodeElement
            {
            public:
                complex voltageA;
	            complex voltageB;
	            complex voltageC;
	            complex voltageAB;	
	            complex voltageBC;
	            complex voltageCA;

                VectorD3 basePower;

	            VectorD3 powerLoad;
	            VectorD3 currentLoad;
	            VectorD3 impedanceLoad;

                VectorD3 powerFraction;
	            VectorD3 impedanceFraction;
	            VectorD3 currentFraction;
	            
	            VectorD3 powerPreviousFraction;
	            VectorD3 currentPreviousFraction;
	            VectorD3 impedancePreviousFraction;
	            
	            
            };

            // -----------------------------------------------------------------
            // LoadBusElement (PQ Load)
            // -----------------------------------------------------------------
            class LoadBusElement : public LoadElement
            {
            public:
                std::array<double,6> impedanceP;
	            std::array<double,6> impedanceQ;
	            std::array<double,6> currentM;
	            std::array<double,6> currentA;
	            std::array<double,6> powerP;
	            std::array<double,6> powerQ;

	            double Zp; 
                double Zq; 
                double Im; 
                double Ia; 
                double Pp; 
                double Pq;
	            complex kZ; 
                complex kI; 
                complex kP;
            };


            // -----------------------------------------------------------------
            // TriplexNodeElement
            // -----------------------------------------------------------------
            class TriplexNodeElement : public NodeElement
            {
            public:
                VectorC3 impedance;
	            VectorC3 shuntImpedance;
            };


            // -----------------------------------------------------------------
            // CapacitorControl
            //  operation strategy
            // -----------------------------------------------------------------
            enum class CapacitorControl
            {
                Manual = 0, 
                VAr = 1, 
                Volt = 2, 
                VArVolt = 3, 
                Current = 4,
                Individual = 8 //bank or individual control
            };

            // -----------------------------------------------------------------
            // CapacitorSwitch
            // -----------------------------------------------------------------
            enum class CapacitorSwitch
            {
                Open = 0,
                Closed = 1
            };

            // -----------------------------------------------------------------
            // CapacitorSwitchState
            // -----------------------------------------------------------------
            class CapacitorSwitchState
            {
            public:
                // The current state
                CapacitorSwitch current;
                // The previous state
                CapacitorSwitch previous;
                // The initial state
                CapacitorSwitch initial;

                // The next state
                CapacitorSwitch next;

                // The requested next state
                CapacitorSwitch requestedNext;

                bool changed() const
                {
                    return current != previous;
                }
            };


            // -----------------------------------------------------------------
            // CapacitorPhaseInfo
            // -----------------------------------------------------------------
            class CapacitorPhaseInfo
            {
            public:
                CapacitorSwitchState state;
                double capacitance;
                complex admittance;
                double var;
                double current;
                TimeSpan lockoutInterval;
            };


            // -----------------------------------------------------------------
            // CapacitorElement
            // -----------------------------------------------------------------
            class CapacitorElement : public NodeElement
            {
            public:
	            Phase phasePT;
	            Phase connectedPhases;		
                // voltage set points for voltage control 
                //   low : turn on
                //   high : turn off
                Range<double> voltageSetPoints;
	            // VAR set points for VAR control
                //   low : turn on
                //   high : turn off
	            Range<double> varSetPoints;
                // current set points for current control
                //   low : turn off
                //   high : turn on
	            Range<double> currentSetPoints;	
	            
	            CapacitorControl control;
	            
                CapacitorPhaseInfo a;
                CapacitorPhaseInfo b;
                CapacitorPhaseInfo c;

	            Component* remoteSensor;
	            Component* secondaryRemote;

	            TimeSpan timeDelay;
	            TimeSpan dwellTime;
	            TimeSpan lockoutTime;
            
	            NodeElement* remoteNode;
                EdgeElement* remoteLink;
            };


            // -----------------------------------------------------------------
            // SubstationReferencePhase
            // -----------------------------------------------------------------
            enum class SubstationReferencePhase
            {
                A = 1,
                B = 2,
                C = 3
            };

            // -----------------------------------------------------------------
            // SubstationElement
            // -----------------------------------------------------------------
            class SubstationElement : public NodeElement
            {
            public:
	            DateTime timeStamp;
            
                // The positive sequence voltage of the substation object
	            complex positiveSequenceVoltage;
                // The point of reference for the positive 
                // sequence voltage conversion
	            SubstationReferencePhase referencePhase;

                // average constant power load
	            complex averageTransmissionPowerLoad;
                // average constant impedance load
	            complex averageTransmissionImpedanceLoad;
                // average constant current load
	            complex averageTransmissionCurrentLoad;
                // average of the loads on all three phases 
	            complex averageDistributionLoad;

	            complex distributionPowerA;					
	            complex distributionPowerB;					
	            complex distributionPowerC;	
                
	            VectorC3 sequenceVoltages;
	            double distributionRealEnergy;
	            double basePower;

                // Threshold of convergence for pw load connected items
	            double powerConvergence;
                

                // The angle to shift the sequence voltages by
	            complex referenceAngle;
                // the transformation matrix used to convert 
                // sequence voltages to phase voltages
	            MatrixC3x3 sequenceVoltagesTransform;
	            complex previousPowerA;
	            complex previousPowerB;
	            complex previousPowerC;
	            complex voltageA;
	            complex voltageB;
	            complex voltageC;

	            complex constantPowerLoad;
	            complex constantCurrentLoad;
	            complex constantImpedanceLoad;
                
	            double transformerNominalVoltage;
            };


            // -----------------------------------------------------------------
            // MeterElement
            // -----------------------------------------------------------------
            class MeterElement : public NodeElement
            {
            public:
                // measured voltage
                VectorC3 voltage;
                // measured voltage drop between lines
	            VectorC3 voltageDelta;	
                // measured current
	            VectorC3 current;
                // metered real energy consumption
	            double realEnergy;
                // metered reactive energy consumption
	            double reactiveEnergy;
                // metered power
	            complex power;
                // metered real power
	            double realPower;
                // metered reactive power
	            double reactivePower;
                // metered demand (peak of power)
	            double peakOfPower;
                
                // previous metered real power
	            double previousRealPower; 
                // metered power on each phase
	            VectorC3 powerOnPhase;
                // Reliability flag 
	            bool interrupted;
                // Reliability flag 
	            bool momentarilyInterrupted;
            };


            // -----------------------------------------------------------------
            // TriplexMeterElement
            // -----------------------------------------------------------------
            class TriplexMeterElement : public TriplexNodeElement
            {
            };




            enum class EdgeElementType
            {
                // normal link/transformer
		        Normal = 0,
                // regulator
		        Regulator = 1,
                // Delta-Gwye transformer
		        DeltaGwye = 2,
                // split-phase transformer
		        SplitPhase = 3,
                // Switch
		        Switch = 4
            };

            // flow directions
            enum class EdgeElementFlowDirection
            {
                // Flow is undetermined
                Unknown		= 0x000,
                // A flow information
                PhaseAMask		= 0x00f,
                // Flow over phase A is normal
                PhaseANormal	= 0x001,
                // Flow over phase A is reversed
                PhaseAReverse	= 0x002,
                // No flow over of phase A 
                PhaseANone		= 0x003,
                // B flow information
                PhaseBMask		= 0x0f0,
                // Flow over phase B is normal
                PhaseBNormal	= 0x010,
                // Flow over phase B is reversed
                PhaseBReverse	= 0x020,
                // No flow over of phase B 
                PhaseBNone		= 0x030,
                // phase C flow information
                PhaseCMask		= 0xf00,
                // Flow over phase C is normal
                PhaseCNormal	= 0x100,
                // Flow over phase C is reversed
                PhaseCReverse	= 0x200,
                // No flow over of phase C 
                PhaseCNone		= 0x300	
            };
            DEFINE_ENUM_FLAG_OPERATORS(EdgeElementFlowDirection)


            enum class EdgeElementStatus
            {
                // indicates an impedance change / line contact
                ImpedanceChanged	= 1,
                // indicates line contact 
                LineContact			= 2,
                // use this status to indicate a controller failure
                ControlFailed		= 4
            };
            DEFINE_ENUM_FLAG_OPERATORS(EdgeElementStatus)

            class EdgeElementRatings
            {
                double continuous;
	            double emergency;
            public:
                EdgeElementRatings()
                    : continuous(0.0),
                      emergency(0.0)
                {}

                EdgeElementRatings(double theContinuous, double theEmergency )
                    : continuous(theContinuous),
                      emergency(theEmergency)
                {}

                double Continuous() const { return continuous; }
                EdgeElementRatings& SetContinuous( double theValue ) { continuous = theValue; return *this; }

                double Emergency() const { return emergency; }
                EdgeElementRatings& SetEmergency( double theValue ) { emergency = theValue; return *this; }


            };


            class EdgeElement : public PowerElement
            {
            public:
                // The 'a' matrix
	            MatrixC3x3 a;
                // The 'b' matrix
	            MatrixC3x3 b;
                // The 'c' matrix
	            MatrixC3x3 c;
                // The 'd' matrix
	            MatrixC3x3 d;
                // The 'A' matrix
	            MatrixC3x3 A;
                // The 'B' matrix
	            MatrixC3x3 B;

                // Used to calculate return current
	            VectorC3 tn;

                // transition to admittance
	            MatrixC3x3 toY;

                // transition from admittance
	            MatrixC3x3 fromY;

                // admittance as seen from the "from" side when the edge is a transformer
	            MatrixC3x3 fromYS;
                // admittance as seen from the "to" side when the edge is a transformer
	            MatrixC3x3 toYS;

                // voltage ratio
	            double voltageRatio;

                // Index of Edge
	            int index;

                // Flag for exceptions to the normal handling
	            EdgeElementType type;	

                // Direction of the powerflow
	            EdgeElementFlowDirection flowDirection;

	            double faultCurrentSolved;
	            
	            TimeSpan meanRepairTime;
                
	            EdgeElementRatings edgeLimits;
	            EdgeElementRatings edgeRatings;
	            
            public:
                // Edge status 
	            EdgeElementStatus status;

                // Previous status to detect recalculation 
	            EdgeElementStatus previousStatus;

                // indicates that current has been calculated
	            bool currentAccumulated;

                // do we need to take edge limits into account?
	            bool checkEdgeLimits;
                // source node
	            NodeElement *from;
                //load node
	            NodeElement *to; 

                // current flow into the edge from the source 
	            VectorC3 currentIn;

                // current flow out of the link into the load node
	            VectorC3 currentOut;

                // Target current flow into the edge from the source
	            VectorC3 targetCurrentIn;	

                // Target current flow out of the edge into the load
	            VectorC3 targetCurrentOut;

                // fault current flow into the edge from the source
	            VectorC3 faultCurrentIn;	

                // fault current flow out of the edge into the load
	            VectorC3 faultCurrentOut;

                // power flow into the edge from the source
	            complex powerIn;

                // power flow out of the edge into the load
	            complex powerOut;
                // power loss in a transformer
	            complex powerLoss;

                // individual quantities of the power flow
	            VectorC3 individualPowerIn;
	            VectorC3 individualPowerOut;
	            VectorC3 individualPowerLoss;

                // reliability: index of the protection objects 
                // for the different phase faults
	            std::array<int,3> protectionIndexes;

            public:
	            // Which phases were affected by status change 
	            Phase affectedPhases;
	            
                // Resistance when status==EdgeStatus::ImpedanceChanged 
	            double resistance;
	            
                // Indicates how line was connected
	            Phase connectedPhases;

            };


            // -----------------------------------------------------------------
            // Conductor
            // -----------------------------------------------------------------
            class Conductor
            {
                double geometricMeanRadius;
                EdgeElementRatings winter;
                EdgeElementRatings emergencyWinter;
                EdgeElementRatings summer;
                EdgeElementRatings emergencySummer;
            };


            // -----------------------------------------------------------------
            // LineConductor
            // -----------------------------------------------------------------
            class LineConductor : public Conductor
            {
                double diameter;
	            double resistance;
	            

	            
            };

            // -----------------------------------------------------------------
            // OverheadLineConductor
            // -----------------------------------------------------------------
            class OverheadLineConductor : public LineConductor
            {
	            
            };

            // -----------------------------------------------------------------
            // UndergroundLineConductor
            // -----------------------------------------------------------------
            class UndergroundLineConductor : public LineConductor
            {
                double outerDiameter;

	            double neutralGeometricMeanRadius;
	            double neutralDiameter;
	            double neutralResistance;
	            short  neutralStrands;
	            double insulationRelativePermitivity;
	            double shieldGeometricMeanRadius;
	            double shieldResistance;
	            
            };


            // -----------------------------------------------------------------
            // TriplexLineConductor
            // -----------------------------------------------------------------
            class TriplexLineConductor : public Conductor
            {
                double resistance;
	            
	            
            };


            // -----------------------------------------------------------------
            // LineSpacing
            // -----------------------------------------------------------------
            class LineSpacing
            {

                // distance between cables:
                //   A and B
                double aToB;
                //   B and C
	            double bToC;
                //   A and C
	            double aToC;

                //   A and Neutral
	            double aToN;
                //   B and Neutral
	            double bToN;
                //   C and Neutral
	            double cToN;

                // distance bewteen cables and earth 
                //   A
	            double aToE;
                //   B
	            double bToE;
                //   C
	            double cToE;
                //   Neutral
	            double nToE;
            };

            // -----------------------------------------------------------------
            // LineConfiguration
            // -----------------------------------------------------------------
            class LineConfiguration 
            {
                Conductor* phaseAConductor;
	            Conductor* phaseBConductor;
	            Conductor* phaseCConductor;
	            Conductor* phaseNConductor;
                LineSpacing* lineSpacing;

                // Define the z-bus matrix
	            MatrixC3x3 impedance;



            };


            // -----------------------------------------------------------------
            // LineElement
            // -----------------------------------------------------------------
            class LineElement : public EdgeElement
            {
            public:
                double length;
                LineConfiguration *configuration;

            };

            // -----------------------------------------------------------------
            // SwitchMode
            // -----------------------------------------------------------------
            enum class SwitchBankMode
            {
                Individual = 0,
                Banked = 1
            };

            // -----------------------------------------------------------------
            // SwitchState
            // -----------------------------------------------------------------
            enum class SwitchState
            {
                Open = 0,
                Closed = 1,
                Faulted = 2
            };


            // -----------------------------------------------------------------
            // SwitchElement
            // -----------------------------------------------------------------
            class SwitchElement : public EdgeElement
            {
            public:
                SwitchBankMode switchBankMode;
                SwitchBankMode prefaultSwitchBankMode;
	            
                SwitchState phaseAState;
	            SwitchState phaseBState;
	            SwitchState phaseCState;

            };
            
            // -----------------------------------------------------------------
            // RecloserElement
            // -----------------------------------------------------------------
            class RecloserElement : public SwitchElement
            {
            public:
                DateTime retryTime;
	            int maxTries;
	            int currentTry;
	            DateTime returnTime;
	            DateTime previousRecoveryTime;
            };


            // -----------------------------------------------------------------
            // RegulatorConnectionType
            // -----------------------------------------------------------------
            enum class RegulatorConnectionType
            {
                WyeWye = 1,
		        OpenDeltaABBC,
		        OpenDeltaBCAC,
		        OpenDeltaCABA,
		        ClosedDelta,
		        ConnectTypeMax
            };


            // -----------------------------------------------------------------
            // RegulatorControl
            // -----------------------------------------------------------------
            enum class RegulatorControl
            {
                Manual = 1,
		        OutputVoltage = 2,
		        RemoteNode = 3,
		        LineDropComp = 4
            };

            // -----------------------------------------------------------------
            // RegulatorBankMode
            // -----------------------------------------------------------------
            enum class RegulatorBankMode
            {
                Individual = 0,
                Banked = 1
            };
            // -----------------------------------------------------------------
            // RegulatorType
            // -----------------------------------------------------------------
            enum class RegulatorType
            {
                A = 1,
		        B = 2
            };

            // -----------------------------------------------------------------
            // RegulatorConfiguration
            // -----------------------------------------------------------------
            class RegulatorConfiguration
            {
            public:
	            RegulatorControl control;
	            RegulatorBankMode bankMode;
	            RegulatorType type;
	            RegulatorConnectionType connectionType;

	            // band center for regulator control
	            double bandCenter;
                // band width for regulator control
	            double bandWidth;
                // time delay for regulator control
	            double dwellTime;
                // mechanical delay between tap changes 
	            double timeDelay;
                // the number of raise taps
	            short raiseTaps;
                // the number of lower taps
	            short lowerTaps;
                // current transformer rating 
	            double CTRatio;
                // potential transformer rating 
	            double PTRatio;
                // Line Drop Compensation R in volts
	            VectorD3 lineDropCompensationR;
                // Line Drop Compensation X in volts
	            VectorD3 lineDropCompensationX;

                // monitored phases 
                //   by CT
	            Phase phasesCT;
                //   by PT
	            Phase phasesPT;

                // voltage regulation in %
	            double regulation;

	            std::array<short,3> tapPositions;


            };

            // -----------------------------------------------------------------
            // RegulatorTap
            // -----------------------------------------------------------------
            class RegulatorTap
            {
            public:
                short position;
                short previousPosition;
                complex volt;
                complex compensation;
                complex current;
                double changes;

                // next time step after change
                TimeSpan timeDelay;	 
                // advance only after sensing over/under 
                // voltage for a certain dwellTime
	            TimeSpan dwellTime;	 
	            // indicates whether a state change is 
                // okay due to mechanical tap changes
	            short  mechanicalFlag;		 
                // indicates whether a state change is 
                // okay due to dwell time limitations
	            short  dwellFlag;	 
                // prevents the system from failing due to 
                // a bad guess at the initial tap position
	            short  firstRunFlag; 
                // Voltage that is checked with
	            complex checkVoltage;

            };

            // -----------------------------------------------------------------
            // RegulatorElement
            // -----------------------------------------------------------------
            class RegulatorElement : public EdgeElement
            {
            public:
                RegulatorConfiguration* configuration;
                RegulatorTap A;
                RegulatorTap B;
                RegulatorTap C;

                double voltageTapChange;
	            double tapChangePer;
                Range<double> voltageLimits;
	            MatrixC3x3 D;
	            MatrixC3x3 W;
	            
                // Remote node voltage values 
                // in RemoteNode Control mode
	            NodeElement *remoteNode; 
	            
                // final return for next time step
	            TimeSpan nextTime;		 
	            
                // detect off-nominal timesteps and 
                // perform do exception on them
                bool offNominalTime;	

            };


            // -----------------------------------------------------------------
            // TransformerConnectionType
            // -----------------------------------------------------------------
            enum class TransformerConnectionType
            {
                WyeWye = 1, 
                DeltaDelta, 
                DeltaGWye, 
                SinglePhase, 
                SinglePhaseCenterTapped
            };

            // -----------------------------------------------------------------
            // TransformerInstallationType
            // -----------------------------------------------------------------
            enum class TransformerInstallationType
            {
                PoleTop = 1, 
                PadMount, 
                Vault
            };

            // -----------------------------------------------------------------
            // TransformerCoolantType
            // -----------------------------------------------------------------
            enum class TransformerCoolantType
            {
                MineralOil = 1,
                Dry = 2
            };

            // -----------------------------------------------------------------
            // TransformerCoolingType
            // -----------------------------------------------------------------
            enum class TransformerCoolingType
            {
                OA=1, 
                FA=2, 
                NDFOA=3, 
                NDFOW=4, 
                DFOA=5, 
                DFOW=6
            };


            // -----------------------------------------------------------------
            // TransformerConfiguration
            // -----------------------------------------------------------------
            class TransformerConfiguration
            {
            public:
                TransformerConnectionType connectionType;
	            TransformerInstallationType installationType;
                // primary voltage level
	            double primaryVoltage;
                // secondary voltage level kV
	            double secondaryVoltage;   
	            
                // kVA rating of transformer
	            double phaseAkVARating;
	            double phaseBkVARating;
	            double phaseCkVARating;
                // Series impedance
	            std::vector<complex> impedance;
                // Shunt impedance - values are summed 
                // and reflected back to the primary
	            complex shuntImpedance;	
                // alternative way for specifying 
                // transformer impedances
	            double noLoadLoss;
	            double fullLoadLoss;			
                // the reactance to resistance ratio
	            double RX;
	            // thermal model input
	            TransformerCoolantType coolantType;
	            TransformerCoolingType coolingType;
                // Weight of the core & coil assembly
	            double coreCoilWeight;		
                // Weight of the tank & fittings
	            double tankFittingsWeight;
                // Volume of oil in the transformer
	            double oilVolume;
                // The rated winding time constant in hours.
	            double ratedWindingTime;
                // Top-oil hotspot rise over the 
                // ambient temperature at the rated load
	            double topOilDTheta;
                // Winding hotspot rise over the 
                // ambient temperature at the rated load
	            double windingDTheta;
                // Normal lifetime of transformer insulation 
                // at the rated load
                TimeSpan insulationLifeTime;
            };

            // -----------------------------------------------------------------
            // TransformerInsulation
            // -----------------------------------------------------------------
            class TransformerInsulation
            {
            public:
                // aging rate for the transformer insulation. 
	            double insulationAgingFactor;
                // aging acceleration factor.
	            double insulationAgingAccelerationFactor;
                // equivalent aging acceleration factor.
	            double insulationEquivalentAgingAccelerationFactor;
                
                // the installed insulation life of the transformer.
	            TimeSpan insulationLifetime;
                // percent loss of life.
	            double lifeLoss;
            };

            // -----------------------------------------------------------------
            // TransformerThermalModel
            // -----------------------------------------------------------------
            class TransformerThermalModel
            {
            public:
                double thermalCapacity;
                // ratio of the current load to the rated load, per unit.
	            double K;
                // derived exponent for calculating the 
                // variation of windingDTheta with changes 
                // in the load
	            double m;
                // derived exponent for calculating the 
                // variation of topOilDTheta with changes 
                // in the load
	            double n;
                // ratio of the full load loss 
                // to the no-load loss.
	            double R;
                // ambient temperature.
	            double ambientTemperature;
                // winding hotspot temperature
	            double windingTheta;
                // top-oil hotspot temperature
	            double topOilTheta;

                // winding hotspot rise over the 
                // top-oil temperature
	            double windingDTheta;
                // initial winding hotspot rise over the 
                // top-oil temperature
	            double windingInitialDTheta;
                // winding hotspot rise over the top-oil 
                // temperature at the rated load
	            double windingDThetaR;
                // ultimate winding hotspot rise over the top-oil 
                // temperature for current load
	            double windingDThetaU;

                // top-oil hotspot rise over the 
                // ambient temperature
	            double topOilDTheta;
                // initial top-oil hotspot rise over 
                // the ambient temperature
	            double topOilInitialDTheta;
                // ultimate top-oil hotspot rise over the 
                // ambient temperature for the current load
	            double topOilDThetaU;

                // the oil time constant for the rated 
                // load with topOilInitialDTheta = 0
	            TimeSpan topOilRatedTime;
                // the oil time constant for any load and any 
                // difference between topOilDThetaU and topOilInitialDTheta
	            TimeSpan topOilTime;
            };

            // -----------------------------------------------------------------
            // TransformerElement
            // -----------------------------------------------------------------
            class TransformerElement : public EdgeElement
            {
            public:
                TransformerConfiguration* configuration;
                
                // enable the thermal model.
	            bool useThermalModel;
                TransformerThermalModel thermalModel;
	            TransformerInsulation insulation;
                
	            TimeSpan transformerReplacements;
                // timestep before updating the models
	            TimeSpan agingStep;
	            DateTime returnAt;
            };


            // -----------------------------------------------------------------
            // FuseState
            // -----------------------------------------------------------------
            enum class FuseState
            {
                Blown = 0,
                Good  = 1
            };

            // -----------------------------------------------------------------
            // FuseMeanTimeToRestore
            // -----------------------------------------------------------------
            enum class FuseMeanTimeToRestoreType
            {
                None = 0,
                Exponential = 1
            };

            // -----------------------------------------------------------------
            // FuseElement
            // -----------------------------------------------------------------
            class FuseElement : public EdgeElement
            {
            public:
	            FuseMeanTimeToRestoreType restoreType;
                FuseState phaseAState;
	            FuseState phaseBState;
	            FuseState phaseCState;

                // Current limit for the fuse
	            double currentLimit;
	            
	            TimeSpan meanReplacementTime;
	            

            };


            // -----------------------------------------------------------------
            // RelayElement
            // -----------------------------------------------------------------
            class RelayElement : public EdgeElement
            {
            public:
                DateTime relayTime;

                // time for state to change
	            TimeSpan timeToChange;
                // time delay before relay
	            TimeSpan relayDelay;
                // number of times relay has tried
	            short relayTries;	
                // maximum number of relay tries
	            short relayLimit;
	            
                bool relayEvent;

            };


            // -----------------------------------------------------------------
            // SectionalizerElement
            // -----------------------------------------------------------------
            class SectionalizerElement : public SwitchElement
            {
            public:
                

            };

            // -----------------------------------------------------------------
            // SeriesReactorElement
            // -----------------------------------------------------------------
            class SeriesReactorElement : public EdgeElement
            {
            public:
                // impedance of the reactor
                complex phaseAImpedance;
	            complex phaseBImpedance;
	            complex phaseCImpedance;
                // Current rating
	            double ratedCurrentLimit;

            };



            // -----------------------------------------------------------------
            // Node
            // -----------------------------------------------------------------
            class Edge;
            class NodeData;
            class Node
            {
                mutable NodeData* data;
                const NodeData* Data() const;
                NodeData* Data();
            public:
                Node();
                Node(const Node& other);
                Node(Node&& other);
                ~Node( );

                Node& operator = (const Node& other);
                Node& operator = (Node&& other);

                operator bool() const { return data != nullptr; } 

                String Name() const;
                Node& SetName( const String& theName );

                Phase Phases() const;
                Node& SetPhases( Phase thePhases );

	            Phase OriginalPhases() const;
                Node& SetOriginalPhases( Phase theOriginalPhases );

                NodeElementType Type() const;
                Node& SetType(NodeElementType theNodeType);

                Node ParentNode() const;
                Node& SetParentNode(const Node& theParentNode  );

                const std::vector<Node>& ChildNodes() const;
                std::vector<Node>& ChildNodes();

                // edges connecting to this node
                const std::vector<Edge>& Edges() const;
                std::vector<Edge>& Edges();

                // voltage (V)
                const std::vector< complex >& Voltage() const;
                std::vector< complex >& Voltage();

                // constant power (S)
                const std::vector< complex >& Power() const;
                std::vector< complex >& Power();


                // constant admittance/impedance loads (Y)
                const std::vector< complex >& Admittance() const;
                std::vector< complex >& Admittance();

                // constant current (I)
                const std::vector< complex >& Current() const;
                std::vector< complex >& Current();

                // differently-connected children or triplex calculations
                const std::vector< complex >& TriplexData() const;
                std::vector< complex >& TriplexData();

                // nominal residence current 
                const std::vector< complex > ResidenceData() const;
                std::vector< complex > ResidenceData();
                    
                // total real power load (PL)
                const VectorD3& PL() const;
                VectorD3& PL();
                // total reactive power load (QL)
                const VectorD3& QL() const;
                VectorD3& QL();
                // real power generation (for a generator) (PG)
                const VectorD3& PG() const;
                VectorD3& PG();
                // reactive power generation (for a generator) (QG)
                const VectorD3& QG() const;
                VectorD3& QG();

                // kV basis
                double KvBasis() const;
                Node& SetKvBasis( double theValue );
                // MVA basis
                double MVABasis() const;
                Node& SetMVABasis(double theValue);

                // Jacobian matrix work variables
                const std::array< VectorD3,4>& Jacobian() const;
                std::array< VectorD3,4>& Jacobian();
                
                // Maximum voltage error for the node
                double MaxVoltageError() const;
                Node& SetMaxVoltageError( double theValue );

                // Index in matrices
                unsigned Index() const;
                Node& SetIndex(unsigned theValue );


            };


            enum class EdgeType
            {
                UGOHline = 0, 
                TriplexLine = 1, 
                Switch = 2, 
                Fuse = 3, 
                Transformer = 4, 
                Sectionalizer = 5, 
                Recloser = 6
            };

            // -----------------------------------------------------------------
            // Edge
            // -----------------------------------------------------------------
            class EdgeData;
            class Edge
            {
                mutable EdgeData* data;
                const EdgeData* Data() const;
                EdgeData* Data();
            public:
                Edge();
                Edge(const Edge& other);
                Edge(Edge&& other);
                ~Edge( );

                Edge& operator = (const Edge& other);
                Edge& operator = (Edge&& other);

                operator bool() const { return data != nullptr; } 

                String Name() const;
                Edge& SetName( const String& theName );

                Phase Phases() const;
                Edge& SetPhases( Phase thePhases );

	            Phase OriginalPhases() const;
                Edge& SetOriginalPhases( Phase theOriginalPhases );


                EdgeType Type() const;
                Edge& SetType(EdgeType theValue);

                Node From();
                Edge& SetFrom(const Node& theNode);

                Node To() const;
                Edge& SetTo(const Node& theNode);

                // induced faults, prevent restoration of edge
	            Phase FaultPhases() const;
                Edge& SetFaultPhases(Phase theValue);

                // edge admittance of the from side
                const std::vector< complex >& AdmittanceFrom() const;
                std::vector< complex >& AdmittanceFrom();
                // edge admittance of the to side
	            const std::vector< complex >& AdmittanceTo() const;
                std::vector< complex >& AdmittanceTo();
                // self admittance seen on from side
	            const std::vector< complex >& SelfAdmittanceFrom() const;
                std::vector< complex >& SelfAdmittanceFrom();
                // self admittance on the to side
	            const std::vector< complex >& SelfAdmittanceTo() const;
                std::vector< complex >& SelfAdmittanceTo();
                // 3 phase fault currents on the from side
	            const std::vector< complex >& FaultCurrentsFrom() const;
                std::vector< complex >& FaultCurrentsFrom();
                // 3 phase fault currents on the to side 
	            const std::vector< complex >& FaultCurrentsTo() const;
                std::vector< complex >& FaultCurrentsTo();

                // from/to voltage ratio
                double VoltageRatio() const;
                Edge& SetVoltageRatio(double theValue);

                // Next faulted edge below the current edge
                Edge FaultEdge() const;
                Edge& SetFaultEdge(const Edge& theFaultEdge);

                // Edge (switch) status
                const std::vector<bool>& Status() const;
                std::vector<bool>& Status();


            };



            // -----------------------------------------------------------------
            // BaseData
            // -----------------------------------------------------------------
            class BaseData 
            {
                long referenceCount;
                String name;
	            Phase phases;
	            Phase originalPhases;
            public:
                BaseData()
                    : referenceCount(1),
                      phases(Phase::None),
                      originalPhases(Phase::None)
                {}

                virtual ~BaseData()
                {}

                long AddRef()
                {
                    return InterlockedIncrement(&referenceCount);
                }

                long Release()
                {
                    long result = InterlockedDecrement(&referenceCount);
                    if(!result)
                    {
                        delete this;
                    }
                    return result;
                }


                String Name() const { return name; }
                BaseData& SetName( const String& theName )
                {
                    name = theName;
                    return *this;
                }

                Phase Phases() const { return phases; }
                BaseData& SetPhases( Phase thePhases )
                {
                    phases = thePhases;
                    return *this;
                }

	            Phase OriginalPhases() const { return originalPhases; }
                BaseData& SetOriginalPhases( Phase theOriginalPhases )
                {
                    originalPhases = theOriginalPhases;
                    return *this;
                }

            };

            // -----------------------------------------------------------------
            // NodeData
            // -----------------------------------------------------------------
            class NodeData : public BaseData 
            {
	            NodeElementType nodeType;

                Node parentNode;
	            std::vector<Node> childNodes;
                std::vector<Node>::iterator childNode;

                // edges connecting to this node
                std::vector<Edge> edges;

                // voltage (V)
                std::vector< complex > voltage;
                // constant power (S)
	            std::vector< complex > power;
                // constant admittance/impedance loads (Y)
	            std::vector< complex > admittance;
                // constant current (I)
	            std::vector< complex > current;

                // differently-connected children or triplex calculations
	            std::vector< complex > triplexData;
                // nominal residence current 
	            std::vector< complex > residenceData;
                    
                // total real power load (PL)
	            VectorD3 totalRealPowerLoad;
                // total reactive power load (QL)
	            VectorD3 totalReactivePowerLoad;
                // real power generation (for a generator) (PG)
	            VectorD3 totalRealGeneratedPower;
                // reactive power generation (for a generator) (QG)
	            VectorD3 totalReactiveGeneratedPower;
                // kV basis
	            double kvBasis;
                // MVA basis
                double mvaBasis;

                // Jacobian matrix work variables
                std::array< VectorD3,4> jacobian;

                
                // Maximum voltage error for the node
	            double maxVoltageError;	

                // Index in matrices
	            unsigned index;
            public:
                NodeData()
                    : nodeType(NodeElementType::PQ),
                      kvBasis(0.0),
                      mvaBasis(0.0),
                      maxVoltageError(0.0),
                      index(0)
                {
                }



                NodeElementType Type() const { return nodeType; }
                void SetType(NodeElementType theNodeType) { nodeType = theNodeType; }

                Node ParentNode() const { return parentNode; }
                void SetParentNode(const Node& theParentNode  ) { parentNode = theParentNode; }

                const std::vector<Node>& ChildNodes() const { return childNodes; }
                std::vector<Node>& ChildNodes() { return childNodes; }

                // edges connecting to this node
                const std::vector<Edge>& Edges() const { return edges; }
                std::vector<Edge>& Edges() { return edges; }

                // voltage (V)
                const std::vector< complex >& Voltage() const { return voltage; }
                std::vector< complex >& Voltage() { return voltage; }

                // constant power (S)
                const std::vector< complex >& Power() const { return power; }
                std::vector< complex >& Power() { return power; }


                // constant admittance/impedance loads (Y)
                const std::vector< complex >& Admittance() const { return admittance; }
                std::vector< complex >& Admittance() { return admittance; }

                // constant current (I)
                const std::vector< complex >& Current() const { return current; }
                std::vector< complex >& Current() { return current; }

                // differently-connected children or triplex calculations
                const std::vector< complex >& TriplexData() const { return triplexData; }
                std::vector< complex >& TriplexData() { return triplexData; }

                // nominal residence current 
                const std::vector< complex > ResidenceData() const { return residenceData; }
                std::vector< complex > ResidenceData() { return residenceData; }
                    
                // total real power load (PL)
                const VectorD3& PL() const { return totalRealPowerLoad; }
                VectorD3& PL() { return totalRealPowerLoad; }
                // total reactive power load (QL)
                const VectorD3& QL() const { return totalReactivePowerLoad; }
                VectorD3& QL() { return totalReactivePowerLoad; }
                // real power generation (for a generator) (PG)
                const VectorD3& PG() const { return totalRealGeneratedPower; }
                VectorD3& PG() { return totalRealGeneratedPower; }
                // reactive power generation (for a generator) (QG)
                const VectorD3& QG() const { return totalReactiveGeneratedPower; }
                VectorD3& QG() { return totalReactiveGeneratedPower; }

                // kV basis
                double KvBasis() const { return kvBasis; }
                void SetKvBasis( double theValue ) { kvBasis = theValue; }
                // MVA basis
                double MVABasis() const { return mvaBasis; }
                void SetMVABasis(double theValue) { mvaBasis = theValue; }

                // Jacobian matrix work variables
                const std::array< VectorD3,4>& Jacobian() const { return jacobian; }
                std::array< VectorD3,4>& Jacobian() { return jacobian; }
                
                // Maximum voltage error for the node
                double MaxVoltageError() const { return maxVoltageError; }
                void SetMaxVoltageError( double theValue ) { maxVoltageError = theValue; }

                // Index in matrices
                unsigned Index() const { return index; }
                void SetIndex(unsigned theValue ) { index = theValue; }
            };


            // -----------------------------------------------------------------
            // EdgeData
            // -----------------------------------------------------------------
            class EdgeData : public BaseData 
            {
                EdgeType type;

                Node from;
	            Node to;

                // induced faults, prevent restoration of edge
	            Phase faultPhases;

                // edge admittance of the from side
                std::vector< complex > admittanceFrom;
                // edge admittance of the to side
	            std::vector< complex > admittanceTo;
                // self admittance seen on from side
	            std::vector< complex > selfAdmittanceFrom;
                // self admittance on the to side
	            std::vector< complex > selfAdmittanceTo;
                // 3 phase fault currents on the from side
	            std::vector< complex > faultCurrentsFrom;
                // 3 phase fault currents on the to side 
	            std::vector< complex > faultCurrentsTo;

                // from/to voltage ratio
	            double voltageRatio;

                // Next faulted edge below the current edge
	            Edge faultEdge;
                // Edge (switch) status
	            std::vector<bool> status;
            public:

	            
                EdgeType Type() const { return type; }
                void SetType(EdgeType theValue) { type = theValue; }

                Node From() const
                {
                    return from;
                }
                void SetFrom(const Node& theNode) { from = theNode; }

                Node To() const { return to; }
                void SetTo(const Node& theNode) { to = theNode; }

                // induced faults, prevent restoration of edge
	            Phase FaultPhases() const
                {
                    return faultPhases;
                }

                void SetFaultPhases(Phase theValue) { faultPhases = theValue; }

                // edge admittance of the from side
                const std::vector< complex >& AdmittanceFrom() const { return admittanceFrom; }
                std::vector< complex >& AdmittanceFrom() { return admittanceFrom; }
                // edge admittance of the to side
	            const std::vector< complex >& AdmittanceTo() const { return admittanceTo; }
                std::vector< complex >& AdmittanceTo() { return admittanceTo; }
                // self admittance seen on from side
	            const std::vector< complex >& SelfAdmittanceFrom() const { return selfAdmittanceFrom; }
                std::vector< complex >& SelfAdmittanceFrom() { return selfAdmittanceFrom; }
                // self admittance on the to side
	            const std::vector< complex >& SelfAdmittanceTo() const { return selfAdmittanceTo; }
                std::vector< complex >& SelfAdmittanceTo() { return selfAdmittanceTo; }
                // 3 phase fault currents on the from side
	            const std::vector< complex >& FaultCurrentsFrom() const { return faultCurrentsFrom; }
                std::vector< complex >& FaultCurrentsFrom() { return faultCurrentsFrom; }
                // 3 phase fault currents on the to side 
	            const std::vector< complex >& FaultCurrentsTo() const { return faultCurrentsTo; }
                std::vector< complex >& FaultCurrentsTo() { return faultCurrentsTo; }

                // from/to voltage ratio
                double VoltageRatio() const { return voltageRatio; }
                void SetVoltageRatio(double theValue) { voltageRatio = theValue; }

                // Next faulted edge below the current edge
                Edge FaultEdge() const { return faultEdge; }
                void SetFaultEdge(const Edge& theValue) { faultEdge = theValue; }

                // Edge (switch) status
                const std::vector<bool>& Status() const { return status; }
                std::vector<bool>& Status() { return status; }

            };

            // -----------------------------------------------------------------
            // SolverData
            // -----------------------------------------------------------------
            class SolverData
            {
                long referenceCount;
                std::vector< Node > nodes;
                std::vector< Edge > edges;
                bool errors;
                long long iterations;
            public:

                SolverData()
                    : referenceCount(1)
                {}

                SolverData(const std::vector< Node >& theNodes, const std::vector< Edge >& theEdges )
                    : referenceCount(1),
                      nodes(theNodes),
                      edges(theEdges)
                {}

                long AddRef()
                {
                    return InterlockedIncrement(&referenceCount);
                }

                long Release()
                {
                    long result = InterlockedDecrement(&referenceCount);
                    if(!result)
                    {
                        delete this;
                    }
                    return result;
                }

                HPWR_EXPORT void Solve();
                HPWR_EXPORT bool HasSolution() const;

                const std::vector< Node > Nodes() const { return nodes; }
                std::vector< Node > Nodes() { return nodes; }

                const std::vector< Edge > Edges() const { return edges; }
                std::vector< Edge > Edges() { return edges; }

                long long Result() const { return iterations; }

            };

            // -----------------------------------------------------------------
            // Solver
            // -----------------------------------------------------------------
            class Solver
            {
                SolverData* data;
            public:
                Solver()
                    : data(new SolverData())
                {}

                Solver(const std::vector< Node >& theNodes, const std::vector< Edge >& theEdges)
                    : data(new SolverData(theNodes,theEdges))
                {}

                Solver& Solve() 
                {
                    data->Solve();
                    return *this;
                }
                bool HasSolution() const
                {
                    return data->HasSolution();
                }

                const std::vector< Node > Nodes() const { return data->Nodes(); }
                std::vector< Node > Nodes() { return data->Nodes(); }

                const std::vector< Edge > Edges() const { return data->Edges(); }
                std::vector< Edge > Edges() { return data->Edges(); }

                long long Result() const { return data->Result(); }



            };


            // -----------------------------------------------------------------
            // Node implementation
            // -----------------------------------------------------------------
            const NodeData* Node::Data() const
            {
                if(!data)
                {
                    data = new NodeData();
                }
                return data;
            }
            NodeData* Node::Data()
            {
                if(!data)
                {
                    data = new NodeData();
                }
                return data;
            }

            inline Node::Node()
                : data(nullptr)
            {}
            inline Node::Node(const Node& other)
                : data(other.data)
            {
                if(data)
                {
                    data->AddRef();
                }
            }
            inline Node::Node(Node&& other)
                : data(other.data)
            {
                other.data = nullptr;
            }
            inline Node::~Node( )
            {
                if(data)
                {
                    data->Release();
                }
            }

            inline Node& Node::operator = (const Node& other)
            {
                if(data != other.data)
                {
                    if(data)
                    {
                        data->Release();
                    }
                    data = other.data;
                    if(data)
                    {
                        data->AddRef();
                    }
                }
                return *this;
            }
            inline Node& Node::operator = (Node&& other)
            {
                if(this != &other)
                {
                    if(data)
                    {
                        data->Release();
                    }
                    data = other.data;
                    if(data)
                    {
                        data->AddRef();
                    }
                }
                return *this;
            }


            inline String Node::Name() const
            {
                return Data()->Name();
            }
            inline Node& Node::SetName( const String& theName )
            {
                Data()->SetName(theName);
                return *this;
            }

            inline Phase Node::Phases() const
            {
                return Data()->Phases();
            }
            inline Node& Node::SetPhases( Phase thePhases )
            {
                Data()->SetPhases(thePhases);
                return *this;
            }

	        inline Phase Node::OriginalPhases() const
            {
                return Data()->OriginalPhases();
            }
            inline Node& Node::SetOriginalPhases( Phase theOriginalPhases )
            {
                Data()->SetOriginalPhases(theOriginalPhases);
                return *this;
            }

            inline NodeElementType Node::Type() const
            {
                return Data()->Type();
            }
            inline Node& Node::SetType(NodeElementType theNodeType)
            {
                Data()->SetType(theNodeType);
                return *this;
            }

            inline Node Node::ParentNode() const
            {
                return Data()->ParentNode();
            }
            inline Node& Node::SetParentNode(const Node& theParentNode  )
            {
                Data()->SetParentNode(theParentNode);
                return *this;
            }

            inline const std::vector<Node>& Node::ChildNodes() const
            {
                return Data()->ChildNodes();
            }
            inline std::vector<Node>& Node::ChildNodes()
            {
                return Data()->ChildNodes();
            }

            // edges connecting to this node
            inline const std::vector<Edge>& Node::Edges() const
            {
                return Data()->Edges();
            }
            inline std::vector<Edge>& Node::Edges()
            {
                return Data()->Edges();
            }

            // voltage (V)
            inline const std::vector< complex >& Node::Voltage() const
            {
                return Data()->Voltage();
            }
            inline std::vector< complex >& Node::Voltage()
            {
                return Data()->Voltage();
            }

            // constant power (S)
            inline const std::vector< complex >& Node::Power() const
            {
                return Data()->Power();
            }
            inline std::vector< complex >& Node::Power()
            {
                return Data()->Power();
            }


            // constant admittance/impedance loads (Y)
            inline const std::vector< complex >& Node::Admittance() const
            {
                return Data()->Admittance();
            }
            inline std::vector< complex >& Node::Admittance()
            {
                return Data()->Admittance();
            }

            // constant current (I)
            inline const std::vector< complex >& Node::Current() const
            {
                return Data()->Current();
            }
            inline std::vector< complex >& Node::Current()
            {
                return Data()->Current();
            }

            // differently-connected children or triplex calculations
            inline const std::vector< complex >& Node::TriplexData() const
            {
                return Data()->TriplexData();
            }
            inline std::vector< complex >& Node::TriplexData()
            {
                return Data()->TriplexData();
            }

            // nominal residence current 
            inline const std::vector< complex > Node::ResidenceData() const
            {
                return Data()->ResidenceData();
            }
            inline std::vector< complex > Node::ResidenceData()
            {
                return Data()->ResidenceData();
            }
                    
            // total real power load (PL)
            inline const VectorD3& Node::PL() const
            {
                return Data()->PL();
            }
            inline VectorD3& Node::PL()
            {
                return Data()->PL();
            }
            // total reactive power load (QL)
            inline const VectorD3& Node::QL() const
            {
                return Data()->QL();
            }
            inline VectorD3& Node::QL()
            {
                return Data()->QL();
            }
            // real power generation (for a generator) (PG)
            inline const VectorD3& Node::PG() const
            {
                return Data()->PG();
            }
            inline VectorD3& Node::PG()
            {
                return Data()->PG();
            }
            // reactive power generation (for a generator) (QG)
            inline const VectorD3& Node::QG() const
            {
                return Data()->QG();
            }
            inline VectorD3& Node::QG()
            {
                return Data()->QG();
            }

            // kV basis
            inline double Node::KvBasis() const
            {
                return Data()->KvBasis();
            }
            inline Node& Node::SetKvBasis( double theValue )
            {
                Data()->SetKvBasis( theValue );
                return *this;
            }
            // MVA basis
            inline double Node::MVABasis() const
            {
                return Data()->MVABasis();
            }
            inline Node& Node::SetMVABasis(double theValue)
            {
                Data()->SetMVABasis( theValue );
                return *this;
            }

            // Jacobian matrix work variables
            inline const std::array< VectorD3,4>& Node::Jacobian() const
            {
                return Data()->Jacobian();
            }

            inline std::array< VectorD3,4>& Node::Jacobian()
            {
                return Data()->Jacobian();
            }

                
            // Maximum voltage error for the node
            inline double Node::MaxVoltageError() const
            {
                return Data()->MaxVoltageError();
            }
            inline Node& Node::SetMaxVoltageError( double theValue )
            {
                Data()->SetMaxVoltageError( theValue );
                return *this;
            }

            // Index in matrices
            inline unsigned Node::Index() const
            {
                return Data()->Index();
            }

            inline Node& Node::SetIndex(unsigned theValue )
            {
                Data()->SetIndex( theValue );
                return *this;
            }

            // -----------------------------------------------------------------
            // Edge implementation
            // -----------------------------------------------------------------
            const EdgeData* Edge::Data() const
            {
                if(!data)
                {
                    data = new EdgeData();
                }
                return data;
            }
            EdgeData* Edge::Data()
            {
                if(!data)
                {
                    data = new EdgeData();
                }
                return data;
            }

            
            Edge::Edge()
                : data(nullptr)
            {}
            Edge::Edge(const Edge& other)
                : data(other.data)
            {
                if(data)
                {
                    data->AddRef();
                }
            }
            Edge::Edge(Edge&& other)
                : data(other.data)
            {
                other.data = nullptr;
            }
            Edge::~Edge( )
            {
                if(data)
                {
                    data->Release();
                }
            }

            inline Edge& Edge::operator = (const Edge& other)
            {
                if(data != other.data)
                {
                    if(data)
                    {
                        data->Release();
                    }
                    data = other.data;
                    if(data)
                    {
                        data->AddRef();
                    }
                }
                return *this;
            }
            inline Edge& Edge::operator = (Edge&& other)
            {
                if(this != &other)
                {
                    if(data)
                    {
                        data->Release();
                    }
                    data = other.data;
                    if(data)
                    {
                        data->AddRef();
                    }
                }
                return *this;
            }


            inline String Edge::Name() const
            {
                return Data()->Name();
            }
            inline Edge& Edge::SetName( const String& theName )
            {
                Data()->SetName(theName);
                return *this;
            }

            inline Phase Edge::Phases() const
            {
                return Data()->Phases();
            }
            inline Edge& Edge::SetPhases( Phase thePhases )
            {
                Data()->SetPhases(thePhases);
                return *this;
            }

	        inline Phase Edge::OriginalPhases() const
            {
                return Data()->OriginalPhases();
            }
            inline Edge& Edge::SetOriginalPhases( Phase theOriginalPhases )
            {
                Data()->SetOriginalPhases(theOriginalPhases);
                return *this;
            }


            EdgeType Edge::Type() const
            {
                return Data()->Type();
            }
            Edge& Edge::SetType(EdgeType theValue)
            {
                Data()->SetType(theValue);
                return *this;
            }

            Node Edge::From()
            {
                return Data()->From();
            }
            Edge& Edge::SetFrom(const Node& theNode)
            {
                Data()->SetFrom(theNode);
                return *this;
            }

            Node Edge::To() const
            {
                return Data()->To();
            }
            Edge& Edge::SetTo(const Node& theNode)
            {
                Data()->SetTo(theNode);
                return *this;
            }

            // induced faults, prevent restoration of edge
	        Phase Edge::FaultPhases() const
            {
                return Data()->FaultPhases();
            }
            Edge& Edge::SetFaultPhases(Phase theValue)
            {
                Data()->SetFaultPhases(theValue);
                return *this;
            }

            // edge admittance of the from side
            const std::vector< complex >& Edge::AdmittanceFrom() const
            {
                return Data()->AdmittanceFrom();
            }
            std::vector< complex >& Edge::AdmittanceFrom()
            {
                return Data()->AdmittanceFrom();
            }
            // edge admittance of the to side
	        const std::vector< complex >& Edge::AdmittanceTo() const
            {
                return Data()->AdmittanceTo();
            }
            std::vector< complex >& Edge::AdmittanceTo()
            {
                return Data()->AdmittanceTo();
            }
            // self admittance seen on from side
	        const std::vector< complex >& Edge::SelfAdmittanceFrom() const
            {
                return Data()->SelfAdmittanceFrom();
            }
            std::vector< complex >& Edge::SelfAdmittanceFrom()
            {
                return Data()->SelfAdmittanceFrom();
            }
            // self admittance on the to side
	        const std::vector< complex >& Edge::SelfAdmittanceTo() const
            {
                return Data()->SelfAdmittanceTo();
            }
            std::vector< complex >& Edge::SelfAdmittanceTo()
            {
                return Data()->SelfAdmittanceTo();
            }
            // 3 phase fault currents on the from side
	        const std::vector< complex >& Edge::FaultCurrentsFrom() const
            {
                return Data()->FaultCurrentsFrom();
            }
            std::vector< complex >& Edge::FaultCurrentsFrom()
            {
                return Data()->FaultCurrentsFrom();
            }
            // 3 phase fault currents on the to side 
	        const std::vector< complex >& Edge::FaultCurrentsTo() const
            {
                return Data()->FaultCurrentsTo();
            }
            std::vector< complex >& Edge::FaultCurrentsTo()
            {
                return Data()->FaultCurrentsTo();
            }

            // from/to voltage ratio
            double Edge::VoltageRatio() const
            {
                return Data()->VoltageRatio();
            }
            Edge& Edge::SetVoltageRatio(double theValue)
            {
                Data()->SetVoltageRatio(theValue);
                return *this;
            }

            // Next faulted edge below the current edge
            Edge Edge::FaultEdge() const
            {
                return Data()->FaultEdge();
            }
            Edge& Edge::SetFaultEdge(const Edge& theFaultEdge)
            {
                Data()->SetFaultEdge(theFaultEdge);
                return *this;
            }

            // Edge (switch) status
            const std::vector<bool>& Edge::Status() const
            {
                return Data()->Status();
            }
            std::vector<bool>& Edge::Status()
            {
                return Data()->Status();
            }




        };
    };
};



#endif //__HPOWERNETSOLVER_H__

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Architect Sea Surveillance AS
Norway Norway
Chief Architect - Sea Surveillance AS.

Specializing in integrated operations and high performance computing solutions.

I’ve been fooling around with computers since the early eighties, I’ve even done work on CP/M and MP/M.

Wrote my first “real” program on a BBC micro model B based on a series in a magazine at that time. It was fun and I got hooked on this thing called programming ...

A few Highlights:

  • High performance application server development
  • Model Driven Architecture and Code generators
  • Real-Time Distributed Solutions
  • C, C++, C#, Java, TSQL, PL/SQL, Delphi, ActionScript, Perl, Rexx
  • Microsoft SQL Server, Oracle RDBMS, IBM DB2, PostGreSQL
  • AMQP, Apache qpid, RabbitMQ, Microsoft Message Queuing, IBM WebSphereMQ, Oracle TuxidoMQ
  • Oracle WebLogic, IBM WebSphere
  • Corba, COM, DCE, WCF
  • AspenTech InfoPlus.21(IP21), OsiSoft PI


More information about what I do for a living can be found at: harlinn.com or LinkedIn

You can contact me at espen@harlinn.no

Comments and Discussions