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 switch (data.activePowerUnit) {
100 data.activePower = data.activePower / systemPowerBase;
104 data.activePower = (data.activePower * 1e3) / systemPowerBase;
108 data.activePower = (data.activePower * 1e6) / systemPowerBase;
114 switch (data.reactivePowerUnit) {
116 data.reactivePower = data.reactivePower / systemPowerBase;
120 data.reactivePower = (data.reactivePower * 1e3) / systemPowerBase;
124 data.reactivePower = (data.reactivePower * 1e6) / systemPowerBase;
143 wxString tipText = m_electricalData.name;
145 double activePower = m_electricalData.activePower;
146 if (!m_online) activePower = 0.0;
147 tipText += _(
"\nP = ") + wxString::FromDouble(activePower, 5);
148 switch (m_electricalData.activePowerUnit) {
150 tipText += _(
" p.u.");
164 double reactivePower = m_electricalData.reactivePower;
165 if (!m_online) reactivePower = 0.0;
166 tipText += _(
"\nQ = ") + wxString::FromDouble(reactivePower, 5);
167 switch (m_electricalData.reactivePowerUnit) {
169 tipText += _(
" p.u.");
172 tipText += _(
" var");
175 tipText += _(
" kvar");
178 tipText += _(
" Mvar");
187rapidxml::xml_node<>* IndMotor::SaveElement(rapidxml::xml_document<>& doc, rapidxml::xml_node<>* elementListNode)
189 auto elementNode = XMLParser::AppendNode(doc, elementListNode,
"IndMotor");
190 XMLParser::SetNodeAttribute(doc, elementNode,
"ID", m_elementID);
192 SaveCADProperties(doc, elementNode);
196 auto electricalProp = XMLParser::AppendNode(doc, elementNode,
"ElectricalProperties");
197 auto isOnline = XMLParser::AppendNode(doc, electricalProp,
"IsOnline");
198 XMLParser::SetNodeValue(doc, isOnline, m_online);
199 auto name = XMLParser::AppendNode(doc, electricalProp,
"Name");
200 XMLParser::SetNodeValue(doc, name, m_electricalData.name);
201 auto ratedPower = XMLParser::AppendNode(doc, electricalProp,
"RatedPower");
202 XMLParser::SetNodeValue(doc, ratedPower, m_electricalData.ratedPower);
203 XMLParser::SetNodeAttribute(doc, ratedPower,
"UnitID",
static_cast<int>(m_electricalData.activePowerUnit));
204 auto activePower = XMLParser::AppendNode(doc, electricalProp,
"ActivePower");
205 XMLParser::SetNodeValue(doc, activePower, m_electricalData.activePower);
206 XMLParser::SetNodeAttribute(doc, activePower,
"UnitID",
static_cast<int>(m_electricalData.activePowerUnit));
207 auto reactivePower = XMLParser::AppendNode(doc, electricalProp,
"ReactivePower");
208 XMLParser::SetNodeValue(doc, reactivePower, m_electricalData.reactivePower);
209 XMLParser::SetNodeAttribute(doc, reactivePower,
"UnitID",
static_cast<int>(m_electricalData.reactivePowerUnit));
210 auto useMachineBase = XMLParser::AppendNode(doc, electricalProp,
"UseMachineBase");
211 XMLParser::SetNodeValue(doc, useMachineBase, m_electricalData.useMachinePowerAsBase);
214 auto stability = XMLParser::AppendNode(doc, electricalProp,
"Stability");
215 auto plotMotor = XMLParser::AppendNode(doc, stability,
"PlotIndMachine");
216 XMLParser::SetNodeValue(doc, plotMotor, m_electricalData.plotIndMachine);
217 auto inertia = XMLParser::AppendNode(doc, stability,
"Inertia");
218 XMLParser::SetNodeValue(doc, inertia, m_electricalData.inertia);
219 auto r1 = XMLParser::AppendNode(doc, stability,
"StatorResistence");
220 XMLParser::SetNodeValue(doc, r1, m_electricalData.r1);
221 auto x1 = XMLParser::AppendNode(doc, stability,
"StatorReactance");
222 XMLParser::SetNodeValue(doc, x1, m_electricalData.x1);
223 auto r2 = XMLParser::AppendNode(doc, stability,
"RotorResistence");
224 XMLParser::SetNodeValue(doc, r2, m_electricalData.r2);
225 auto x2 = XMLParser::AppendNode(doc, stability,
"RotorReactance");
226 XMLParser::SetNodeValue(doc, x2, m_electricalData.x2);
227 auto xm = XMLParser::AppendNode(doc, stability,
"MagnetizingReactance");
228 XMLParser::SetNodeValue(doc, xm, m_electricalData.xm);
229 auto useCageFactor = XMLParser::AppendNode(doc, stability,
"UseCageFactor");
230 XMLParser::SetNodeValue(doc, useCageFactor, m_electricalData.useKf);
231 auto cageFactor = XMLParser::AppendNode(doc, stability,
"CageFactor");
232 XMLParser::SetNodeValue(doc, cageFactor, m_electricalData.kf);
233 auto loadChar = XMLParser::AppendNode(doc, stability,
"LoadCharacteristic");
234 auto aw = XMLParser::AppendNode(doc, loadChar,
"Constant");
235 XMLParser::SetNodeValue(doc, aw, m_electricalData.aw);
236 auto bw = XMLParser::AppendNode(doc, loadChar,
"Linear");
237 XMLParser::SetNodeValue(doc, bw, m_electricalData.bw);
238 auto cw = XMLParser::AppendNode(doc, loadChar,
"Quadratic");
239 XMLParser::SetNodeValue(doc, cw, m_electricalData.cw);
241 SaveSwitchingData(doc, electricalProp);
246bool IndMotor::OpenElement(rapidxml::xml_node<>* elementNode, std::vector<Element*> parentList)
248 if (!OpenCADProperties(elementNode, parentList))
return false;
250 auto electricalProp = elementNode->first_node(
"ElectricalProperties");
251 if (!electricalProp)
return false;
254 SetOnline(XMLParser::GetNodeValueInt(electricalProp,
"IsOnline"));
255 m_electricalData.name = electricalProp->first_node(
"Name")->value();
256 m_electricalData.ratedPower = XMLParser::GetNodeValueDouble(electricalProp,
"RatedPower");
257 m_electricalData.ratedPowerUnit =
258 static_cast<ElectricalUnit>(XMLParser::GetAttributeValueInt(electricalProp,
"RatedPower",
"UnitID"));
259 m_electricalData.activePower = XMLParser::GetNodeValueDouble(electricalProp,
"ActivePower");
260 m_electricalData.activePowerUnit =
261 static_cast<ElectricalUnit>(XMLParser::GetAttributeValueInt(electricalProp,
"ActivePower",
"UnitID"));
262 m_electricalData.reactivePower = XMLParser::GetNodeValueDouble(electricalProp,
"ReactivePower");
263 m_electricalData.reactivePowerUnit =
264 static_cast<ElectricalUnit>(XMLParser::GetAttributeValueInt(electricalProp,
"ReactivePower",
"UnitID"));
265 m_electricalData.useMachinePowerAsBase = XMLParser::GetNodeValueInt(electricalProp,
"UseMachineBase");
268 auto stability = electricalProp->first_node(
"Stability");
269 m_electricalData.plotIndMachine = XMLParser::GetNodeValueInt(stability,
"PlotIndMachine");
270 m_electricalData.inertia = XMLParser::GetNodeValueDouble(stability,
"Inertia");
271 m_electricalData.r1 = XMLParser::GetNodeValueDouble(stability,
"StatorResistence");
272 m_electricalData.x1 = XMLParser::GetNodeValueDouble(stability,
"StatorReactance");
273 m_electricalData.r2 = XMLParser::GetNodeValueDouble(stability,
"RotorResistence");
274 m_electricalData.x2 = XMLParser::GetNodeValueDouble(stability,
"RotorReactance");
275 m_electricalData.xm = XMLParser::GetNodeValueDouble(stability,
"MagnetizingReactance");
276 m_electricalData.useKf = XMLParser::GetNodeValueInt(stability,
"UseCageFactor");
277 m_electricalData.kf = XMLParser::GetNodeValueDouble(stability,
"CageFactor");
278 auto loadChar = stability->first_node(
"LoadCharacteristic");
279 m_electricalData.aw = XMLParser::GetNodeValueDouble(loadChar,
"Constant");
280 m_electricalData.bw = XMLParser::GetNodeValueDouble(loadChar,
"Linear");
281 m_electricalData.cw = XMLParser::GetNodeValueDouble(loadChar,
"Quadratic");
283 if (!OpenSwitchingData(electricalProp))
return false;
293 if (!m_electricalData.plotIndMachine)
return false;
294 plotData.SetName(m_electricalData.name);
295 plotData.SetCurveType(ElementPlotData::CurveType::CT_IND_MOTOR);
297 plotData.AddData(m_electricalData.terminalVoltageVector, _(
"Terminal voltage"));
298 plotData.AddData(m_electricalData.activePowerVector, _(
"Active power"));
299 plotData.AddData(m_electricalData.reactivePowerVector, _(
"Reactive power"));
300 plotData.AddData(m_electricalData.currentVector, _(
"Current"));
301 plotData.AddData(m_electricalData.electricalTorqueVector, _(
"Electrical torque"));
302 plotData.AddData(m_electricalData.mechanicalTorqueVector, _(
"Mechanical torque"));
303 plotData.AddData(m_electricalData.velocityVector, _(
"Speed"));
304 plotData.AddData(m_electricalData.slipVector, _(
"Slip"));
308void IndMotor::InitPowerFlowMotor(
double systemPowerBase,
int busNumber)
311 if (m_electricalData.useMachinePowerAsBase) {
312 double oldBase = GetValueFromUnit(m_electricalData.ratedPower, m_electricalData.ratedPowerUnit);
313 k = systemPowerBase / oldBase;
316 m_electricalData.r1t = m_electricalData.r1 * k;
317 m_electricalData.r2t = m_electricalData.r2 * k;
318 m_electricalData.x1t = m_electricalData.x1 * k;
319 m_electricalData.x2t = m_electricalData.x2 * k;
320 m_electricalData.xmt = m_electricalData.xm * k;
322 m_electricalData.xt = m_electricalData.x1t +
323 (m_electricalData.x2t * m_electricalData.xmt) / (m_electricalData.x2t + m_electricalData.xmt);
324 m_electricalData.x0 = m_electricalData.x1t + m_electricalData.xmt;
326 double r1 = m_electricalData.r1t;
327 double r2 = m_electricalData.r2t;
328 if (m_electricalData.useKf) r2 *= (1.0 + m_electricalData.kf * m_electricalData.r2t);
329 double x1 = m_electricalData.x1t;
330 double x2 = m_electricalData.x2t;
331 double xm = m_electricalData.xmt;
332 m_electricalData.k1 = x2 + xm;
333 m_electricalData.k2 = -x1 * m_electricalData.k1 - x2 * xm;
334 m_electricalData.k3 = xm + x1;
335 m_electricalData.k4 = r1 * m_electricalData.k1;
337 auto puData = GetPUElectricalData(systemPowerBase);
338 m_electricalData.p0 = puData.activePower;
339 m_electricalData.busNum = busNumber;
342bool IndMotor::CalculateReactivePower(
double voltage)
344 double a = m_electricalData.p0 *
345 (m_electricalData.r1t * m_electricalData.r1t + m_electricalData.k3 * m_electricalData.k3) -
346 voltage * voltage * m_electricalData.r1t;
347 double b = 2.0 * m_electricalData.p0 *
348 (m_electricalData.r1t * m_electricalData.k2 + m_electricalData.k3 * m_electricalData.k4) -
349 voltage * voltage * (m_electricalData.k2 + m_electricalData.k1 * m_electricalData.k3);
351 m_electricalData.p0 * (m_electricalData.k2 * m_electricalData.k2 + m_electricalData.k4 * m_electricalData.k4) -
352 voltage * voltage * m_electricalData.k1 * m_electricalData.k4;
353 double d = (b * b - 4.0 * a * c);
354 if (d < 0.0)
return false;
355 double r2_s = (-b + std::sqrt(d)) / (2.0 * a);
357 double qa = m_electricalData.k1 * (r2_s * m_electricalData.r1t - m_electricalData.x1t * m_electricalData.k1 -
358 m_electricalData.x2t * m_electricalData.xmt);
360 r2_s * (r2_s * (m_electricalData.xmt + m_electricalData.x1t) + m_electricalData.r1t * m_electricalData.k1);
361 double qc = r2_s * m_electricalData.r1t - m_electricalData.x1t * m_electricalData.k1 -
362 m_electricalData.x2t * m_electricalData.xmt;
363 double qd = r2_s * (m_electricalData.xmt + m_electricalData.x1t) + m_electricalData.r1t * m_electricalData.k1;
364 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 Element * GetCopy()
Get a the element copy.
virtual bool GetPlotData(ElementPlotData &plotData, PlotStudy study=PlotStudy::STABILITY)
Fill the plot data.
virtual bool ShowForm(wxWindow *parent, Element *element)
Show element data form.
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