22 m_elementType = TYPE_LOAD;
25Load::Load(wxString name) :
Shunt()
27 m_elementType = TYPE_LOAD;
28 m_electricalData.name = name;
36 m_parentList.push_back(parent);
38 wxPoint2DDouble parentPt =
43 m_position = parentPt + wxPoint2DDouble(0.0, 100.0);
44 m_width = m_height = 20.0;
45 m_rect = wxRect2DDouble(m_position.m_x - 10.0, m_position.m_y - 10.0, m_width, m_height);
47 m_pointList.push_back(parentPt);
48 m_pointList.push_back(
GetSwitchPoint(parent, parentPt, m_position));
49 m_pointList.push_back(m_position + wxPoint2DDouble(0.0, -20.0));
50 m_pointList.push_back(m_position + wxPoint2DDouble(0.0, -10.0));
52 m_triangPts.push_back(wxPoint2DDouble(-m_width / 2.0, -m_height / 2.0));
53 m_triangPts.push_back(wxPoint2DDouble(m_width / 2.0, -m_height / 2.0));
54 m_triangPts.push_back(wxPoint2DDouble(0.0, m_height / 2.0));
58 wxRect2DDouble genRect(0, 0, 0, 0);
59 m_switchRect.push_back(genRect);
62 UpdatePowerFlowArrowsPosition();
130void Load::DrawDC(wxPoint2DDouble translation,
double scale, wxGraphicsContext* gc)
const
132 wxColour elementColour;
135 elementColour = m_dynamicEventColour;
137 elementColour = m_onlineElementColour;
140 elementColour = m_offlineElementColour;
145 gc->SetPen(wxPen(m_selectionColour, 2 + m_borderSize * 2.0));
146 gc->SetBrush(*wxTRANSPARENT_BRUSH);
148 gc->StrokeLines(m_pointList.size(), &m_pointList[0]);
150 gc->SetPen(*wxTRANSPARENT_PEN);
151 gc->SetBrush(wxBrush(m_selectionColour));
153 std::vector<wxPoint2DDouble> selTriangPts;
154 selTriangPts.push_back(m_triangPts[0] + m_position +
155 wxPoint2DDouble(-m_borderSize / scale, -m_borderSize / scale));
156 selTriangPts.push_back(m_triangPts[1] + m_position +
157 wxPoint2DDouble(m_borderSize / scale, -m_borderSize / scale));
158 selTriangPts.push_back(m_triangPts[2] + m_position + wxPoint2DDouble(0.0, m_borderSize / scale));
163 gc->Translate(m_position.m_x, m_position.m_y);
164 gc->Rotate(wxDegToRad(m_angle));
165 gc->Translate(-m_position.m_x, -m_position.m_y);
170 DrawDCCircle(m_pointList[0], 5.0 + m_borderSize / scale, 10, gc);
174 gc->SetPen(wxPen(elementColour, 2));
175 gc->SetBrush(*wxTRANSPARENT_BRUSH);
176 gc->StrokeLines(m_pointList.size(), &m_pointList[0]);
179 gc->SetPen(*wxTRANSPARENT_PEN);
180 gc->SetBrush(wxBrush(elementColour));
186 std::vector<wxPoint2DDouble> triangPts;
187 for (
int i = 0; i < 3; i++) { triangPts.push_back(m_triangPts[i] + m_position); }
189 gc->Translate(m_position.m_x, m_position.m_y);
190 gc->Rotate(wxDegToRad(m_angle));
191 gc->Translate(-m_position.m_x, -m_position.m_y);
192 gc->SetPen(*wxTRANSPARENT_PEN);
193 gc->SetBrush(wxBrush(elementColour));
199void Load::DrawDC(wxPoint2DDouble translation,
double scale, wxDC& dc)
const
201 wxColour elementColour;
204 elementColour = m_dynamicEventColour;
206 elementColour = m_onlineElementColour;
209 elementColour = m_offlineElementColour;
211 std::vector<wxPoint> pointListInt;
212 for (
auto& pt : m_pointList) {
213 pointListInt.emplace_back(
static_cast<int>(pt.m_x),
static_cast<int>(pt.m_y));
215 wxPoint pos = wxPoint(
static_cast<int>(m_position.m_x),
static_cast<int>(m_position.m_y));
220 dc.SetPen(wxPen(m_selectionColour, 2 + m_borderSize * 2.0));
221 dc.SetBrush(*wxTRANSPARENT_BRUSH);
223 dc.DrawLines(pointListInt.size(), &pointListInt[0]);
225 dc.SetPen(*wxTRANSPARENT_PEN);
226 dc.SetBrush(wxBrush(m_selectionColour));
229 wxPoint selTriangPts[3];
230 p = m_triangPts[0] + m_position + wxPoint2DDouble(-m_borderSize / scale, -m_borderSize / scale);
231 selTriangPts[0] = RotateAround(p, m_position, m_angle);
232 p = m_triangPts[1] + m_position + wxPoint2DDouble(m_borderSize / scale, -m_borderSize / scale);
233 selTriangPts[1] = RotateAround(p, m_position, m_angle);
234 p = m_triangPts[2] + m_position + wxPoint2DDouble(0.0, m_borderSize / scale);
235 selTriangPts[2] = RotateAround(p, m_position, m_angle);
237 dc.DrawPolygon(3, selTriangPts);
240 DrawDCCircle(m_pointList[0], 5.0 + m_borderSize / scale, dc);
244 dc.SetPen(wxPen(elementColour, 2));
245 dc.SetBrush(*wxTRANSPARENT_BRUSH);
246 dc.DrawLines(pointListInt.size(), &pointListInt[0]);
249 dc.SetPen(*wxTRANSPARENT_PEN);
250 dc.SetBrush(wxBrush(elementColour));
257 wxPoint triangPts[3];
260 for (
int i = 0; i < 3; i++) {
261 p = m_triangPts[i] + m_position;
262 triangPts[i] = RotateAround(p, m_position, m_angle);
264 dc.SetPen(*wxTRANSPARENT_PEN);
265 dc.SetBrush(wxBrush(elementColour));
266 dc.DrawPolygon(3, triangPts);
272 double rotAngle = m_rotationAngle;
273 if (!clockwise) rotAngle = -m_rotationAngle;
276 if (m_angle >= 360 || m_angle <= -360) m_angle = 0.0;
279 UpdateSwitchesPosition();
280 UpdatePowerFlowArrowsPosition();
287 wxMenu* textMenu =
new wxMenu();
289 textMenu->Append(ID_TXT_NAME, _(
"Name"));
290 textMenu->Append(ID_TXT_ACTIVE_POWER, _(
"Active power"));
291 textMenu->Append(ID_TXT_REACTIVE_POWER, _(
"Reactive power"));
292 textMenu->SetClientData(menu.GetClientData());
295 menu.AppendSubMenu(textMenu, _(
"Add text"));
304 loadForm.CenterOnParent();
305 if (loadForm.ShowModal() == wxID_OK) {
314 switch (data.activePowerUnit) {
316 data.activePower = data.activePower / systemPowerBase;
320 data.activePower = (data.activePower * 1e3) / systemPowerBase;
324 data.activePower = (data.activePower * 1e6) / systemPowerBase;
330 switch (data.reactivePowerUnit) {
332 data.reactivePower = data.reactivePower / systemPowerBase;
336 data.reactivePower = (data.reactivePower * 1e3) / systemPowerBase;
340 data.reactivePower = (data.reactivePower * 1e6) / systemPowerBase;
359 wxString tipText = m_electricalData.name;
362 double activePower = m_electricalData.activePower;
363 double reactivePower = m_electricalData.reactivePower;
368 if (m_online && m_electricalData.loadType == CONST_IMPEDANCE) {
369 std::complex<double> v =
static_cast<Bus*
>(m_parentList[0])->GetElectricalData().voltage;
370 reactivePower *= std::pow(std::abs(v), 2);
371 activePower *= std::pow(std::abs(v), 2);
374 tipText += _(
"\nP = ") + wxString::FromDouble(activePower, 5);
375 switch (m_electricalData.activePowerUnit) {
377 tipText += _(
" p.u.");
391 tipText += _(
"\nQ = ") + wxString::FromDouble(reactivePower, 5);
392 switch (m_electricalData.reactivePowerUnit) {
394 tipText += _(
" p.u.");
397 tipText += _(
" var");
400 tipText += _(
" kvar");
403 tipText += _(
" Mvar");
414 if (!m_electricalData.plotLoad)
return false;
415 plotData.SetName(m_electricalData.name);
416 plotData.SetCurveType(ElementPlotData::CurveType::CT_LOAD);
418 std::vector<double> absVoltage, activePower, reactivePower, current;
419 for (
unsigned int i = 0; i < m_electricalData.voltageVector.size(); ++i) {
420 absVoltage.push_back(std::abs(m_electricalData.voltageVector[i]));
421 activePower.push_back(std::real(m_electricalData.electricalPowerVector[i]));
422 reactivePower.push_back(std::imag(m_electricalData.electricalPowerVector[i]));
423 current.push_back(std::abs(std::complex<double>(activePower[i], -reactivePower[i]) /
424 std::conj(m_electricalData.voltageVector[i])));
427 plotData.AddData(absVoltage, _(
"Voltage"));
428 plotData.AddData(activePower, _(
"Active power"));
429 plotData.AddData(reactivePower, _(
"Reactive power"));
430 plotData.AddData(current, _(
"Current"));
435rapidxml::xml_node<>* Load::SaveElement(rapidxml::xml_document<>& doc, rapidxml::xml_node<>* elementListNode)
437 auto elementNode = XMLParser::AppendNode(doc, elementListNode,
"Load");
438 XMLParser::SetNodeAttribute(doc, elementNode,
"ID", m_elementID);
440 SaveCADProperties(doc, elementNode);
442 auto electricalProp = XMLParser::AppendNode(doc, elementNode,
"ElectricalProperties");
443 auto isOnline = XMLParser::AppendNode(doc, electricalProp,
"IsOnline");
444 XMLParser::SetNodeValue(doc, isOnline, m_online);
445 auto name = XMLParser::AppendNode(doc, electricalProp,
"Name");
446 XMLParser::SetNodeValue(doc, name, m_electricalData.name);
447 auto activePower = XMLParser::AppendNode(doc, electricalProp,
"ActivePower");
448 XMLParser::SetNodeValue(doc, activePower, m_electricalData.activePower);
449 XMLParser::SetNodeAttribute(doc, activePower,
"UnitID",
static_cast<int>(m_electricalData.activePowerUnit));
450 auto reactivePower = XMLParser::AppendNode(doc, electricalProp,
"ReactivePower");
451 XMLParser::SetNodeValue(doc, reactivePower, m_electricalData.reactivePower);
452 XMLParser::SetNodeAttribute(doc, reactivePower,
"UnitID",
static_cast<int>(m_electricalData.reactivePowerUnit));
453 auto loadType = XMLParser::AppendNode(doc, electricalProp,
"LoadType");
454 XMLParser::SetNodeValue(doc, loadType, m_electricalData.loadType);
456 auto stability = XMLParser::AppendNode(doc, electricalProp,
"Stability");
457 auto plotLoad = XMLParser::AppendNode(doc, stability,
"PlotLoad");
458 XMLParser::SetNodeValue(doc, plotLoad, m_electricalData.plotLoad);
459 auto useCompLoad = XMLParser::AppendNode(doc, stability,
"UseCompositeLoad");
460 XMLParser::SetNodeValue(doc, useCompLoad, m_electricalData.useCompLoad);
461 auto activePowerCompl = XMLParser::AppendNode(doc, stability,
"ActivePowerComposition");
462 auto pzl = XMLParser::AppendNode(doc, activePowerCompl,
"ConstantImpedance");
463 XMLParser::SetNodeValue(doc, pzl, m_electricalData.constImpedanceActive);
464 auto pil = XMLParser::AppendNode(doc, activePowerCompl,
"ConstantCurrent");
465 XMLParser::SetNodeValue(doc, pil, m_electricalData.constCurrentActive);
466 auto ppl = XMLParser::AppendNode(doc, activePowerCompl,
"ConstantPower");
467 XMLParser::SetNodeValue(doc, ppl, m_electricalData.constPowerActive);
468 auto reactivePowerCompl = XMLParser::AppendNode(doc, stability,
"ReactivePowerComposition");
469 auto qzl = XMLParser::AppendNode(doc, reactivePowerCompl,
"ConstantImpedance");
470 XMLParser::SetNodeValue(doc, qzl, m_electricalData.constImpedanceReactive);
471 auto qil = XMLParser::AppendNode(doc, reactivePowerCompl,
"ConstantCurrent");
472 XMLParser::SetNodeValue(doc, qil, m_electricalData.constCurrentReactive);
473 auto qpl = XMLParser::AppendNode(doc, reactivePowerCompl,
"ConstantPower");
474 XMLParser::SetNodeValue(doc, qpl, m_electricalData.constPowerReactive);
476 SaveSwitchingData(doc, electricalProp);
481bool Load::OpenElement(rapidxml::xml_node<>* elementNode, std::vector<Element*> parentList)
483 if (!OpenCADProperties(elementNode, parentList))
return false;
485 m_triangPts.push_back(wxPoint2DDouble(-m_width / 2.0, -m_height / 2.0));
486 m_triangPts.push_back(wxPoint2DDouble(m_width / 2.0, -m_height / 2.0));
487 m_triangPts.push_back(wxPoint2DDouble(0.0, m_height / 2.0));
489 auto electricalProp = elementNode->first_node(
"ElectricalProperties");
490 if (!electricalProp)
return false;
492 SetOnline(XMLParser::GetNodeValueInt(electricalProp,
"IsOnline"));
493 m_electricalData.name = electricalProp->first_node(
"Name")->value();
494 m_electricalData.activePower = XMLParser::GetNodeValueDouble(electricalProp,
"ActivePower");
495 m_electricalData.activePowerUnit =
496 static_cast<ElectricalUnit>(XMLParser::GetAttributeValueInt(electricalProp,
"ActivePower",
"UnitID"));
497 m_electricalData.reactivePower = XMLParser::GetNodeValueDouble(electricalProp,
"ReactivePower");
498 m_electricalData.reactivePowerUnit =
499 static_cast<ElectricalUnit>(XMLParser::GetAttributeValueInt(electricalProp,
"ReactivePower",
"UnitID"));
500 m_electricalData.loadType =
static_cast<LoadType
>(XMLParser::GetNodeValueInt(electricalProp,
"LoadType"));
502 auto stability = electricalProp->first_node(
"Stability");
504 m_electricalData.plotLoad = XMLParser::GetNodeValueInt(stability,
"PlotLoad");
505 m_electricalData.useCompLoad = XMLParser::GetNodeValueInt(stability,
"UseCompositeLoad");
506 auto activePowerComp = stability->first_node(
"ActivePowerComposition");
507 m_electricalData.constImpedanceActive = XMLParser::GetNodeValueDouble(activePowerComp,
"ConstantImpedance");
508 m_electricalData.constCurrentActive = XMLParser::GetNodeValueDouble(activePowerComp,
"ConstantCurrent");
509 m_electricalData.constPowerActive = XMLParser::GetNodeValueDouble(activePowerComp,
"ConstantPower");
510 auto reactivePowerComp = stability->first_node(
"ReactivePowerComposition");
511 m_electricalData.constImpedanceReactive = XMLParser::GetNodeValueDouble(reactivePowerComp,
"ConstantImpedance");
512 m_electricalData.constCurrentReactive = XMLParser::GetNodeValueDouble(reactivePowerComp,
"ConstantCurrent");
513 m_electricalData.constPowerReactive = XMLParser::GetNodeValueDouble(reactivePowerComp,
"ConstantPower");
516 if (!OpenSwitchingData(electricalProp))
return false;
ElectricalUnit
Electrical units.
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 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 void DrawDCTriangle(std::vector< wxPoint2DDouble > points, wxGraphicsContext *gc) const
Draw rectangle.
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.
Loas shunt power element.
virtual wxString GetTipText() const
Get the tip text.
virtual bool GetContextMenu(wxMenu &menu)
Get the element contex menu.
virtual Element * GetCopy()
Get a the element copy.
virtual void Rotate(bool clockwise=true)
Rotate the element.
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 bool AddParent(Element *parent, wxPoint2DDouble position)
Add a parent to the element. This method must be used on power elements that connect to a bus,...
virtual void DrawDC(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 DrawDCSwitches(wxGraphicsContext *gc) const
Draw switch.
virtual void UpdateSwitches()
Update the switch position.
virtual void DrawDCPowerFlowPts(wxGraphicsContext *gc) const
Draw power flow arrows.
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