summaryrefslogtreecommitdiffstats
path: root/Project/ImportForm.cpp
diff options
context:
space:
mode:
authorThales Lima Oliveira <thaleslima.ufu@gmail.com>2018-04-03 22:06:26 -0300
committerThales Lima Oliveira <thaleslima.ufu@gmail.com>2018-04-03 22:06:26 -0300
commitaef98fb30666fd86cbbafc8bd748e4815d3c819b (patch)
tree5ee58837c00eb62122798841a02409aaef0ce9bc /Project/ImportForm.cpp
parent15d73e75d8f8a30c5d89f61bff05af4caf6202b1 (diff)
downloadPSP.git-aef98fb30666fd86cbbafc8bd748e4815d3c819b.tar.gz
PSP.git-aef98fb30666fd86cbbafc8bd748e4815d3c819b.tar.xz
PSP.git-aef98fb30666fd86cbbafc8bd748e4815d3c819b.zip
.PWF parse implemented, some electrical data set too
Diffstat (limited to 'Project/ImportForm.cpp')
-rw-r--r--Project/ImportForm.cpp575
1 files changed, 445 insertions, 130 deletions
diff --git a/Project/ImportForm.cpp b/Project/ImportForm.cpp
index cadc5f0..352efc9 100644
--- a/Project/ImportForm.cpp
+++ b/Project/ImportForm.cpp
@@ -1,3 +1,20 @@
+/*
+ * Copyright (C) 2018 Thales Lima Oliveira <thales@ufu.br>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
#include "Bus.h"
#include "Capacitor.h"
#include "ImportForm.h"
@@ -5,7 +22,9 @@
#include "Inductor.h"
#include "Line.h"
#include "Load.h"
+#include "PropertiesData.h"
#include "SyncGenerator.h"
+#include "SyncMotor.h"
#include "Transformer.h"
#include "Workspace.h"
@@ -43,140 +62,293 @@ bool ImportForm::ImportSelectedFiles()
if(!parseAnarede.Parse()) return false;
double scale = 1.25;
+ double mvaBasePower = parseAnarede.GetMVAPowerBase();
+ auto simProp = m_workspace->GetProperties()->GetSimulationPropertiesData();
+ simProp.basePower = mvaBasePower;
+ m_workspace->GetProperties()->SetSimulationPropertiesData(simProp);
+
std::vector<Element*> elementList;
std::vector<Bus*> busList;
std::vector<SyncGenerator*> syncGeneratorList;
+ std::vector<SyncMotor*> syncMotorList;
std::vector<Load*> loadList;
std::vector<Inductor*> indList;
+ std::vector<Capacitor*> capList;
std::vector<IndMotor*> indMotorList;
std::vector<Transformer*> transformerList;
std::vector<Line*> lineList;
auto components = parseAnarede.GetComponents();
for(auto it = components.begin(), itEnd = components.end(); it != itEnd; ++it) {
- switch((*it).type) {
+ switch((*it)->type) {
case ANA_BUS: {
- Bus* bus = new Bus(wxPoint2DDouble((*it).position.m_x * scale, (*it).position.m_y * scale));
- bus->SetID((*it).id);
- bus->SetWidth((*it).length * scale);
- // bus->SetPosition(bus->GetPosition()); // Update bus rect
+ Bus* bus = new Bus(wxPoint2DDouble((*it)->position.m_x * scale, (*it)->position.m_y * scale));
+ bus->SetID((*it)->id);
+ bus->SetWidth((*it)->length * scale);
bus->StartMove(bus->GetPosition());
- if((*it).rotationID == 0) {
+ if((*it)->rotationID == 0) {
bus->Move(bus->GetPosition() + wxPoint2DDouble(bus->GetWidth() / 2, bus->GetHeight() / 2));
- } else if((*it).rotationID == 1) {
- for(int i = 0; i < (*it).rotationID * 2; ++i) bus->Rotate();
+ } else if((*it)->rotationID == 1) {
+ for(int i = 0; i < (*it)->rotationID * 2; ++i) bus->Rotate();
bus->Move(bus->GetPosition() + wxPoint2DDouble(-bus->GetHeight() / 2, bus->GetWidth() / 2));
- } else if((*it).rotationID == 2) {
- for(int i = 0; i < (*it).rotationID * 2; ++i) bus->Rotate();
+ } else if((*it)->rotationID == 2) {
+ for(int i = 0; i < (*it)->rotationID * 2; ++i) bus->Rotate();
bus->Move(bus->GetPosition() + wxPoint2DDouble(-bus->GetWidth() / 2, -bus->GetHeight() / 2));
- } else if((*it).rotationID == 3) {
- for(int i = 0; i < (*it).rotationID * 2; ++i) bus->Rotate();
+ } else if((*it)->rotationID == 3) {
+ for(int i = 0; i < (*it)->rotationID * 2; ++i) bus->Rotate();
bus->Move(bus->GetPosition() + wxPoint2DDouble(-bus->GetHeight() / 2, -bus->GetWidth() / 2));
}
+ // Electrical data
+ auto data = bus->GetElectricalData();
+ ParseAnarede::BusData* busData = parseAnarede.GetBusDataFromID((*it)->electricalID);
+ if(busData) {
+ data.number = busData->id;
+ data.name = busData->busName;
+ switch(busData->type) {
+ case 0:
+ case 3: {
+ data.isVoltageControlled = false;
+ data.slackBus = false;
+ } break;
+ case 1: {
+ data.isVoltageControlled = true;
+ data.slackBus = false;
+ } break;
+ case 2: {
+ data.isVoltageControlled = true;
+ data.slackBus = true;
+ } break;
+ default: {
+ return false;
+ } break;
+ }
+ data.voltage = std::complex<double>(busData->voltage * std::cos(wxDegToRad(busData->angle)),
+ busData->voltage * std::sin(wxDegToRad(busData->angle)));
+ data.controlledVoltage = busData->voltage;
+ } else
+ return false;
+
+ bus->SetElectricalData(data);
busList.push_back(bus);
} break;
- case ANA_GENERATOR:
- case ANA_IND_GENERATOR: {
+ case ANA_GENERATOR: {
// Find parent bus
- Bus* parentBus = GetBusFromID(busList, (*it).busConnectionID[0].first);
+ Bus* parentBus = GetBusFromID(busList, (*it)->busConnectionID[0].first);
+ wxPoint2DDouble nodePos =
+ parseAnarede.GetNodePositionFromID(parentBus, scale, (*it)->busConnectionNode[0].second);
+
+ ParseAnarede::BusData* busData = parseAnarede.GetBusDataFromID((*it)->busConnectionID[0].second);
+ bool isMotor = false;
+ if(busData->genPower.real() <= 0.0) isMotor = true;
+ Machines* machine = NULL;
+
+ if(!isMotor) {
+ SyncGenerator* syncGenerator = new SyncGenerator();
+
+ auto data = syncGenerator->GetElectricalData();
+ data.name = _("Generator") + wxT(" (") + busData->busName + wxT(")");
+ data.activePower = busData->genPower.real();
+ data.reactivePower = busData->genPower.imag();
+ data.minReactive = busData->minReactivePower;
+ data.maxReactive = busData->maxReactivePower;
+
+ syncGenerator->SetElectricalData(data);
+
+ machine = syncGenerator;
+ } else {
+ SyncMotor* syncMotor = new SyncMotor();
+
+ auto data = syncMotor->GetElectricalData();
+ data.name = _("Synchronous compensator") + wxT(" (") + busData->busName + wxT(")");
+ 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;
+
+ syncMotor->SetElectricalData(data);
+
+ machine = syncMotor;
+ }
+
+ if(machine) {
+ machine->SetID((*it)->id);
+ machine->AddParent(parentBus, nodePos);
+
+ machine->StartMove(machine->GetPosition());
+ machine->Move(wxPoint2DDouble((*it)->position.m_x * scale, (*it)->position.m_y * scale));
+
+ for(int i = 0; i < 2; ++i) machine->Rotate(false); // Set to ANAREDE default rotation
+ for(int i = 0; i < (*it)->rotationID * 2; ++i) machine->Rotate();
+
+ if(!isMotor)
+ syncGeneratorList.push_back(static_cast<SyncGenerator*>(machine));
+ else
+ syncMotorList.push_back(static_cast<SyncMotor*>(machine));
+ }
+ } break;
+ case ANA_IND_GENERATOR: {
+ // Same as ANA_GENERATOR, but with a transformer connecting the bus
+ Bus* parentBus = GetBusFromID(busList, (*it)->busConnectionID[0].first);
wxPoint2DDouble nodePos =
- parseAnarede.GetNodePositionFromID(parentBus, scale, (*it).busConnectionNode[0].second);
+ parseAnarede.GetNodePositionFromID(parentBus, scale, (*it)->busConnectionNode[0].second);
+
+ wxPoint2DDouble genPosition((*it)->position.m_x * scale,
+ (*it)->position.m_y * scale); // Element position.
+ // Calculate the new generator position:
+ wxPoint2DDouble offset;
+ double angle = wxRadToDeg(std::atan2(genPosition.m_y - nodePos.m_y, genPosition.m_x - nodePos.m_x));
+
+ int tRot = 0; // Number of transformer rotations
+ int bRot = 0; // Number of bus rotations
+ if(angle >= -45 && angle <= 45) {
+ offset = wxPoint2DDouble(75.0, 0.0);
+ tRot = 4;
+ bRot = 2;
+ } else if(angle < -45 && angle > -135) {
+ offset = wxPoint2DDouble(0.0, -75.0);
+ tRot = 2;
+ } else if(angle <= -135 || angle >= 135) {
+ offset = wxPoint2DDouble(-75.0, 0.0);
+ bRot = 2;
+ } else {
+ offset = wxPoint2DDouble(0.0, 75.0);
+ tRot = 6;
+ }
+
+ // Auxiliary bus
+ Bus* auxBus = new Bus(genPosition);
+ for(int i = 0; i < bRot; ++i) auxBus->Rotate();
+ // Transformer
+ Transformer* transformer = new Transformer();
+ transformer->AddParent(auxBus, auxBus->GetPosition());
+ transformer->AddParent(parentBus, nodePos);
+ for(int i = 0; i < tRot; ++i) transformer->Rotate();
+ transformer->StartMove(transformer->GetPosition());
+ transformer->Move(genPosition - offset);
SyncGenerator* syncGenerator = new SyncGenerator();
- syncGenerator->SetID((*it).id);
- syncGenerator->AddParent(parentBus, nodePos);
+ syncGenerator->SetID((*it)->id);
+ syncGenerator->AddParent(auxBus, auxBus->GetPosition());
syncGenerator->StartMove(syncGenerator->GetPosition());
- syncGenerator->Move(wxPoint2DDouble((*it).position.m_x * scale, (*it).position.m_y * scale));
+ syncGenerator->Move(genPosition + offset);
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();
+ 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);
} break;
case ANA_LOAD:
case ANA_IND_LOAD: {
- Bus* parentBus = GetBusFromID(busList, (*it).busConnectionID[0].first);
+ Bus* parentBus = GetBusFromID(busList, (*it)->busConnectionID[0].first);
wxPoint2DDouble nodePos =
- parseAnarede.GetNodePositionFromID(parentBus, scale, (*it).busConnectionNode[0].second);
+ parseAnarede.GetNodePositionFromID(parentBus, scale, (*it)->busConnectionNode[0].second);
Load* load = new Load();
- load->SetID((*it).id);
+ load->SetID((*it)->id);
load->AddParent(parentBus, nodePos);
load->StartMove(load->GetPosition());
- load->Move(wxPoint2DDouble((*it).position.m_x * scale, (*it).position.m_y * scale));
+ load->Move(wxPoint2DDouble((*it)->position.m_x * scale, (*it)->position.m_y * scale));
- for(int i = 0; i < (*it).rotationID * 2; ++i) load->Rotate();
+ for(int i = 0; i < (*it)->rotationID * 2; ++i) load->Rotate();
loadList.push_back(load);
} break;
case ANA_SHUNT:
case ANA_IND_SHUNT: {
- Bus* parentBus = GetBusFromID(busList, (*it).busConnectionID[0].first);
+ Bus* parentBus = GetBusFromID(busList, (*it)->busConnectionID[0].first);
wxPoint2DDouble nodePos =
- parseAnarede.GetNodePositionFromID(parentBus, scale, (*it).busConnectionNode[0].second);
-
- Inductor* ind = new Inductor();
- ind->SetID((*it).id);
- ind->AddParent(parentBus, nodePos);
-
- ind->StartMove(ind->GetPosition());
- // Offset (ind->GetHeight() / 2 + 10) to adequate the y coordinate
- ind->Move(wxPoint2DDouble((*it).position.m_x * scale,
- (*it).position.m_y * scale + ind->GetHeight() / 2 + 10));
- if((*it).rotationID != 0) {
- // Remove offset in position
- ind->Move(wxPoint2DDouble((*it).position.m_x * scale, (*it).position.m_y * scale));
- // Get the rotated point ralated to the offset
- wxPoint2DDouble movePt =
- ind->RotateAtPosition(ind->GetPosition() + wxPoint2DDouble(0, ind->GetHeight() / 2 + 10),
- (*it).rotationID * 90.0, true);
- ind->Move(movePt);
-
- for(int i = 0; i < (*it).rotationID * 2; ++i) ind->Rotate();
+ parseAnarede.GetNodePositionFromID(parentBus, scale, (*it)->busConnectionNode[0].second);
+
+ ParseAnarede::BusData* busData = parseAnarede.GetBusDataFromID((*it)->busConnectionID[0].second);
+ bool isInductor = false;
+ if(busData->shuntReactive <= 0.0) isInductor = true;
+ Shunt* shuntElement = NULL;
+ if(!isInductor) {
+ Capacitor* cap = new Capacitor();
+ auto data = cap->GetElectricalData();
+ data.name = _("Capacitor") + wxT("(") + busData->busName + wxT(")");
+ 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.reactivePower = -busData->shuntReactive;
+ ind->SetElectricalData(data);
+ shuntElement = ind;
}
- indList.push_back(ind);
+ if(shuntElement) {
+ shuntElement->SetID((*it)->id);
+ shuntElement->AddParent(parentBus, nodePos);
+
+ shuntElement->StartMove(shuntElement->GetPosition());
+ // Offset (ind->GetHeight() / 2 + 10) to adequate the y coordinate
+ shuntElement->Move(wxPoint2DDouble(
+ (*it)->position.m_x * scale, (*it)->position.m_y * scale + shuntElement->GetHeight() / 2 + 10));
+ if((*it)->rotationID != 0) {
+ // Remove offset in position
+ shuntElement->Move(wxPoint2DDouble((*it)->position.m_x * scale, (*it)->position.m_y * scale));
+ // Get the rotated point ralated to the offset
+ wxPoint2DDouble movePt = shuntElement->RotateAtPosition(
+ shuntElement->GetPosition() + wxPoint2DDouble(0, shuntElement->GetHeight() / 2 + 10),
+ (*it)->rotationID * 90.0, true);
+ shuntElement->Move(movePt);
+
+ for(int i = 0; i < (*it)->rotationID * 2; ++i) shuntElement->Rotate();
+ }
+
+ if(!isInductor)
+ capList.push_back(static_cast<Capacitor*>(shuntElement));
+ else
+ indList.push_back(static_cast<Inductor*>(shuntElement));
+ }
} break;
case ANA_MIT: {
// Find parent bus
- Bus* parentBus = GetBusFromID(busList, (*it).busConnectionID[0].first);
+ Bus* parentBus = GetBusFromID(busList, (*it)->busConnectionID[0].first);
wxPoint2DDouble nodePos =
- parseAnarede.GetNodePositionFromID(parentBus, scale, (*it).busConnectionNode[0].second);
+ parseAnarede.GetNodePositionFromID(parentBus, scale, (*it)->busConnectionNode[0].second);
IndMotor* indMotor = new IndMotor();
- indMotor->SetID((*it).id);
+ indMotor->SetID((*it)->id);
indMotor->AddParent(parentBus, nodePos);
indMotor->StartMove(indMotor->GetPosition());
- indMotor->Move(wxPoint2DDouble((*it).position.m_x * scale, (*it).position.m_y * scale));
+ indMotor->Move(wxPoint2DDouble((*it)->position.m_x * scale, (*it)->position.m_y * scale));
for(int i = 0; i < 2; ++i) indMotor->Rotate(false); // Set to ANAREDE default rotation
- for(int i = 0; i < (*it).rotationID * 2; ++i) indMotor->Rotate();
+ for(int i = 0; i < (*it)->rotationID * 2; ++i) indMotor->Rotate();
indMotorList.push_back(indMotor);
} break;
case ANA_TRANSFORMER: {
- Bus* parentBus1 = GetBusFromID(busList, (*it).busConnectionID[0].first);
- Bus* parentBus2 = GetBusFromID(busList, (*it).busConnectionID[1].first);
+ Bus* parentBus1 = GetBusFromID(busList, (*it)->busConnectionID[0].first);
+ Bus* parentBus2 = GetBusFromID(busList, (*it)->busConnectionID[1].first);
wxPoint2DDouble nodePos1 =
- parseAnarede.GetNodePositionFromID(parentBus1, scale, (*it).busConnectionNode[0].second);
+ parseAnarede.GetNodePositionFromID(parentBus1, scale, (*it)->busConnectionNode[0].second);
wxPoint2DDouble nodePos2 =
- parseAnarede.GetNodePositionFromID(parentBus2, scale, (*it).busConnectionNode[1].second);
+ parseAnarede.GetNodePositionFromID(parentBus2, scale, (*it)->busConnectionNode[1].second);
Transformer* transformer = new Transformer();
- transformer->SetID((*it).id);
+ transformer->SetID((*it)->id);
transformer->AddParent(parentBus1, nodePos1);
transformer->AddParent(parentBus2, nodePos2);
transformer->StartMove(transformer->GetPosition());
- transformer->Move(wxPoint2DDouble((*it).position.m_x * scale, (*it).position.m_y * scale));
+ transformer->Move(wxPoint2DDouble((*it)->position.m_x * scale, (*it)->position.m_y * scale));
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();
+ for(int i = 0; i < (*it)->rotationID * 2; ++i) transformer->Rotate();
transformerList.push_back(transformer);
} break;
@@ -187,19 +359,20 @@ bool ImportForm::ImportSelectedFiles()
auto powerLines = parseAnarede.GetLines();
for(auto it = powerLines.begin(), itEnd = powerLines.end(); it != itEnd; ++it) {
- if((*it).type == ANA_LINE) {
- Bus* parentBus1 = GetBusFromID(busList, (*it).busConnectionID[0].first);
- Bus* parentBus2 = GetBusFromID(busList, (*it).busConnectionID[1].first);
+ if((*it)->type == ANA_LINE) {
+ Bus* parentBus1 = GetBusFromID(busList, (*it)->busConnectionID[0].first);
+ Bus* parentBus2 = GetBusFromID(busList, (*it)->busConnectionID[1].first);
wxPoint2DDouble nodePos1 =
- parseAnarede.GetNodePositionFromID(parentBus1, scale, (*it).busConnectionNode[0].second);
+ parseAnarede.GetNodePositionFromID(parentBus1, scale, (*it)->busConnectionNode[0].second);
wxPoint2DDouble nodePos2 =
- parseAnarede.GetNodePositionFromID(parentBus2, scale, (*it).busConnectionNode[1].second);
+ parseAnarede.GetNodePositionFromID(parentBus2, scale, (*it)->busConnectionNode[1].second);
Line* line = new Line();
- line->SetID((*it).id);
+ line->SetID((*it)->id);
line->AddParent(parentBus1, nodePos1);
- for(unsigned int i = 0; i < (*it).nodesPosition.size(); ++i)
- line->AddPoint(wxPoint2DDouble((*it).nodesPosition[i].m_x * scale, (*it).nodesPosition[i].m_y * scale));
+ for(unsigned int i = 0; i < (*it)->nodesPosition.size(); ++i)
+ line->AddPoint(
+ wxPoint2DDouble((*it)->nodesPosition[i].m_x * scale, (*it)->nodesPosition[i].m_y * scale));
line->AddParent(parentBus2, nodePos2);
lineList.push_back(line);
@@ -209,8 +382,10 @@ bool ImportForm::ImportSelectedFiles()
for(auto it = busList.begin(), itEnd = busList.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);
for(auto it = loadList.begin(), itEnd = loadList.end(); it != itEnd; ++it) elementList.push_back(*it);
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);
@@ -248,39 +423,39 @@ bool ParseAnarede::Parse()
case 'C': { // Component
int parsePosition = 1;
- Component component;
+ Component* component = new Component();
- component.id = wxAtoi(GetLSTLineNextValue(line, parsePosition));
+ component->id = wxAtoi(GetLSTLineNextValue(line, parsePosition));
// Check if is component type is valid
- if(StrToElementType(GetLSTLineNextValue(line, parsePosition), component.type)) {
- if(component.type == ANA_BUS) {
- if(!GetLenghtAndRotationFromBusCode(GetLSTLineNextValue(line, parsePosition), component.length,
- component.rotationID))
+ if(StrToElementType(GetLSTLineNextValue(line, parsePosition), component->type)) {
+ if(component->type == ANA_BUS) {
+ if(!GetLenghtAndRotationFromBusCode(GetLSTLineNextValue(line, parsePosition), component->length,
+ component->rotationID))
return false;
} else {
- component.rotationID = wxAtoi(GetLSTLineNextValue(line, parsePosition));
+ component->rotationID = wxAtoi(GetLSTLineNextValue(line, parsePosition));
}
parsePosition += 2; // Jump to position
- if(!GetLSTLineNextValue(line, parsePosition).ToCDouble(&component.position.m_x)) return false;
- if(!GetLSTLineNextValue(line, parsePosition).ToCDouble(&component.position.m_y)) return false;
+ if(!GetLSTLineNextValue(line, parsePosition).ToCDouble(&component->position.m_x)) return false;
+ if(!GetLSTLineNextValue(line, parsePosition).ToCDouble(&component->position.m_y)) return false;
parsePosition += 8; // Jump to electrical ID
- component.electricalID = wxAtoi(GetLSTLineNextValue(line, parsePosition));
+ component->electricalID = wxAtoi(GetLSTLineNextValue(line, parsePosition));
// Bus connection IDs
- if(component.type != ANA_BUS) {
+ if(component->type != ANA_BUS) {
int fromBus = wxAtoi(GetLSTLineNextValue(line, parsePosition)); // Origin bus
int toBus = 0;
// If the component is a transformer, parse the next value (toBus)
- if(component.type == ANA_TRANSFORMER) {
+ if(component->type == ANA_TRANSFORMER) {
toBus = wxAtoi(GetLSTLineNextValue(line, parsePosition)); // Destiny bus
}
// Iterate through the already parsed components (the buses is saved first)
for(auto it = m_components.begin(), itEnd = m_components.end(); it != itEnd; ++it) {
- if((*it).type == ANA_BUS) {
- if(fromBus == (*it).electricalID) {
- component.busConnectionID[0] = std::make_pair((*it).id, fromBus);
- } else if(toBus == (*it).electricalID) {
- component.busConnectionID[1] = std::make_pair((*it).id, toBus);
+ if((*it)->type == ANA_BUS) {
+ if(fromBus == (*it)->electricalID) {
+ component->busConnectionID[0] = std::make_pair((*it)->id, fromBus);
+ } else if(toBus == (*it)->electricalID) {
+ component->busConnectionID[1] = std::make_pair((*it)->id, toBus);
}
}
}
@@ -291,10 +466,10 @@ bool ParseAnarede::Parse()
case 'L': { // Line
int parsePosition = 1;
- PowerLine pLine;
+ PowerLine* pLine = new PowerLine();
- pLine.id = wxAtoi(GetLSTLineNextValue(line, parsePosition));
- pLine.type = static_cast<ElementTypeAnarede>(wxAtoi(GetLSTLineNextValue(line, parsePosition)));
+ pLine->id = wxAtoi(GetLSTLineNextValue(line, parsePosition));
+ pLine->type = static_cast<ElementTypeAnarede>(wxAtoi(GetLSTLineNextValue(line, parsePosition)));
parsePosition += 4; // Jump to from bus
int fromBus = wxAtoi(GetLSTLineNextValue(line, parsePosition)); // Origin bus
@@ -302,15 +477,15 @@ bool ParseAnarede::Parse()
// Iterate through the already parsed components
for(auto it = m_components.begin(), itEnd = m_components.end(); it != itEnd; ++it) {
- if((*it).type == ANA_BUS) {
- if(fromBus == (*it).id) {
- pLine.busConnectionID[0] = std::make_pair((*it).id, (*it).electricalID);
- } else if(toBus == (*it).id) {
- pLine.busConnectionID[1] = std::make_pair((*it).id, (*it).electricalID);
+ if((*it)->type == ANA_BUS) {
+ if(fromBus == (*it)->id) {
+ pLine->busConnectionID[0] = std::make_pair((*it)->id, (*it)->electricalID);
+ } else if(toBus == (*it)->id) {
+ pLine->busConnectionID[1] = std::make_pair((*it)->id, (*it)->electricalID);
}
}
}
- pLine.electricalID = wxAtoi(GetLSTLineNextValue(line, parsePosition));
+ pLine->electricalID = wxAtoi(GetLSTLineNextValue(line, parsePosition));
m_lines.push_back(pLine);
} break;
@@ -333,33 +508,33 @@ bool ParseAnarede::Parse()
if(data5 != -1) {
// Iterate through parsed lines
for(auto it = m_lines.begin(), itEnd = m_lines.end(); it != itEnd; ++it) {
- if(data5 == (*it).id) {
- (*it).busConnectionNode[0] = std::make_pair(data1, data2);
- (*it).busConnectionNode[1] = std::make_pair(data3, data4);
+ if(data5 == (*it)->id) {
+ (*it)->busConnectionNode[0] = std::make_pair(data1, data2);
+ (*it)->busConnectionNode[1] = std::make_pair(data3, data4);
for(int i = 0; i < data6; ++i) {
wxPoint2DDouble nodePt;
if(!GetLSTLineNextValue(line, parsePosition).ToCDouble(&nodePt.m_x)) return false;
if(!GetLSTLineNextValue(line, parsePosition).ToCDouble(&nodePt.m_y)) return false;
- (*it).nodesPosition.push_back(nodePt);
+ (*it)->nodesPosition.push_back(nodePt);
}
}
}
} else {
// Iterate through parsed components
for(auto it = m_components.begin(), itEnd = m_components.end(); it != itEnd; ++it) {
- if(data1 == (*it).id) {
- if((*it).type == ANA_BUS) {
+ if(data1 == (*it)->id) {
+ if((*it)->type == ANA_BUS) {
// If the data1 is a bus ID, the element is a element with different data order.
// Find the correct element ID with data3
for(auto itDiff = m_components.begin(), itDiffEnd = m_components.end();
itDiff != itDiffEnd; ++itDiff) {
- if(data3 == (*itDiff).id) {
- (*itDiff).busConnectionNode[data4 - 1] = std::make_pair(data1, data2);
+ if(data3 == (*itDiff)->id) {
+ (*itDiff)->busConnectionNode[data4 - 1] = std::make_pair(data1, data2);
break;
}
}
} else {
- (*it).busConnectionNode[data2 - 1] = std::make_pair(data3, data4);
+ (*it)->busConnectionNode[data2 - 1] = std::make_pair(data3, data4);
break;
}
}
@@ -501,48 +676,144 @@ bool ParseAnarede::ParsePWFExeCode(wxString data, wxString exeCode)
wxString rest = "";
lineData = data.BeforeFirst('\n', &rest);
data = rest;
- BusData busData;
- if(!GetPWFStructuredData(lineData, 0, 5, busData.id)) return false;
+ BusData* busData = new BusData();
+
+ if(!GetPWFStructuredData(lineData, 0, 5, busData->id)) return false;
wxString isOnlineCode = lineData.Mid(6, 1);
- if(isOnlineCode == "L")
- busData.isOnline = true;
+ if(isOnlineCode == "L" || isOnlineCode == " ")
+ busData->isOnline = true;
else if(isOnlineCode == "D")
- busData.isOnline = false;
+ busData->isOnline = false;
else
return false;
- if(!GetPWFStructuredData(lineData, 7, 1, busData.type)) return false;
- if(!GetPWFStructuredData(lineData, 8, 2, busData.voltageBase)) return false;
- 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;
+ if(!GetPWFStructuredData(lineData, 7, 1, busData->type)) return false;
+ if(!GetPWFStructuredData(lineData, 8, 2, busData->voltageBase)) return false;
+ 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;
double pg, qg;
if(!GetPWFStructuredData(lineData, 32, 5, pg)) return false;
if(!GetPWFStructuredData(lineData, 37, 5, qg)) return false;
- busData.genPower = std::complex<double>(pg, qg);
- if(!GetPWFStructuredData(lineData, 42, 5, busData.minReactivePower)) return false;
- if(!GetPWFStructuredData(lineData, 47, 5, busData.maxReactivePower)) return false;
- if(!GetPWFStructuredData(lineData, 52, 6, busData.ctrlBusID)) return false;
+ busData->genPower = std::complex<double>(pg, qg);
+ if(!GetPWFStructuredData(lineData, 42, 5, busData->minReactivePower)) return false;
+ if(!GetPWFStructuredData(lineData, 47, 5, busData->maxReactivePower)) return false;
+ if(!GetPWFStructuredData(lineData, 52, 6, busData->ctrlBusID)) return false;
double pl, ql;
if(!GetPWFStructuredData(lineData, 58, 5, pl)) return false;
if(!GetPWFStructuredData(lineData, 63, 5, ql)) return false;
- busData.loadPower = std::complex<double>(pl, ql);
- if(!GetPWFStructuredData(lineData, 68, 5, busData.shuntReactive)) return false;
-
- wxMessageBox(wxString::Format("ID = %d\nonline = %d\ntype = %d\nbaseVoltage = %d\nName = \"%s\"\nTensao = "
- "%f\nAngulo = %f\nPg = %f\nQg = %f\nminQ = %f\nmaxQ = %f\nctrlBus = %d\nPl = "
- "%f\nQl = %f\nshuntMVA = %f",
- busData.id, busData.isOnline, busData.type, busData.voltageBase,
- busData.busName, busData.voltage, busData.angle, busData.genPower.real(),
- busData.genPower.imag(), busData.minReactivePower, busData.maxReactivePower,
- busData.ctrlBusID, busData.loadPower.real(), busData.loadPower.imag(),
- busData.shuntReactive));
+ busData->loadPower = std::complex<double>(pl, ql);
+ if(!GetPWFStructuredData(lineData, 68, 5, busData->shuntReactive)) return false;
+
+ m_busData.push_back(busData);
+ }
+ } else if(exeCode == "DLIN") {
+ wxString lineData = "";
+ while(data != "") {
+ wxString rest = "";
+ lineData = data.BeforeFirst('\n', &rest);
+ data = rest;
+ BranchData* branchData = new BranchData();
+
+ if(!GetPWFStructuredData(lineData, 15, 2, branchData->id)) return false;
+ int from, to;
+ if(!GetPWFStructuredData(lineData, 0, 5, from)) return false;
+ if(!GetPWFStructuredData(lineData, 10, 5, to)) return false;
+ branchData->busConnections = std::make_pair(from, to);
+
+ wxString isOnlineCode = lineData.Mid(6, 1) + lineData.Mid(9, 1) + lineData.Mid(17, 1);
+ if(isOnlineCode.Find('D') == wxNOT_FOUND)
+ branchData->isOnline = true;
+ else
+ branchData->isOnline = false;
+ if(!GetPWFStructuredData(lineData, 20, 6, branchData->resistance, 4)) return false;
+ if(!GetPWFStructuredData(lineData, 26, 6, branchData->indReactance, 4)) return false;
+ if(!GetPWFStructuredData(lineData, 32, 6, branchData->capSusceptance, 4)) return false;
+ if(!GetPWFStructuredData(lineData, 38, 5, branchData->tap, 2)) return false;
+ if(!GetPWFStructuredData(lineData, 53, 5, branchData->phaseShift, 3)) return false;
+
+ m_branchData.push_back(branchData);
+ }
+ } else if(exeCode == "DCAI") {
+ wxString lineData = "";
+ while(data != "") {
+ wxString rest = "";
+ lineData = data.BeforeFirst('\n', &rest);
+ data = rest;
+ IndElementData* indData = new IndElementData();
+ ;
+ indData->type = ANA_IND_LOAD;
+
+ if(!GetPWFStructuredData(lineData, 9, 2, indData->id)) return false;
+ if(!GetPWFStructuredData(lineData, 0, 5, indData->busConnection)) return false;
+
+ wxString isOnlineCode = lineData.Mid(13, 1);
+ if(isOnlineCode == "L" || isOnlineCode == " ")
+ indData->isOnline = true;
+ else if(isOnlineCode == "D")
+ indData->isOnline = false;
+ else
+ return false;
+
+ double pl, ql;
+ if(!GetPWFStructuredData(lineData, 22, 5, pl)) return false;
+ if(!GetPWFStructuredData(lineData, 28, 5, ql)) return false;
+ indData->power = std::complex<double>(pl, ql);
+ // Unities in operation
+ if(!GetPWFStructuredData(lineData, 18, 3, indData->numUnits)) return false;
+
+ m_indElementData.push_back(indData);
+ }
+ } else if(exeCode == "DGEI") {
+ wxString lineData = "";
+ while(data != "") {
+ wxString rest = "";
+ lineData = data.BeforeFirst('\n', &rest);
+ data = rest;
+ IndGenData* genData = new IndGenData();
+ genData->type = ANA_IND_GENERATOR;
+
+ if(!GetPWFStructuredData(lineData, 9, 2, genData->id)) return false;
+ if(!GetPWFStructuredData(lineData, 0, 5, genData->busConnection)) return false;
+
+ wxString isOnlineCode = lineData.Mid(12, 1);
+ if(isOnlineCode == "L" || isOnlineCode == " ")
+ genData->isOnline = true;
+ else if(isOnlineCode == "D")
+ genData->isOnline = false;
+ else
+ return false;
+
+ double pg, qg;
+ if(!GetPWFStructuredData(lineData, 22, 5, pg)) return false;
+ if(!GetPWFStructuredData(lineData, 27, 5, qg)) return false;
+ genData->power = std::complex<double>(pg, qg);
+ // Unities in operation
+ if(!GetPWFStructuredData(lineData, 16, 3, genData->numUnits)) return false;
+ if(!GetPWFStructuredData(lineData, 32, 5, genData->minReactivePower)) return false;
+ if(!GetPWFStructuredData(lineData, 37, 5, genData->maxReactivePower)) return false;
+ if(!GetPWFStructuredData(lineData, 42, 6, genData->xt, 2)) return false;
+ if(!GetPWFStructuredData(lineData, 49, 5, genData->xd, 4)) return false;
+ if(!GetPWFStructuredData(lineData, 54, 5, genData->xq, 4)) return false;
+ if(!GetPWFStructuredData(lineData, 59, 5, genData->xl, 4)) return false;
+ if(!GetPWFStructuredData(lineData, 69, 5, genData->ratedPower, 3)) return false;
+
+ m_indElementData.push_back(genData);
}
}
+
return true;
}
-bool ParseAnarede::GetPWFStructuredData(wxString data, int startPos, int dataLenght, int& value, int decimalPos)
+bool ParseAnarede::GetPWFStructuredData(wxString data,
+ unsigned int startPos,
+ unsigned int dataLenght,
+ int& value,
+ int decimalPos)
{
+ if(data.length() < startPos || data.length() < (startPos + dataLenght)) {
+ value = 0;
+ return true;
+ }
wxString strValue = data.Mid(startPos, dataLenght);
strValue.Replace(' ', '0');
long lValue = 0;
@@ -551,11 +822,55 @@ bool ParseAnarede::GetPWFStructuredData(wxString data, int startPos, int dataLen
return true;
}
-bool ParseAnarede::GetPWFStructuredData(wxString data, int startPos, int dataLenght, double& value, int decimalPos)
+bool ParseAnarede::GetPWFStructuredData(wxString data,
+ unsigned int startPos,
+ unsigned int dataLenght,
+ double& value,
+ int decimalPos)
{
+ if(data.length() < startPos || data.length() < (startPos + dataLenght)) {
+ value = 0.0;
+ return true;
+ }
wxString strValue = data.Mid(startPos, dataLenght);
if(strValue.Find('-') == wxNOT_FOUND) strValue.Replace(' ', '0');
- if(decimalPos != -1) strValue.insert(decimalPos, '.');
+ if(decimalPos != -1 && strValue.Find('.') == wxNOT_FOUND) strValue.insert(decimalPos, '.');
if(!strValue.ToCDouble(&value)) return false;
return true;
}
+
+ParseAnarede::BusData* ParseAnarede::GetBusDataFromID(int id)
+{
+ for(auto it = m_busData.begin(), itEnd = m_busData.end(); it != itEnd; ++it) {
+ if((*it)->id == id) return *it;
+ }
+ return NULL;
+}
+
+ParseAnarede::BranchData* ParseAnarede::GetBranchDataFromID(int id, int fromBus, int toBus) { return NULL; }
+
+ParseAnarede::IndElementData* ParseAnarede::GetIndElementDataFromID(int id, int bus) { return NULL; }
+
+void ParseAnarede::ClearData()
+{
+ for(auto it = m_components.begin(), itEnd = m_components.end(); it != itEnd; ++it) {
+ if(*it) delete *it;
+ }
+ m_components.clear();
+ for(auto it = m_lines.begin(), itEnd = m_lines.end(); it != itEnd; ++it) {
+ if(*it) delete *it;
+ }
+ m_lines.clear();
+ for(auto it = m_busData.begin(), itEnd = m_busData.end(); it != itEnd; ++it) {
+ if(*it) delete *it;
+ }
+ m_busData.clear();
+ for(auto it = m_branchData.begin(), itEnd = m_branchData.end(); it != itEnd; ++it) {
+ if(*it) delete *it;
+ }
+ m_branchData.clear();
+ for(auto it = m_indElementData.begin(), itEnd = m_indElementData.end(); it != itEnd; ++it) {
+ if(*it) delete *it;
+ }
+ m_indElementData.clear();
+} \ No newline at end of file