19#include "../../forms/ReactiveShuntElementForm.h"
21Inductor::Inductor() :
Shunt()
23 m_elementType = TYPE_INDUCTOR;
26Inductor::Inductor(wxString name) :
Shunt()
28 m_elementType = TYPE_INDUCTOR;
29 m_electricalData.name = name;
32Inductor::~Inductor() {}
37 m_parentList.push_back(parent);
39 wxPoint2DDouble parentPt =
44 m_position = parentPt + wxPoint2DDouble(0.0, 100.0);
47 m_rect = wxRect2DDouble(m_position.m_x - m_width / 2.0, m_position.m_y - m_height / 2.0, m_width, m_height);
49 m_pointList.push_back(parentPt);
50 m_pointList.push_back(
GetSwitchPoint(parent, parentPt, m_position));
51 m_pointList.push_back(m_position + wxPoint2DDouble(0.0, -m_height / 2.0 - 10.0));
52 m_pointList.push_back(m_position + wxPoint2DDouble(0.0, -m_height / 2.0));
56 wxRect2DDouble genRect(0, 0, 0, 0);
57 m_switchRect.push_back(genRect);
126 wxColour elementColour;
131 elementColour = guiColour->enabled;
134 elementColour = guiColour->disable;
138 gc->SetPen(wxPen(guiColour->selection, 2 + m_borderSize * 2.0));
139 gc->SetBrush(*wxTRANSPARENT_BRUSH);
141 gc->StrokeLines(m_pointList.size(), &m_pointList[0]);
146 gc->Translate(m_position.m_x, m_position.m_y);
147 gc->Rotate(wxDegToRad(m_angle));
148 gc->Translate(-m_position.m_x, -m_position.m_y);
150 DrawDCArc(m_position + wxPoint2DDouble(0, -m_height / 2.0 + 10.0), 10, 45, 270, 30, gc);
151 DrawDCArc(m_position + wxPoint2DDouble(0, -m_height / 2.0 + 25.0), 10, 45, 315, 30, gc);
152 DrawDCArc(m_position + wxPoint2DDouble(0, -m_height / 2.0 + 40.0), 10, 90, 315, 30, gc);
154 DrawDCGround(m_position + wxPoint2DDouble(0, -m_height / 2.0 + 50.0), gc);
159 gc->SetPen(*wxTRANSPARENT_PEN);
160 gc->SetBrush(wxBrush(guiColour->selection));
161 DrawDCCircle(m_pointList[0], 5.0 + m_borderSize / scale, 10, gc);
164 gc->SetPen(*wxTRANSPARENT_PEN);
165 gc->SetBrush(wxBrush(wxColour(elementColour)));
168 gc->SetPen(wxPen(wxColour(elementColour), 2));
169 gc->SetBrush(*wxTRANSPARENT_BRUSH);
170 gc->StrokeLines(m_pointList.size(), &m_pointList[0]);
177 gc->Translate(m_position.m_x, m_position.m_y);
178 gc->Rotate(wxDegToRad(m_angle));
179 gc->Translate(-m_position.m_x, -m_position.m_y);
181 gc->SetPen(wxPen(wxColour(elementColour), 2));
182 gc->SetBrush(*wxTRANSPARENT_BRUSH);
183 DrawDCArc(m_position + wxPoint2DDouble(0, -m_height / 2.0 + 10.0), 10, 45, 270, 10, gc);
184 DrawDCArc(m_position + wxPoint2DDouble(0, -m_height / 2.0 + 25.0), 10, 45, 315, 10, gc);
185 DrawDCArc(m_position + wxPoint2DDouble(0, -m_height / 2.0 + 40.0), 10, 90, 315, 10, gc);
187 DrawDCGround(m_position + wxPoint2DDouble(0, -m_height / 2.0 + 50.0), gc);
192 DrawStabilityEventGC(gc, translation, scale, guiColour);
199 wxColour elementColour;
202 elementColour = guiColour->eventElement;
204 elementColour = guiColour->enabled;
207 elementColour = guiColour->disable;
209 std::vector<wxPoint> pointListInt;
210 for (
auto& pt : m_pointList) {
211 pointListInt.emplace_back(
static_cast<int>(pt.m_x),
static_cast<int>(pt.m_y));
217 p = m_position + wxPoint2DDouble(0, -m_height / 2.0 + 10.0);
218 arcPts[0] = RotateAround(p, m_position, m_angle);
219 p = m_position + wxPoint2DDouble(0, -m_height / 2.0 + 25.0);
220 arcPts[1] = RotateAround(p, m_position, m_angle);
221 p = m_position + wxPoint2DDouble(0, -m_height / 2.0 + 40.0);
222 arcPts[2] = RotateAround(p, m_position, m_angle);
225 dc.SetPen(wxPen(guiColour->selection, 2 + m_borderSize * 2.0));
226 dc.SetBrush(*wxTRANSPARENT_BRUSH);
228 dc.DrawLines(pointListInt.size(), &pointListInt[0]);
230 DrawDCArc(arcPts[0], 10, 90 - m_angle, 315 - m_angle, dc);
231 DrawDCArc(arcPts[1], 10, 45 - m_angle, 315 - m_angle, dc);
232 DrawDCArc(arcPts[2], 10, 45 - m_angle, 270 - m_angle, dc);
234 DrawDCGround(m_position + wxPoint2DDouble(0, -m_height / 2.0 + 50.0), dc);
237 dc.SetPen(*wxTRANSPARENT_PEN);
238 dc.SetBrush(wxBrush(guiColour->selection));
239 DrawDCCircle(m_pointList[0], 5.0 + m_borderSize / scale, dc);
242 dc.SetPen(*wxTRANSPARENT_PEN);
243 dc.SetBrush(wxBrush(wxColour(elementColour)));
246 dc.SetPen(wxPen(wxColour(elementColour), 2));
247 dc.SetBrush(*wxTRANSPARENT_BRUSH);
248 dc.DrawLines(pointListInt.size(), &pointListInt[0]);
252 dc.SetPen(wxPen(wxColour(elementColour), 2));
253 dc.SetBrush(*wxTRANSPARENT_BRUSH);
254 DrawDCArc(arcPts[0], 10, 90 - m_angle, 315 - m_angle, dc);
255 DrawDCArc(arcPts[1], 10, 45 - m_angle, 315 - m_angle, dc);
256 DrawDCArc(arcPts[2], 10, 45 - m_angle, 270 - m_angle, dc);
258 DrawDCGround(m_position + wxPoint2DDouble(0, -m_height / 2.0 + 50.0), dc);
264 double rotAngle = m_rotationAngle;
265 if (!clockwise) rotAngle = -m_rotationAngle;
268 if (m_angle >= 360 || m_angle <= -360) m_angle = 0.0;
271 UpdateSwitchesPosition();
278 wxMenu* textMenu =
new wxMenu();
280 textMenu->Append(ID_TXT_NAME, _(
"Name"));
281 textMenu->Append(ID_TXT_REACTIVE_POWER, _(
"Reactive power"));
282 textMenu->SetClientData(menu.GetClientData());
283 menu.AppendSubMenu(textMenu, _(
"Add text"));
292 return m_rect.Contains(ptR);
299 inductorForm.SetTitle(_(
"Inductor"));
300 inductorForm.CenterOnParent();
301 if (inductorForm.ShowModal() == wxID_OK) {
310 switch (data.reactivePowerUnit) {
311 case ElectricalUnit::UNIT_var: {
312 data.reactivePower = data.reactivePower / systemPowerBase;
313 data.reactivePowerUnit = ElectricalUnit::UNIT_PU;
315 case ElectricalUnit::UNIT_kvar: {
316 data.reactivePower = (data.reactivePower * 1e3) / systemPowerBase;
317 data.reactivePowerUnit = ElectricalUnit::UNIT_PU;
319 case ElectricalUnit::UNIT_Mvar: {
320 data.reactivePower = (data.reactivePower * 1e6) / systemPowerBase;
321 data.reactivePowerUnit = ElectricalUnit::UNIT_PU;
339 wxString tipText = m_electricalData.name;
342 double reactivePower = m_electricalData.reactivePower;
346 std::complex<double> v =
static_cast<Bus*
>(m_parentList[0])->GetElectricalData().voltage;
347 reactivePower *= std::pow(std::abs(v), 2);
350 tipText += _(
"\nQ = ") + wxString::FromDouble(reactivePower, 5);
351 switch (m_electricalData.reactivePowerUnit) {
352 case ElectricalUnit::UNIT_PU: {
353 tipText += _(
" p.u.");
355 case ElectricalUnit::UNIT_var: {
356 tipText += _(
" var");
358 case ElectricalUnit::UNIT_kvar: {
359 tipText += _(
" kvar");
361 case ElectricalUnit::UNIT_Mvar: {
362 tipText += _(
" Mvar");
371rapidxml::xml_node<>* Inductor::SaveElement(rapidxml::xml_document<>& doc, rapidxml::xml_node<>* elementListNode)
373 auto elementNode = XMLParser::AppendNode(doc, elementListNode,
"Inductor");
374 XMLParser::SetNodeAttribute(doc, elementNode,
"ID", m_elementID);
376 SaveCADProperties(doc, elementNode);
378 auto electricalProp = XMLParser::AppendNode(doc, elementNode,
"ElectricalProperties");
379 auto isOnline = XMLParser::AppendNode(doc, electricalProp,
"IsOnline");
380 XMLParser::SetNodeValue(doc, isOnline, m_online);
381 auto name = XMLParser::AppendNode(doc, electricalProp,
"Name");
382 XMLParser::SetNodeValue(doc, name, m_electricalData.name);
383 auto reactivePower = XMLParser::AppendNode(doc, electricalProp,
"ReactivePower");
384 XMLParser::SetNodeValue(doc, reactivePower, m_electricalData.reactivePower);
385 XMLParser::SetNodeAttribute(doc, reactivePower,
"UnitID",
static_cast<int>(m_electricalData.reactivePowerUnit));
387 SaveSwitchingData(doc, electricalProp);
392bool Inductor::OpenElement(rapidxml::xml_node<>* elementNode, std::vector<Element*> parentList)
394 if (!OpenCADProperties(elementNode, parentList))
return false;
396 auto electricalProp = elementNode->first_node(
"ElectricalProperties");
397 if (!electricalProp)
return false;
399 SetOnline(XMLParser::GetNodeValueInt(electricalProp,
"IsOnline"));
400 m_electricalData.name = electricalProp->first_node(
"Name")->value();
401 m_electricalData.reactivePower = XMLParser::GetNodeValueDouble(electricalProp,
"ReactivePower");
402 m_electricalData.reactivePowerUnit =
403 static_cast<ElectricalUnit
>(XMLParser::GetAttributeValueInt(electricalProp,
"ReactivePower",
"UnitID"));
405 if (!OpenSwitchingData(electricalProp))
return false;
Node for power elements. All others power elements are connected through this.
Base class of all elements of the program. This class is responsible for manage graphical and his dat...
virtual bool RotatedRectanglesIntersects(wxRect2DDouble rect1, wxRect2DDouble rect2, double angle1, double angle2) const
Check if two roteted rectangles intersect.
virtual void GeneralMenuItens(wxMenu &menu)
Insert general itens to context menu.
wxPoint2DDouble GetPosition() const
Get the element position.
double GetAngle() const
Get the element angle.
virtual wxPoint2DDouble RotateAtPosition(wxPoint2DDouble pointToRotate, double angle, bool degrees=true) const
Rotate a point as element position being the origin.
virtual void AddChild(Element *child)
Add a child to the child list.
bool SetOnline(bool online=true)
Set if the element is online or offline.
virtual void DrawDCCircle(wxPoint2DDouble position, double radius, int numSegments, wxGraphicsContext *gc) const
Draw a circle using device context.
Inductor shunt power element.
virtual bool ShowForm(wxWindow *parent, Element *element, wxWindow *workspace=nullptr)
Show element data form.
virtual bool Intersects(wxRect2DDouble rect) const
Check if the element's rect intersects other rect.
virtual Element * GetCopy()
Get a the element copy.
virtual void Rotate(bool clockwise=true)
Rotate the element.
virtual bool GetContextMenu(wxMenu &menu)
Get the element contex menu.
virtual wxString GetTipText() const
Get the tip text.
virtual bool Contains(wxPoint2DDouble position) const
Checks if the element contains a position.
virtual bool AddParent(Element *parent, wxPoint2DDouble position, bool isOpening=false)
Add a parent to the element. This method must be used on power elements that connect to a bus,...
virtual void DrawDC(GUIColour *guiColour, wxPoint2DDouble translation, double scale, wxGraphicsContext *gc) const
Draw the element using GDI+.
virtual void SetDynamicEvent(bool dynEvent=true)
Set if the power element have dynamic event.
virtual void UpdateSwitches()
Update the switch position.
virtual void DrawDCSwitches(GUIColour *guiColour, wxGraphicsContext *gc) const
Draw switch.
virtual wxPoint2DDouble GetSwitchPoint(Element *parent, wxPoint2DDouble parentPoint, wxPoint2DDouble secondPoint) const
Get the correct switch position.
Abstract class for shunt power elements.
std::vector< double > swTime