Power System Platform  2026w10a-beta
Loading...
Searching...
No Matches
SyncMotor.cpp
1/*
2 * Copyright (C) 2017 Thales Lima Oliveira <thales@ufu.br>
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <https://www.gnu.org/licenses/>.
16 */
17
18#include "../../forms/SyncMachineForm.h"
19#include "SyncMotor.h"
20
21SyncMotor::SyncMotor() : Machines()
22{
23 m_elementType = TYPE_SYNC_MOTOR;
24}
25
26SyncMotor::SyncMotor(wxString name) : Machines()
27{
28 m_elementType = TYPE_SYNC_MOTOR;
29 m_electricalData.name = name;
30}
31
32SyncMotor::~SyncMotor() {}
33
34//void SyncMotor::DrawSymbol() const { DrawArc(m_position, 12, 30, 330, 10, GL_LINE_STRIP); }
35void SyncMotor::DrawDCSymbol(wxGraphicsContext* gc) const
36{
37 DrawDCArc(m_position, 12, 30, 330, 10, gc);
38}
39
40void SyncMotor::DrawDCSymbol(wxDC& dc) const
41{
42 DrawDCArc(m_position, 12, 30, 330, dc);
43}
44
45bool SyncMotor::GetContextMenu(wxMenu& menu)
46{
47 menu.Append(ID_EDIT_ELEMENT, _("Edit Synchronous Condenser"));
48
49 wxMenu* textMenu = new wxMenu();
50
51 textMenu->Append(ID_TXT_NAME, _("Name"));
52 textMenu->Append(ID_TXT_ACTIVE_POWER, _("Active power"));
53 textMenu->Append(ID_TXT_REACTIVE_POWER, _("Reactive power"));
54 textMenu->SetClientData(menu.GetClientData());
55 menu.AppendSubMenu(textMenu, _("Add text"));
56
57 GeneralMenuItens(menu);
58
59 return true;
60}
61
62bool SyncMotor::ShowForm(wxWindow* parent, Element* element)
63{
64 SyncMachineForm syncMotorForm(parent, this);
65 syncMotorForm.SetTitle(_("Synchronous Condenser"));
66 syncMotorForm.CenterOnParent();
67 if (syncMotorForm.ShowModal() == wxID_OK) {
68 return true;
69 }
70 return false;
71}
72
73SyncMotorElectricalData SyncMotor::GetPUElectricalData(double systemPowerBase)
74{
75 SyncMotorElectricalData data = m_electricalData;
76 double machineBasePower = 1.0;
77 if (data.useMachineBase) { machineBasePower = GetValueFromUnit(data.nominalPower, data.nominalPowerUnit); }
78
79 // Active power
80 double activePower = GetValueFromUnit(data.activePower, data.activePowerUnit);
81 if (!m_online) activePower = 0.0;
82 if (data.activePowerUnit == ElectricalUnit::UNIT_PU) {
83 if (data.useMachineBase) data.activePower = (activePower * machineBasePower) / systemPowerBase;
84 }
85 else {
86 data.activePower = activePower / systemPowerBase;
87 }
88 data.activePowerUnit = ElectricalUnit::UNIT_PU;
89
90 // Reactive power
91 double reactivePower = GetValueFromUnit(data.reactivePower, data.reactivePowerUnit);
92 if (!m_online) reactivePower = 0.0;
93 if (data.reactivePowerUnit == ElectricalUnit::UNIT_PU) {
94 if (data.useMachineBase) data.reactivePower = (reactivePower * machineBasePower) / systemPowerBase;
95 }
96 else {
97 data.reactivePower = reactivePower / systemPowerBase;
98 }
99 data.reactivePowerUnit = ElectricalUnit::UNIT_PU;
100
101 // Max reactive power
102 double maxReactive = GetValueFromUnit(data.maxReactive, data.maxReactiveUnit);
103 if (data.maxReactiveUnit == ElectricalUnit::UNIT_PU) {
104 if (data.useMachineBase) data.maxReactive = (maxReactive * machineBasePower) / systemPowerBase;
105 }
106 else {
107 data.maxReactive = maxReactive / systemPowerBase;
108 }
109 data.maxReactiveUnit = ElectricalUnit::UNIT_PU;
110
111 // Min reactive power
112 double minReactive = GetValueFromUnit(data.minReactive, data.minReactiveUnit);
113 if (data.minReactiveUnit == ElectricalUnit::UNIT_PU) {
114 if (data.useMachineBase) data.minReactive = (minReactive * machineBasePower) / systemPowerBase;
115 }
116 else {
117 data.minReactive = minReactive / systemPowerBase;
118 }
119 data.minReactiveUnit = ElectricalUnit::UNIT_PU;
120
121 double baseVoltage = GetValueFromUnit(data.nominalVoltage, data.nominalVoltageUnit);
122 double systemBaseImpedance = (baseVoltage * baseVoltage) / systemPowerBase;
123 double machineBaseImpedance = (baseVoltage * baseVoltage) / machineBasePower;
124
125 // Fault data
126 if (data.useMachineBase) {
127 data.positiveResistance = (data.positiveResistance * machineBaseImpedance) / systemBaseImpedance;
128 data.positiveReactance = (data.positiveReactance * machineBaseImpedance) / systemBaseImpedance;
129 data.negativeResistance = (data.negativeResistance * machineBaseImpedance) / systemBaseImpedance;
130 data.negativeReactance = (data.negativeReactance * machineBaseImpedance) / systemBaseImpedance;
131 data.zeroResistance = (data.zeroResistance * machineBaseImpedance) / systemBaseImpedance;
132 data.zeroReactance = (data.zeroReactance * machineBaseImpedance) / systemBaseImpedance;
133 data.groundResistance = (data.groundResistance * machineBaseImpedance) / systemBaseImpedance;
134 data.groundReactance = (data.groundReactance * machineBaseImpedance) / systemBaseImpedance;
135 }
136
137 if (!m_online) {
138 data.faultCurrent[0] = std::complex<double>(0, 0);
139 data.faultCurrent[1] = std::complex<double>(0, 0);
140 data.faultCurrent[2] = std::complex<double>(0, 0);
141 }
142
143 return data;
144}
145
146void SyncMotor::SetNominalVoltage(std::vector<double> nominalVoltage, std::vector<ElectricalUnit> nominalVoltageUnit)
147{
148 if (nominalVoltage.size() > 0) {
149 m_electricalData.nominalVoltage = nominalVoltage[0];
150 m_electricalData.nominalVoltageUnit = nominalVoltageUnit[0];
151 }
152}
153
155{
156 SyncMotor* copy = new SyncMotor();
157 *copy = *this;
158 return copy;
159}
160
161wxString SyncMotor::GetTipText() const
162{
163 wxString tipText = m_electricalData.name;
164 tipText += "\n";
165 double activePower = m_electricalData.activePower;
166 if (!m_online) activePower = 0.0;
167 tipText += _("\nP = ") + wxString::FromDouble(activePower, 5);
168 switch (m_electricalData.activePowerUnit) {
170 tipText += _(" p.u.");
171 } break;
173 tipText += _(" W");
174 } break;
176 tipText += _(" kW");
177 } break;
179 tipText += _(" MW");
180 } break;
181 default:
182 break;
183 }
184 double reactivePower = m_electricalData.reactivePower;
185 if (!m_online) reactivePower = 0.0;
186 tipText += _("\nQ = ") + wxString::FromDouble(reactivePower, 5);
187 switch (m_electricalData.reactivePowerUnit) {
189 tipText += _(" p.u.");
190 } break;
192 tipText += _(" var");
193 } break;
195 tipText += _(" kvar");
196 } break;
198 tipText += _(" Mvar");
199 } break;
200 default:
201 break;
202 }
203
204 return tipText;
205}
206
207rapidxml::xml_node<>* SyncMotor::SaveElement(rapidxml::xml_document<>& doc, rapidxml::xml_node<>* elementListNode)
208{
209 auto elementNode = XMLParser::AppendNode(doc, elementListNode, "SyncMotor");
210 XMLParser::SetNodeAttribute(doc, elementNode, "ID", m_elementID);
211
212 SaveCADProperties(doc, elementNode);
213
214 auto electricalProp = XMLParser::AppendNode(doc, elementNode, "ElectricalProperties");
215 auto isOnline = XMLParser::AppendNode(doc, electricalProp, "IsOnline");
216 XMLParser::SetNodeValue(doc, isOnline, m_online);
217 auto name = XMLParser::AppendNode(doc, electricalProp, "Name");
218 XMLParser::SetNodeValue(doc, name, m_electricalData.name);
219 auto nominalPower = XMLParser::AppendNode(doc, electricalProp, "NominalPower");
220 XMLParser::SetNodeValue(doc, nominalPower, m_electricalData.nominalPower);
221 XMLParser::SetNodeAttribute(doc, nominalPower, "UnitID", static_cast<int>(m_electricalData.nominalPowerUnit));
222 auto activePower = XMLParser::AppendNode(doc, electricalProp, "ActivePower");
223 XMLParser::SetNodeValue(doc, activePower, m_electricalData.activePower);
224 XMLParser::SetNodeAttribute(doc, activePower, "UnitID", static_cast<int>(m_electricalData.activePowerUnit));
225 auto reactivePower = XMLParser::AppendNode(doc, electricalProp, "ReactivePower");
226 XMLParser::SetNodeValue(doc, reactivePower, m_electricalData.reactivePower);
227 XMLParser::SetNodeAttribute(doc, reactivePower, "UnitID", static_cast<int>(m_electricalData.reactivePowerUnit));
228 auto haveMaxReactive = XMLParser::AppendNode(doc, electricalProp, "HaveMaxReactive");
229 XMLParser::SetNodeValue(doc, haveMaxReactive, m_electricalData.haveMaxReactive);
230 auto maxReactive = XMLParser::AppendNode(doc, electricalProp, "MaxReactive");
231 XMLParser::SetNodeValue(doc, maxReactive, m_electricalData.maxReactive);
232 XMLParser::SetNodeAttribute(doc, maxReactive, "UnitID", static_cast<int>(m_electricalData.maxReactiveUnit));
233 auto haveMinReactive = XMLParser::AppendNode(doc, electricalProp, "HaveMinReactive");
234 XMLParser::SetNodeValue(doc, haveMinReactive, m_electricalData.haveMinReactive);
235 auto minReactive = XMLParser::AppendNode(doc, electricalProp, "MinReactive");
236 XMLParser::SetNodeValue(doc, minReactive, m_electricalData.minReactive);
237 XMLParser::SetNodeAttribute(doc, minReactive, "UnitID", static_cast<int>(m_electricalData.minReactiveUnit));
238 auto useMachineBase = XMLParser::AppendNode(doc, electricalProp, "UseMachineBase");
239 XMLParser::SetNodeValue(doc, useMachineBase, m_electricalData.useMachineBase);
240
241 auto fault = XMLParser::AppendNode(doc, electricalProp, "Fault");
242 auto positiveResistance = XMLParser::AppendNode(doc, fault, "PositiveResistance");
243 XMLParser::SetNodeValue(doc, positiveResistance, m_electricalData.positiveResistance);
244 auto positiveReactance = XMLParser::AppendNode(doc, fault, "PositiveReactance");
245 XMLParser::SetNodeValue(doc, positiveReactance, m_electricalData.positiveReactance);
246 auto negativeResistance = XMLParser::AppendNode(doc, fault, "NegativeResistance");
247 XMLParser::SetNodeValue(doc, negativeResistance, m_electricalData.negativeResistance);
248 auto negativeReactance = XMLParser::AppendNode(doc, fault, "NegativeReactance");
249 XMLParser::SetNodeValue(doc, negativeReactance, m_electricalData.negativeReactance);
250 auto zeroResistance = XMLParser::AppendNode(doc, fault, "ZeroResistance");
251 XMLParser::SetNodeValue(doc, zeroResistance, m_electricalData.zeroResistance);
252 auto zeroReactance = XMLParser::AppendNode(doc, fault, "ZeroReactance");
253 XMLParser::SetNodeValue(doc, zeroReactance, m_electricalData.zeroReactance);
254 auto groundResistance = XMLParser::AppendNode(doc, fault, "GroundResistance");
255 XMLParser::SetNodeValue(doc, groundResistance, m_electricalData.groundResistance);
256 auto groundReactance = XMLParser::AppendNode(doc, fault, "GroundReactance");
257 XMLParser::SetNodeValue(doc, groundReactance, m_electricalData.groundReactance);
258 auto groundNeutral = XMLParser::AppendNode(doc, fault, "GroundNeutral");
259 XMLParser::SetNodeValue(doc, groundNeutral, m_electricalData.groundNeutral);
260
261 return elementNode;
262}
263
264bool SyncMotor::OpenElement(rapidxml::xml_node<>* elementNode, std::vector<Element*> parentList)
265{
266 if (!OpenCADProperties(elementNode, parentList)) return false;
267
268 auto electricalProp = elementNode->first_node("ElectricalProperties");
269 if (!electricalProp) return false;
270
271 SetOnline(XMLParser::GetNodeValueInt(electricalProp, "IsOnline"));
272 m_electricalData.name = electricalProp->first_node("Name")->value();
273 m_electricalData.nominalPower = XMLParser::GetNodeValueDouble(electricalProp, "NominalPower");
274 m_electricalData.nominalPowerUnit =
275 static_cast<ElectricalUnit>(XMLParser::GetAttributeValueInt(electricalProp, "NominalPower", "UnitID"));
276 m_electricalData.activePower = XMLParser::GetNodeValueDouble(electricalProp, "ActivePower");
277 m_electricalData.activePowerUnit =
278 static_cast<ElectricalUnit>(XMLParser::GetAttributeValueInt(electricalProp, "ActivePower", "UnitID"));
279 m_electricalData.reactivePower = XMLParser::GetNodeValueDouble(electricalProp, "ReactivePower");
280 m_electricalData.reactivePowerUnit =
281 static_cast<ElectricalUnit>(XMLParser::GetAttributeValueInt(electricalProp, "ReactivePower", "UnitID"));
282 m_electricalData.haveMaxReactive = XMLParser::GetNodeValueInt(electricalProp, "HaveMaxReactive");
283 m_electricalData.maxReactive = XMLParser::GetNodeValueDouble(electricalProp, "MaxReactive");
284 m_electricalData.maxReactiveUnit =
285 static_cast<ElectricalUnit>(XMLParser::GetAttributeValueInt(electricalProp, "MaxReactive", "UnitID"));
286 m_electricalData.haveMinReactive = XMLParser::GetNodeValueInt(electricalProp, "HaveMinReactive");
287 m_electricalData.minReactive = XMLParser::GetNodeValueDouble(electricalProp, "MinReactive");
288 m_electricalData.minReactiveUnit =
289 static_cast<ElectricalUnit>(XMLParser::GetAttributeValueInt(electricalProp, "MinReactive", "UnitID"));
290 m_electricalData.useMachineBase = XMLParser::GetNodeValueInt(electricalProp, "UseMachineBase");
291
292 auto fault = electricalProp->first_node("Fault");
293 if (!fault) return false;
294 m_electricalData.positiveResistance = XMLParser::GetNodeValueDouble(fault, "PositiveResistance");
295 m_electricalData.positiveReactance = XMLParser::GetNodeValueDouble(fault, "PositiveReactance");
296 m_electricalData.negativeResistance = XMLParser::GetNodeValueDouble(fault, "NegativeResistance");
297 m_electricalData.negativeReactance = XMLParser::GetNodeValueDouble(fault, "NegativeReactance");
298 m_electricalData.zeroResistance = XMLParser::GetNodeValueDouble(fault, "ZeroResistance");
299 m_electricalData.zeroReactance = XMLParser::GetNodeValueDouble(fault, "ZeroReactance");
300 m_electricalData.groundResistance = XMLParser::GetNodeValueDouble(fault, "GroundResistance");
301 m_electricalData.groundReactance = XMLParser::GetNodeValueDouble(fault, "GroundReactance");
302 m_electricalData.groundNeutral = XMLParser::GetNodeValueInt(fault, "GroundNeutral");
303
304 m_inserted = true;
305
306 return true;
307}
@ ID_EDIT_ELEMENT
Definition Element.h:75
ElectricalUnit
Electrical units.
Base class of all elements of the program. This class is responsible for manage graphical and his dat...
Definition Element.h:112
virtual void GeneralMenuItens(wxMenu &menu)
Insert general itens to context menu.
Definition Element.cpp:457
bool SetOnline(bool online=true)
Set if the element is online or offline.
Definition Element.cpp:447
Abstract class for rotary machines power elements.
Definition Machines.h:34
Form to edit the synchronous machine power data.
Synchronous motor (synchronous compensator) power element.
Definition SyncMotor.h:135
virtual Element * GetCopy()
Get a the element copy.
virtual void SetNominalVoltage(std::vector< double > nominalVoltage, std::vector< ElectricalUnit > nominalVoltageUnit)
Set nominal voltage of the element.
virtual wxString GetTipText() const
Get the tip text.
virtual bool ShowForm(wxWindow *parent, Element *element)
Show element data form.
Definition SyncMotor.cpp:62
virtual bool GetContextMenu(wxMenu &menu)
Get the element contex menu.
Definition SyncMotor.cpp:45