Power System Platform  2026w10a-beta
Loading...
Searching...
No Matches
Fault Class Reference

Calculate the fault of the system and update the elements data. More...

#include <Fault.h>

Inheritance diagram for Fault:
Collaboration diagram for Fault:

Public Member Functions

 Fault (std::vector< Element * > elementList)
 Contructor.
 
 Fault ()
 Default contructor. Use GetElementsFromList(std::vector<Element*> elementList).
 
 ~Fault ()
 Destructor.
 
virtual bool RunFaultCalculation (double systemPowerBase)
 Calculate the fault of the system. Return true if was possible the calculation.
 
virtual bool RunSCPowerCalcutation (double systemPowerBase)
 Calculate the short-circuit power of the system. Return true if was possible the calculation.
 
virtual void UpdateElementsFault (double systemPowerBase)
 Update the data of the elements.
 
virtual wxString GetErrorMessage ()
 Get the error message generated in RunFaultCalculation(double systemPowerBase).
 
- Public Member Functions inherited from ElectricCalculation
 ElectricCalculation ()
 Constructor.
 
 ~ElectricCalculation ()
 Destructor.
 
virtual void GetElementsFromList (std::vector< Element * > elementList)
 Separate the power elements from a generic list.
 
virtual bool GetYBus (std::vector< std::vector< std::complex< double > > > &yBus, double systemPowerBase, YBusSequence sequence=POSITIVE_SEQ, bool includeSyncMachines=false, bool allLoadsAsImpedances=false, bool usePowerFlowVoltagesOnImpedances=false)
 Get the admittance matrix from the list of elements (use GetElementsFromList first).
 
virtual bool InvertMatrix (std::vector< std::vector< std::complex< double > > > matrix, std::vector< std::vector< std::complex< double > > > &inverse)
 Invert a matrix.
 
virtual void UpdateElementsPowerFlow (std::vector< std::complex< double > > voltage, std::vector< std::complex< double > > power, std::vector< BusType > busType, std::vector< ReactiveLimits > reactiveLimit, double systemPowerBase)
 Update the elements after the power flow calculation.
 
void ABCtoDQ0 (std::complex< double > complexValue, double angle, double &dValue, double &qValue)
 Convert a complex phasor in ABC representation to DQ components.
 
void DQ0toABC (double dValue, double qValue, double angle, std::complex< double > &complexValue)
 Convert DQ components to a complex phasor in ABC representation.
 
std::vector< std::complex< double > > GaussianElimination (std::vector< std::vector< std::complex< double > > > matrix, std::vector< std::complex< double > > array)
 Solve a linear system using Gaussian elimination (complex version).
 
std::vector< double > GaussianElimination (std::vector< std::vector< double > > matrix, std::vector< double > array)
 Solve a linear system using Gaussian elimination (real version).
 
Machines::SyncMachineModel GetMachineModel (SyncGenerator *generator)
 Get the synchronous machine model used by the generator based on user-defined parameters.
 
std::vector< std::complex< double > > ComplexMatrixTimesVector (std::vector< std::vector< std::complex< double > > > matrix, std::vector< std::complex< double > > vector)
 Multiply a complex matrix by a complex vector.
 
void GetLUDecomposition (std::vector< std::vector< std::complex< double > > > matrix, std::vector< std::vector< std::complex< double > > > &matrixL, std::vector< std::vector< std::complex< double > > > &matrixU)
 Compute the LU decomposition of a matrix.
 
std::vector< std::complex< double > > LUEvaluate (std::vector< std::vector< std::complex< double > > > u, std::vector< std::vector< std::complex< double > > > l, std::vector< std::complex< double > > b)
 Solve a linear system using LU decomposition.
 
bool GetParentBus (Element *childElement, Bus *&parentBus)
 Get the parent bus of a given shunt element.
 
bool GetParentBus (Element *childElement, Bus *&parentBus1, Bus *&parentBus2)
 Get the parent buses of a two-terminal element (branch).
 
bool CalculateEMTElementsAdmittance (const double &basePower, wxString &errorMsg)
 Calculate the admittance of EMT elements.
 
bool CalculateEMTElementsPower (const double &basePower, wxString &errorMsg, bool updateCurrent=true)
 Calculate the power of EMT elements.
 
double CalculateEMTPowerError (const std::vector< std::complex< double > > &voltage, std::vector< std::complex< double > > &power, const double &basePower, wxString &errorMsg)
 Calculate the power mismatch error for EMT simulation.
 
const std::vector< PowerElement * > GetPowerElementList () const
 Get the power elements of the system (use GetElementsFromList first).
 
const std::vector< Bus * > GetBusList () const
 Get the buses of the system (use GetElementsFromList first).
 
const std::vector< Capacitor * > GetCapacitorList () const
 Get the capacitors of the system (use GetElementsFromList first).
 
