summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorThales Lima Oliveira <thaleslima.ufu@gmail.com>2018-04-04 21:31:28 -0300
committerThales Lima Oliveira <thaleslima.ufu@gmail.com>2018-04-04 21:31:28 -0300
commit54b3719953815bd6a2648bb6dac662f513d80fca (patch)
tree10a68f1c0ae1911a50a2cdc922a43dac58290208
parentaef98fb30666fd86cbbafc8bd748e4815d3c819b (diff)
downloadPSP.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.cpp60
-rw-r--r--Project/ImportForm.h14
-rw-r--r--Project/PowerFlow.cpp6
-rw-r--r--Project/Project.mk2
-rw-r--r--Project/PropertiesData.h1
-rw-r--r--Project/Workspace.cpp102
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()) {