summaryrefslogtreecommitdiffstats
path: root/Project/Electromechanical.cpp
diff options
context:
space:
mode:
authorThales Lima Oliveira <thaleslima.ufu@gmail.com>2017-05-24 17:50:36 -0300
committerThales Lima Oliveira <thaleslima.ufu@gmail.com>2017-05-24 17:50:36 -0300
commitc91e58bb903adeff1e8c0fff1868e80783010e58 (patch)
treed9eaa3ff5b186cddb8bd658a8386e58591fd8174 /Project/Electromechanical.cpp
parent2c60c7c13ecc8e45e072346193a820f697fb6fdf (diff)
downloadPSP.git-c91e58bb903adeff1e8c0fff1868e80783010e58.tar.gz
PSP.git-c91e58bb903adeff1e8c0fff1868e80783010e58.tar.xz
PSP.git-c91e58bb903adeff1e8c0fff1868e80783010e58.zip
Dynamic elements initialization implemented
Diffstat (limited to 'Project/Electromechanical.cpp')
-rw-r--r--Project/Electromechanical.cpp164
1 files changed, 142 insertions, 22 deletions
diff --git a/Project/Electromechanical.cpp b/Project/Electromechanical.cpp
index 895a6f3..d2d9ae9 100644
--- a/Project/Electromechanical.cpp
+++ b/Project/Electromechanical.cpp
@@ -1,12 +1,37 @@
#include "Electromechanical.h"
+#include "ControlElementSolver.h"
-Electromechanical::Electromechanical(std::vector<Element*> elementList)
+Electromechanical::Electromechanical(wxWindow* parent, std::vector<Element*> elementList)
{
+ m_parent = parent;
GetElementsFromList(elementList);
SetEventTimeList();
}
Electromechanical::~Electromechanical() {}
+bool Electromechanical::RunStabilityCalculation()
+{
+ // Calculate the admittance matrix with the synchronous machines.
+ if(!GetYBus(m_yBus, m_powerSystemBase, POSITIVE_SEQ, false, true)) {
+ m_errorMsg = _("It was not possible to build the admittance matrix.");
+ return false;
+ }
+ InsertSyncMachinesOnYBus();
+
+ if(!InitializeDynamicElements()) return false;
+
+ // test
+ double simTime = 10.0;
+ double currentTime = 0.0;
+ while(currentTime <= simTime) {
+ if(HasEvent(currentTime)) {
+ SetEvent(currentTime);
+ }
+ currentTime += m_timeStep;
+ }
+ return true;
+}
+
void Electromechanical::SetEventTimeList()
{
// Fault
@@ -297,27 +322,6 @@ void Electromechanical::SetEvent(double currentTime)
}
}
-bool Electromechanical::RunStabilityCalculation()
-{
- // Calculate the admittance matrix with the synchronous machines.
- if(!GetYBus(m_yBus, m_powerSystemBase, POSITIVE_SEQ, false, true)) {
- m_errorMsg = _("It was not possible to build the admittance matrix.");
- return false;
- }
- InsertSyncMachinesOnYBus();
-
- // test
- double simTime = 10.0;
- double currentTime = 0.0;
- while(currentTime <= simTime) {
- if(HasEvent(currentTime)) {
- SetEvent(currentTime);
- }
- currentTime += m_timeStep;
- }
- return true;
-}
-
void Electromechanical::InsertSyncMachinesOnYBus()
{
for(auto it = m_syncGeneratorList.begin(), itEnd = m_syncGeneratorList.end(); it != itEnd; ++it) {
@@ -366,3 +370,119 @@ std::complex<double> Electromechanical::GetSyncMachineAdmittance(SyncGenerator*
double xdq = 0.5 * (xd + xq);
return std::complex<double>(ra, -xdq) / std::complex<double>(ra * ra + xd * xq, 0.0);
}
+
+bool Electromechanical::InitializeDynamicElements()
+{
+ // Synchronous generators
+ for(auto it = m_syncGeneratorList.begin(), itEnd = m_syncGeneratorList.end(); it != itEnd; ++it) {
+ SyncGenerator* syncGenerator = *it;
+ if(syncGenerator->IsOnline()) {
+ auto data = syncGenerator->GetPUElectricalData(m_powerSystemBase);
+ double k = 1.0; // Power base change factor.
+ if(data.useMachineBase) {
+ double oldBase = data.nominalPower * std::pow(1000.0f, data.nominalPowerUnit);
+ k = m_powerSystemBase / oldBase;
+ }
+ data.terminalVoltage = static_cast<Bus*>(syncGenerator->GetParentList()[0])->GetElectricalData().voltage;
+
+ std::complex<double> conjS(data.activePower, -data.reactivePower);
+ std::complex<double> conjV = std::conj(data.terminalVoltage);
+ std::complex<double> ia = conjS / conjV;
+
+ double xd = data.syncXd * k;
+ double xq = data.syncXq * k;
+ double ra = data.armResistance * k;
+
+ // Initialize state variables
+ std::complex<double> eq0 = data.terminalVoltage + std::complex<double>(ra, xq) * ia;
+ data.delta = std::arg(eq0);
+
+ double teta0 = std::arg(data.terminalVoltage);
+ double vd0, vq0;
+ ABCtoDQ0(data.terminalVoltage, data.delta - teta0, vd0, vq0);
+
+ double fi0 = std::arg(ia);
+ double id0, iq0;
+ ABCtoDQ0(ia, data.delta - fi0, id0, iq0);
+
+ data.initialFieldVoltage = std::abs(eq0) - (xd - xq) * id0;
+ data.pm = std::real((data.terminalVoltage * std::conj(ia)) + (std::abs(ia) * std::abs(ia) * ra));
+ data.speed = 2.0 * M_PI * 60.0;
+
+ switch(GetMachineModel(syncGenerator)) {
+ case SM_MODEL_1: {
+ data.tranEq = 0.0;
+ data.tranEd = 0.0;
+ data.subEq = 0.0;
+ data.subEd = 0.0;
+ } break;
+ case SM_MODEL_2: {
+ double tranXd = data.transXd * k;
+
+ data.tranEq = data.initialFieldVoltage + (xd - tranXd) * id0;
+ data.tranEd = 0.0;
+ data.subEd = 0.0;
+ data.subEq = 0.0;
+ } break;
+ case SM_MODEL_3: {
+ double tranXd = data.transXd * k;
+ double tranXq = data.transXq * k;
+
+ data.tranEq = data.initialFieldVoltage + (xd - tranXd) * id0;
+ data.tranEd = -(xq - tranXq) * iq0;
+ data.subEd = 0.0;
+ data.subEq = 0.0;
+ } break;
+ case SM_MODEL_4: {
+ double tranXd = data.transXd * k;
+ double subXd = data.subXd * k;
+ double subXq = data.subXq * k;
+
+ data.tranEq = data.initialFieldVoltage + (xd - tranXd) * id0;
+ data.tranEd = 0.0;
+ data.subEq = data.tranEq + (tranXd - subXd) * id0;
+ data.subEd = -(xq - subXq) * iq0;
+ } break;
+ case SM_MODEL_5: {
+ double tranXd = data.transXd * k;
+ double tranXq = data.transXq * k;
+ double subXd = data.subXd * k;
+ double subXq = data.subXq * k;
+
+ data.tranEq = data.initialFieldVoltage + (xd - tranXd) * id0;
+ data.tranEd = -(xq - tranXq) * iq0;
+ data.subEq = data.tranEq + (tranXd - subXd) * id0;
+ data.subEd = data.tranEd + (tranXq - subXq) * iq0;
+ } break;
+ default: {
+ break;
+ }
+ }
+
+ // Initialize controllers
+ if(data.useAVR) {
+ if(data.avrSolver) delete data.avrSolver;
+ data.avrSolver = new ControlElementSolver(data.avr, m_timeStep, 1e-3, false,
+ std::abs(data.terminalVoltage), m_parent);
+ if(!data.avrSolver->IsOK()) {
+ m_errorMsg = _("Error on initializate the AVR of \"") + data.name + _("\".");
+ syncGenerator->SetElectricalData(data);
+ return false;
+ }
+ }
+ if(data.useSpeedGovernor) {
+ if(data.speedGovSolver) delete data.speedGovSolver;
+ data.speedGovSolver =
+ new ControlElementSolver(data.speedGov, m_timeStep, 1e-3, false, data.speed, m_parent);
+ if(!data.speedGovSolver->IsOK()) {
+ m_errorMsg = _("Error on initializate the speed governor of \"") + data.name + _("\".");
+ syncGenerator->SetElectricalData(data);
+ return false;
+ }
+ }
+
+ syncGenerator->SetElectricalData(data);
+ }
+ }
+ return true;
+}