const std::vector< IndMotor * > GetIndMotorList () const
 Get the induction motors of the system (use GetElementsFromList first).
 
const std::vector< Inductor * > GetInductorList () const
 Get the inductors of the system (use GetElementsFromList first).
 
const std::vector< Line * > GetLineList () const
 Get the lines of the system (use GetElementsFromList first).
 
const std::vector< Load * > GetLoadList () const
 Get the loads of the system (use GetElementsFromList first).
 
const std::vector< SyncGenerator * > GetSyncGeneratorList () const
 Get the synchronous generators of the system (use GetElementsFromList first).
 
const std::vector< SyncMotor * > GetSyncMotorList () const
 Get the synchronous motors of the system (use GetElementsFromList first).
 
const std::vector< Transformer * > GetTransformerList () const
 Get the transformers of the system (use GetElementsFromList first).
 
const std::vector< HarmCurrent * > GetHarmCurrentList () const
 Get the harmonic current source of the system (use GetElementsFromList first).
 
const std::vector< EMTElement * > GetEMTElementList () const
 Get the electromagnetic element list of the system (use GetElementsFromList first).
 

Protected Attributes

wxString m_errorMsg = ""
 
double m_systemPowerBase
 
std::vector< std::vector< std::complex< double > > > m_zBusPos
 
std::vector< std::vector< std::complex< double > > > m_zBusNeg
 
std::vector< std::vector< std::complex< double > > > m_zBusZero
 
std::vector< std::complex< double > > m_posFaultVoltagePos
 
std::vector< std::complex< double > > m_posFaultVoltageNeg
 
std::vector< std::complex< double > > m_posFaultVoltageZero
 
std::complex< double > m_fCurrentA
 
std::complex< double > m_fCurrentB
 
std::complex< double > m_fCurrentC
 
std::vector< std::complex< double > > m_posFaultVoltageA
 
std::vector< std::complex< double > > m_posFaultVoltageB
 
std::vector< std::complex< double > > m_posFaultVoltageC
 
- Protected Attributes inherited from ElectricCalculation
std::vector< PowerElement * > m_powerElementList
 List of power elements in the system.
 
std::vector< Bus * > m_busList
 List of buses in the system.
 
std::vector< Capacitor * > m_capacitorList
 List of capacitor elements in the system.
 
std::vector< IndMotor * > m_indMotorList
 List of induction motors in the system.
 
std::vector< Inductor * > m_inductorList
 List of inductors in the system.
 
std::vector< Line * > m_lineList
 List of transmission lines in the system.
 
std::vector< Load * > m_loadList
 List of load elements in the system.
 
std::vector< SyncGenerator * > m_syncGeneratorList
 List of synchronous generators in the system.
 
std::vector< SyncMotor * > m_syncMotorList
 List of synchronous motors in the system.
 
std::vector< Transformer * > m_transformerList
 List of transformers in the system.
 
std::vector< HarmCurrent * > m_harmCurrentList
 List of harmonic current sources in the system.
 
std::vector< EMTElement * > m_emtElementList
 List of electromagnetic transient (EMT) elements in the system.
 

Additional Inherited Members

- Protected Member Functions inherited from ElectricCalculation
void GetNextConnection (const unsigned int &checkBusNumber, const std::vector< std::vector< std::complex< double > > > &yBus, std::vector< bool > &connToSlack)
 Recursively check if a bus is electrically connected to the slack bus.
 
void DistributeReactivePower (std::vector< ReactiveMachine > &machines, double qTotal)
 Distribute reactive power among synchronous machines connected to the same bus.
 

Detailed Description

Calculate the fault of the system and update the elements data.

Author
Thales Lima Oliveira
Date
10/01/2017

Definition at line 30 of file Fault.h.

Constructor & Destructor Documentation

◆ Fault() [1/2]

Fault::Fault ( std::vector< Element * >  elementList)

Contructor.

Parameters
elementListList of elements in workspace

Definition at line 24 of file Fault.cpp.

24{ GetElementsFromList(elementList); }
virtual void GetElementsFromList(std::vector< Element * > elementList)
Separate the power elements from a generic list.
Here is the call graph for this function:

◆ Fault() [2/2]

Fault::Fault ( )

Default contructor. Use GetElementsFromList(std::vector<Element*> elementList).

Definition at line 23 of file Fault.cpp.

◆ ~Fault()

Fault::~Fault ( )

Destructor.

Definition at line 25 of file Fault.cpp.

25{}

Member Function Documentation

◆ GetErrorMessage()

virtual wxString Fault::GetErrorMessage ( )
inlinevirtual

Get the error message generated in RunFaultCalculation(double systemPowerBase).

Returns
Error message.

Definition at line 71 of file Fault.h.

71{ return m_errorMsg; }

