summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorThales Lima Oliveira <thaleslima.ufu@gmail.com>2019-07-13 01:14:14 -0300
committerThales Lima Oliveira <thaleslima.ufu@gmail.com>2019-07-13 01:14:14 -0300
commit4d4f39cb101bb0ccb1d336587a9e143b392dbefc (patch)
tree649c4b6e6425dd25cbabf63b9efe373995485ac1
parentfed838330b39f69a682b64b1b885fec17ff901d7 (diff)
downloadPSP.git-4d4f39cb101bb0ccb1d336587a9e143b392dbefc.tar.gz
PSP.git-4d4f39cb101bb0ccb1d336587a9e143b392dbefc.tar.xz
PSP.git-4d4f39cb101bb0ccb1d336587a9e143b392dbefc.zip
Multiple motor initialization implemented
-rw-r--r--Project/Electromechanical.cpp82
-rw-r--r--Project/ElementForm.wxcp276
-rw-r--r--Project/ElementFormBase.cpp31
-rw-r--r--Project/ElementFormBase.h7
-rw-r--r--Project/IndMotor.cpp22
-rw-r--r--Project/IndMotor.h32
-rw-r--r--Project/IndMotorForm.cpp23
-rw-r--r--Project/IndMotorForm.h1
8 files changed, 415 insertions, 59 deletions
diff --git a/Project/Electromechanical.cpp b/Project/Electromechanical.cpp
index 64fdb9a..bd95fbe 100644
--- a/Project/Electromechanical.cpp
+++ b/Project/Electromechanical.cpp
@@ -788,6 +788,11 @@ bool Electromechanical::InitializeDynamicElements()
data.te = 0.0;
}
+ // Variables to extrapolate.
+ data.oldTe = data.te;
+ data.oldIr = data.ir;
+ data.oldIm = data.im;
+
// Reset plot data
data.slipVector.clear();
data.slipVector.shrink_to_fit();
@@ -799,6 +804,12 @@ bool Electromechanical::InitializeDynamicElements()
data.velocityVector.shrink_to_fit();
data.currentVector.clear();
data.currentVector.shrink_to_fit();
+ data.terminalVoltageVector.clear();
+ data.terminalVoltageVector.shrink_to_fit();
+ data.activePowerVector.clear();
+ data.activePowerVector.shrink_to_fit();
+ data.reactivePowerVector.clear();
+ data.reactivePowerVector.shrink_to_fit();
indMotor->SetElectricalData(data);
}
@@ -1030,28 +1041,26 @@ void Electromechanical::CalculateIntegrationConstants(SyncGenerator* syncGenerat
void Electromechanical::CalculateIntegrationConstants(IndMotor* indMotor, double ir, double im, double k)
{
double w0 = 2.0 * M_PI * m_systemFreq;
- for(auto it = m_indMotorList.begin(), itEnd = m_indMotorList.end(); it != itEnd; ++it) {
- IndMotor* motor = *it;
- auto data = motor->GetElectricalData();
- // Mechanical equations
- // s
- data.icSlip.m = m_timeStep / ((4.0f * data.inertia / w0) / k + data.bs * m_timeStep);
- data.icSlip.c = data.slip * (1.0 - 2.0 * data.bs * data.icSlip.m) +
- data.icSlip.m * (2.0 * data.as + data.cs * data.slip * data.slip - data.te);
-
- // Electrical equations
- // Er
- data.icTranEr.m = m_timeStep / (2.0 * data.t0 + m_timeStep);
- data.icTranEr.c = data.tranEr * (1.0 - 2.0 * data.icTranEr.m) +
- data.icTranEr.m * (w0 * data.t0 * data.slip * data.tranEm - (data.x0 - data.xt) * im);
- // Em
- data.icTranEm.m = m_timeStep / (2.0 * data.t0 + m_timeStep);
- data.icTranEm.c = data.tranEm * (1.0 - 2.0 * data.icTranEm.m) -
- data.icTranEm.m * (w0 * data.t0 * data.slip * data.tranEr - (data.x0 - data.xt) * ir);
+ auto data = indMotor->GetElectricalData();
- motor->SetElectricalData(data);
- }
+ // Mechanical equations
+ // s
+ data.icSlip.m = m_timeStep / ((4.0f * data.inertia / w0) / k + data.bs * m_timeStep);
+ data.icSlip.c = data.slip * (1.0 - 2.0 * data.bs * data.icSlip.m) +
+ data.icSlip.m * (2.0 * data.as + data.cs * data.slip * data.slip - data.te);
+
+ // Electrical equations
+ // Er
+ data.icTranEr.m = m_timeStep / (2.0 * data.t0 + m_timeStep);
+ data.icTranEr.c = data.tranEr * (1.0 - 2.0 * data.icTranEr.m) +
+ data.icTranEr.m * (w0 * data.t0 * data.slip * data.tranEm - (data.x0 - data.xt) * im);
+ // Em
+ data.icTranEm.m = m_timeStep / (2.0 * data.t0 + m_timeStep);
+ data.icTranEm.c = data.tranEm * (1.0 - 2.0 * data.icTranEm.m) -
+ data.icTranEm.m * (w0 * data.t0 * data.slip * data.tranEr - (data.x0 - data.xt) * ir);
+
+ indMotor->SetElectricalData(data);
}
bool Electromechanical::SolveMachines()
@@ -1269,8 +1278,14 @@ void Electromechanical::SaveData()
data.mechanicalTorqueVector.emplace_back(tm);
double w = (1.0 - data.slip) * 2.0 * M_PI * m_systemFreq;
data.velocityVector.emplace_back(w);
- double i1 = std::sqrt(data.ir * data.ir + data.im * data.im);
- data.currentVector.emplace_back(i1);
+ std::complex<double> i1 = std::complex<double>(data.ir, data.im);
+ data.currentVector.emplace_back(std::abs(i1));
+ int n = static_cast<Bus*>(motor->GetParentList()[0])->GetElectricalData().number;
+ std::complex<double> v = m_vBus[n];
+ data.terminalVoltageVector.emplace_back(std::abs(v));
+ std::complex<double> s = v * std::conj(i1);
+ data.activePowerVector.emplace_back(std::real(s));
+ data.reactivePowerVector.emplace_back(std::imag(s));
motor->SetElectricalData(data);
}
}
@@ -1485,7 +1500,7 @@ double Electromechanical::CalculateIntVariables(IndMotor* indMotor, double ir, d
// Mechanical differential equations
// Using Newton method to solve the non-linear slip equation: s = Cs + Ms * (C * s^2 - Te):
- double slip = data.slip; // Initial value. CAN BE THE PROBLEM ON MOTOR START!
+ double slip = 0.0; // Initial value. CAN BE THE PROBLEM ON MOTOR START!
double ds = (data.icSlip.c + data.icSlip.m * (data.cs * slip * slip - te) - slip) /
(1.0 - 2.0 * data.icSlip.m * data.cs * slip * slip);
int iteration = 0;
@@ -1496,21 +1511,22 @@ double Electromechanical::CalculateIntVariables(IndMotor* indMotor, double ir, d
iteration++;
if(iteration > m_maxIterations) break;
}
-
+
if(!indMotor->IsOnline()) slip = 1.0 - 1e-7;
error = std::max(error, std::abs(data.slip - slip));
data.slip = slip;
- // Electrical differential equations
+ // Change T'0 with the cage factor
+ if(data.useKf)
+ data.t0 = (data.x2t + data.xmt) / (2.0 * M_PI * m_systemFreq * data.r2t * (1.0 + data.kf * data.r2t));
+ // Electrical differential equations
double tranEr = data.icTranEr.c + data.icTranEr.m * (w0 * data.t0 * slip * data.tranEm - (data.x0 - data.xt) * im);
error = std::max(error, std::abs(data.tranEr - tranEr));
double tranEm = data.icTranEm.c - data.icTranEm.m * (w0 * data.t0 * slip * data.tranEr - (data.x0 - data.xt) * ir);
error = std::max(error, std::abs(data.tranEm - tranEm));
- // wxMessageBox(wxString::Format("%f\n%f\n\n%f\n%f", data.tranEr, data.tranEm, tranEr, tranEm));
-
data.tranEr = tranEr;
data.tranEm = tranEm;
@@ -1763,6 +1779,8 @@ bool Electromechanical::CalculateIndMachinesTransientValues(IndMotor* motor)
k = m_powerSystemBase / oldBase;
}
+ data.terminalVoltage = static_cast<Bus*>(motor->GetParentList()[0])->GetElectricalData().voltage;
+
// Calculate the induction machine transient constants at the machine base
double r1t = data.r1 * k;
double r2t = data.r2 * k;
@@ -1776,21 +1794,19 @@ bool Electromechanical::CalculateIndMachinesTransientValues(IndMotor* motor)
data.xmt = xmt;
double xt = x1t + (x2t * xmt) / (x2t + xmt);
- double t0 = (x2t + xmt) / (2.0 * M_PI * m_systemFreq * r2t);
double x0 = x1t + xmt;
data.xt = xt;
- data.t0 = t0;
data.x0 = x0;
- data.terminalVoltage = static_cast<Bus*>(motor->GetParentList()[0])->GetElectricalData().voltage;
-
- //[Ref.] Induction Motor Static Models for Power Flow and Voltage Stability Studies
double p = dataPU.activePower;
double v = std::abs(data.terminalVoltage);
+
+ //[Ref.] Induction Motor Static Models for Power Flow and Voltage Stability Studies
// If the motor is offline, calculate the nominal slip to user-defined power input and 1.0 p.u. voltage
if(!motor->IsOnline()) v = 1.0;
double r1 = data.r1t;
double r2 = data.r2t;
+ if(data.useKf) r2 *= (1.0 + data.kf * r2t);
double x1 = data.x1t;
double x2 = data.x2t;
double xm = data.xmt;
@@ -1815,6 +1831,8 @@ bool Electromechanical::CalculateIndMachinesTransientValues(IndMotor* motor)
double qd = r2_s * (xm + x1) + r1 * k1;
data.q0 = (-v * v * (qa - qb)) / (qc * qc + qd * qd);
+ data.t0 = (x2t + xmt) / (2.0 * M_PI * m_systemFreq * r2);
+
motor->SetElectricalData(data);
return true;
}
diff --git a/Project/ElementForm.wxcp b/Project/ElementForm.wxcp
index fa20d40..db8b092 100644
--- a/Project/ElementForm.wxcp
+++ b/Project/ElementForm.wxcp
@@ -1,7 +1,7 @@
{
"metadata": {
"m_generatedFilesDir": ".",
- "m_objCounter": 2177,
+ "m_objCounter": 2190,
"m_includeFiles": [],
"m_bitmapFunction": "wxC9EE9InitBitmapResources",
"m_bitmapsFile": "ElementFormBitmaps.cpp",
@@ -30022,6 +30022,81 @@
}],
"m_events": [],
"m_children": [{
+ "m_type": 4415,
+ "proportion": 0,
+ "border": 5,
+ "gbSpan": "1,1",
+ "gbPosition": "0,0",
+ "m_styles": [],
+ "m_sizerFlags": ["wxALL", "wxLEFT", "wxRIGHT", "wxTOP", "wxBOTTOM", "wxALIGN_CENTER_VERTICAL"],
+ "m_properties": [{
+ "type": "winid",
+ "m_label": "ID:",
+ "m_winid": "wxID_ANY"
+ }, {
+ "type": "string",
+ "m_label": "Size:",
+ "m_value": "-1,-1"
+ }, {
+ "type": "string",
+ "m_label": "Minimum Size:",
+ "m_value": "-1,-1"
+ }, {
+ "type": "string",
+ "m_label": "Name:",
+ "m_value": "m_checkBoxPlotIndMachine"
+ }, {
+ "type": "multi-string",
+ "m_label": "Tooltip:",
+ "m_value": ""
+ }, {
+ "type": "colour",
+ "m_label": "Bg Colour:",
+ "colour": "<Default>"
+ }, {
+ "type": "colour",
+ "m_label": "Fg Colour:",
+ "colour": "<Default>"
+ }, {
+ "type": "font",
+ "m_label": "Font:",
+ "m_value": ""
+ }, {
+ "type": "bool",
+ "m_label": "Hidden",
+ "m_value": false
+ }, {
+ "type": "bool",
+ "m_label": "Disabled",
+ "m_value": false
+ }, {
+ "type": "bool",
+ "m_label": "Focused",
+ "m_value": false
+ }, {
+ "type": "string",
+ "m_label": "Class Name:",
+ "m_value": ""
+ }, {
+ "type": "string",
+ "m_label": "Include File:",
+ "m_value": ""
+ }, {
+ "type": "string",
+ "m_label": "Style:",
+ "m_value": ""
+ }, {
+ "type": "string",
+ "m_label": "Label:",
+ "m_value": "Plot induction machine data"
+ }, {
+ "type": "bool",
+ "m_label": "Value:",
+ "m_value": false
+ }],
+ "m_events": [],
+ "m_children": []
+ }, {
"m_type": 4452,
"proportion": 0,
"border": 5,
@@ -31836,6 +31911,203 @@
"m_children": []
}]
}]
+ }, {
+ "m_type": 4401,
+ "proportion": 0,
+ "border": 5,
+ "gbSpan": "1,1",
+ "gbPosition": "0,0",
+ "m_styles": [],
+ "m_sizerFlags": ["wxEXPAND"],
+ "m_properties": [{
+ "type": "string",
+ "m_label": "Minimum Size:",
+ "m_value": "-1,-1"
+ }, {
+ "type": "string",
+ "m_label": "Name:",
+ "m_value": "boxSizerLvl4_9"
+ }, {
+ "type": "string",
+ "m_label": "Style:",
+ "m_value": ""
+ }, {
+ "type": "choice",
+ "m_label": "Orientation:",
+ "m_selection": 0,
+ "m_options": ["wxVERTICAL", "wxHORIZONTAL"]
+ }],
+ "m_events": [],
+ "m_children": [{
+ "m_type": 4415,
+ "proportion": 0,
+ "border": 5,
+ "gbSpan": "1,1",
+ "gbPosition": "0,0",
+ "m_styles": [],
+ "m_sizerFlags": ["wxLEFT", "wxRIGHT", "wxTOP", "wxALIGN_CENTER_VERTICAL"],
+ "m_properties": [{
+ "type": "winid",
+ "m_label": "ID:",
+ "m_winid": "wxID_ANY"
+ }, {
+ "type": "string",
+ "m_label": "Size:",
+ "m_value": "-1,-1"
+ }, {
+ "type": "string",
+ "m_label": "Minimum Size:",
+ "m_value": "-1,-1"
+ }, {
+ "type": "string",
+ "m_label": "Name:",
+ "m_value": "m_checkBoxUseKf"
+ }, {
+ "type": "multi-string",
+ "m_label": "Tooltip:",
+ "m_value": ""
+ }, {
+ "type": "colour",
+ "m_label": "Bg Colour:",
+ "colour": "<Default>"
+ }, {
+ "type": "colour",
+ "m_label": "Fg Colour:",
+ "colour": "<Default>"
+ }, {
+ "type": "font",
+ "m_label": "Font:",
+ "m_value": ""
+ }, {
+ "type": "bool",
+ "m_label": "Hidden",
+ "m_value": false
+ }, {
+ "type": "bool",
+ "m_label": "Disabled",
+ "m_value": false
+ }, {
+ "type": "bool",
+ "m_label": "Focused",
+ "m_value": false
+ }, {
+ "type": "string",
+ "m_label": "Class Name:",
+ "m_value": ""
+ }, {
+ "type": "string",
+ "m_label": "Include File:",
+ "m_value": ""
+ }, {
+ "type": "string",
+ "m_label": "Style:",
+ "m_value": ""
+ }, {
+ "type": "string",
+ "m_label": "Label:",
+ "m_value": "Use cage factor"
+ }, {
+ "type": "bool",
+ "m_label": "Value:",
+ "m_value": false
+ }],
+ "m_events": [{
+ "m_eventName": "wxEVT_COMMAND_CHECKBOX_CLICKED",
+ "m_eventClass": "wxCommandEvent",
+ "m_eventHandler": "wxCommandEventHandler",
+ "m_functionNameAndSignature": "OnCheckboxUseCageFactorClick(wxCommandEvent& event)",
+ "m_description": "Process a wxEVT_COMMAND_CHECKBOX_CLICKED event, when the checkbox is clicked.",
+ "m_noBody": false
+ }],
+ "m_children": []
+ }, {
+ "m_type": 4406,
+ "proportion": 1,
+ "border": 5,
+ "gbSpan": "1,1",
+ "gbPosition": "0,0",
+ "m_styles": [],
+ "m_sizerFlags": ["wxLEFT", "wxRIGHT", "wxBOTTOM", "wxEXPAND", "wxALIGN_CENTER_VERTICAL"],
+ "m_properties": [{
+ "type": "winid",
+ "m_label": "ID:",
+ "m_winid": "wxID_ANY"
+ }, {
+ "type": "string",
+ "m_label": "Size:",
+ "m_value": "-1,-1"
+ }, {
+ "type": "string",
+ "m_label": "Minimum Size:",
+ "m_value": "-1,-1"
+ }, {
+ "type": "string",
+ "m_label": "Name:",
+ "m_value": "m_textCtrlKf"
+ }, {
+ "type": "multi-string",
+ "m_label": "Tooltip:",
+ "m_value": ""
+ }, {
+ "type": "colour",
+ "m_label": "Bg Colour:",
+ "colour": "<Default>"
+ }, {
+ "type": "colour",
+ "m_label": "Fg Colour:",
+ "colour": "<Default>"
+ }, {
+ "type": "font",
+ "m_label": "Font:",
+ "m_value": ""
+ }, {
+ "type": "bool",
+ "m_label": "Hidden",
+ "m_value": false
+ }, {
+ "type": "bool",
+ "m_label": "Disabled",
+ "m_value": false
+ }, {
+ "type": "bool",
+ "m_label": "Focused",
+ "m_value": false
+ }, {
+ "type": "string",
+ "m_label": "Class Name:",
+ "m_value": ""
+ }, {
+ "type": "string",
+ "m_label": "Include File:",
+ "m_value": ""
+ }, {
+ "type": "string",
+ "m_label": "Style:",
+ "m_value": ""
+ }, {
+ "type": "string",
+ "m_label": "Value:",
+ "m_value": ""
+ }, {
+ "type": "string",
+ "m_label": "Text Hint",
+ "m_value": ""
+ }, {
+ "type": "string",
+ "m_label": "Max Length:",
+ "m_value": "0"
+ }, {
+ "type": "bool",
+ "m_label": "Auto Complete Directories:",
+ "m_value": false
+ }, {
+ "type": "bool",
+ "m_label": "Auto Complete Files:",
+ "m_value": false
+ }],
+ "m_events": [],
+ "m_children": []
+ }]
}]
}, {
"m_type": 4401,
@@ -31946,7 +32218,7 @@
"gbSpan": "1,1",
"gbPosition": "0,0",
"m_styles": [],
- "m_sizerFlags": ["wxALL", "wxLEFT", "wxRIGHT", "wxTOP", "wxBOTTOM", "wxEXPAND"],
+ "m_sizerFlags": ["wxEXPAND"],
"m_properties": [{
"type": "string",
"m_label": "Minimum Size:",
diff --git a/Project/ElementFormBase.cpp b/Project/ElementFormBase.cpp
index 4429b1c..6a75ec7 100644
--- a/Project/ElementFormBase.cpp
+++ b/Project/ElementFormBase.cpp
@@ -3200,6 +3200,12 @@ IndMotorFormBase::IndMotorFormBase(wxWindow* parent,
wxBoxSizer* boxSizerLvl2_2 = new wxBoxSizer(wxVERTICAL);
m_panelStability->SetSizer(boxSizerLvl2_2);
+ m_checkBoxPlotIndMachine = new wxCheckBox(m_panelStability, wxID_ANY, _("Plot induction machine data"),
+ wxDefaultPosition, wxDLG_UNIT(m_panelStability, wxSize(-1, -1)), 0);
+ m_checkBoxPlotIndMachine->SetValue(false);
+
+ boxSizerLvl2_2->Add(m_checkBoxPlotIndMachine, 0, wxALL | wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
+
wxGridSizer* gridSizerLvl3_2 = new wxGridSizer(0, 2, 0, 0);
boxSizerLvl2_2->Add(gridSizerLvl3_2, 0, wxEXPAND, WXC_FROM_DIP(5));
@@ -3373,6 +3379,25 @@ IndMotorFormBase::IndMotorFormBase(wxWindow* parent,
boxSizerLvl5_8->Add(m_staticTextPU_5, 0, wxRIGHT | wxBOTTOM | wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
+ wxBoxSizer* boxSizerLvl4_9 = new wxBoxSizer(wxVERTICAL);
+
+ gridSizerLvl3_2->Add(boxSizerLvl4_9, 0, wxEXPAND, WXC_FROM_DIP(5));
+
+ m_checkBoxUseKf = new wxCheckBox(m_panelStability, wxID_ANY, _("Use cage factor"), wxDefaultPosition,
+ wxDLG_UNIT(m_panelStability, wxSize(-1, -1)), 0);
+ m_checkBoxUseKf->SetValue(false);
+
+ boxSizerLvl4_9->Add(m_checkBoxUseKf, 0, wxLEFT | wxRIGHT | wxTOP | wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
+
+ m_textCtrlKf = new wxTextCtrl(m_panelStability, wxID_ANY, wxT(""), wxDefaultPosition,
+ wxDLG_UNIT(m_panelStability, wxSize(-1, -1)), 0);
+#if wxVERSION_NUMBER >= 3000
+ m_textCtrlKf->SetHint(wxT(""));
+#endif
+
+ boxSizerLvl4_9->Add(m_textCtrlKf, 1, wxLEFT | wxRIGHT | wxBOTTOM | wxEXPAND | wxALIGN_CENTER_VERTICAL,
+ WXC_FROM_DIP(5));
+
wxBoxSizer* boxSizerLvl3_3 = new wxBoxSizer(wxVERTICAL);
boxSizerLvl2_2->Add(boxSizerLvl3_3, 0, wxEXPAND, WXC_FROM_DIP(5));
@@ -3386,7 +3411,7 @@ IndMotorFormBase::IndMotorFormBase(wxWindow* parent,
wxGridSizer* gridSizerLvl4_8 = new wxGridSizer(0, 3, 0, 0);
- boxSizerLvl3_3->Add(gridSizerLvl4_8, 1, wxALL | wxEXPAND, WXC_FROM_DIP(5));
+ boxSizerLvl3_3->Add(gridSizerLvl4_8, 1, wxEXPAND, WXC_FROM_DIP(5));
wxBoxSizer* boxSizerLvl5_9 = new wxBoxSizer(wxHORIZONTAL);
@@ -3485,6 +3510,8 @@ IndMotorFormBase::IndMotorFormBase(wxWindow* parent,
}
#endif
// Connect events
+ m_checkBoxUseKf->Connect(wxEVT_COMMAND_CHECKBOX_CLICKED,
+ wxCommandEventHandler(IndMotorFormBase::OnCheckboxUseCageFactorClick), NULL, this);
m_buttonSwitchingButton->Connect(wxEVT_COMMAND_BUTTON_CLICKED,
wxCommandEventHandler(IndMotorFormBase::OnStabilityButtonClick), NULL, this);
m_buttonOK->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(IndMotorFormBase::OnOKButtonClick), NULL,
@@ -3495,6 +3522,8 @@ IndMotorFormBase::IndMotorFormBase(wxWindow* parent,
IndMotorFormBase::~IndMotorFormBase()
{
+ m_checkBoxUseKf->Disconnect(wxEVT_COMMAND_CHECKBOX_CLICKED,
+ wxCommandEventHandler(IndMotorFormBase::OnCheckboxUseCageFactorClick), NULL, this);
m_buttonSwitchingButton->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED,
wxCommandEventHandler(IndMotorFormBase::OnStabilityButtonClick), NULL, this);
m_buttonOK->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(IndMotorFormBase::OnOKButtonClick), NULL,
diff --git a/Project/ElementFormBase.h b/Project/ElementFormBase.h
index fbfa746..734681c 100644
--- a/Project/ElementFormBase.h
+++ b/Project/ElementFormBase.h
@@ -773,6 +773,7 @@ class IndMotorFormBase : public wxDialog
wxChoice* m_choiceReactivePower;
wxCheckBox* m_checkBoxUseMachinePower;
wxPanel* m_panelStability;
+ wxCheckBox* m_checkBoxPlotIndMachine;
wxStaticText* m_staticTextInertia;
wxTextCtrl* m_textCtrlInertia;
wxStaticText* m_staticTextS_1;
@@ -791,6 +792,8 @@ class IndMotorFormBase : public wxDialog
wxStaticText* m_staticTextMagnetizingReactance;
wxTextCtrl* m_textCtrlMagnetizingReactance;
wxStaticText* m_staticTextPU_5;
+ wxCheckBox* m_checkBoxUseKf;
+ wxTextCtrl* m_textCtrlKf;
wxStaticText* m_staticTextLoadCharacteristic;
wxTextCtrl* m_textCtrlA;
wxStaticText* m_staticTextPlus;
@@ -803,6 +806,7 @@ class IndMotorFormBase : public wxDialog
wxButton* m_ButtonCancel;
protected:
+ virtual void OnCheckboxUseCageFactorClick(wxCommandEvent& event) { event.Skip(); }
virtual void OnStabilityButtonClick(wxCommandEvent& event) { event.Skip(); }
virtual void OnOKButtonClick(wxCommandEvent& event) { event.Skip(); }
virtual void OnCancelButtonClick(wxCommandEvent& event) { event.Skip(); }
@@ -821,6 +825,7 @@ class IndMotorFormBase : public wxDialog
wxChoice* GetChoiceReactivePower() { return m_choiceReactivePower; }
wxCheckBox* GetCheckBoxUseMachinePower() { return m_checkBoxUseMachinePower; }
wxPanel* GetPanelGeneral() { return m_panelGeneral; }
+ wxCheckBox* GetCheckBoxPlotIndMachine() { return m_checkBoxPlotIndMachine; }
wxStaticText* GetStaticTextInertia() { return m_staticTextInertia; }
wxTextCtrl* GetTextCtrlInertia() { return m_textCtrlInertia; }
wxStaticText* GetStaticTextS_1() { return m_staticTextS_1; }
@@ -839,6 +844,8 @@ class IndMotorFormBase : public wxDialog
wxStaticText* GetStaticTextMagnetizingReactance() { return m_staticTextMagnetizingReactance; }
wxTextCtrl* GetTextCtrlMagnetizingReactance() { return m_textCtrlMagnetizingReactance; }
wxStaticText* GetStaticTextPU_5() { return m_staticTextPU_5; }
+ wxCheckBox* GetCheckBoxUseKf() { return m_checkBoxUseKf; }
+ wxTextCtrl* GetTextCtrlKf() { return m_textCtrlKf; }
wxStaticText* GetStaticTextLoadCharacteristic() { return m_staticTextLoadCharacteristic; }
wxTextCtrl* GetTextCtrlA() { return m_textCtrlA; }
wxStaticText* GetStaticTextPlus() { return m_staticTextPlus; }
diff --git a/Project/IndMotor.cpp b/Project/IndMotor.cpp
index 8d84608..13e9b4d 100644
--- a/Project/IndMotor.cpp
+++ b/Project/IndMotor.cpp
@@ -171,6 +171,8 @@ rapidxml::xml_node<>* IndMotor::SaveElement(rapidxml::xml_document<>& doc, rapid
// Stability
auto stability = XMLParser::AppendNode(doc, electricalProp, "Stability");
+ auto plotMotor = XMLParser::AppendNode(doc, stability, "PlotIndMachine");
+ XMLParser::SetNodeValue(doc, plotMotor, m_electricalData.plotIndMachine);
auto inertia = XMLParser::AppendNode(doc, stability, "Inertia");
XMLParser::SetNodeValue(doc, inertia, m_electricalData.inertia);
auto r1 = XMLParser::AppendNode(doc, stability, "StatorResistence");
@@ -183,6 +185,10 @@ rapidxml::xml_node<>* IndMotor::SaveElement(rapidxml::xml_document<>& doc, rapid
XMLParser::SetNodeValue(doc, x2, m_electricalData.x2);
auto xm = XMLParser::AppendNode(doc, stability, "MagnetizingReactance");
XMLParser::SetNodeValue(doc, xm, m_electricalData.xm);
+ auto useCageFactor = XMLParser::AppendNode(doc, stability, "UseCageFactor");
+ XMLParser::SetNodeValue(doc, useCageFactor, m_electricalData.useKf);
+ auto cageFactor = XMLParser::AppendNode(doc, stability, "CageFactor");
+ XMLParser::SetNodeValue(doc, cageFactor, m_electricalData.kf);
auto loadChar = XMLParser::AppendNode(doc, stability, "LoadCharacteristic");
auto aw = XMLParser::AppendNode(doc, loadChar, "Constant");
XMLParser::SetNodeValue(doc, aw, m_electricalData.aw);
@@ -219,17 +225,20 @@ bool IndMotor::OpenElement(rapidxml::xml_node<>* elementNode, std::vector<Elemen
// Stability
auto stability = electricalProp->first_node("Stability");
- m_electricalData.inertia = XMLParser::GetNodeValueDouble(stability, "Inertia");
+ m_electricalData.plotIndMachine = XMLParser::GetNodeValueInt(stability, "Inertia");
+ m_electricalData.inertia = XMLParser::GetNodeValueDouble(stability, "PlotIndMachine");
m_electricalData.r1 = XMLParser::GetNodeValueDouble(stability, "StatorResistence");
m_electricalData.x1 = XMLParser::GetNodeValueDouble(stability, "StatorReactance");
m_electricalData.r2 = XMLParser::GetNodeValueDouble(stability, "RotorResistence");
m_electricalData.x2 = XMLParser::GetNodeValueDouble(stability, "RotorReactance");
m_electricalData.xm = XMLParser::GetNodeValueDouble(stability, "MagnetizingReactance");
+ m_electricalData.useKf = XMLParser::GetNodeValueInt(stability, "UseCageFactor");
+ m_electricalData.kf = XMLParser::GetNodeValueDouble(stability, "CageFactor");
auto loadChar = stability->first_node("LoadCharacteristic");
m_electricalData.aw = XMLParser::GetNodeValueDouble(loadChar, "Constant");
m_electricalData.bw = XMLParser::GetNodeValueDouble(loadChar, "Linear");
m_electricalData.cw = XMLParser::GetNodeValueDouble(loadChar, "Quadratic");
-
+
if(!OpenSwitchingData(electricalProp)) return false;
if(m_swData.swTime.size() != 0) SetDynamicEvent(true);
@@ -244,10 +253,13 @@ bool IndMotor::GetPlotData(ElementPlotData& plotData, PlotStudy study)
plotData.SetName(m_electricalData.name);
plotData.SetCurveType(ElementPlotData::CT_IND_MOTOR);
- plotData.AddData(m_electricalData.slipVector, _("Slip"));
+ plotData.AddData(m_electricalData.terminalVoltageVector, _("Terminal voltage"));
+ plotData.AddData(m_electricalData.activePowerVector, _("Active power"));
+ plotData.AddData(m_electricalData.reactivePowerVector, _("Reactive power"));
+ plotData.AddData(m_electricalData.currentVector, _("Current"));
plotData.AddData(m_electricalData.electricalTorqueVector, _("Electrical torque"));
plotData.AddData(m_electricalData.mechanicalTorqueVector, _("Mechanical torque"));
- plotData.AddData(m_electricalData.velocityVector, _("Velocity"));
- plotData.AddData(m_electricalData.currentVector, _("Current"));
+ plotData.AddData(m_electricalData.velocityVector, _("Speed"));
+ plotData.AddData(m_electricalData.slipVector, _("Slip"));
return true;
}
diff --git a/Project/IndMotor.h b/Project/IndMotor.h
index 4137e6f..760a65a 100644
--- a/Project/IndMotor.h
+++ b/Project/IndMotor.h
@@ -34,7 +34,7 @@ struct IndMotorElectricalData {
bool useMachinePowerAsBase = true;
// Stability
- bool plotIndMachine = true;
+ bool plotIndMachine = false;
double inertia = 1.0; // Motor and load inertia
double s0; // Initial slip
double q0; // Initial reactive power
@@ -43,15 +43,17 @@ struct IndMotorElectricalData {
double r2 = 1.0; // Rotor resistence data
double x2 = 0.0; // Rotor reactance data
double xm = 100.0; // Magnetizing reactance data
+ double kf = 0.0; // Cage factor
+ bool useKf = false;
// Transient values
double xt = 1.0; // Transient reactance
double x0 = 1.0; // Open-circuit reactance
double r1t = 0.0; // Stator resistence in system power base
- double x1t = 1.0; // Stator reactance in system power base
- double r2t = 1.0; // Rotor resistence in system power base
- double x2t = 0.0; // Rotor reactance in system power base
- double xmt = 100.0; // Magnetizing reactance in system power base
+ double x1t = 1.0; // Stator reactance in system power base
+ double r2t = 1.0; // Rotor resistence in system power base
+ double x2t = 0.0; // Rotor reactance in system power base
+ double xmt = 100.0; // Magnetizing reactance in system power base
double t0 = 1.0; // Open-circuit time constant
@@ -63,15 +65,15 @@ struct IndMotorElectricalData {
double cs = 0.0; // Slip quadratic dependent torque
// Internal machine variables
- double tranEr;
- double tranEm;
- double ir;
- double im;
+ double tranEr = 0.0;
+ double tranEm = 0.0;
+ double ir = 0.0;
+ double im = 0.0;
// Variables to extrapolate
- double oldIr;
- double oldIm;
- double oldTe;
+ double oldIr = 0.0;
+ double oldIm = 0.0;
+ double oldTe = 0.0;
// Integration constants
IntegrationConstant icSlip;
@@ -88,8 +90,8 @@ struct IndMotorElectricalData {
std::vector<double> mechanicalTorqueVector;
std::vector<double> velocityVector;
std::vector<double> currentVector;
- std::complex<double> electricalPower;
- std::vector<std::complex<double> > electricalPowerVector;
+ std::vector<double> activePowerVector;
+ std::vector<double> reactivePowerVector;
};
/**
@@ -114,7 +116,7 @@ class IndMotor : public Machines
virtual IndMotorElectricalData GetElectricalData() { return m_electricalData; }
virtual IndMotorElectricalData GetPUElectricalData(double systemPowerBase);
virtual void SetElectricalData(IndMotorElectricalData electricalData) { m_electricalData = electricalData; }
-
+
virtual bool GetPlotData(ElementPlotData& plotData, PlotStudy study = STABILITY);
virtual rapidxml::xml_node<>* SaveElement(rapidxml::xml_document<>& doc, rapidxml::xml_node<>* elementListNode);
diff --git a/Project/IndMotorForm.cpp b/Project/IndMotorForm.cpp
index 5b91f0a..6df1684 100644
--- a/Project/IndMotorForm.cpp
+++ b/Project/IndMotorForm.cpp
@@ -82,12 +82,16 @@ IndMotorForm::IndMotorForm(wxWindow* parent, IndMotor* indMotor) : IndMotorFormB
m_checkBoxUseMachinePower->SetValue(data.useMachinePowerAsBase);
// Stability
+ m_checkBoxPlotIndMachine->SetValue(data.plotIndMachine);
m_textCtrlInertia->SetValue(IndMotor::StringFromDouble(data.inertia));
m_textCtrlStatorResistence->SetValue(IndMotor::StringFromDouble(data.r1));
m_textCtrlStatorReactance->SetValue(IndMotor::StringFromDouble(data.x1));
m_textCtrlRotorResistence->SetValue(IndMotor::StringFromDouble(data.r2));
m_textCtrlRotorReactance->SetValue(IndMotor::StringFromDouble(data.x2));
m_textCtrlMagnetizingReactance->SetValue(IndMotor::StringFromDouble(data.xm));
+ m_checkBoxUseKf->SetValue(data.useKf);
+ m_textCtrlKf->SetValue(IndMotor::StringFromDouble(data.kf));
+ m_textCtrlKf->Enable(data.useKf);
m_textCtrlA->SetValue(IndMotor::StringFromDouble(data.aw));
m_textCtrlB->SetValue(IndMotor::StringFromDouble(data.bw));
@@ -172,6 +176,7 @@ bool IndMotorForm::ValidateData()
data.useMachinePowerAsBase = m_checkBoxUseMachinePower->GetValue();
// Stability
+ data.plotIndMachine = m_checkBoxPlotIndMachine->GetValue();
if(!m_indMotor->DoubleFromString(m_parent, m_textCtrlInertia->GetValue(), data.inertia,
_("Value entered incorrectly in the field \"Inertia\".")))
return false;
@@ -190,6 +195,10 @@ bool IndMotorForm::ValidateData()
if(!m_indMotor->DoubleFromString(m_parent, m_textCtrlMagnetizingReactance->GetValue(), data.xm,
_("Value entered incorrectly in the field \"Magnetizing reactance\".")))
return false;
+ data.useKf = m_checkBoxUseKf->GetValue();
+ if(!m_indMotor->DoubleFromString(m_parent, m_textCtrlKf->GetValue(), data.kf,
+ _("Value entered incorrectly in the field \"Cage factor\".")))
+ return false;
if(!m_indMotor->DoubleFromString(m_parent, m_textCtrlA->GetValue(), data.aw,
_("Value entered incorrectly in the field \"Constant torque\".")))
@@ -201,14 +210,20 @@ bool IndMotorForm::ValidateData()
_("Value entered incorrectly in the field \"Quadratic torque\".")))
return false;
- /*double sum = data.aw + data.bw + data.cw;
- if(sum > 1.01 || sum < 0.99) {
- wxString errorMsg = _("The sum of the portions of the torque must be unitary");
+ double sum = data.aw + data.bw + data.cw;
+ double tolerance = 1e-4;
+ if(sum > (1.0 + tolerance) || sum < (1.0 - tolerance)) {
+ wxString errorMsg = _("The sum of the torque portions must be unitary.\nThe current value is ") +
+ m_indMotor->StringFromDouble(sum);
wxMessageDialog msgDialog(m_parent, errorMsg, _("Error"), wxOK | wxCENTRE | wxICON_ERROR);
msgDialog.ShowModal();
return false;
- }*/
+ }
m_indMotor->SetElectricalData(data);
return true;
}
+void IndMotorForm::OnCheckboxUseCageFactorClick(wxCommandEvent& event)
+{
+ m_textCtrlKf->Enable(m_checkBoxUseKf->GetValue());
+}
diff --git a/Project/IndMotorForm.h b/Project/IndMotorForm.h
index e221a8b..5a476a6 100644
--- a/Project/IndMotorForm.h
+++ b/Project/IndMotorForm.h
@@ -36,6 +36,7 @@ class IndMotorForm : public IndMotorFormBase
virtual bool ValidateData();
protected:
+ virtual void OnCheckboxUseCageFactorClick(wxCommandEvent& event);
virtual void OnCancelButtonClick(wxCommandEvent& event) { EndModal(wxID_CANCEL); };
virtual void OnOKButtonClick(wxCommandEvent& event);
virtual void OnStabilityButtonClick(wxCommandEvent& event);