diff options
author | Thales1330 <thaleslima.ufu@gmail.com> | 2016-11-07 17:23:07 -0200 |
---|---|---|
committer | Thales1330 <thaleslima.ufu@gmail.com> | 2016-11-07 17:23:07 -0200 |
commit | b6d4815859b494cc6e5e1f1718a3b410fdd6037a (patch) | |
tree | b66acbfab636dd4606d8b893c489d76b34977749 /Project | |
parent | 9919f24692c1fe9b8e11fde5c6d5c18f169b5c10 (diff) | |
download | PSP.git-b6d4815859b494cc6e5e1f1718a3b410fdd6037a.tar.gz PSP.git-b6d4815859b494cc6e5e1f1718a3b410fdd6037a.tar.xz PSP.git-b6d4815859b494cc6e5e1f1718a3b410fdd6037a.zip |
Reactive limits under implementation
Diffstat (limited to 'Project')
-rw-r--r-- | Project/ElectricCalculation.cpp | 133 | ||||
-rw-r--r-- | Project/ElectricCalculation.h | 8 | ||||
-rw-r--r-- | Project/PowerFlow.cpp | 91 | ||||
-rw-r--r-- | Project/PowerFlow.h | 13 | ||||
-rw-r--r-- | Project/Project.mk | 2 | ||||
-rw-r--r-- | Project/Release/ElectricCalculation.cpp.o | bin | 65799 -> 66771 bytes | |||
-rw-r--r-- | Project/Release/PSP-UFU.exe | bin | 4075084 -> 4076970 bytes | |||
-rw-r--r-- | Project/Release/PowerFlow.cpp.o | bin | 39066 -> 41283 bytes |
8 files changed, 157 insertions, 90 deletions
diff --git a/Project/ElectricCalculation.cpp b/Project/ElectricCalculation.cpp index 3cda1af..a68cc19 100644 --- a/Project/ElectricCalculation.cpp +++ b/Project/ElectricCalculation.cpp @@ -156,10 +156,10 @@ bool ElectricCalculation::GetYBus(std::vector<std::vector<std::complex<double> > return true; } -void ElectricCalculation::ValidateElementsPowerFlow(std::vector<std::complex<double> > voltage, - std::vector<std::complex<double> > power, - std::vector<BusType> busType, - double systemPowerBase) +void ElectricCalculation::UpdateElementsPowerFlow(std::vector<std::complex<double> > voltage, + std::vector<std::complex<double> > power, + std::vector<BusType> busType, + double systemPowerBase) { // Buses voltages for(int i = 0; i < (int)m_busList.size(); i++) { @@ -262,6 +262,11 @@ void ElectricCalculation::ValidateElementsPowerFlow(std::vector<std::complex<dou LoadElectricalData childData = load->GetPUElectricalData(systemPowerBase); if(childData.loadType == CONST_POWER) loadPower += std::complex<double>(childData.activePower, childData.reactivePower); + + if(childData.activePower >= 0.0) + load->SetPowerFlowDirection(PF_TO_ELEMENT); + else + load->SetPowerFlowDirection(PF_TO_BUS); } } for(auto itim = m_indMotorList.begin(); itim != m_indMotorList.end(); itim++) { @@ -269,72 +274,75 @@ void ElectricCalculation::ValidateElementsPowerFlow(std::vector<std::complex<dou if(bus == indMotor->GetParentList()[0] && indMotor->IsOnline()) { IndMotorElectricalData childData = indMotor->GetPUElectricalData(systemPowerBase); loadPower += std::complex<double>(childData.activePower, childData.reactivePower); + + if(childData.activePower >= 0.0) + indMotor->SetPowerFlowDirection(PF_TO_ELEMENT); + else + indMotor->SetPowerFlowDirection(PF_TO_BUS); } } // Set the sync generator power - if(busType[i] == BUS_SLACK || busType[i] == BUS_PV) { - for(auto itsg = syncGeneratorsOnBus.begin(); itsg != syncGeneratorsOnBus.end(); itsg++) { - SyncGenerator* generator = *itsg; - if(generator->IsOnline()) { - SyncGeneratorElectricalData childData = generator->GetElectricalData(); - - if(busType[i] == BUS_SLACK) { - double activePower = (power[i].real() + loadPower.real()) * systemPowerBase / - (double)(syncGeneratorsOnBus.size()); - - switch(childData.activePowerUnit) { - case UNIT_PU: { - activePower /= systemPowerBase; - } break; - case UNIT_kW: { - activePower /= 1e3; - } break; - case UNIT_MW: { - activePower /= 1e6; - } break; - default: - break; - } - - if(activePower >= 0.0) - generator->SetPowerFlowDirection(PF_TO_BUS); - else - generator->SetPowerFlowDirection(PF_TO_ELEMENT); - - childData.activePower = activePower; - } - if(busType[i] == BUS_PV || busType[i] == BUS_SLACK) { - double reactivePower = (power[i].imag() + loadPower.imag()) * systemPowerBase / - (double)(syncGeneratorsOnBus.size() + syncMotorsOnBus.size()); - switch(childData.reactivePowerUnit) { - case UNIT_PU: { - reactivePower /= systemPowerBase; - } break; - case UNIT_kVAr: { - reactivePower /= 1e3; - } break; - case UNIT_MVAr: { - reactivePower /= 1e6; - } break; - default: - break; - } - childData.reactivePower = reactivePower; + for(auto itsg = syncGeneratorsOnBus.begin(); itsg != syncGeneratorsOnBus.end(); itsg++) { + SyncGenerator* generator = *itsg; + if(generator->IsOnline()) { + SyncGeneratorElectricalData childData = generator->GetElectricalData(); + + if(busType[i] == BUS_SLACK) { + double activePower = + (power[i].real() + loadPower.real()) * systemPowerBase / (double)(syncGeneratorsOnBus.size()); + + switch(childData.activePowerUnit) { + case UNIT_PU: { + activePower /= systemPowerBase; + } break; + case UNIT_kW: { + activePower /= 1e3; + } break; + case UNIT_MW: { + activePower /= 1e6; + } break; + default: + break; } - generator->SetElectricalData(childData); + childData.activePower = activePower; } + if(busType[i] == BUS_PV || busType[i] == BUS_SLACK) { + double reactivePower = (power[i].imag() + loadPower.imag()) * systemPowerBase / + (double)(syncGeneratorsOnBus.size() + syncMotorsOnBus.size()); + switch(childData.reactivePowerUnit) { + case UNIT_PU: { + reactivePower /= systemPowerBase; + } break; + case UNIT_kVAr: { + reactivePower /= 1e3; + } break; + case UNIT_MVAr: { + reactivePower /= 1e6; + } break; + default: + break; + } + childData.reactivePower = reactivePower; + } + + if(childData.activePower >= 0.0) + generator->SetPowerFlowDirection(PF_TO_BUS); + else + generator->SetPowerFlowDirection(PF_TO_ELEMENT); + + generator->SetElectricalData(childData); } } // Set the sync motor reactive power - if(busType[i] == BUS_PV) { - for(auto itmg = syncMotorsOnBus.begin(); itmg != syncMotorsOnBus.end(); itmg++) { - SyncMotor* syncMotor = *itmg; - if(syncMotor->IsOnline()) { - SyncMotorElectricalData childData = syncMotor->GetElectricalData(); + for(auto itmg = syncMotorsOnBus.begin(); itmg != syncMotorsOnBus.end(); itmg++) { + SyncMotor* syncMotor = *itmg; + if(syncMotor->IsOnline()) { + SyncMotorElectricalData childData = syncMotor->GetElectricalData(); + if(busType[i] == BUS_PV || busType[i] == BUS_SLACK) { double reactivePower = (power[i].imag() + loadPower.imag()) * systemPowerBase / (double)(syncGeneratorsOnBus.size() + syncMotorsOnBus.size()); switch(childData.reactivePowerUnit) { @@ -351,9 +359,14 @@ void ElectricCalculation::ValidateElementsPowerFlow(std::vector<std::complex<dou break; } childData.reactivePower = reactivePower; - - syncMotor->SetElectricalData(childData); } + + if(childData.activePower > 0.0) + syncMotor->SetPowerFlowDirection(PF_TO_ELEMENT); + else + syncMotor->SetPowerFlowDirection(PF_TO_BUS); + + syncMotor->SetElectricalData(childData); } } } diff --git a/Project/ElectricCalculation.h b/Project/ElectricCalculation.h index 02a45e0..ac573cd 100644 --- a/Project/ElectricCalculation.h +++ b/Project/ElectricCalculation.h @@ -24,10 +24,10 @@ class ElectricCalculation ~ElectricCalculation(); virtual void GetElementsFromList(std::vector<Element*> elementList); virtual bool GetYBus(std::vector<std::vector<std::complex<double> > >& yBus, double systemPowerBase); - virtual void ValidateElementsPowerFlow(std::vector<std::complex<double> > voltage, - std::vector<std::complex<double> > power, - std::vector<BusType> busType, - double systemPowerBase); + virtual void UpdateElementsPowerFlow(std::vector<std::complex<double> > voltage, + std::vector<std::complex<double> > power, + std::vector<BusType> busType, + double systemPowerBase); protected: std::vector<Bus*> m_busList; diff --git a/Project/PowerFlow.cpp b/Project/PowerFlow.cpp index ff79722..8d8850f 100644 --- a/Project/PowerFlow.cpp +++ b/Project/PowerFlow.cpp @@ -20,6 +20,9 @@ bool PowerFlow::RunGaussSeidel(double systemPowerBase, std::vector<BusType> busType; // Bus type std::vector<std::complex<double> > voltage; // Voltage of buses std::vector<std::complex<double> > power; // Injected power + std::vector<ReactiveLimits> reactiveLimit; // Limit of reactive power on PV buses + + reactiveLimit.resize(numberOfBuses); int busNumber = 0; for(auto itb = m_busList.begin(); itb != m_busList.end(); itb++) { @@ -66,6 +69,20 @@ bool PowerFlow::RunGaussSeidel(double systemPowerBase, if(bus == syncGenerator->GetParentList()[0]) { SyncGeneratorElectricalData childData = syncGenerator->GetPUElectricalData(systemPowerBase); power[busNumber] += std::complex<double>(childData.activePower, childData.reactivePower); + + if(busType[busNumber] == BUS_PV) { + if(childData.haveMaxReactive && reactiveLimit[busNumber].maxLimitType != RL_UNLIMITED_SOURCE) { + reactiveLimit[busNumber].maxLimitType = RL_LIMITED; + reactiveLimit[busNumber].maxLimit += childData.maxReactive; + } else if(!childData.haveMaxReactive) + reactiveLimit[busNumber].maxLimitType = RL_UNLIMITED_SOURCE; + + if(childData.haveMinReactive && reactiveLimit[busNumber].minLimitType != RL_UNLIMITED_SOURCE) { + reactiveLimit[busNumber].minLimitType = RL_LIMITED; + reactiveLimit[busNumber].minLimit += childData.minReactive; + } else if(!childData.haveMinReactive) + reactiveLimit[busNumber].minLimitType = RL_UNLIMITED_SOURCE; + } } } } @@ -76,6 +93,20 @@ bool PowerFlow::RunGaussSeidel(double systemPowerBase, if(bus == syncMotor->GetParentList()[0]) { SyncMotorElectricalData childData = syncMotor->GetPUElectricalData(systemPowerBase); power[busNumber] += std::complex<double>(-childData.activePower, childData.reactivePower); + + if(busType[busNumber] == BUS_PV) { + if(childData.haveMaxReactive && reactiveLimit[busNumber].maxLimitType != RL_UNLIMITED_SOURCE) { + reactiveLimit[busNumber].maxLimitType = RL_LIMITED; + reactiveLimit[busNumber].maxLimit += childData.maxReactive; + } else if(!childData.haveMaxReactive) + reactiveLimit[busNumber].maxLimitType = RL_UNLIMITED_SOURCE; + + if(childData.haveMinReactive && reactiveLimit[busNumber].minLimitType != RL_UNLIMITED_SOURCE) { + reactiveLimit[busNumber].minLimitType = RL_LIMITED; + reactiveLimit[busNumber].minLimit += childData.minReactive; + } else if(!childData.haveMinReactive) + reactiveLimit[busNumber].minLimitType = RL_UNLIMITED_SOURCE; + } } } } @@ -120,22 +151,24 @@ bool PowerFlow::RunGaussSeidel(double systemPowerBase, } haveSlackBus = true; } - if(!haveSlackBus) { - m_errorMsg = _("There is no slack bus on the system."); - return false; - } - if(!slackBusHaveGeneration) { - m_errorMsg = _("The slack bus don't have generation."); - return false; - } + } + if(!haveSlackBus) { + m_errorMsg = _("There is no slack bus on the system."); + return false; + } + if(!slackBusHaveGeneration) { + m_errorMsg = _("The slack bus don't have generation."); + return false; } // Gauss-Seidel method std::vector<std::complex<double> > oldVoltage; // Old voltage array. oldVoltage.resize(voltage.size()); + + auto oldBusType = busType; int iteration = 0; // Current itaration number. - + while(true) { // Reach the max number of iterations. if(iteration >= maxIteration) { @@ -201,7 +234,28 @@ bool PowerFlow::RunGaussSeidel(double systemPowerBase, if(busError > iterationError) iterationError = busError; } - if(iterationError < error) break; + if(iterationError < error) { + bool limitReach = false; + for(int i = 0; i < numberOfBuses; i++) { + if(busType[i] == BUS_PV) { + if(reactiveLimit[i].maxLimitType == RL_LIMITED) { + if(power[i].imag() > reactiveLimit[i].maxLimit) { + power[i] = std::complex<double>(power[i].real(), reactiveLimit[i].maxLimit); + busType[i] = BUS_PQ; + limitReach = true; + } + } + if(reactiveLimit[i].minLimitType == RL_LIMITED) { + if(power[i].imag() < reactiveLimit[i].minLimit) { + power[i] = std::complex<double>(power[i].real(), reactiveLimit[i].minLimit); + busType[i] = BUS_PQ; + limitReach = true; + } + } + } + } + if(!limitReach) break; + } iteration++; } @@ -214,22 +268,9 @@ bool PowerFlow::RunGaussSeidel(double systemPowerBase, power[i] = sBus; } - wxString str = ""; - /*for(int i = 0; i < numberOfBuses; i++) { - str += wxString::Format("%.5f/_%.2f\n", std::abs(voltage[i]), wxRadToDeg(std::arg(voltage[i]))); - } - wxLogMessage(str); + UpdateElementsPowerFlow(voltage, power, oldBusType, systemPowerBase); - str = ""; - for(int i = 0; i < numberOfBuses; i++) { - str += wxString::Format("%.5f + j%.5f\n", power[i].real(), power[i].imag()); - } - wxLogMessage(str); - - wxLogMessage(wxString::Format("Num iteracoes = %d", iteration));*/ - - ValidateElementsPowerFlow(voltage, power, busType, systemPowerBase); - + wxString str = ""; for(auto itb = m_busList.begin(); itb != m_busList.end(); itb++) { Bus* bus = *itb; BusElectricalData data = bus->GetEletricalData(); diff --git a/Project/PowerFlow.h b/Project/PowerFlow.h index 1e5c621..0ead448 100644 --- a/Project/PowerFlow.h +++ b/Project/PowerFlow.h @@ -7,6 +7,19 @@ #include <wx/intl.h> //_() #include <wx/log.h> //temp +enum ReactiveLimitsType { + RL_UNLIMITED = 0, // The bus can generate any ammount of reactive power. + RL_LIMITED, // The bus reactive power generation is limited. + RL_UNLIMITED_SOURCE, // The bus have at least one source of infinite reative power. +}; + +struct ReactiveLimits { + double maxLimit = 0.0; + double minLimit = 0.0; + ReactiveLimitsType maxLimitType = RL_UNLIMITED; + ReactiveLimitsType minLimitType = RL_UNLIMITED; +}; + class PowerFlow : public ElectricCalculation { public: diff --git a/Project/Project.mk b/Project/Project.mk index 09c2818..79121dc 100644 --- a/Project/Project.mk +++ b/Project/Project.mk @@ -13,7 +13,7 @@ CurrentFileName := CurrentFilePath := CurrentFileFullPath := User :=Thales -Date :=04/11/2016 +Date :=07/11/2016 CodeLitePath :="C:/Program Files/CodeLite" LinkerName :=C:/TDM-GCC-64/bin/g++.exe SharedObjectLinkerName :=C:/TDM-GCC-64/bin/g++.exe -shared -fPIC diff --git a/Project/Release/ElectricCalculation.cpp.o b/Project/Release/ElectricCalculation.cpp.o Binary files differindex 91c3101..0586bd9 100644 --- a/Project/Release/ElectricCalculation.cpp.o +++ b/Project/Release/ElectricCalculation.cpp.o diff --git a/Project/Release/PSP-UFU.exe b/Project/Release/PSP-UFU.exe Binary files differindex dceb0d5..7f37d30 100644 --- a/Project/Release/PSP-UFU.exe +++ b/Project/Release/PSP-UFU.exe diff --git a/Project/Release/PowerFlow.cpp.o b/Project/Release/PowerFlow.cpp.o Binary files differindex 0827969..64f5719 100644 --- a/Project/Release/PowerFlow.cpp.o +++ b/Project/Release/PowerFlow.cpp.o |