◆ RunFaultCalculation()

bool Fault::RunFaultCalculation ( double  systemPowerBase)
virtual

Calculate the fault of the system. Return true if was possible the calculation.

Parameters
systemPowerBaseSystem base of power.

Definition at line 26 of file Fault.cpp.

27{
28 m_systemPowerBase = systemPowerBase;
29 int numberOfBuses = static_cast<int>(m_busList.size());
30 if (numberOfBuses == 0) {
31 m_errorMsg = _("There is no buses in the system.");
32 return false;
33 }
34
35 // Pre-fault voltages (power flow solution).
36 std::vector<std::complex<double> > preFaultVoltages;
37 preFaultVoltages.resize(m_busList.size());
38
39 // Get adimittance matrices first to setup disconnected buses.
40 std::vector<std::vector<std::complex<double> > > yBusPos;
41 GetYBus(yBusPos, systemPowerBase, POSITIVE_SEQ, true, true);
42 std::vector<std::vector<std::complex<double> > > yBusNeg;
43 GetYBus(yBusNeg, systemPowerBase, NEGATIVE_SEQ, true, true);
44 std::vector<std::vector<std::complex<double> > > yBusZero;
45 GetYBus(yBusZero, systemPowerBase, ZERO_SEQ, true, true);
46
47 // Get fault parameters.
48 int fNumber = -1;
49 int nBusFaulted = 0;
52 std::complex<double> fImpedance = std::complex<double>(0.0, 0.0);
53 for (auto it = m_busList.begin(), itEnd = m_busList.end(); it != itEnd; ++it) {
54 Bus* bus = *it;
55 BusElectricalData data = bus->GetElectricalData();
56 if (data.number >= 0)
57 preFaultVoltages[data.number] = data.voltage;
58
59 if (data.hasFault && data.isConnected) {
60 fNumber = data.number;
61 fType = data.faultType;
62 fLocation = data.faultLocation;
63 fImpedance = std::complex<double>(data.faultResistance, data.faultReactance);
64 nBusFaulted++;
65 }
66 }
67 if (fNumber == -1) {
68 m_errorMsg = _("There is no fault in the system or the faulty bus is disconnected.");
69 return false;
70 }
71 else if (nBusFaulted > 1) {
72 wxMessageDialog msgDialog(nullptr, _("There is more than one fault in the system, and this can lead to inconsistent results.\nDo you wish to proceed?"), _("Warning"), wxYES_NO | wxCENTRE | wxICON_WARNING);
73 if (msgDialog.ShowModal() == wxID_NO) {
74 m_errorMsg = _("Fault calculation was cancelled by the user.");
75 return false;
76 }
77 }
78
79
80
81 // Calculate the impedance matrices.
82 if (!InvertMatrix(yBusPos, m_zBusPos)) {
83 m_errorMsg = _("Fail to invert the positive sequence admittance matrix.");
84 return false;
85 }
86 if (!InvertMatrix(yBusNeg, m_zBusNeg)) {
87 m_errorMsg = _("Fail to invert the negative sequence admittance matrix.");
88 return false;
89 }
90 if (!InvertMatrix(yBusZero, m_zBusZero)) {
91 m_errorMsg = _("Fail to invert the zero sequence admittance matrix.");
92 return false;
93 }
94
95 // Fault calculation.
96 std::complex<double> fCurrentPos = std::complex<double>(0.0, 0.0);
97 std::complex<double> fCurrentNeg = std::complex<double>(0.0, 0.0);
98 std::complex<double> fCurrentZero = std::complex<double>(0.0, 0.0);
99
100 std::complex<double> preFaultVoltage = preFaultVoltages[fNumber];
101 std::complex<double> a = std::complex<double>(-0.5, 0.866025403784);
102 std::complex<double> a2 = std::complex<double>(-0.5, -0.866025403784);
103
104 switch (fType) {
106 fCurrentPos = preFaultVoltage / (m_zBusPos[fNumber][fNumber] + fImpedance);
107 } break;
109 fCurrentPos = preFaultVoltage / (m_zBusPos[fNumber][fNumber] + m_zBusNeg[fNumber][fNumber] + fImpedance);
110
111 switch (fLocation) {
113 fCurrentNeg = -a2 * fCurrentPos;
114 } break;
116 fCurrentNeg = -fCurrentPos;
117 } break;
119 fCurrentNeg = -a * fCurrentPos;
120 } break;
121 default:
122 break;
123 }
124 } break;
126 std::complex<double> z1 = m_zBusPos[fNumber][fNumber];
127 std::complex<double> z2 = m_zBusNeg[fNumber][fNumber];
128 std::complex<double> z0 = m_zBusZero[fNumber][fNumber];
129 std::complex<double> zf_3 = std::complex<double>(3.0, 0.0) * fImpedance;
130
131 fCurrentPos = (preFaultVoltage * (z2 + z0 + zf_3)) / (z1 * z2 + z2 * z0 + z2 * zf_3 + z1 * z0 + z1 * zf_3);
132
133 switch (fLocation) {
135 fCurrentNeg = -a2 * ((preFaultVoltage - z1 * fCurrentPos) / z2);
136 fCurrentZero = -a * ((preFaultVoltage - z1 * fCurrentPos) / (z0 + zf_3));
137 } break;
139 fCurrentNeg = -((preFaultVoltage - z1 * fCurrentPos) / z2);
140 fCurrentZero = -((preFaultVoltage - z1 * fCurrentPos) / (z0 + zf_3));
141 } break;
143 fCurrentNeg = -a * ((preFaultVoltage - z1 * fCurrentPos) / z2);
144 fCurrentZero = -a2 * ((preFaultVoltage - z1 * fCurrentPos) / (z0 + zf_3));
145 } break;
146 default:
147 break;
148 }
149 } break;
151 fCurrentPos =
152 preFaultVoltage / (m_zBusPos[fNumber][fNumber] + m_zBusNeg[fNumber][fNumber] +
153 m_zBusZero[fNumber][fNumber] + std::complex<double>(3.0, 0.0) * fImpedance);
154 switch (fLocation) {
156 fCurrentNeg = fCurrentPos;
157 fCurrentZero = fCurrentPos;
158 } break;
160 fCurrentNeg = a * fCurrentPos;
161 fCurrentZero = a2 * fCurrentPos;
162 } break;
164 fCurrentNeg = a2 * fCurrentPos;
165 fCurrentZero = a * fCurrentPos;
166 } break;
167 default:
168 break;
169 }
170 } break;
171 default:
172 break;
173 }
174
175 // Convert sequence currents to ABC. [Iabc] = [A]*[I012]
176 m_fCurrentA = fCurrentZero + fCurrentPos + fCurrentNeg;
177 m_fCurrentB = fCurrentZero + a2 * fCurrentPos + a * fCurrentNeg;
178 m_fCurrentC = fCurrentZero + a * fCurrentPos + a2 * fCurrentNeg;
179
180 // Pos-fault voltages calculation
181 m_posFaultVoltagePos.clear();
182 m_posFaultVoltageNeg.clear();
183 m_posFaultVoltageZero.clear();
184 m_posFaultVoltageA.clear();
185 m_posFaultVoltageB.clear();
186 m_posFaultVoltageC.clear();
187
188 int connectedBusIndex = 0;
189 for (int i = 0; i < numberOfBuses; ++i) {
190 if (std::abs(preFaultVoltages[i]) > 1e-6) { // Only connected buses
191 m_posFaultVoltagePos.push_back(preFaultVoltages[i] - m_zBusPos[connectedBusIndex][fNumber] * fCurrentPos);
192 m_posFaultVoltageNeg.push_back(-m_zBusNeg[connectedBusIndex][fNumber] * fCurrentNeg);
193 m_posFaultVoltageZero.push_back(-m_zBusZero[connectedBusIndex][fNumber] * fCurrentZero);
194 connectedBusIndex++;
195 }
196 else {
197 m_posFaultVoltagePos.push_back(std::complex<double>(0.0, 0.0));
198 m_posFaultVoltageNeg.push_back(std::complex<double>(0.0, 0.0));
199 m_posFaultVoltageZero.push_back(std::complex<double>(0.0, 0.0));
200 }
201
202 // V012 -> Vabc
203 m_posFaultVoltageA.push_back(m_posFaultVoltageZero[i] + m_posFaultVoltagePos[i] + m_posFaultVoltageNeg[i]);
204 m_posFaultVoltageB.push_back(m_posFaultVoltageZero[i] + a2 * m_posFaultVoltagePos[i] +
205 a * m_posFaultVoltageNeg[i]);
206 m_posFaultVoltageC.push_back(m_posFaultVoltageZero[i] + a * m_posFaultVoltagePos[i] +
207 a2 * m_posFaultVoltageNeg[i]);
208 }
209
210 UpdateElementsFault(systemPowerBase);
211 return true;
212}
@ POSITIVE_SEQ
@ NEGATIVE_SEQ
FaultData
Information about fault (type and location).
@ FAULT_LINE_GROUND
@ FAULT_2LINE_GROUND
@ FAULT_THREEPHASE
Node for power elements. All others power elements are connected through this.
Definition Bus.h:86
std::vector< Bus * > m_busList
List of buses in the system.
virtual bool GetYBus(std::vector< std::vector< std::complex< double > > > &yBus, double systemPowerBase, YBusSequence sequence=POSITIVE_SEQ, bool includeSyncMachines=false, bool allLoadsAsImpedances=false, bool usePowerFlowVoltagesOnImpedances=false)
Get the admittance matrix from the list of elements (use GetElementsFromList first).
virtual bool InvertMatrix(std::vector< std::vector< std::complex< double > > > matrix, std::vector< std::vector< std::complex< double > > > &inverse)
Invert a matrix.
virtual void UpdateElementsFault(double systemPowerBase)
Update the data of the elements.
Definition Fault.cpp:214
Here is the call graph for this function:

