// 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__