19#include "../../forms/IndMotorForm.h"
23 m_elementType = TYPE_IND_MOTOR;
26IndMotor::IndMotor(wxString name) :
Machines()
28 m_elementType = TYPE_IND_MOTOR;
29 m_electricalData.name = name;
32IndMotor::~IndMotor() {}
45void IndMotor::DrawDCSymbol(wxGraphicsContext* gc)
const
47 std::vector<wxPoint2DDouble> mPts;
48 mPts.push_back(wxPoint2DDouble(-10, 13) + m_position);
49 mPts.push_back(wxPoint2DDouble(-10, -13) + m_position);
50 mPts.push_back(wxPoint2DDouble(0, 2) + m_position);
51 mPts.push_back(wxPoint2DDouble(10, -13) + m_position);
52 mPts.push_back(wxPoint2DDouble(10, 13) + m_position);
53 gc->StrokeLines(mPts.size(), &mPts[0]);
56void IndMotor::DrawDCSymbol(wxDC& dc)
const
59 wxPoint pos = wxPoint((
int)m_position.m_x, (
int)m_position.m_y);
60 mPts[0] = wxPoint(-10, 13) + pos;
61 mPts[1] = wxPoint(-10, -13) + pos;
62 mPts[2] = wxPoint(0, 2) + pos;
63 mPts[3] = wxPoint(10, -13) + pos;
64 mPts[4] = wxPoint(10, 13) + pos;
65 dc.DrawLines(5, mPts);
72 wxMenu* textMenu =
new wxMenu();
74 textMenu->Append(ID_TXT_NAME, _(
"Name"));
75 textMenu->Append(ID_TXT_ACTIVE_POWER, _(
"Active power"));
76 textMenu->Append(ID_TXT_REACTIVE_POWER, _(
"Reactive power"));
77 textMenu->SetClientData(menu.GetClientData());
78 menu.AppendSubMenu(textMenu, _(
"Add text"));
87 indMotorForm.CentreOnParent();
88 if (indMotorForm.ShowModal() == wxID_OK) {
98 data.name = m_electricalData.name;
99 data.activePower = m_electricalData.activePower;
100 data.activePowerUnit = m_electricalData.activePowerUnit;
101 data.reactivePower = m_electricalData.reactivePower;
102 data.reactivePowerUnit = m_electricalData.reactivePowerUnit;
105 switch (data.activePowerUnit) {
107 data.activePower = data.activePower / systemPowerBase;
111 data.activePower = (data.activePower * 1e3) / systemPowerBase;
115 data.activePower = (data.activePower * 1e6) / systemPowerBase;
121 switch (data.reactivePowerUnit) {
123 data.reactivePower = data.reactivePower / systemPowerBase;
127 data.reactivePower = (data.reactivePower * 1e3) / systemPowerBase;
131 data.reactivePower = (data.reactivePower * 1e6) / systemPowerBase;
150 wxString tipText = m_electricalData.name;
152 double activePower = m_electricalData.activePower;
153 if (!m_online) activePower = 0.0;
154 tipText += _(
"\nP = ") + wxString::FromDouble(activePower, 5);
155 switch (m_electricalData.activePowerUnit) {
157 tipText += _(
" p.u.");
171 double reactivePower = m_electricalData.reactivePower;
172 if (!m_online) reactivePower = 0.0;
173 tipText += _(
"\nQ = ") + wxString::FromDouble(reactivePower, 5);
174 switch (m_electricalData.reactivePowerUnit) {
176 tipText += _(
" p.u.");
179 tipText += _(
" var");
182 tipText += _(
" kvar");
185 tipText += _(
" Mvar");
194rapidxml::xml_node<>* IndMotor::SaveElement(rapidxml::xml_document<>& doc, rapidxml::xml_node<>* elementListNode)
196 auto elementNode = XMLParser::AppendNode(doc, elementListNode,
"IndMotor");
197 XMLParser::SetNodeAttribute(doc, elementNode,
"ID", m_elementID);
199 SaveCADProperties(doc, elementNode);
203 auto electricalProp = XMLParser::AppendNode(doc, elementNode,
"ElectricalProperties");
204 auto isOnline = XMLParser::AppendNode(doc, electricalProp,
"IsOnline");
205 XMLParser::SetNodeValue(doc, isOnline, m_online);
206 auto name = XMLParser::AppendNode(doc, electricalProp,
"Name");
207 XMLParser::SetNodeValue(doc, name, m_electricalData.name);
208 auto ratedPower = XMLParser::AppendNode(doc, electricalProp,
"RatedPower");
209 XMLParser::SetNodeValue(doc, ratedPower, m_electricalData.ratedPower);
210 XMLParser::SetNodeAttribute(doc, ratedPower,
"UnitID",
static_cast<int>(m_electricalData.activePowerUnit));
211 auto activePower = XMLParser::AppendNode(doc, electricalProp,
"ActivePower");
212 XMLParser::SetNodeValue(doc, activePower, m_electricalData.activePower);
213 XMLParser::SetNodeAttribute(doc, activePower,
"UnitID",
static_cast<int>(m_electricalData.activePowerUnit));
214 auto reactivePower = XMLParser::AppendNode(doc, electricalProp,
"ReactivePower");
215 XMLParser::SetNodeValue(doc, reactivePower, m_electricalData.reactivePower);
216 XMLParser::SetNodeAttribute(doc, reactivePower,
"UnitID",
static_cast<int>(m_electricalData.reactivePowerUnit));
217 auto useMachineBase = XMLParser::AppendNode(doc, electricalProp,
"UseMachineBase");
218 XMLParser::SetNodeValue(doc, useMachineBase, m_electricalData.useMachinePowerAsBase);
221 auto stability = XMLParser::AppendNode(doc, electricalProp,
"Stability");
222 auto plotMotor = XMLParser::AppendNode(doc, stability,
"PlotIndMachine");
223 XMLParser::SetNodeValue(doc, plotMotor, m_electricalData.plotIndMachine);
224 auto inertia = XMLParser::AppendNode(doc, stability,
"Inertia");
225 XMLParser::SetNodeValue(doc, inertia, m_electricalData.inertia);
226 auto r1 = XMLParser::AppendNode(doc, stability,
"StatorResistence");
227 XMLParser::SetNodeValue(doc, r1, m_electricalData.r1);
228 auto x1 = XMLParser::AppendNode(doc, stability,
"StatorReactance");
229 XMLParser::SetNodeValue(doc, x1, m_electricalData.x1);
230 auto r2 = XMLParser::AppendNode(doc, stability,
"RotorResistence");
231 XMLParser::SetNodeValue(doc, r2, m_electricalData.r2);
232 auto x2 = XMLParser::AppendNode(doc, stability,
"RotorReactance");
233 XMLParser::SetNodeValue(doc, x2, m_electricalData.x2);
234 auto xm = XMLParser::AppendNode(doc, stability,
"MagnetizingReactance");
235 XMLParser::SetNodeValue(doc, xm, m_electricalData.xm);
236 auto useCageFactor = XMLParser::AppendNode(doc, stability,
"UseCageFactor");
237 XMLParser::SetNodeValue(doc, useCageFactor, m_electricalData.useKf);
238 auto cageFactor = XMLParser::AppendNode(doc, stability,
"CageFactor");
239 XMLParser::SetNodeValue(doc, cageFactor, m_electricalData.kf);
240 auto loadChar = XMLParser::AppendNode(doc, stability,
"LoadCharacteristic");
241 auto aw = XMLParser::AppendNode(doc, loadChar,
"Constant");
242 XMLParser::SetNodeValue(doc, aw, m_electricalData.aw);
243 auto bw = XMLParser::AppendNode(doc, loadChar,
"Linear");
244 XMLParser::SetNodeValue(doc, bw, m_electricalData.bw);
245 auto cw = XMLParser::AppendNode(doc, loadChar,
"Quadratic");
246 XMLParser::SetNodeValue(doc, cw, m_electricalData.cw);
248 SaveSwitchingData(doc, electricalProp);
253bool IndMotor::OpenElement(rapidxml::xml_node<>* elementNode, std::vector<Element*> parentList)
255 if (!OpenCADProperties(elementNode, parentList))
return false;
257 auto electricalProp = elementNode->first_node(
"ElectricalProperties");
258 if (!electricalProp)
return false;
261 SetOnline(XMLParser::GetNodeValueInt(electricalProp,
"IsOnline"));
262 m_electricalData.name = electricalProp->first_node(
"Name")->value();
263 m_electricalData.ratedPower = XMLParser::GetNodeValueDouble(electricalProp,
"RatedPower");
264 m_electricalData.ratedPowerUnit =
265 static_cast<ElectricalUnit>(XMLParser::GetAttributeValueInt(electricalProp,
"RatedPower",
"UnitID"));
266 m_electricalData.activePower = XMLParser::GetNodeValueDouble(electricalProp,
"ActivePower");
267 m_electricalData.activePowerUnit =
268 static_cast<ElectricalUnit>(XMLParser::GetAttributeValueInt(electricalProp,
"ActivePower",
"UnitID"));
269 m_electricalData.reactivePower = XMLParser::GetNodeValueDouble(electricalProp,
"ReactivePower");
270 m_electricalData.reactivePowerUnit =
271 static_cast<ElectricalUnit>(XMLParser::GetAttributeValueInt(electricalProp,
"ReactivePower",
"UnitID"));
272 m_electricalData.useMachinePowerAsBase = XMLParser::GetNodeValueInt(electricalProp,
"UseMachineBase");
275 auto stability = electricalProp->first_node(
"Stability");
276 m_electricalData.plotIndMachine = XMLParser::GetNodeValueInt(stability,
"PlotIndMachine");
277 m_electricalData.inertia = XMLParser::GetNodeValueDouble(stability,
"Inertia");
278 m_electricalData.r1 = XMLParser::GetNodeValueDouble(stability,
"StatorResistence");
279 m_electricalData.x1 = XMLParser::GetNodeValueDouble(stability,
"StatorReactance");
280 m_electricalData.r2 = XMLParser::GetNodeValueDouble(stability,
"RotorResistence");
281 m_electricalData.x2 = XMLParser::GetNodeValueDouble(stability,
"RotorReactance");
282 m_electricalData.xm = XMLParser::GetNodeValueDouble(stability,
"MagnetizingReactance");
283 m_electricalData.useKf = XMLParser::GetNodeValueInt(stability,
"UseCageFactor");
284 m_electricalData.kf = XMLParser::GetNodeValueDouble(stability,
"CageFactor");
285 auto loadChar = stability->first_node(
"LoadCharacteristic");
286 m_electricalData.aw = XMLParser::GetNodeValueDouble(loadChar,
"Constant");
287 m_electricalData.bw = XMLParser::GetNodeValueDouble(loadChar,
"Linear");
288 m_electricalData.cw = XMLParser::GetNodeValueDouble(loadChar,
"Quadratic");
290 if (!OpenSwitchingData(electricalProp))
return false;
300 if (!m_electricalData.plotIndMachine)
return false;
301 plotData.SetName(m_electricalData.name);
302 plotData.SetCurveType(ElementPlotData::CurveType::CT_IND_MOTOR);
304 plotData.AddData(m_electricalData.terminalVoltageVector, _(
"Terminal voltage"));
305 plotData.AddData(m_electricalData.activePowerVector, _(
"Active power"));
306 plotData.AddData(m_electricalData.reactivePowerVector, _(
"Reactive power"));
307 plotData.AddData(m_electricalData.currentVector, _(
"Current"));
308 plotData.AddData(m_electricalData.electricalTorqueVector, _(
"Electrical torque"));
309 plotData.AddData(m_electricalData.mechanicalTorqueVector, _(
"Mechanical torque"));
310 plotData.AddData(m_electricalData.velocityVector, _(
"Speed"));
311 plotData.AddData(m_electricalData.slipVector, _(
"Slip"));
315void IndMotor::InitPowerFlowMotor(
double systemPowerBase,
int busNumber)
318 if (m_electricalData.useMachinePowerAsBase) {
319 double oldBase = GetValueFromUnit(m_electricalData.ratedPower, m_electricalData.ratedPowerUnit);
320 k = systemPowerBase / oldBase;
323 m_electricalData.r1t = m_electricalData.r1 * k;
324 m_electricalData.r2t = m_electricalData.r2 * k;
325 m_electricalData.x1t = m_electricalData.x1 * k;
326 m_electricalData.x2t = m_electricalData.x2 * k;
327 m_electricalData.xmt = m_electricalData.xm * k;
329 m_electricalData.xt = m_electricalData.x1t +
330 (m_electricalData.x2t * m_electricalData.xmt) / (m_electricalData.x2t + m_electricalData.xmt);
331 m_electricalData.x0 = m_electricalData.x1t + m_electricalData.xmt;
333 double r1 = m_electricalData.r1t;
334 double r2 = m_electricalData.r2t;
335 if (m_electricalData.useKf) r2 *= (1.0 + m_electricalData.kf * m_electricalData.r2t);
336 double x1 = m_electricalData.x1t;
337 double x2 = m_electricalData.x2t;
338 double xm = m_electricalData.xmt;
339 m_electricalData.k1 = x2 + xm;
340 m_electricalData.k2 = -x1 * m_electricalData.k1 - x2 * xm;
341 m_electricalData.k3 = xm + x1;
342 m_electricalData.k4 = r1 * m_electricalData.k1;
344 auto puData = GetPUElectricalData(systemPowerBase);
345 m_electricalData.p0 = puData.activePower;
346 m_electricalData.busNum = busNumber;
349bool IndMotor::CalculateReactivePower(
double voltage)
351 double a = m_electricalData.p0 *
352 (m_electricalData.r1t * m_electricalData.r1t + m_electricalData.k3 * m_electricalData.k3) -
353 voltage * voltage * m_electricalData.r1t;
354 double b = 2.0 * m_electricalData.p0 *
355 (m_electricalData.r1t * m_electricalData.k2 + m_electricalData.k3 * m_electricalData.k4) -
356 voltage * voltage * (m_electricalData.k2 + m_electricalData.k1 * m_electricalData.k3);
358 m_electricalData.p0 * (m_electricalData.k2 * m_electricalData.k2 + m_electricalData.k4 * m_electricalData.k4) -
359 voltage * voltage * m_electricalData.k1 * m_electricalData.k4;
360 double d = (b * b - 4.0 * a * c);
361 if (d < 0.0)
return false;
362 double r2_s = (-b + std::sqrt(d)) / (2.0 * a);
364 double qa = m_electricalData.k1 * (r2_s * m_electricalData.r1t - m_electricalData.x1t * m_electricalData.k1 -
365 m_electricalData.x2t * m_electricalData.xmt);
367 r2_s * (r2_s * (m_electricalData.xmt + m_electricalData.x1t) + m_electricalData.r1t * m_electricalData.k1);
368 double qc = r2_s * m_electricalData.r1t - m_electricalData.x1t * m_electricalData.k1 -
369 m_electricalData.x2t * m_electricalData.xmt;
370 double qd = r2_s * (m_electricalData.xmt + m_electricalData.x1t) + m_electricalData.r1t * m_electricalData.k1;
371 m_electricalData.qValue = (-voltage * voltage * (qa - qb)) / (qc * qc + qd * qd);
ElectricalUnit
Electrical units.
Base class of all elements of the program. This class is responsible for manage graphical and his dat...
virtual void GeneralMenuItens(wxMenu &menu)
Insert general itens to context menu.
bool SetOnline(bool online=true)
Set if the element is online or offline.
Induction motor power element.
virtual bool GetContextMenu(wxMenu &menu)
Get the element contex menu.
virtual bool ShowForm(wxWindow *parent, Element *element, wxWindow *workspace=nullptr)
Show element data form.
virtual Element * GetCopy()
Get a the element copy.
virtual bool GetPlotData(ElementPlotData &plotData, PlotStudy study=PlotStudy::STABILITY)
Fill the plot data.
virtual wxString GetTipText() const
Get the tip text.
Abstract class for rotary machines power elements.
virtual void SetDynamicEvent(bool dynEvent=true)
Set if the power element have dynamic event.
std::vector< double > swTime