◆ RunSCPowerCalcutation()

bool Fault::RunSCPowerCalcutation ( double  systemPowerBase)
virtual

Calculate the short-circuit power of the system. Return true if was possible the calculation.

Parameters
systemPowerBaseSystem base of power.

Definition at line 422 of file Fault.cpp.

423{
424 // Get adimittance matrix.
425 std::vector<std::vector<std::complex<double> > > yBusPos;
426 GetYBus(yBusPos, systemPowerBase, POSITIVE_SEQ, true);
427
428 // Calculate the impedance matrix.
429 if (!InvertMatrix(yBusPos, m_zBusPos)) {
430 m_errorMsg = _("Fail to invert the positive sequence admittance matrix.");
431 return false;
432 }
433
434 // Set the SC power.
435 for (auto it = m_busList.begin(), itEnd = m_busList.end(); it != itEnd; ++it) {
436 Bus* bus = *it;
437 auto data = bus->GetElectricalData();
438 if (data.isConnected) {
439 int n = data.number;
440 data.scPower = 1.0 / std::abs(m_zBusPos[n][n]);
441 bus->SetElectricalData(data);
442 }
443 }
444
445 return true;
446}
Here is the call graph for this function:

◆ UpdateElementsFault()

void Fault::UpdateElementsFault ( double  systemPowerBase)
virtual

