diff options
author | Thales Lima Oliveira <thaleslima.ufu@gmail.com> | 2019-07-13 01:14:14 -0300 |
---|---|---|
committer | Thales Lima Oliveira <thaleslima.ufu@gmail.com> | 2019-07-13 01:14:14 -0300 |
commit | 4d4f39cb101bb0ccb1d336587a9e143b392dbefc (patch) | |
tree | 649c4b6e6425dd25cbabf63b9efe373995485ac1 /Project | |
parent | fed838330b39f69a682b64b1b885fec17ff901d7 (diff) | |
download | PSP.git-4d4f39cb101bb0ccb1d336587a9e143b392dbefc.tar.gz PSP.git-4d4f39cb101bb0ccb1d336587a9e143b392dbefc.tar.xz PSP.git-4d4f39cb101bb0ccb1d336587a9e143b392dbefc.zip |
Multiple motor initialization implemented
Diffstat (limited to 'Project')
-rw-r--r-- | Project/Electromechanical.cpp | 82 | ||||
-rw-r--r-- | Project/ElementForm.wxcp | 276 | ||||
-rw-r--r-- | Project/ElementFormBase.cpp | 31 | ||||
-rw-r--r-- | Project/ElementFormBase.h | 7 | ||||
-rw-r--r-- | Project/IndMotor.cpp | 22 | ||||
-rw-r--r-- | Project/IndMotor.h | 32 | ||||
-rw-r--r-- | Project/IndMotorForm.cpp | 23 | ||||
-rw-r--r-- | Project/IndMotorForm.h | 1 |
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); |