diff options
author | Thales Lima Oliveira <thaleslima.ufu@gmail.com> | 2018-04-04 21:31:28 -0300 |
---|---|---|
committer | Thales Lima Oliveira <thaleslima.ufu@gmail.com> | 2018-04-04 21:31:28 -0300 |
commit | 54b3719953815bd6a2648bb6dac662f513d80fca (patch) | |
tree | 10a68f1c0ae1911a50a2cdc922a43dac58290208 | |
parent | aef98fb30666fd86cbbafc8bd748e4815d3c819b (diff) | |
download | PSP.git-54b3719953815bd6a2648bb6dac662f513d80fca.tar.gz PSP.git-54b3719953815bd6a2648bb6dac662f513d80fca.tar.xz PSP.git-54b3719953815bd6a2648bb6dac662f513d80fca.zip |
Some ANAREDE to PSP electric data implemented
Some bugfixes
-rw-r--r-- | Project/ImportForm.cpp | 60 | ||||
-rw-r--r-- | Project/ImportForm.h | 14 | ||||
-rw-r--r-- | Project/PowerFlow.cpp | 6 | ||||
-rw-r--r-- | Project/Project.mk | 2 | ||||
-rw-r--r-- | Project/PropertiesData.h | 1 | ||||
-rw-r--r-- | Project/Workspace.cpp | 102 |
6 files changed, 101 insertions, 84 deletions
diff --git a/Project/ImportForm.cpp b/Project/ImportForm.cpp index 352efc9..53afe23 100644 --- a/Project/ImportForm.cpp +++ b/Project/ImportForm.cpp @@ -148,11 +148,12 @@ bool ImportForm::ImportSelectedFiles() SyncGenerator* syncGenerator = new SyncGenerator(); auto data = syncGenerator->GetElectricalData(); - data.name = _("Generator") + wxT(" (") + busData->busName + wxT(")"); + data.name = wxString::Format("%s %u (%s)", _("Generator"), indList.size() + 1, busData->busName); data.activePower = busData->genPower.real(); data.reactivePower = busData->genPower.imag(); data.minReactive = busData->minReactivePower; data.maxReactive = busData->maxReactivePower; + data.useMachineBase = false; // ANAREDE use system's base syncGenerator->SetElectricalData(data); @@ -161,11 +162,13 @@ bool ImportForm::ImportSelectedFiles() SyncMotor* syncMotor = new SyncMotor(); auto data = syncMotor->GetElectricalData(); - data.name = _("Synchronous compensator") + wxT(" (") + busData->busName + wxT(")"); + data.name = wxString::Format("%s %u (%s)", _("Synchronous compensator"), indList.size() + 1, + busData->busName); data.activePower = busData->genPower.real() == 0.0 ? 0.0 : -busData->genPower.real(); data.reactivePower = busData->genPower.imag(); data.minReactive = busData->minReactivePower; data.maxReactive = busData->maxReactivePower; + data.useMachineBase = false; // ANAREDE use system's base syncMotor->SetElectricalData(data); @@ -238,8 +241,6 @@ bool ImportForm::ImportSelectedFiles() for(int i = 0; i < 2; ++i) syncGenerator->Rotate(false); // Set to ANAREDE default rotation for(int i = 0; i < (*it)->rotationID * 2; ++i) syncGenerator->Rotate(); - syncGeneratorList.push_back(syncGenerator); - busList.push_back(auxBus); transformerList.push_back(transformer); syncGeneratorList.push_back(syncGenerator); @@ -250,6 +251,8 @@ bool ImportForm::ImportSelectedFiles() wxPoint2DDouble nodePos = parseAnarede.GetNodePositionFromID(parentBus, scale, (*it)->busConnectionNode[0].second); + ParseAnarede::BusData* busData = parseAnarede.GetBusDataFromID((*it)->busConnectionID[0].second); + Load* load = new Load(); load->SetID((*it)->id); load->AddParent(parentBus, nodePos); @@ -257,6 +260,12 @@ bool ImportForm::ImportSelectedFiles() load->StartMove(load->GetPosition()); load->Move(wxPoint2DDouble((*it)->position.m_x * scale, (*it)->position.m_y * scale)); + auto data = load->GetElectricalData(); + data.name = wxString::Format("%s %u (%s)", _("Load"), indList.size() + 1, busData->busName); + data.activePower = busData->loadPower.real(); + data.reactivePower = busData->loadPower.imag(); + load->SetElectricalData(data); + for(int i = 0; i < (*it)->rotationID * 2; ++i) load->Rotate(); loadList.push_back(load); @@ -274,14 +283,14 @@ bool ImportForm::ImportSelectedFiles() if(!isInductor) { Capacitor* cap = new Capacitor(); auto data = cap->GetElectricalData(); - data.name = _("Capacitor") + wxT("(") + busData->busName + wxT(")"); + data.name = wxString::Format("%s %u (%s)", _("Capacitor"), indList.size() + 1, busData->busName); data.reactivePower = busData->shuntReactive; cap->SetElectricalData(data); shuntElement = cap; } else { Inductor* ind = new Inductor(); auto data = ind->GetElectricalData(); - data.name = _("Inductor") + wxT("(") + busData->busName + wxT(")"); + data.name = wxString::Format("%s %u (%s)", _("Inductor"), indList.size() + 1, busData->busName); data.reactivePower = -busData->shuntReactive; ind->SetElectricalData(data); shuntElement = ind; @@ -339,6 +348,9 @@ bool ImportForm::ImportSelectedFiles() wxPoint2DDouble nodePos2 = parseAnarede.GetNodePositionFromID(parentBus2, scale, (*it)->busConnectionNode[1].second); + ParseAnarede::BranchData* branchData = parseAnarede.GetBranchDataFromID( + (*it)->electricalID, (*it)->busConnectionID[0].second, (*it)->busConnectionID[1].second); + Transformer* transformer = new Transformer(); transformer->SetID((*it)->id); transformer->AddParent(parentBus1, nodePos1); @@ -350,6 +362,16 @@ bool ImportForm::ImportSelectedFiles() for(int i = 0; i < 2; ++i) transformer->Rotate(); // Set to ANAREDE default rotation for(int i = 0; i < (*it)->rotationID * 2; ++i) transformer->Rotate(); + auto data = transformer->GetElectricalData(); + data.name = + wxString::Format("%s %u (%s - %s)", _("Transformer"), lineList.size() + 1, + parentBus1->GetElectricalData().name, parentBus2->GetElectricalData().name); + data.resistance = branchData->resistance / 100.0; + data.indReactance = branchData->indReactance / 100.0; + data.turnsRatio = branchData->tap; + data.phaseShift = branchData->phaseShift; + transformer->SetElectricaData(data); + transformerList.push_back(transformer); } break; default: { @@ -367,6 +389,9 @@ bool ImportForm::ImportSelectedFiles() wxPoint2DDouble nodePos2 = parseAnarede.GetNodePositionFromID(parentBus2, scale, (*it)->busConnectionNode[1].second); + ParseAnarede::BranchData* branchData = parseAnarede.GetBranchDataFromID( + (*it)->electricalID, (*it)->busConnectionID[0].second, (*it)->busConnectionID[1].second); + Line* line = new Line(); line->SetID((*it)->id); line->AddParent(parentBus1, nodePos1); @@ -375,11 +400,21 @@ bool ImportForm::ImportSelectedFiles() wxPoint2DDouble((*it)->nodesPosition[i].m_x * scale, (*it)->nodesPosition[i].m_y * scale)); line->AddParent(parentBus2, nodePos2); + auto data = line->GetElectricalData(); + data.name = wxString::Format("%s %u (%s - %s)", _("Line"), lineList.size() + 1, + parentBus1->GetElectricalData().name, parentBus2->GetElectricalData().name); + data.resistance = branchData->resistance / 100.0; + data.indReactance = branchData->indReactance / 100.0; + data.capSusceptance = branchData->capSusceptance / mvaBasePower; + line->SetElectricalData(data); + lineList.push_back(line); } } for(auto it = busList.begin(), itEnd = busList.end(); it != itEnd; ++it) elementList.push_back(*it); + for(auto it = transformerList.begin(), itEnd = transformerList.end(); it != itEnd; ++it) elementList.push_back(*it); + for(auto it = lineList.begin(), itEnd = lineList.end(); it != itEnd; ++it) elementList.push_back(*it); for(auto it = syncGeneratorList.begin(), itEnd = syncGeneratorList.end(); it != itEnd; ++it) elementList.push_back(*it); for(auto it = syncMotorList.begin(), itEnd = syncMotorList.end(); it != itEnd; ++it) elementList.push_back(*it); @@ -387,8 +422,6 @@ bool ImportForm::ImportSelectedFiles() for(auto it = indList.begin(), itEnd = indList.end(); it != itEnd; ++it) elementList.push_back(*it); for(auto it = capList.begin(), itEnd = capList.end(); it != itEnd; ++it) elementList.push_back(*it); for(auto it = indMotorList.begin(), itEnd = indMotorList.end(); it != itEnd; ++it) elementList.push_back(*it); - for(auto it = transformerList.begin(), itEnd = transformerList.end(); it != itEnd; ++it) elementList.push_back(*it); - for(auto it = lineList.begin(), itEnd = lineList.end(); it != itEnd; ++it) elementList.push_back(*it); m_workspace->SetElementList(elementList); m_workspace->SetName(parseAnarede.GetProjectName()); @@ -687,7 +720,7 @@ bool ParseAnarede::ParsePWFExeCode(wxString data, wxString exeCode) else return false; if(!GetPWFStructuredData(lineData, 7, 1, busData->type)) return false; - if(!GetPWFStructuredData(lineData, 8, 2, busData->voltageBase)) return false; + busData->voltageBase = lineData.Mid(8, 2); busData->busName = lineData.Mid(10, 12).Trim(); if(!GetPWFStructuredData(lineData, 24, 4, busData->voltage, 1)) return false; if(!GetPWFStructuredData(lineData, 28, 4, busData->angle)) return false; @@ -847,7 +880,14 @@ ParseAnarede::BusData* ParseAnarede::GetBusDataFromID(int id) return NULL; } -ParseAnarede::BranchData* ParseAnarede::GetBranchDataFromID(int id, int fromBus, int toBus) { return NULL; } +ParseAnarede::BranchData* ParseAnarede::GetBranchDataFromID(int id, int fromBus, int toBus) +{ + for(auto it = m_branchData.begin(), itEnd = m_branchData.end(); it != itEnd; ++it) { + if((*it)->id == id && (*it)->busConnections.first == fromBus && (*it)->busConnections.second == toBus) + return *it; + } + return NULL; +} ParseAnarede::IndElementData* ParseAnarede::GetIndElementDataFromID(int id, int bus) { return NULL; } diff --git a/Project/ImportForm.h b/Project/ImportForm.h index f561bcd..021ba66 100644 --- a/Project/ImportForm.h +++ b/Project/ImportForm.h @@ -114,13 +114,13 @@ class ParseAnarede std::vector<wxPoint2DDouble> nodesPosition; /**< Coordinates of the line breaks, if any */ }; struct BusData { - int id = 0; /**< Bus electrical ID */ - bool isOnline = true; /**< Element is online */ - int type = 0; /**< Bus Type: 0 = PQ; 1 = PV; 2 = Ref.; 3 = PQ with voltage between */ - int voltageBase = 0; /**< Voltage base ID */ - wxString busName = "Bus"; /**< Bus name */ - double voltage = 1.0; /**< Bus abs voltage (controlled value for PV and Ref. types) */ - double angle = 0.0; /**< Angle of voltage */ + int id = 0; /**< Bus electrical ID */ + bool isOnline = true; /**< Element is online */ + int type = 0; /**< Bus Type: 0 = PQ; 1 = PV; 2 = Ref.; 3 = PQ with voltage between */ + wxString voltageBase = "0"; /**< Voltage base identifier */ + wxString busName = "Bus"; /**< Bus name */ + double voltage = 1.0; /**< Bus abs voltage (controlled value for PV and Ref. types) */ + double angle = 0.0; /**< Angle of voltage */ std::complex<double> genPower = std::complex<double>(0, 0); /**< Generated power */ double minReactivePower = -9999.0; /**< Minimal reactive power */ double maxReactivePower = 99999.0; /**< Maximum reactive power */ diff --git a/Project/PowerFlow.cpp b/Project/PowerFlow.cpp index 4a2b7c9..bafbbfb 100644 --- a/Project/PowerFlow.cpp +++ b/Project/PowerFlow.cpp @@ -26,6 +26,7 @@ bool PowerFlow::RunGaussSeidel(double systemPowerBase, double initAngle, double accFactor) { + double radInitAngle = wxDegToRad(initAngle); // Calculate the Ybus. if(!GetYBus(m_yBus, systemPowerBase)) { m_errorMsg = _("No buses found on the system."); @@ -73,9 +74,10 @@ bool PowerFlow::RunGaussSeidel(double systemPowerBase, // Fill the voltages array if(data.isVoltageControlled && busType[busNumber] != BUS_PQ) { - voltage.push_back(std::complex<double>(data.controlledVoltage, 0.0)); + voltage.push_back(std::complex<double>(data.controlledVoltage * std::cos(radInitAngle), + data.controlledVoltage * std::sin(radInitAngle))); } else { - voltage.push_back(std::complex<double>(1.0, 0.0)); + voltage.push_back(std::complex<double>(std::cos(radInitAngle), std::sin(radInitAngle))); } // Fill the power array diff --git a/Project/Project.mk b/Project/Project.mk index c0a13dc..375fd2e 100644 --- a/Project/Project.mk +++ b/Project/Project.mk @@ -13,7 +13,7 @@ CurrentFileName := CurrentFilePath := CurrentFileFullPath := User :=NDSE-69 -Date :=03/04/2018 +Date :=04/04/2018 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/PropertiesData.h b/Project/PropertiesData.h index deba3e9..127eb59 100644 --- a/Project/PropertiesData.h +++ b/Project/PropertiesData.h @@ -37,6 +37,7 @@ struct SimulationData { double accFator = 1.0; double powerFlowTolerance = 1e-7; int powerFlowMaxIterations = 5000; + double initAngle = 0.0; // Stability double stabilityFrequency = 60.0; diff --git a/Project/Workspace.cpp b/Project/Workspace.cpp index 9bd249b..45944ab 100644 --- a/Project/Workspace.cpp +++ b/Project/Workspace.cpp @@ -15,34 +15,35 @@ * along with this program. If not, see <https://www.gnu.org/licenses/>. */ -#include "Workspace.h" #include "Camera.h" #include "Element.h" +#include "Workspace.h" //#include "Bus.h" +#include "Capacitor.h" +#include "ElementDataObject.h" +#include "IndMotor.h" +#include "Inductor.h" #include "Line.h" -#include "Transformer.h" +#include "Load.h" #include "SyncGenerator.h" -#include "IndMotor.h" #include "SyncMotor.h" -#include "Load.h" -#include "Inductor.h" -#include "Capacitor.h" -#include "ElementDataObject.h" +#include "Transformer.h" #include "Text.h" -#include "PowerFlow.h" -#include "Fault.h" #include "Electromechanical.h" +#include "Fault.h" +#include "PowerFlow.h" -#include "ElementPlotData.h" #include "ChartView.h" +#include "ElementPlotData.h" #include "PropertiesData.h" // Workspace Workspace::Workspace() : WorkspaceBase(NULL) {} -Workspace::Workspace(wxWindow* parent, wxString name, wxStatusBar* statusBar, wxGLContext* sharedGLContext) : WorkspaceBase(parent) +Workspace::Workspace(wxWindow* parent, wxString name, wxStatusBar* statusBar, wxGLContext* sharedGLContext) + : WorkspaceBase(parent) { m_timer->Start(); m_name = name; @@ -51,9 +52,7 @@ Workspace::Workspace(wxWindow* parent, wxString name, wxStatusBar* statusBar, wx m_camera = new Camera(); m_selectionRect = wxRect2DDouble(0, 0, 0, 0); - for(int i = 0; i < NUM_ELEMENTS; ++i) { - m_elementNumber[i] = 1; - } + for(int i = 0; i < NUM_ELEMENTS; ++i) { m_elementNumber[i] = 1; } const int widths[4] = {-3, -1, 100, 100}; m_statusBar->SetStatusWidths(4, widths); @@ -78,7 +77,7 @@ Workspace::~Workspace() void Workspace::OnPaint(wxPaintEvent& event) { if(!m_glCanvas->IsShown()) return; - + wxPaintDC dc(m_glCanvas); m_glContext->SetCurrent(*m_glCanvas); SetViewport(); @@ -182,9 +181,7 @@ void Workspace::OnLeftClickDown(wxMouseEvent& event) } // The line element can have an indefined number of points. if(!foundElement) { - if(typeid(*newElement) == typeid(Line)) { - newElement->AddPoint(m_camera->ScreenToWorld(clickPoint)); - } + if(typeid(*newElement) == typeid(Line)) { newElement->AddPoint(m_camera->ScreenToWorld(clickPoint)); } } foundElement = true; } else { @@ -217,9 +214,7 @@ void Workspace::OnLeftClickDown(wxMouseEvent& event) clickPickbox = true; } // If didn't found a pickbox, move the element - if(!clickPickbox) { - m_mode = MODE_MOVE_ELEMENT; - } + if(!clickPickbox) { m_mode = MODE_MOVE_ELEMENT; } } // Click in a switch. @@ -430,9 +425,7 @@ void Workspace::OnLeftClickUp(wxMouseEvent& event) } else { // Deselect if(!event.ControlDown()) { - if(!element->Contains(m_camera->ScreenToWorld(event.GetPosition()))) { - element->SetSelected(false); - } + if(!element->Contains(m_camera->ScreenToWorld(event.GetPosition()))) { element->SetSelected(false); } } if(element->PickboxContains(m_camera->ScreenToWorld(event.GetPosition()))) { @@ -454,9 +447,7 @@ void Workspace::OnLeftClickUp(wxMouseEvent& event) text->SetSelected(false); } } else if(!event.ControlDown()) { - if(!text->Contains(m_camera->ScreenToWorld(event.GetPosition()))) { - text->SetSelected(false); - } + if(!text->Contains(m_camera->ScreenToWorld(event.GetPosition()))) { text->SetSelected(false); } } } @@ -464,17 +455,11 @@ void Workspace::OnLeftClickUp(wxMouseEvent& event) std::rotate(itnp, itnp + 1, m_elementList.end()); updateVoltages = true; } - if(!foundPickbox) { - SetCursor(wxCURSOR_ARROW); - } + if(!foundPickbox) { SetCursor(wxCURSOR_ARROW); } - if(m_mode != MODE_INSERT) { - m_mode = MODE_EDIT; - } + if(m_mode != MODE_INSERT) { m_mode = MODE_EDIT; } - if(updateVoltages) { - ValidateElementsVoltages(); - } + if(updateVoltages) { ValidateElementsVoltages(); } if(m_continuousCalc && m_disconnectedElement) { m_disconnectedElement = false; @@ -705,9 +690,7 @@ void Workspace::OnKeyDown(wxKeyEvent& event) } } break; case 'F': { - if(event.GetModifiers() == wxMOD_SHIFT) { - Fit(); - } + if(event.GetModifiers() == wxMOD_SHIFT) { Fit(); } } break; case 'R': // Rotate the selected elements. { @@ -818,9 +801,7 @@ void Workspace::OnKeyDown(wxKeyEvent& event) } break; case 'V': { if(!insertingElement) { - if(event.GetModifiers() == wxMOD_CONTROL) { - Paste(); - } + if(event.GetModifiers() == wxMOD_CONTROL) { Paste(); } } } break; default: @@ -892,9 +873,7 @@ void Workspace::OnPopupClick(wxCommandEvent& event) // Parent's element rotating... for(int i = 0; i < (int)iElement->GetParentList().size(); i++) { Element* parent = iElement->GetParentList()[i]; - if(parent == element) { - iElement->RotateNode(parent); - } + if(parent == element) { iElement->RotateNode(parent); } } } Redraw(); @@ -906,9 +885,7 @@ void Workspace::OnPopupClick(wxCommandEvent& event) // Parent's element rotating... for(int i = 0; i < (int)iElement->GetParentList().size(); i++) { Element* parent = iElement->GetParentList()[i]; - if(parent == element) { - iElement->RotateNode(parent, false); - } + if(parent == element) { iElement->RotateNode(parent, false); } } } Redraw(); @@ -930,9 +907,7 @@ void Workspace::OnPopupClick(wxCommandEvent& event) std::vector<Element*> parentList = element->GetParentList(); for(auto itp = parentList.begin(), itEnd = parentList.end(); itp != itEnd; ++itp) { Element* parent = *itp; - if(parent) { - parent->RemoveChild(element); - } + if(parent) { parent->RemoveChild(element); } } for(auto itt = m_textList.begin(); itt != m_textList.end(); ++itt) { @@ -1005,9 +980,7 @@ void Workspace::DeleteSelectedElements() std::vector<Element*> parentList = element->GetParentList(); for(auto itp = parentList.begin(), itEnd = parentList.end(); itp != itEnd; ++itp) { Element* parent = *itp; - if(parent) { - parent->RemoveChild(element); - } + if(parent) { parent->RemoveChild(element); } } for(auto itt = m_textList.begin(); itt != m_textList.end(); ++itt) { @@ -1060,9 +1033,7 @@ void Workspace::Fit() wxPoint2DDouble leftUpCorner(0, 0); wxPoint2DDouble rightDownCorner(0, 0); std::vector<Element*> elementList = GetElementList(); - for(auto it = m_textList.begin(), itEnd = m_textList.end(); it != itEnd; ++it) { - elementList.push_back(*it); - } + for(auto it = m_textList.begin(), itEnd = m_textList.end(); it != itEnd; ++it) { elementList.push_back(*it); } if(!GetElementsCorners(leftUpCorner, rightDownCorner, elementList)) return; wxPoint2DDouble middleCoords = (leftUpCorner + rightDownCorner) / 2.0; @@ -1137,8 +1108,15 @@ void Workspace::ValidateElementsVoltages() bool Workspace::RunPowerFlow() { + auto simProp = m_properties->GetSimulationPropertiesData(); + double basePower = simProp.basePower; + if(simProp.basePowerUnit == UNIT_MVA) + basePower *= 1e6; + else if(simProp.basePowerUnit == UNIT_kVA) + basePower *= 1e3; PowerFlow pf(GetElementList()); - bool result = pf.RunGaussSeidel(); + bool result = pf.RunGaussSeidel(basePower, simProp.powerFlowMaxIterations, simProp.powerFlowTolerance, + simProp.initAngle, simProp.accFator); if(!result) { wxMessageDialog msgDialog(this, pf.GetErrorMessage(), _("Error"), wxOK | wxCENTRE | wxICON_ERROR); msgDialog.ShowModal(); @@ -1181,15 +1159,11 @@ void Workspace::CopySelection() bus->SetElectricalData(data); busNumber++; } - if(element->IsSelected()) { - selectedElements.push_back(element); - } + if(element->IsSelected()) { selectedElements.push_back(element); } } for(auto it = m_textList.begin(), itEnd = m_textList.end(); it != itEnd; ++it) { Text* text = *it; - if(text->IsSelected()) { - selectedElements.push_back(text); - } + if(text->IsSelected()) { selectedElements.push_back(text); } } ElementDataObject* dataObject = new ElementDataObject(selectedElements); if(wxTheClipboard->Open()) { |