Update the data of the elements.

Parameters
systemPowerBaseSystem base of power.

Definition at line 214 of file Fault.cpp.

215{
216 std::complex<double> a = std::complex<double>(-0.5, 0.866025403784);
217 std::complex<double> a2 = std::complex<double>(-0.5, -0.866025403784);
218
219 for (auto it = m_busList.begin(), itEnd = m_busList.end(); it != itEnd; ++it) {
220 Bus* bus = *it;
221 auto data = bus->GetElectricalData();
222 if (data.hasFault) {
223 data.faultCurrent[0] = m_fCurrentA;
224 data.faultCurrent[1] = m_fCurrentB;
225 data.faultCurrent[2] = m_fCurrentC;
226 }
227 else {
228 data.faultCurrent[0] = data.faultCurrent[1] = data.faultCurrent[2] = std::complex<double>(0.0, 0.0);
229 }
230 data.faultVoltage[0] = data.number >= 0 ? m_posFaultVoltageA[data.number] : 0.0;
231 data.faultVoltage[1] = data.number >= 0 ? m_posFaultVoltageB[data.number] : 0.0;
232 data.faultVoltage[2] = data.number >= 0 ? m_posFaultVoltageC[data.number] : 0.0;
233 bus->SetElectricalData(data);
234 }
235
236 for (auto it = m_lineList.begin(), itEnd = m_lineList.end(); it != itEnd; ++it) {
237 Line* line = *it;
238 if (line->IsOnline()) {
239 int n1 = static_cast<Bus*>(line->GetParentList()[0])->GetElectricalData().number;
240 int n2 = static_cast<Bus*>(line->GetParentList()[1])->GetElectricalData().number;
241 auto data = line->GetElectricalData();
242 auto puData = line->GetPUElectricalData(m_systemPowerBase);
243 std::complex<double> vPos[2] = { n1 >= 0 ? m_posFaultVoltagePos[n1] : 0.0, n2 >= 0 ? m_posFaultVoltagePos[n2] : 0.0 };
244 std::complex<double> vNeg[2] = { n1 >= 0 ? m_posFaultVoltageNeg[n1] : 0.0, n2 >= 0 ? m_posFaultVoltageNeg[n2] : 0.0 };
245 std::complex<double> vZero[2] = { n1 >= 0 ? m_posFaultVoltageZero[n1] : 0.0, n2 >= 0 ? m_posFaultVoltageZero[n2] : 0.0 };
246 std::complex<double> zPos(puData.resistance, puData.indReactance);
247 std::complex<double> bPos(0.0, puData.capSusceptance / 2.0);
248 std::complex<double> zZero(puData.zeroResistance, puData.zeroIndReactance);
249 std::complex<double> bZero(0.0, puData.zeroCapSusceptance / 2.0);
250
251 std::complex<double> lineCurrentPos[2];
252 std::complex<double> lineCurrentNeg[2];
253 std::complex<double> lineCurrentZero[2];
254
255 lineCurrentPos[0] = ((vPos[0] - vPos[1]) / zPos) + (vPos[0] * bPos);
256 lineCurrentNeg[0] = ((vNeg[0] - vNeg[1]) / zPos) + (vNeg[0] * bPos);
257 lineCurrentZero[0] = ((vZero[0] - vZero[1]) / zZero) + (vZero[0] * bZero);
258 lineCurrentPos[1] = ((vPos[1] - vPos[0]) / zPos) + (vPos[1] * bPos);
259 lineCurrentNeg[1] = ((vNeg[1] - vNeg[0]) / zPos) + (vNeg[1] * bPos);
260 lineCurrentZero[1] = ((vZero[1] - vZero[0]) / zZero) + (vZero[1] * bZero);
261
262 data.faultCurrent[0][0] = lineCurrentZero[0] + lineCurrentPos[0] + lineCurrentNeg[0];
263 data.faultCurrent[0][1] = lineCurrentZero[0] + a2 * lineCurrentPos[0] + a * lineCurrentNeg[0];
264 data.faultCurrent[0][2] = lineCurrentZero[0] + a * lineCurrentPos[0] + a2 * lineCurrentNeg[0];
265 data.faultCurrent[1][0] = lineCurrentZero[1] + lineCurrentPos[1] + lineCurrentNeg[1];
266 data.faultCurrent[1][1] = lineCurrentZero[1] + a2 * lineCurrentPos[1] + a * lineCurrentNeg[1];
267 data.faultCurrent[1][2] = lineCurrentZero[1] + a * lineCurrentPos[1] + a2 * lineCurrentNeg[1];
268
269 line->SetElectricalData(data);
270 }
271 }
272
273 for (auto it = m_transformerList.begin(), itEnd = m_transformerList.end(); it != itEnd; ++it) {
274 Transformer* transformer = *it;
275 if (transformer->IsOnline()) {
276 int n1 = static_cast<Bus*>(transformer->GetParentList()[0])->GetElectricalData().number;
277 int n2 = static_cast<Bus*>(transformer->GetParentList()[1])->GetElectricalData().number;
278 auto data = transformer->GetElectricalData();
279 auto puData = transformer->GetPUElectricalData(m_systemPowerBase);
280
281 std::complex<double> vPos[2] = { n1 >= 0 ? m_posFaultVoltagePos[n1] : 0.0, n2 >= 0 ? m_posFaultVoltagePos[n2] : 0.0 };
282 std::complex<double> vNeg[2] = { n1 >= 0 ? m_posFaultVoltageNeg[n1] : 0.0, n2 >= 0 ? m_posFaultVoltageNeg[n2] : 0.0 };
283 std::complex<double> vZero[2] = { n1 >= 0 ? m_posFaultVoltageZero[n1] : 0.0, n2 >= 0 ? m_posFaultVoltageZero[n2] : 0.0 };
284 std::complex<double> zPos(puData.resistance, puData.indReactance);
285 std::complex<double> zZero(puData.zeroResistance, puData.zeroIndReactance);
286
287 std::complex<double> transformerCurrentPos[2];
288 std::complex<double> transformerCurrentNeg[2];
289 std::complex<double> transformerCurrentZero[2];
290
291 if (data.turnsRatio == 1.0 && data.phaseShift == 0.0) {
292 transformerCurrentPos[0] = (vPos[0] - vPos[1]) / zPos;
293 transformerCurrentNeg[0] = (vNeg[0] - vNeg[1]) / zPos;
294 transformerCurrentZero[0] = (vZero[0] - vZero[1]) / zZero;
295 transformerCurrentPos[1] = (vPos[1] - vPos[0]) / zPos;
296 transformerCurrentNeg[1] = (vNeg[1] - vNeg[0]) / zPos;
297 transformerCurrentZero[1] = (vZero[1] - vZero[0]) / zZero;
298 }
299 else {
300 double radPhaseShift = wxDegToRad(data.phaseShift);
301 std::complex<double> t = std::complex<double>(data.turnsRatio * std::cos(radPhaseShift),
302 -data.turnsRatio * std::sin(radPhaseShift));
303
304 transformerCurrentPos[0] =
305 vPos[0] * (1.0 / (std::pow(std::abs(t), 2.0) * zPos)) - vPos[1] * (1.0 / (std::conj(t) * zPos));
306 transformerCurrentNeg[0] =
307 vNeg[0] * (1.0 / (std::pow(std::abs(t), 2.0) * zPos)) - vNeg[1] * (1.0 / (t * zPos));
308
309 transformerCurrentPos[1] = -vPos[0] * (1.0 / (t * zPos)) + vPos[1] / zPos;
310 transformerCurrentNeg[1] = -vNeg[0] * (1.0 / (std::conj(t) * zPos)) + vNeg[1] / zPos;
311 }
312
313 switch (data.connection) {
314 case GWYE_GWYE: {
315 transformerCurrentZero[0] = (vZero[0] - vZero[1]) / zZero;
316 transformerCurrentZero[1] = (vZero[1] - vZero[0]) / zZero;
317 break;
318 }
319 case GWYE_DELTA: {
320 transformerCurrentZero[0] = vZero[0] / zZero;
321 transformerCurrentZero[1] = std::complex<double>(0.0, 0.0);
322 break;
323 }
324 case DELTA_GWYE: {
325 transformerCurrentZero[0] = std::complex<double>(0.0, 0.0);
326 transformerCurrentZero[1] = vZero[1] / zZero;
327 break;
328 }
329 default: {
330 transformerCurrentZero[0] = std::complex<double>(0.0, 0.0);
331 transformerCurrentZero[1] = std::complex<double>(0.0, 0.0);
332 break;
333 }
334 }
335
336 data.faultCurrent[0][0] = transformerCurrentZero[0] + transformerCurrentPos[0] + transformerCurrentNeg[0];
337 data.faultCurrent[0][1] =
338 transformerCurrentZero[0] + a2 * transformerCurrentPos[0] + a * transformerCurrentNeg[0];
339 data.faultCurrent[0][2] =
340 transformerCurrentZero[0] + a * transformerCurrentPos[0] + a2 * transformerCurrentNeg[0];
341 data.faultCurrent[1][0] = transformerCurrentZero[1] + transformerCurrentPos[1] + transformerCurrentNeg[1];
342 data.faultCurrent[1][1] =
343 transformerCurrentZero[1] + a2 * transformerCurrentPos[1] + a * transformerCurrentNeg[1];
344 data.faultCurrent[1][2] =
345 transformerCurrentZero[1] + a * transformerCurrentPos[1] + a2 * transformerCurrentNeg[1];
346
347 transformer->SetElectricaData(data);
348 }
349 }
350
351 for (auto it = m_syncGeneratorList.begin(), itEnd = m_syncGeneratorList.end(); it != itEnd; ++it) {
352 SyncGenerator* syncGenerator = *it;
353 if (syncGenerator->IsOnline()) {
354 Bus* bus = static_cast<Bus*>(syncGenerator->GetParentList()[0]);
355 int n = bus->GetElectricalData().number;
356 std::complex<double> v = bus->GetElectricalData().voltage; // Pre-fault voltage.
357 auto data = syncGenerator->GetElectricalData();
358 auto puData = syncGenerator->GetPUElectricalData(m_systemPowerBase);
359
360 std::complex<double> vPos = n >= 0 ? m_posFaultVoltagePos[n] : 0.0;
361 std::complex<double> vNeg = n >= 0 ? m_posFaultVoltageNeg[n] : 0.0;
362 std::complex<double> vZero = n >= 0 ? m_posFaultVoltageZero[n] : 0.0;
363
364 std::complex<double> zPos(puData.positiveResistance, puData.positiveReactance);
365 std::complex<double> zNeg(puData.negativeResistance, puData.negativeReactance);
366 std::complex<double> zZero(puData.zeroResistance + 3.0 * puData.groundResistance,
367 puData.zeroReactance + 3.0 * puData.groundReactance);
368
369 // Internal voltage
370 std::complex<double> i = std::complex<double>(puData.activePower, -puData.reactivePower) / std::conj(v);
371 std::complex<double> e = v + zPos * i;
372
373 std::complex<double> syncGeneratorCurrentPos = n >= 0 ? (e - vPos) / zPos : 0.0;
374 std::complex<double> syncGeneratorCurrentNeg = n >= 0 ? (-vNeg) / zNeg : 0.0;
375 std::complex<double> syncGeneratorCurrentZero(0.0, 0.0);
376 if (data.groundNeutral) syncGeneratorCurrentZero = n >= 0 ? (-vZero) / zZero : 0.0;
377
378 data.faultCurrent[0] = syncGeneratorCurrentZero + syncGeneratorCurrentPos + syncGeneratorCurrentNeg;
379 data.faultCurrent[1] =
380 syncGeneratorCurrentZero + a2 * syncGeneratorCurrentPos + a * syncGeneratorCurrentNeg;
381 data.faultCurrent[2] =
382 syncGeneratorCurrentZero + a * syncGeneratorCurrentPos + a2 * syncGeneratorCurrentNeg;
383
384 syncGenerator->SetElectricalData(data);
385 }
386 }
387
388 for (auto it = m_syncMotorList.begin(), itEnd = m_syncMotorList.end(); it != itEnd; ++it) {
389 SyncMotor* syncMotor = *it;
390 if (syncMotor->IsOnline()) {
391 Bus* bus = static_cast<Bus*>(syncMotor->GetParentList()[0]);
392 int n = bus->GetElectricalData().number;
393 std::complex<double> v = bus->GetElectricalData().voltage; // Pre-fault voltage.
394 auto data = syncMotor->GetElectricalData();
395 auto puData = syncMotor->GetPUElectricalData(m_systemPowerBase);
396
397 std::complex<double> vPos = n >= 0 ? m_posFaultVoltagePos[n] : 0.0;
398 std::complex<double> vNeg = n >= 0 ? m_posFaultVoltageNeg[n] : 0.0;
399 std::complex<double> vZero = n >= 0 ? m_posFaultVoltageZero[n] : 0.0;
400
401 std::complex<double> zPos(puData.positiveResistance, puData.positiveReactance);
402 std::complex<double> zNeg(puData.negativeResistance, puData.negativeReactance);
403 std::complex<double> zZero(puData.zeroResistance + 3.0 * puData.groundResistance,
404 puData.zeroReactance + 3.0 * puData.groundReactance);
405
406 std::complex<double> syncMotorCurrentPos = n >= 0 ? (v - vPos) / zPos : 0.0;
407 std::complex<double> syncMotorCurrentNeg = n >= 0 ? (-vNeg) / zNeg : 0.0;
408 std::complex<double> syncMotorCurrentZero(0.0, 0.0);
409 if (data.groundNeutral) syncMotorCurrentZero = n >= 0 ? (-vZero) / zZero : 0.0;
410
411 data.faultCurrent[0] = syncMotorCurrentZero + syncMotorCurrentPos + syncMotorCurrentNeg;
412 data.faultCurrent[1] =
413 syncMotorCurrentZero + a2 * syncMotorCurrentPos + a * syncMotorCurrentNeg;
414 data.faultCurrent[2] =
415 syncMotorCurrentZero + a * syncMotorCurrentPos + a2 * syncMotorCurrentNeg;
416
417 syncMotor->SetElectricalData(data);
418 }
419 }
420}
std::vector< Line * > m_lineList
List of transmission lines in the system.
std::vector< Transformer * > m_transformerList
List of transformers in the system.
std::vector< SyncGenerator * > m_syncGeneratorList
List of synchronous generators in the system.
std::vector< SyncMotor * > m_syncMotorList
List of synchronous motors in the system.
virtual std::vector< Element * > GetParentList() const
Get the parent list.
Definition Element.h:559
bool IsOnline() const
Checks if the element is online or offline.
Definition Element.h:226
Power line element.
Definition Line.h:64
Synchronous generator power element.
Synchronous motor (synchronous compensator) power element.
Definition SyncMotor.h:135
Two-winding transformer power element.
Definition Transformer.h:84
Here is the call graph for this function:
Here is the caller graph for this function:

Member Data Documentation

◆ m_errorMsg

wxString Fault::m_errorMsg = ""
protected

Definition at line 73 of file Fault.h.

◆ m_fCurrentA

std::complex<double> Fault::m_fCurrentA
protected

Definition at line 85 of file Fault.h.

◆ m_fCurrentB

std::complex<double> Fault::m_fCurrentB
protected

Definition at line 86 of file Fault.h.

◆ m_fCurrentC

std::complex<double> Fault::m_fCurrentC
protected

Definition at line 87 of file Fault.h.

◆ m_posFaultVoltageA

std::vector<std::complex<double> > Fault::m_posFaultVoltageA
protected

Definition at line 89 of file Fault.h.

◆ m_posFaultVoltageB

std::vector<std::complex<double> > Fault::m_posFaultVoltageB
protected

Definition at line 90 of file Fault.h.

◆ m_posFaultVoltageC

std::vector<std::complex<double> > Fault::m_posFaultVoltageC
protected

Definition at line 91 of file Fault.h.

◆ m_posFaultVoltageNeg

std::vector<std::complex<double> > Fault::m_posFaultVoltageNeg
protected

Definition at line 82 of file Fault.h.

◆ m_posFaultVoltagePos

std::vector<std::complex<double> > Fault::m_posFaultVoltagePos
protected

Definition at line 81 of file Fault.h.

◆ m_posFaultVoltageZero

std::vector<std::complex<double> > Fault::m_posFaultVoltageZero
protected

Definition at line 83 of file Fault.h.

◆ m_systemPowerBase

double Fault::m_systemPowerBase
protected

Definition at line 75 of file Fault.h.

◆ m_zBusNeg

std::vector<std::vector<std::complex<double> > > Fault::m_zBusNeg
protected

Definition at line 78 of file Fault.h.

◆ m_zBusPos

std::vector<std::vector<std::complex<double> > > Fault::m_zBusPos
protected

Definition at line 77 of file Fault.h.

◆ m_zBusZero

std::vector<std::vector<std::complex<double> > > Fault::m_zBusZero
protected

Definition at line 79 of file Fault.h.


The documentation for this class was generated from the following files: